Thursday, June 07, 2012

How To Series Sample 7 : Reverse Delegate Permissions and Rights Report

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

  1. ## EWS Managed API Connect Module Script written by Glen Scales  
  2. ## Requires the EWS Managed API and Powershell V2.0 or greator  
  3. $rptArray = New-Object System.Collections.ArrayList  
  4. ## Load Managed API dll  
  5. Add-Type -Path "C:\Program Files\Microsoft\Exchange\Web Services\1.1\Microsoft.Exchange.WebServices.dll"  
  7. ## Set Exchange Version  
  8. $ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP1  
  10. ## Create Exchange Service Object  
  11. $service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($ExchangeVersion)  
  13. ## Set Credentials to use two options are availible Option1 to use explict credentials or Option 2 use the Default (logged On) credentials  
  15. #Credentials Option 1 using UPN for the windows Account  
  16. $psCred = Get-Credential  
  17. $creds = New-Object System.Net.NetworkCredential($psCred.UserName.ToString(),$psCred.GetNetworkCredential().password.ToString())  
  18. $service.Credentials = $creds      
  20. #Credentials Option 2  
  21. #service.UseDefaultCredentials = $true  
  23. ## Choose to ignore any SSL Warning issues caused by Self Signed Certificates  
  25. [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}  
  29. function CovertBitValue($String){  
  30.     $numItempattern = '(?=\().*(?=bytes)'  
  31.     $matchedItemsNumber = [regex]::matches($String$numItempattern)   
  32.     $Mb = [INT64]$matchedItemsNumber[0].Value.Replace("(","").Replace(",","")  
  33.     return [math]::round($Mb/1048576,0)  
  34. }  
  37. Get-Mailbox -ResultSize Unlimited | ForEach-Object{   
  38.     $MailboxName = $_.PrimarySMTPAddress.ToString()  
  39.     "Processing Mailbox : " + $MailboxName  
  40.     if($service.url -eq $null){  
  41.         ## 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  
  43.         #CAS URL Option 1 Autodiscover  
  44.         $service.AutodiscoverUrl($MailboxName,{$true})  
  45.         "Using CAS Server : " + $Service.url   
  47.         #CAS URL Option 2 Hardcoded  
  48.         #$uri=[system.URI] "https://casservername/ews/exchange.asmx"  
  49.         #$service.Url = $uri    
  50.     }  
  52.     $service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $MailboxName)  
  53.     $delegates = $service.getdelegates($MailboxName,$true)    
  54.     foreach($Delegate in $delegates.DelegateUserResponses){    
  55.         $rptObj = "" | select Delegate,Mailbox,Inbox,Calendar,Contacts,Tasks,Notes,Journal,MeetingMessages,ViewPrivateItems    
  56.         $rptObj.Mailbox = $MailboxName  
  57.         $rptObj.Delegate = $Delegate.DelegateUser.UserId.PrimarySmtpAddress    
  58.         $rptObj.Inbox = $Delegate.DelegateUser.Permissions.InboxFolderPermissionLevel    
  59.         $rptObj.Calendar = $Delegate.DelegateUser.Permissions.CalendarFolderPermissionLevel    
  60.         $rptObj.Contacts = $Delegate.DelegateUser.Permissions.ContactsFolderPermissionLevel    
  61.         $rptObj.Tasks = $Delegate.DelegateUser.Permissions.TasksFolderPermissionLevel    
  62.         $rptObj.Notes = $Delegate.DelegateUser.Permissions.NotesFolderPermissionLevel    
  63.         $rptObj.Journal = $Delegate.DelegateUser.Permissions.JournalFolderPermissionLevel    
  64.         $rptObj.ViewPrivateItems = $Delegate.DelegateUser.ViewPrivateItems    
  65.         $rptObj.MeetingMessages = $Delegate.DelegateUser.ReceiveCopiesOfMeetingMessages   
  66.         [Void]$rptArray.Add($rptObj)  
  68.     }    
  69. }  
  70. $rptArray | Sort-Object Delegate | Export-Csv -Path c:\temp\ReverseDelegateReport.csv -NoTypeInformation  


Anonymous said...

Hi Glen. Pretty impressed with your skill level here in scripts and ideas. I am having trouble making this script work. Is there any special permissions one needs to run this? I had to change the path that points to the Microsoft.Exchange.WebServices.dll file, and each time its reporting an error as below. I dont have full domain admin rights unfortunately only Local Account Operators but also belong to the Organization Management group as well.

I added the lines below to get around lack of permissions but to no avail.
#$ErrorActionPreference = 'SilentlyContinue'
The error received is as below.

Processing Mailbox :
Using CAS Server :
ForEach-Object : Exception calling "GetDelegates" with "3" argument(s): "The account does not have permission to impers
onate the requested user."
At C:\admin\scripts\delegateews.ps1:40 char:77
+ Get-Mailbox -ResultSize Unlimited | ForEach-Object <<<< {
+ CategoryInfo : NotSpecified: (:) [ForEach-Object], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException,Microsoft.PowerShell.Commands.ForEachObjectCommand

Can you please assist?



Glen Scales said...

The script requires the user your using to have impersonation rights granted through RBAC see


Frank said...

Hi Glen

I am trying to get this to work on my server and I am getting 2 errors at the end.

Unexpected token 'in' in expression or statement.
+ CategoryInfo :
+ FullyQualifiedErrorId : UnexpectedToken

Otherwise the script runs clean. I do not get any output either.

I am using the 2.0 version of the EWS API so I changed the line in the script to reflect that.

I am not great at scripting so perhaps I am not executing this right.

As far as I can see there is no other script or packaged report out there that does this type of report and would very much like to make this work.

If you can please let me know if you can help me.