The script expands on part 5 of the how to series and produces a reverse permission report of the delegates of all Mailboxes on a server or within a Exchange Org or Exchange Online tenant. This is to help show for a particular delegate what mailboxes that they have been given delegate rights to and if they can see private Items and do they receive Meeting forwards. This script is designed to be run from within a Remote Powershell session
that is already connected to your Exchange 2010 org (or from a Exchange
Online/Office365 remote Powershell session).
It uses Get-Mailbox to get all the mailboxes in your org and then it uses the EWS Managed API to connect to each mailbox and query the delegates. It then produces a CSV file that looks like
If you want to understand how it works have a read of the How To Series posts and hopefully you should be able to work out how to customize it if you need to for your own environment. The Script as posted uses EWS Impersonation
If you want to customize which mailboxes it reports on then just change the Get-Mailbox line
Get-Mailbox -ResultSize Unlimited | ForEach-Object{
eg if you want to limit to only checking one server you could use
Get-Mailbox -ResultSize Unlimited -Server servernameblah | ForEach-Object{
You could do similar with other filter properties such as Database or OU
I've posted a downloadable copy of the script here the script itself look like
It uses Get-Mailbox to get all the mailboxes in your org and then it uses the EWS Managed API to connect to each mailbox and query the delegates. It then produces a CSV file that looks like
If you want to understand how it works have a read of the How To Series posts and hopefully you should be able to work out how to customize it if you need to for your own environment. The Script as posted uses EWS Impersonation
If you want to customize which mailboxes it reports on then just change the Get-Mailbox line
Get-Mailbox -ResultSize Unlimited | ForEach-Object{
eg if you want to limit to only checking one server you could use
Get-Mailbox -ResultSize Unlimited -Server servernameblah | ForEach-Object{
You could do similar with other filter properties such as Database or OU
I've posted a downloadable copy of the script here the script itself look like
- ## EWS Managed API Connect Module Script written by Glen Scales
- ## Requires the EWS Managed API and Powershell V2.0 or greator
- $rptArray = New-Object System.Collections.ArrayList
- ## Load Managed API dll
- Add-Type -Path "C:\Program Files\Microsoft\Exchange\Web Services\1.1\Microsoft.Exchange.WebServices.dll"
- ## Set Exchange Version
- $ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP1
- ## Create Exchange Service Object
- $service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($ExchangeVersion)
- ## Set Credentials to use two options are availible Option1 to use explict credentials or Option 2 use the Default (logged On) credentials
- #Credentials Option 1 using UPN for the windows Account
- $psCred = Get-Credential
- $creds = New-Object System.Net.NetworkCredential($psCred.UserName.ToString(),$psCred.GetNetworkCredential().password.ToString())
- $service.Credentials = $creds
- #Credentials Option 2
- #service.UseDefaultCredentials = $true
- ## Choose to ignore any SSL Warning issues caused by Self Signed Certificates
- [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
- function CovertBitValue($String){
- $numItempattern = '(?=\().*(?=bytes)'
- $matchedItemsNumber = [regex]::matches($String, $numItempattern)
- $Mb = [INT64]$matchedItemsNumber[0].Value.Replace("(","").Replace(",","")
- return [math]::round($Mb/1048576,0)
- }
- Get-Mailbox -ResultSize Unlimited | ForEach-Object{
- $MailboxName = $_.PrimarySMTPAddress.ToString()
- "Processing Mailbox : " + $MailboxName
- if($service.url -eq $null){
- ## Set the URL of the CAS (Client Access Server) to use two options are availbe to use Autodiscover to find the CAS URL or Hardcode the CAS to use
- #CAS URL Option 1 Autodiscover
- $service.AutodiscoverUrl($MailboxName,{$true})
- "Using CAS Server : " + $Service.url
- #CAS URL Option 2 Hardcoded
- #$uri=[system.URI] "https://casservername/ews/exchange.asmx"
- #$service.Url = $uri
- }
- $service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $MailboxName)
- $delegates = $service.getdelegates($MailboxName,$true)
- foreach($Delegate in $delegates.DelegateUserResponses){
- $rptObj = "" | select Delegate,Mailbox,Inbox,Calendar,Contacts,Tasks,Notes,Journal,MeetingMessages,ViewPrivateItems
- $rptObj.Mailbox = $MailboxName
- $rptObj.Delegate = $Delegate.DelegateUser.UserId.PrimarySmtpAddress
- $rptObj.Inbox = $Delegate.DelegateUser.Permissions.InboxFolderPermissionLevel
- $rptObj.Calendar = $Delegate.DelegateUser.Permissions.CalendarFolderPermissionLevel
- $rptObj.Contacts = $Delegate.DelegateUser.Permissions.ContactsFolderPermissionLevel
- $rptObj.Tasks = $Delegate.DelegateUser.Permissions.TasksFolderPermissionLevel
- $rptObj.Notes = $Delegate.DelegateUser.Permissions.NotesFolderPermissionLevel
- $rptObj.Journal = $Delegate.DelegateUser.Permissions.JournalFolderPermissionLevel
- $rptObj.ViewPrivateItems = $Delegate.DelegateUser.ViewPrivateItems
- $rptObj.MeetingMessages = $Delegate.DelegateUser.ReceiveCopiesOfMeetingMessages
- [Void]$rptArray.Add($rptObj)
- }
- }
- $rptArray | Sort-Object Delegate | Export-Csv -Path c:\temp\ReverseDelegateReport.csv -NoTypeInformation