The estimated reading time 5 minutes
Dealing with PowerShell is a great thing, especially if you have to administer a large and dynamic organization. Let’s spend some time to learn some default use cases lot of exchange admins have to do. In this article I’m showing a various combination of different PowerShell cmdlets, with special focus in the new Exchange Online cmdlets. You can do a much more crazy stuff, but I want to show some basics.
Enough blabla, lets go.
Installation of the new PowerShell Module is quite easy, just follow the instructions on this link.
Here are my commands to install, import and connect EX ON Module:
Install-Module -Name ExchangeOnlineManagement -Scope AllUsers -Verbose -Force Import-Module -Name ExchangeOnlineManagement -Verbose Get-Module ExchangeOnlineManagement $creds = Get-Credential Connect-ExchangeOnline -Credential $creds #Connect-ExchangeOnline -Credential $creds -ShowBanner:$false
After connecting (if you didn’t switch off) you see the new cmdlets in PowerShell console:
As you can see, most of the cmdlets are Get-commands, so the new version at the moment is for analysis. If you want to have an overview of all cmdlets included in this module, use this oneliner.
Get-Module ExchangeOnlineManagement | Select-Object ExportedCommands -ExpandProperty ExportedCommands
After this short introduction, what can we do with this set of cmdlets? Playing around with this new cmdlets
Get-EXONMailbox references
This cmdlet is used to get information about mailbox settings, see also propertysets described in this link.
#1. #find all mailboxes with "alex" in the following attributes: #CommonName (CN),DisplayName,FirstName,LastName,Alias Get-EXOMailbox -Anr alex #2. #using different propertysets to get special information Get-EXOMailbox -PropertySets Quota #combine different propertysets Get-EXOMailbox -PropertySets Quota,Delivery #combine different propertysets with individual properties Get-EXOMailbox -PropertySets Quota,Delivery -Properties EmailAddresses,RecipientTypeDetails #3. #find users with special attributes #find all shared mailboxes and their delivery options Get-EXOMailbox -PropertySets Delivery -Properties RecipientTypeDetails | Where-Object{$_.RecipientTypeDetails -eq "SharedMailbox"} | Sort-Object UserPrincipalName #find all usermailboxes with their delivery options Get-EXOMailbox -PropertySets Delivery -Properties RecipientTypeDetails | Where-Object{$_.RecipientTypeDetails -eq "UserMailbox"} | Sort-Object UserPrincipalName
Get-EXOCasMailbox
with “Get-EXOCasMailbox you can see for example the connections properties for your mailboxes (POP/IMAP/MAPI…), CAS = Client Access Service
Link to the propertysets
#1. #see all mailboxes with their cas settings Get-EXOCasMailbox #2. #see important information with different propertysets Get-EXOCasMailbox -PropertySets Minimum #see all mailboxes IMAP and POP settings Get-EXOCasMailbox -PropertySets Imap,pop #3. #see all users with POP enabled Get-EXOCasMailbox -PropertySets IMAP,POP | Where-Object {$_.PopEnabled -eq $true} #see all users with POP and IMAP enabled Get-EXOCasMailbox -PropertySets IMAP,POP | Where-Object {($_.PopEnabled -eq $true) -and ($_.ImapEnabled -eq $true)} #see all users OWA enabled Get-EXOCasMailbox -Properties OWAEnabled| Where-Object {$_.OWAEnabled -eq $true}
Get-EXOMailboxStatistics
With this cmdlet you are able to see sizes of all mailboxes
#see mailboxsize of special user #UPN,emailaddress,GUID are accepted parameters Get-EXOMailboxStatistics -Identity alexander Get-MailboxFolderStatistics -Identity alexander | ft Folderpath,FolderSize #see statistics of all users Get-EXOMailbox | Get-EXOMailboxStatistics #see statistics of all shared mailboxes Get-EXOMailbox | Where-Object{$_.RecipientTypeDetails -eq "SharedMailbox"} | Get-EXOMailboxStatistics #see detailed statistics of all users Get-EXOMailbox | Get-EXOMailboxStatistics -PropertySets All
Script to get biggest mailbox
$Mailboxstats = Get-EXOMailbox | Get-EXOMailboxStatistics $MailboxStats | Add-Member -MemberType ScriptProperty -Name TotalItemSizeInBytes -Value {$this.TotalItemSize -replace "(.*\()|,| [a-z]*\)", ""} $overview = $MailboxStats | Select-Object DisplayName, TotalItemSizeInBytes,@{Name="TotalItemSize (GB)"; Expression={[math]::Round($_.TotalItemSizeInBytes/1GB,2)}} | Sort-Object "TotalItemSize (GB)" -Descending $overview
Script to get all mailboxes bigger than…
#greaterthan value in GB and with "." as comma $greaterthan = "0.5" $Mailboxstats = Get-EXOMailbox | Get-EXOMailboxStatistics $MailboxStats | Add-Member -MemberType ScriptProperty -Name TotalItemSizeInBytes -Value {$this.TotalItemSize -replace "(.*\()|,| [a-z]*\)", ""} $overview = $MailboxStats | Select-Object DisplayName,TotalItemSizeInBytes,@{Name="TotalItemSizeInGB"; Expression={[math]::Round($_.TotalItemSizeInBytes/1GB,2)}} | Sort-Object "TotalItemSizeInGB" -Descending $overview | Where-Object {$_.TotalItemSizeInGB -gt "$greaterthan"}
Script to get all mailboxes and sum of all mailbox sizes
$Mailboxstats = Get-EXOMailbox -ResultSize unlimited | Get-EXOMailboxStatistics $MailboxStats | Add-Member -MemberType ScriptProperty -Name TotalItemSizeInBytes -Value {$this.TotalItemSize -replace "(.*\()|,| [a-z]*\)", ""} $overview = $MailboxStats | Select-Object DisplayName, TotalItemSizeInBytes,@{Name="TotalItemSizeInGB"; Expression={[math]::Round($_.TotalItemSizeInBytes/1GB,2)}} | Sort-Object "TotalItemSizeInGB" -Descending $sumtemp = ($overview | Measure-Object TotalItemSizeInGB -Sum).Sum $sum = $sumtemp.ToString() $sum = "Sum of all Mailboxes in GB: "+$sum+" GB" Write-Host "$sum" -ForegroundColor Yellow $overview
Get-EXOMailboxFolderPermission
Getting all permissions inside a mailbox
#1. #get special permission on one folder (need to know the foldername) Get-EXOMailboxFolderPermission -Identity alexander:\Inbox #2. #get folders from one mailbox with their permissions $email = "blablabla@it-koehler.com" $folders = (Get-EXOMailboxFolderStatistics -Identity $email) $perm = @() foreach($folder in $folders){# $fname = ($folder.Folderpath -replace '/','\') $foldername = $email +":" +$fname $temp = Get-EXOMailboxFolderPermission -Identity "$foldername" -ErrorAction SilentlyContinue | Select-Object Identity,User,AccessRights $perm += $temp } $perm | ft
Get-EXOMobileDeviceStatistics
Finding mobile devices connected with mailboxes
#1. #get all mobile devices of one mailbox Get-EXOMobileDeviceStatistics -Mailbox blablabla@it-koehler.com | ft DeviceFriendlyName,DeviceOS,DeviceID,DeviceImei,FirstSyncTime,LastSuccessSync #2. #get all users and show their mobile devices $UPN = (Get-EXOMailbox -ResultSize unlimited).Userprincipalname foreach($user in $UPN){ $mobiles = Get-EXOMobileDeviceStatistics -Mailbox $user -ErrorAction SilentlyContinue if($mobiles){ Write-Host "User: $user" -ForegroundColor Yellow $mobiles | ft DeviceFriendlyName,DeviceOS,DeviceID,DeviceImei,FirstSyncTime,LastSuccessSync } }
Disconnect-ExchangeOnline
Disconnect-ExchangeOnline -Confirm:$false
There are much more possibilities with these cmdlets, if you have any questions or did some scripting on your own, write me an comment or email, we can share it here. If you liked these lines, please click on helpful. Stay tuned.
[…] 50 entries can be defined per tenant! See the link AllowList.To enable the feature, a connection to Exchange Online PowerShell must be established.Initially, it can be checked whether the function is active within the […]
[…] Of course you can also do this via Exchange Online PowerShell Console. Exchange Online PowerShell tutorial […]
[…] It is also a feature which can be enabled as global config for all users with Exchange Online PowerShell. See further information about connecting and authentication with Exchange Online here. […]
[…] nur per Exchange Online PowerShell. Wer hierzu Infos zum Thema verbinden etc. benötigt kann sich folgenden Artikel […]
[…] of mailboxes you need a powershell connection to exchange online. If you have no idea see my tutorial for Exchange Online Powershell ModuleHere is a short summary for the lazy guys […]
Hello, I like the code and it works fine. But I am struggling finding out, how to read all messages from a folder (the “mails”) and how to send a message after I connected to exchange? Send-MailMessage does ignore the credentials. Any idea? 1000 thanks!
Hi Axel,
thanks for your comment. Let me explain first, you are not able to send messages via exchange online, just by connecting to remote powershell. This is only for managing your exchange online environment. There are some great articles which show you this kind of task:
Best regards
Alex
Many thanks for the kind reply and the great link. That explains a lot.
Hello,
I’m trying to use the ExchangeOnlineManagement module to manage mail flow rules on an outlook.com cloud exchange.
The get-transportrule cmdlet works ok.
Now I want to use new-transportrule to create new rules.
I’m hitting issues with “TypeNotFound” for the [IncidentReportContent] enum, and the [RecipientIdParameter] class.
I didn’t have Exchange Management Tools installed before, and I’ve installed them now.
Finally resolved the “TypeNotFound” by coding the following:
Import-Module -Name “C:\Program Files\Microsoft\Exchange Server\V15\Bin\Microsoft.Exchange.MessagingPolicies.Rules.dll”
Import-Module -Name “C:\Program Files\Microsoft\Exchange Server\V15\Bin\Microsoft.Exchange.Configuration.Core.dll”
Import-Module -Name “C:\Program Files\Microsoft\Exchange Server\V15\Bin\Microsoft.Exchange.Configuration.RedirectionModule.dll”
and then
using namespace Microsoft.Exchange.MessagingPolicies.Rules
using namespace Microsoft.Exchange.Configuration.Tasks
It’s taken a lot of digging to work this out, and I didn’t expect to have to manually import the dlls like that.
Still working on this, just posting to see if you had any advice?
Thanks
Simon
Hello Simon,
thanks for your advice. It may be easier to use the old way to connect to exchange.
$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
Import-PSSession $Session -DisableNameChecking
I think this kind of connection should do the trick.
Thanks for your comment.
Alexander
Hi A.K.
I’ve got a nicely working solution, let me share for future visitors. All that DLL loading was not necessary in the end.
The company I work for uses a mixture of legacy on-prem AD, and an in-cloud outlook.com Exchange.
The Sales Team requested some rules which will restrict particular domains to only the account managers responsible for those domains. The list of rules required numbered 100+.
This is what worked:
# This first line was the trick. To convert a regular PowerShell into an Exchange enabled PowerShell. This requires the Exchange Management Tools to have been installed.
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn
# Then a straight-forward O365 login to Exchange online
Connect-ExchangeOnline -UserPrincipalName admin@domain.com -ShowProgress $true
# Then the parameters for the rule to fence a customer’s domain:
$params = @{
‘Name’ = ‘Restrict Account – Widgets Inc’
‘FromMemberOf’ = @(
‘SalesTeam@domain.com’
)
‘RecipientDomainIs’ = @(
‘widgets.com’
)
‘ExceptIfFrom’ = @(
‘bossman@domain.com’
‘accountmanager@domain.com’
)
‘RejectMessageReasonText’ = ‘The Widgets account is managed by The Bossman. This email has been blocked.’
‘GenerateIncidentReport’ = ‘incidents@domain.com’
‘IncidentReportContent’ = @(
‘Sender’
‘Recipients’
‘Subject’
‘RuleDetections’
‘AttachOriginalMail’
)
‘Enabled’ = $True
}
New-TransportRule @params
Experimenting some more, this isn’t necessary:
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn
And now I’m not sure even the Exchange Management Tools are required! I went round in a number of circles trying to get this to work, and may have chased a few red-herrings, brought on by being new to Power Shell syntax.
Cheers!
Thanks for your comments, hope it will help other people.
Stay tuned.