Learn Exchange the Guru way !!!


Exchange Powershell cmdlets – Tips and know-how

I thought of listing down some powershell cmdlets tips which I thought useful.

I would start by this:

  1. This cmdlet will return all exchange specific cmdlets

    Get-command -name get-service –synopsis


  2. Get-Help is another one which comes handy. Say, while you were playing with Exchange management shell, you saw a new cmdlet and don’t know what that means.

    For example, you don’t know what Get-Message means. To know more, type

    Get-Help Get-Message

    Get-Message is a cmdlet to retrieve messages from the message queue in Exchange 2007 and 2010

    An example is,

    Get-Message -Filter {FromAddress -like “*”}

    This cmdlet will retrieve all messages from the domain “”

  3. The tilde character (~) represents the shortcut to root directory. For example, 

    Dir ~
    Use it as a shortcut:
    Cp FileName “~\My Documents”

  4. We see the $_ sign in a lot of cmdlets. This is known as a Special Variable.

    The $_ represents the objects being passed from one cmdlet to another cmdlet in the pipeline. The $_ variable is automatically initiated by the shell and is bound to the current pipeline object. You can access the properties of the object assigned to the $_ variable as you would any other object.

    The following example shows how you can view the Name property of each mailbox object
    that is passed through the pipeline:

    Get-Mailbox | ForEach { $_.Name }

    If you need another example, this one lists all running services on an Exchange server

    Get-Service | where {$_.Status -eq “Running”}

    Lets take a look at another one. This one returns the name of the smallest database:

    (Get-MailboxDatabase | foreach { get-childitem $_.edbFilePath | select-object name,length} | sort -property length )[0]

  5. -FILTER and –LIKE commands are often used together. This will filter the information in Double quotes and look for data matching info in Single quotes

    Again, easy when explained with an example:

    Get-Mailbox –RESULTSIZE UNLIMITED -FILTER “Displayname –Like ‘Nair, Ratish'”

    So, this cmdlet is going to get mailbox information where the result will be unlimited and will filter information to ensure only the one with Displayname ‘Nair, Ratish’ is returned.

  6. You can access the event log from the Exchange Management Shell. To retrieve the whole event log, run:

    Get-EventLog Application | Format-List

    To retrieve all Exchange-related events, run:

    Get-EventLog Application | Where { $_.Source -Ilike “*Exchange*” }

  7. Any cmdlet that accepts a size value lets you specify whether the integer value is in kilobytes (KB), megabytes (MB), gigabytes (GB), or terabytes (TB). For example:

    Set-Mailbox “Meera Nair” -ProhibitSendQuota 200MB

  8. You can import CSV files and treat them as objects by using the Import-Csv cmdlet. Each row in a CSV file becomes an element in an array, and each column becomes a property. You can assign the CSV file to a variable or you can pipe its contents directly to another cmdlet. In the following example, there are three columns in the CSV file, Name, Alias and EmailAddress, with several rows that the For Each cmdlet will cycle through. The data in each row is used to create a new mail contact.

    Import-Csv | ForEach { New-MailContact -Name $_.Name -Alias $_.Alias -ExternalEmailAddress $_.EmailAddress -OrganizationalUnit Users }

  9. The Exchange Management Shell can log all the Exchange-related commands that modify objects in some way. Exchange-related command activity is logged to the PowerShell event log. To enable Exchange-related command logging, run the following command:

    Set-ItemProperty HKLM:\SOFTWARE\Microsoft\PowerShell\1\PowerShellSnapIns\Microsoft.Exchange.Management.PowerShell.Admin -Name LogpipelineExecutionDetails -value 1

  10. This one is one of my favourites – Set-Alias

    Say you want to have an Alias for Get-StorageGroup, just type

    Set-Alias GetSg Get-StorageGroup

    From now, Get-StorageGroup cmdlet will have an alias Get-Sg

    For all the current aliases, type:


  11. This one is not exactly a powershell cmdlet tip. This works in command prompt too. CTRL+C will hard-break command in the Exchange Management Shell. If a command is taking too long to run or you want to cancel an operation quickly, press CTRL+C to stop execution.
  12. When some or a group of users complain that they cannot access their mailbox, check the mounted status of all mailbox databases? Type:

    Get-MailboxDatabase -Status | Format-Table Name, Server, Mounted

  13. This one checks the permissions an Active Directory user account has on a specific mailbox? Use:

    Get-Mailbox <Mailbox to Check> | Get-MailboxPermission -User <Active Directory User>

  14. This one returns the list of all devices synchronized with a user’s mailbox:

    A variety of information is returned including device name, operating system, and last sync time.

  15. This one returns the list of the backup status of all mailbox databases in your organization? Type:

    Get-MailboxDatabase -Status | Format-Table Name, Server, *Backup*

    How about just the mailboxes on a specific server? Type:

    Get-MailboxDatabase -Server <Server Name> -Status | Format-Table Name, *Backup*

  16. This one gets a list of all users who are Unified Messaging-enabled type, use:

    Get-UmMailbox | ForEach { If($_.UmEnabled -Eq $True){$_.Name}}

  17. This one will help you control the properties of e-mail messages sent to a specific domain using the RemoteDomain cmdlet.

    Create a new remote domain by using the New-RemoteDomain cmdlet. Type:

    New-RemoteDomain -Name “ Configuration” -DomainName

    Then modify the properties that you want for this remote domain by using the Set-RemoteDomain cmdlet:

    Set-RemoteDomain ” Configuration” -AutoReplyEnabled $True -AutoForwardEnabled $True

  18. Control which features are available to Outlook Web Access users by using the Set-OwaVirtualDirectory cmdlet. Type:

    Set-OwaVirtualDirectory “OWA (Default Web Site)” -ContactsEnabled $True -ChangePasswordEnabled $True

    This one will disable Outlook web access for the user


  19. Move-Mailbox of all users from server EXCH1 to server EXCH2 as follows:

    Get-Mailbox -Server EXCH1 | Move-Mailbox -TargetDatabase EXCH2

  20. The .count parameter is a good one. This helps to count the output (number of mailboxes) in a cmdlet like the one shown below:

    <Get-Mailbox –Server EXCH1 –Resultsize unlimited>.count


