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:
-
This cmdlet will return all exchange specific cmdlets
Get-command -name get-service –synopsis
Get-excommand
-
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 “*@ratishnair.com”}
This cmdlet will retrieve all messages from the domain “ratishnair.com”
-
The tilde character (~) represents the shortcut to root directory. For example,
Dir ~
Use it as a shortcut:
Cp FileName “~\My Documents” -
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]
-
-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.
-
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*” }
-
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
-
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 }
-
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
-
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:
Get-Alias
-
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.
-
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
-
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>
-
This one returns the list of all devices synchronized with a user’s mailbox:
Get-ActiveSyncDeviceStatistics
A variety of information is returned including device name, operating system, and last sync time.
-
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*
-
This one gets a list of all users who are Unified Messaging-enabled type, use:
Get-UmMailbox | ForEach { If($_.UmEnabled -Eq $True){$_.Name}}
-
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 “ratishnair.com Configuration” -DomainName ratishnair.com
Then modify the properties that you want for this remote domain by using the Set-RemoteDomain cmdlet:
Set-RemoteDomain ” ratishnair.com Configuration” -AutoReplyEnabled $True -AutoForwardEnabled $True
-
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 sunder@msexchangeguru.com
Set-CASMailbox sunder@msexchangeguru.com-OWAEnabled:$False
-
Move-Mailbox of all users from server EXCH1 to server EXCH2 as follows:
Get-Mailbox -Server EXCH1 | Move-Mailbox -TargetDatabase EXCH2
-
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.
February 25th, 2011 at 7:25 am
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
February 25th, 2011 at 7:43 am
[…] This post was mentioned on Twitter by Jeffery Hicks, Ratish Sekharan Nair. Ratish Sekharan Nair said: Exchange Powershell cmdlets – Tips and know-how: http://lnkd.in/CDxAjq […]
February 25th, 2011 at 7:53 am
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!
February 25th, 2011 at 8:30 am
Hi Jeffery,
Im adding your inputs right away… Thanks.
Ratish Nair
February 25th, 2011 at 10:01 am
As a counterpoint to Jeffery’s comments, I use frequently use the |% {$_.name} 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.
February 25th, 2011 at 11:58 am
Nice work Ratish. I’ve been looking something similar.
Cheers. Tim
February 25th, 2011 at 1:08 pm
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 $_.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.
February 27th, 2011 at 4:08 am
An added reference from me here: http://windowsadmin.info/viewtopic.php?f=20&t=116
February 27th, 2011 at 12:59 pm
Very nice post, Ratish!
February 1st, 2012 at 6:55 am
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.
NOTE:
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
Regards,
Chandrakala
February 2nd, 2012 at 1:45 am
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.
NOTE:
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
Regards,
Chandrakala
May 30th, 2012 at 9:18 am
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.
May 30th, 2012 at 9:39 am
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
June 21st, 2012 at 5:34 pm
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.
September 21st, 2012 at 9:32 am
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).
October 6th, 2012 at 5:20 pm
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: http://www.prosupport.dk/exchange-2010-powershell-cmdlets-reference-database
December 3rd, 2012 at 5:53 am
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?
December 3rd, 2012 at 1:41 pm
he wants to access all mailboxes on one mailstore only?
December 5th, 2012 at 7:06 am
Yes, just to read them
December 5th, 2012 at 7:06 am
sorry mailbox
January 17th, 2013 at 3:28 pm
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:
-IncludeRecipientInfo
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 Contoso.com 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.
March 19th, 2014 at 1:31 pm
[…] Exchange Powershell cmdlets – Tips and know-how « MSExchangeGuru.com. […]
May 27th, 2014 at 7:36 am
Hi,
Can you tell me how do we get Display name of Database.
Regards,
Raj
May 30th, 2014 at 11:49 am
@Raj
Running the below command will give you all the properties of the DB.
Get-mailboxdatabase | FL
October 9th, 2014 at 9:31 am
Hi,
I need to get the send as permission of shared mail boxes in specific active directory domain.
How do we do it
November 5th, 2014 at 7:02 pm
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
December 4th, 2014 at 8:31 pm
how to get a list of hidden users with their department
February 11th, 2015 at 2:19 pm
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.
M.
March 3rd, 2015 at 1:04 pm
Hi,
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?
March 13th, 2015 at 3:23 pm
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?
Thanks,
Steve
May 7th, 2015 at 4:05 am
I would suggest to export into CSV and sort by any column.
August 3rd, 2015 at 6:02 pm
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.
September 4th, 2015 at 4:16 am
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.
thank
September 8th, 2015 at 11:43 pm
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
September 9th, 2015 at 3:08 am
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.
October 8th, 2015 at 8:43 am
Dears,
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
October 9th, 2015 at 1:28 am
Simply Run the below command and you will get all details.
Get-mailbox mailboxname | fl
October 11th, 2015 at 1:22 am
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
October 11th, 2015 at 4:31 am
which website is better to get all Poewer shell cmd
October 12th, 2015 at 5:26 am
Microsoft Technet
November 19th, 2016 at 10:41 pm
Hello.This article was really interesting, particularly
because I was searching for thoughts on this topic last Saturday.