UPDATE from Jeffery Hicks (Windows PowerShell MVP)

Good list, although I might suggest a few revisions to make them even more PowerShell like and take advantage of the pipeline.

This command (point 4):

Get-Mailbox | ForEach { $_.Name }

works and generates a nice list which is great if you wanted to save it to a text file:

Get-Mailbox | ForEach { $_.Name } | out-file Mailboxes.txt.

But to get just that property all you need is

Select-Object: Get-MailBox | Select Name

I would also suggest that this (Point 16):

Get-UmMailbox | ForEach { If($_.UmEnabled -Eq $True){$_.Name}} is more complicated than it needs to be. This is more efficient.

Get-Mailbox | where {$_.UMEnabled} | Select Name


Thank you Jeff….

Ratish Nair
MVP Exchange
Team@ MSExchangeGuru

Keywords: Exchange powershell tips, learn powershell, exchange management shell, exchange poweshell cmdlets.

41 Responses to “Exchange Powershell cmdlets – Tips and know-how”

  1. Jeffery Hicks Says:

    Good list, although I might suggest a few revisions to make them even more PowerShell like and take advantage of the pipeline. This command:

    Get-Mailbox | ForEach { $_.Name }

    works and generates a nice list which is great if you wanted to save it to a text file. Get-Mailbox | ForEach { $_.Name } | out-file Mailboxes.txt. But to get just that property all you need is Select-Object: Get-MailBox | Select Name

    I would also suggest that this: Get-UmMailbox | ForEach { If($_.UmEnabled -Eq $True){$_.Name}} is more complicated than it needs to be. This is more efficient.

    Get-Mailbox | where {$_.UMEnabled} | Select Name

    Jeffery Hicks
    Windows PowerShell MVP

  2. Tweets that mention Exchange Powershell cmdlets – Tips and know-how « -- Says:

    […] This post was mentioned on Twitter by Jeffery Hicks, Ratish Sekharan Nair. Ratish Sekharan Nair said: Exchange Powershell cmdlets – Tips and know-how: […]

  3. anita Says:

    This is super cool stuff! pretty nice to read,relate and indeed use it 🙂
    Your website seems to be a very credible resource and would be extremely beneficial to all out here..
    Thank you for your time, effort, and the work you have done, we look forward to any thoughts you may have Ratish…. Great work!

  4. Ratish Sekhar Says:

    Hi Jeffery,

    Im adding your inputs right away… Thanks.

    Ratish Nair

  5. Rob Campbell Says:

    As a counterpoint to Jeffery’s comments, I use frequently use the |% {$} convention instead of | select name in scripts when I’m only after a single property of an object.

    As Jeffery notes, it makes a nice text list. The advantage to writing scripts that pass names down the pipeline in this manner instead of as an object property is that it then becomes much easier to convert those scripts for use when you want to re-use them for situations where you need to put that same script to use using input that is being given to you in that form. Speaking as an Exchange/AD administrator this is not an uncommon situation.

  6. Tim Says:

    Nice work Ratish. I’ve been looking something similar.

    Cheers. Tim

  7. Jeffery Hicks Says:

    Granted I haven’t looked at the many of the Exchange cmdlets deeply, but if they take advantage of pipeline binding, then all you need is the object with the right property name. For example, take a cmdlet Get-Foo that writes a Widget object to the pipeline. One of the properties is Name. We also have a Set-Foo cmdlet to modify the widget object using a -Name parameter. If this parameter accepts pipelined input then all I need to do is run Get-Foo | Set-Foo -something 123. The -Name parameter will use the name property of the incoming object. The alternative, which works but isn’t as elegant is something like: Get-Foo | foreach {Set-Foo -name $ -something 123}. If you write advanced functions and scripts you can duplicate this behavior, which is what I encourage. The more you can avoid parsing text, the better. That said, whatever works for you is great.

  8. Manu Says:

    An added reference from me here:

  9. Milind Naphade Says:

    Very nice post, Ratish!

  10. Chandrakala S Says:

    Hi All,

    Please let me knwo the powershell copmmand to change the Alias name for the given list of users as per the requirement in exchange2010.
    1. I have the list of users for whome the Alias name has to be chnaged in CSV file
    2. I have the new Alisa names for the list of users in CSV file


  11. Chandrakala S Says:

    Hi All,

    Please let me know the powershell command to change the Alias name for the given list of users as per the requirement in exchange2010.
    1. I have the list of users for whom the Alias name has to be changed in CSV file
    2. Also I have the new Alias names for the list of users in CSV file


  12. jim sullivan Says:

    ok you powershell gurus.
    how about a shell command to give me all the email accounts (exchange 2010 sp1)where the display name does not equal the alias.

  13. Ratish Sekhar Says:

    I know its possible but how about you dump all details and then play with Excel to get matching values in column !!!

    =IF(A1=B1,”Match”,”NO Match”)

    $AdminSessionADSettings.ViewEntireForest = $True
    Get-Mailbox -ResultSize Unlimited | Ft Displayname, Alias

  14. Michael yurchuk Says:

    is it possible to use powershell command to delete all messages older than X days manually, I don’t want to setup a retention policy, this is just a one time use.

  15. Dovid Says:

    Jim Sullivan,

    Get-Mailbox -ResultSize Unlimited | where {$_.Displayname -ne $_.Alias}

    I find it interesting that you consider this an exception. Displayname is usually the user’s full name possibly with “notes,” while alias is typically the same as the username (login ID).

  16. Kasper Says:

    Very nice. The Get-Excommand is quite nice. If you do like this: Get-ExCommand | Get-Help > c:\Exchange2010cmdlets.txt you can get the same, including help text for each command.

    You can find a database with all the commands and their help text with a good search engine:

  17. Dan Says:

    Ok Guys, I need help with a Powersell command. I have a user who needs read only ,under the Radar access to another mailstore. Any ideas?

  18. Ratish Sekhar Says:

    he wants to access all mailboxes on one mailstore only?

  19. Dan Says:

    Yes, just to read them

  20. Dan Says:

    sorry mailbox

  21. KirkB Says:

    We sent out a legit mass mailing and about 2% are in the queue awaiting retry at delivery. I assume this 2% represents email addresses that are obsolete. We’d like to export these and clean up our database but the get-message -IncludeRecipientInfo does not return the recipient (to) address. The shell Get-Help Get-Message -detailed states the following:
    The IncludeRecipientInfo parameter specifies whether to display the message recipients in the Recipients field.
    If you don’t include the IncludeRecipientInfo parameter, the Recipients field is blank.
    Storing the results of a Get-Message -IncludeRecipientInfo command in a variable allows you to display addition
    al properties for the message recipients. The following list describes the available recipient properties:
    * Address The e-mail address of the recipient.
    * Type The recipient type, which may be External, Mailbox, or Distribution Group. Distribution Group is used
    when the destination is an expansion server.
    * FinalDestination The distinguished name (DN) of the object used to route the message. The object could be a
    connector, a Mailbox server, or an expansion server.
    * Status The recipient status may be Complete, Ready, or Retry.
    * LastError The SMTP response after the last delivery attempt or a localized error message if the message is
    placed in the unreachable queue.
    For example, to store the recipient information of a message in the remote delivery queue that has
    the MessageIdentity value of 1234 to a variable named $x, use the following command.
    To display the extended recipient properties that are now stored in the $x variable, use the following command.

    Can anyone help with the code for the variable and command implementation. I would think this is a pretty universal requirement.

  22. Exchange Powershell cmdlets – Tips and know-how « | Soyka's Blog Says:

    […] Exchange Powershell cmdlets – Tips and know-how « […]

  23. Rajendra Says:


    Can you tell me how do we get Display name of Database.


  24. Prabhat Nigam Says:

    Running the below command will give you all the properties of the DB.
    Get-mailboxdatabase | FL

  25. Shamnad Shaffi Says:


    I need to get the send as permission of shared mail boxes in specific active directory domain.
    How do we do it

  26. John_A Says:

    The below, lists the database name for each member of a given distribution list.

    Get-DistributionGroupMember -Identity distributiongroupname | sort | foreach {Get-Mailbox -Identity $_.Alias} | Select-Object DisplayName,Database

  27. Benny Says:

    how to get a list of hidden users with their department

  28. MIlton Lopez Says:

    Thanks for this useful list.

    How can the output of a cmdlet displaying a number properties be sorted by property name? For example “Get-MailboxDatabase | fl” lists all properties for each database, but the properties are not sorted by name, which makes the output harder to read. I’ve tried a few variations of ” | sort” and ” | sort-object ” without luck.


  29. Nitin Says:


    I am having trouble to get all user details using “Get-MailBox” cmdlet, it is returning only one record which is used for authentication. I have enabled windows authentication on powershell in IIS. This user has administrative rights on our domain.

    Is there any issue with access rights or authentication type?

  30. SJS Says:

    I have a csv file with a column for each Exchange Alias name user called “Alias” and another column called “ProhibitSendReceiveQuota”. I want to use that data to modify existing ProhibitSendReceiveQuota values to new values listed in the csv file. The csv file has multiple users with all different mailbox limits so I need to change each one to a different ProhibitSendReceiveQuota value using a bulk method.

    What Exchange Powershell command can do this?



  31. Prabhat Nigam Says:

    I would suggest to export into CSV and sort by any column.

  32. CharlesBoks Says:

    One of the first challenges with using PowerShell for Exchange Server management is knowing which commands to run for the task you want to perform.

  33. Faic Says:

    Hi PN:
    What’s the Powershell command to export (in csv) email address for mailboxes in a particular database in exch2013 server?

    Please let me know.

  34. Faic Says:

    Hi PN:
    New-MoveRequest -Identity ‘user1’ -TargetDatabase “DB2013”

    Iam using this above powershell command to migrate mailboxes okay for those users in one domain successfully, but when I want to migrate mailboxes for those users in another domain, it is giving the error msge “The operation couln’t be performed because object ‘user2’ couldn’t be found on domain1”. I have three domains and mailboxes for users where their user accounts are on another domains domain2 and domain3 are giving this error on the exchange 2013 powershell.

    What could be the powershell command to achieve this please?
    I have 400-550 users to migrate and very much appreciate your help.

    Many thanks

  35. Faic Says:

    Hi PN:

    Please appreciate if i can get a feedback on my post above dated sept 8th 2015 at 11:43pm.

    I urgently need your help please.

    thank you.

  36. Syed Nazar Says:


    I am very new for Power shell so i want to how to see that particular is in which database and what is his limit can you some one help me out

  37. Prabhat Nigam Says:

    Simply Run the below command and you will get all details.

    Get-mailbox mailboxname | fl

  38. Syed Nazar Says:

    thx. Prabhat i need another help how to migrate the mailbox to the new database in a bulk way for Eg. i need to 10 users mailbox to a new database any coding or script to move them at a time.

    can you help me

  39. Syed Nazar Says:

    which website is better to get all Poewer shell cmd

  40. Prabhat Nigam Says:

    Microsoft Technet

  41. Helen J. Brown Says:

    Hello.This article was really interesting, particularly
    because I was searching for thoughts on this topic last Saturday.

Leave a Reply

migrate exchange to office 365