#Exchange 2010 mailbox delegate management module
#v1.3.5 9/9/13
#1.3.5 Changed Send-As function to work in EMS
#1.3.4 Changed default access to use FMA instead of impersonation
#Paths to EWS Managed API DLL
$ewsAPIPaths = "C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll",
"C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll",
"C:\Program Files\Microsoft\Exchange\Web Services\1.1\Microsoft.Exchange.WebServices.dll",
"C:\Program Files\Microsoft\Exchange\Web Services\1.0\Microsoft.Exchange.WebServices.dll"
#Test if any version of API is installed before loading module functions
foreach ($path in $ewsAPIPaths)
{
if (Test-Path $path)
{
Add-Type -Path $path
$apiFound = $true
break
}
}
if (-not($apiFound))
{
Write-Error "The Exchange Web Services Managed API is required to use this module." -Category NotInstalled
break
}
function Get-ExchangeServerName
{
$configNC = ([ADSI]"LDAP://RootDse").configurationNamingContext
$search = New-Object DirectoryServices.DirectorySearcher([ADSI]"LDAP://$configNC")
$search.Filter = "(&(objectClass=msExchExchangeServer)(versionNumber>=1937801568))"
$search.PageSize=1000
$search.PropertiesToLoad.Clear()
[void] $search.PropertiesToLoad.Add("networkaddress")
$search.FindAll()
}
function Get-ServerFqdnFromNetworkAddress($server)
{
$server.properties["networkaddress"] |
Where-Object {$_.ToString().StartsWith("ncacn_ip_tcp")} | ForEach-Object {$_.ToString().SubString(13)}
}
function Connect-ExchangeServer($server)
{
try
{
Import-PSSession (New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "http://$server/powershell" -Name 'RemoteExchange') -AllowClobber -DisableNameChecking -ErrorAction Stop | Out-Null
$true
}
catch
{
$false
}
}
function Connect-RemoteExchangeServer
{
$exchangeServers = Get-ExchangeServerName
$serverFQDN = $exchangeServers | ForEach-Object {Get-ServerFqdnFromNetworkAddress $_}
#Loop through servers until connection is successful
for ($i = 0; $i -lt $serverFQDN.Length; $i++)
{
$attemptResult = Connect-ExchangeServer $serverFQDN[$i]
if ($attemptResult)
{break}
}
if ($attemptResult)
{$true}
else
{$false}
}
#Test for Exchange cmdlets before loading any module functions
$testcmd = Get-Command Get-Mailbox -ErrorAction SilentlyContinue
if (-not($testcmd))
{
$connectResult = Connect-RemoteExchangeServer
if (-not($connectResult))
{
Write-Error "Unable to connect to any Exchange server." -Category ConnectionError
break
}
}
#Region Helper Functions
function Connect-WebServices ($smtpAddress)
{
$exchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2
$global:exchangeService = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($exchangeVersion)
#Use autodiscover instead of hard-coded URL
$exchangeService.AutodiscoverUrl($smtpAddress)
#Impersonate mailbox
#$exchangeService.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $smtpAddress)
New-Object Microsoft.Exchange.WebServices.Data.Mailbox($smtpAddress)
}
function Find-Mailbox ($identity)
{
try
{
Get-Mailbox $identity -ErrorAction Stop
}
catch
{
Write-Progress 'Done' -Completed -Status " "
Write-Error "A mailbox cannot be found that matches the input string $identity." -ErrorAction Stop -Category ObjectNotFound
}
}
function Get-SID($acl)
{
$aSID = @()
$acl | ForEach-Object {
$adUser = [System.Security.Principal.NTAccount]($_.User.ToString())
$aSID += $adUser.Translate([System.Security.Principal.SecurityIdentifier]).Value
}
$aSID
}
function Get-FMA($identity)
{
Get-MailboxPermission $identity | Where-Object {$_.IsInherited -eq $false -and $_.User -notlike 'S-1-5-21*'}
}
function Get-SendAs($identity)
{
Get-ADPermission $identity | Where-Object {$_.IsInherited -eq $false -and $_.ExtendedRights -like '*Send-As*'}
}
function Get-FolderPermission($mailbox,$folder)
{
Get-MailboxFolderPermission "$mailbox`:\$folder"
}
function Set-FolderPermission($owner,$delegate,$folder,$role)
{
$folderPerm = Get-FolderPermission $owner.Identity $folder
[array]$delegateFolderPerm = $folderPerm | Where-Object {$_.User -eq $delegate.DisplayName}
#Run appropriate cmdlet based on delegate presence in ACL
if ($delegateFolderPerm.Count -eq 1)
{
try
{
Set-MailboxFolderPermission -Identity "$($owner.Identity):\$folder" -User $delegate.Identity -AccessRights $role -ErrorAction Stop | Out-Null
}
catch
{
$false
}
}
else
{
try
{
Add-MailboxFolderPermission -Identity "$($owner.Identity):\$folder" -User $delegate.Identity -AccessRights $role -ErrorAction Stop | Out-Null
}
catch
{
$false
}
}
}
function Convert-StringPermissionToEnum($role)
{
switch ($role)
{
'Reviewer' {[Microsoft.Exchange.WebServices.Data.DelegateFolderPermissionLevel]::Reviewer}
'Author' {[Microsoft.Exchange.WebServices.Data.DelegateFolderPermissionLevel]::Author}
'Editor' {[Microsoft.Exchange.WebServices.Data.DelegateFolderPermissionLevel]::Editor}
'None' {[Microsoft.Exchange.WebServices.Data.DelegateFolderPermissionLevel]::None}
}
}
function Convert-StringDeliveryScopeToEnum($scope)
{
switch ($scope)
{
'DelegatesOnly' {[Microsoft.Exchange.WebServices.Data.MeetingRequestsDeliveryScope]::DelegatesOnly}
'DelegatesAndOwner' {[Microsoft.Exchange.WebServices.Data.MeetingRequestsDeliveryScope]::DelegatesAndMe}
'DelegatesAndInfoToOwner' {[Microsoft.Exchange.WebServices.Data.MeetingRequestsDeliveryScope]::DelegatesAndSendInformationToMe}
}
}
#EndRegion
#Region Main Functions
function Add-MailboxDelegate
{
<#
.Synopsis
Add a mailbox as a delegate of an owner's mailbox.
.Description
Add a mailbox delegate, optionally specifying permission to various folders,
whether private items are viewable by the delegate, and if the delegate should receive
meeting requests for the owner.
.Parameter Owner
Identity string of the user whose mailbox is to have the delegate.
.Parameter Delegate
Identity string of the user who is to be added to owner's mailbox.
.Parameter InboxPermission
Role to assign to the Inbox folder. Valid roles are Reviewer, Author, and Editor.
.Parameter CalendarPermission
Role to assign to the Calendar folder. Valid roles are Reviewer, Author, and Editor.
.Parameter TasksPermission
Role to assign to the Tasks folder. Valid roles are Reviewer, Author, and Editor.
.Parameter ContactsPermission
Role to assign to the Contacts folder. Valid roles are Reviewer, Author, and Editor.
.Parameter SentItemsPermission
Role to assign to the Sent Items folder. Valid roles are Reviewer, Author, and Editor.
.Parameter DeletedItemsPermission
Role to assign to the Deleted Items folder. Valid roles are Reviewer, Author, and Editor.
.Parameter ViewPrivateItems
Enable the delegate to view items marked as private.
.Parameter ReceiveMeetingRequests
Enable the delegate to receive meeting requests for the owner.
.Parameter MeetingRequestDeliveryScope
Specify how meeting requests should be handled for the owner. Valid scopes are DelegatesOnly,
DelegatesAndOwner, and DelegatesAndInfoToOwner. Note that this parameter applies to all delegates.
.Example
Add-MailboxDelegate Username DelegateUsername -InboxPermission Editor -CalendarPermission Editor -ViewPrivateItems
.Example
Add-MailboxDelegate -Owner domain\username -Delegate -CalendarPermission Editor -ReceiveMeetingRequests
.Notes
Version: 1.01
Date: 3/5/13
#>
[CmdletBinding()]
param (
[Parameter(Position=0,Mandatory=$true)][Alias("Manager")][string]$Owner,
[Parameter(Position=1,Mandatory=$true)][string]$Delegate,
[ValidateSet('Reviewer','Author','Editor')][string]$InboxPermission,
[ValidateSet('Reviewer','Author','Editor')][string]$CalendarPermission,
[ValidateSet('Reviewer','Author','Editor')][string]$TasksPermission,
[ValidateSet('Reviewer','Author','Editor')][string]$ContactsPermission,
[ValidateSet('Reviewer','Author','Editor')][string]$SentItemsPermission,
[ValidateSet('Reviewer','Author','Editor')][string]$DeletedItemsPermission,
[Alias("PI")][switch]$ViewPrivateItems,
[Alias("MR")][switch]$ReceiveMeetingRequests,
[ValidateSet('DelegatesOnly','DelegatesAndOwner','DelegatesAndInfoToOwner')][string]$MeetingRequestDeliveryScope
)
#Validate mailboxes
Write-Progress -Activity "Adding Mailbox Delegate" -Status "Validating owner and delegate mailboxes" -PercentComplete 0
$mbOwner = Find-Mailbox $Owner
$mbDelegate = Find-Mailbox $Delegate
$ownerFirstName = (Get-User $mbOwner.Identity).FirstName
$ownerLastName = (Get-User $mbOwner.Identity).LastName
$delegateFirstName = (Get-User $mbDelegate.Identity).FirstName
$delegateLastName = (Get-User $mbDelegate.Identity).LastName
#Get EWS mailbox reference
Write-Progress -Activity "Adding Mailbox Delegate" -Status "Connecting to EWS" -PercentComplete 25
$EWSMailbox = Connect-WebServices $mbOwner.PrimarySMTPAddress.ToString()
#Get collection of delegates, without folder permissions
Write-Progress -Activity "Adding Mailbox Delegate" -Status "Retrieving existing delegates" -PercentComplete 50
$currentDelegates = $exchangeService.GetDelegates($EWSMailbox,$false)
#Check if user is already a delegate
if ($currentDelegates.DelegateUserResponses.Count -gt 0)
{
foreach ($currentDelegate in $currentDelegates.DelegateUserResponses)
{
if ($currentDelegate.DelegateUser.UserId.PrimarySMTPAddress -eq $mbDelegate.PrimarySMTPAddress.ToString())
{
Write-Progress -Activity "Adding Mailbox Delegate" -Completed -Status " "
Write-Host "$delegateFirstName $delegateLastName is already a delegate of $ownerFirstName $ownerLastName. Use Set-MailboxDelegate to update an existing delegate."
return
}
}
}
Write-Progress -Activity "Adding Mailbox Delegate" -Status "Adding delegate" -PercentComplete 75
#Create EWS delegate object
$delegateUser = New-Object Microsoft.Exchange.WebServices.Data.DelegateUser($mbDelegate.PrimarySMTPAddress.ToString())
#Set private items
if ($ViewPrivateItems)
{
$delegateUser.ViewPrivateItems = $true
}
#Set meeting request receipt
if ($ReceiveMeetingRequests)
{
$delegateUser.ReceiveCopiesOfMeetingMessages = $true
}
#Set permissions on folders
if ($InboxPermission)
{
$delegateUser.Permissions.InboxFolderPermissionLevel = Convert-StringPermissionToEnum $InboxPermission
}
if ($CalendarPermission)
{
$delegateUser.Permissions.CalendarFolderPermissionLevel = Convert-StringPermissionToEnum $CalendarPermission
}
if ($TasksPermission)
{
$delegateUser.Permissions.TasksFolderPermissionLevel = Convert-StringPermissionToEnum $TasksPermission
}
if ($ContactsPermission)
{
$delegateUser.Permissions.ContactsFolderPermissionLevel = Convert-StringPermissionToEnum $ContactsPermission
}
if ($SentItemsPermission)
{
$SIPermResponse = Set-FolderPermission $mbOwner $mbDelegate 'Sent Items' $SentItemsPermission
}
if ($DeletedItemsPermission)
{
$DIPermResponse = Set-FolderPermission $mbOwner $mbDelegate 'Deleted Items' $DeletedItemsPermission
}
#Build delegate collection object to use in EWS method
$delegateArray = New-Object Microsoft.Exchange.WebServices.Data.DelegateUser[] 1
$delegateArray[0] = $delegateUser
#Set new meeting request delivery scope if specified
if ($MeetingRequestDeliveryScope)
{
$addResponse = $exchangeService.AddDelegates($EWSMailbox, (Convert-StringDeliveryScopeToEnum $MeetingRequestDeliveryScope), $delegateArray)
}
else
{
$addResponse = $exchangeService.AddDelegates($EWSMailbox, $null, $delegateArray)
}
Write-Progress -Activity "Adding Mailbox Delegate" -Completed -Status " "
if ($addResponse[0].Result -eq [Microsoft.Exchange.WebServices.Data.ServiceResult]::Success)
{
Write-Host "$delegateFirstName $delegateLastName has been added as a delegate of $ownerFirstName $ownerLastName." -ForegroundColor Green
if ($SIPermResponse -eq $false)
{
Write-Host "An error occurred adding the delegate permission to the Sent Items folder." -ForegroundColor Yellow
}
if ($DIPermResponse -eq $false)
{
Write-Host "An error occurred adding the delegate permission to the Deleted Items folder." -ForegroundColor Yellow
}
}
else
{
Write-Host "An error occurred adding $delegateFirstName $delegateLastName as a delegate of $ownerFirstName $ownerLastName." -ForegroundColor Red
}
}
function Set-MailboxDelegate
{
<#
.Synopsis
Update the settings for an existing delegate of an owner's mailbox.
.Description
Update an existing mailbox delegate, specifying any changes to folder permissions,
whether private items are viewable by the delegate, or if the delegate should receive
meeting requests for the owner.
.Parameter Owner
Identity string of the user whose mailbox has the delegate.
.Parameter Delegate
Identity string of the user whose delegate settings are to be updated.
.Parameter InboxPermission
Role to assign to the Inbox folder. Valid roles are Reviewer, Author, Editor, and None.
.Parameter CalendarPermission
Role to assign to the Calendar folder. Valid roles are Reviewer, Author, Editor, and None.
.Parameter TasksPermission
Role to assign to the Tasks folder. Valid roles are Reviewer, Author, Editor, and None.
.Parameter ContactsPermission
Role to assign to the Contacts folder. Valid roles are Reviewer, Author, Editor, and None.
.Parameter SentItemsPermission
Role to assign to the Sent Items folder. Valid roles are Reviewer, Author, Editor, and None.
.Parameter DeletedItemsPermission
Role to assign to the Deleted Items folder. Valid roles are Reviewer, Author, Editor, and None.
.Parameter ViewPrivateItems
Enable the delegate to view items marked as private.
.Parameter ReceiveMeetingRequests
Enable the delegate to receive meeting requests for the owner.
.Parameter MeetingRequestDeliveryScope
Specify how meeting requests should be handled for the owner. Valid scopes are DelegatesOnly,
DelegatesAndOwner, and DelegatesAndInfoToOwner. Note that this parameter applies to all delegates.
.Example
Set-MailboxDelegate Username DelegateUsername -InboxPermission Editor -CalendarPermission Editor -ViewPrivateItems
.Example
Set-MailboxDelegate -Owner domain\username -Delegate -CalendarPermission Editor -ReceiveMeetingRequests
.Notes
Version: 1.01
Date: 3/5/13
#>
[CmdletBinding()]
param (
[Parameter(Position=0,Mandatory=$true)][Alias("Manager")][string]$Owner,
[Parameter(Position=1,Mandatory=$true)][string]$Delegate,
[ValidateSet('Reviewer','Author','Editor','None')][string]$InboxPermission,
[ValidateSet('Reviewer','Author','Editor','None')][string]$CalendarPermission,
[ValidateSet('Reviewer','Author','Editor','None')][string]$TasksPermission,
[ValidateSet('Reviewer','Author','Editor','None')][string]$ContactsPermission,
[ValidateSet('Reviewer','Author','Editor','None')][string]$SentItemsPermission,
[ValidateSet('Reviewer','Author','Editor','None')][string]$DeletedItemsPermission,
[Alias("PI")][switch]$ViewPrivateItems,
[Alias("MR")][switch]$ReceiveMeetingRequests,
[ValidateSet('DelegatesOnly','DelegatesAndOwner','DelegatesAndInfoToOwner')][string]$MeetingRequestDeliveryScope
)
#Validate mailboxes
Write-Progress -Activity "Updating Mailbox Delegate" -Status "Validating owner and delegate mailboxes" -PercentComplete 0
$mbOwner = Find-Mailbox $Owner
$mbDelegate = Find-Mailbox $Delegate
$ownerFirstName = (Get-User $mbOwner.Identity).FirstName
$ownerLastName = (Get-User $mbOwner.Identity).LastName
$delegateFirstName = (Get-User $mbDelegate.Identity).FirstName
$delegateLastName = (Get-User $mbDelegate.Identity).LastName
#Get EWS mailbox reference
Write-Progress -Activity "Updating Mailbox Delegate" -Status "Connecting to EWS" -PercentComplete 25
$EWSMailbox = Connect-WebServices $mbOwner.PrimarySMTPAddress.ToString()
#Get collection of delegates, with folder permissions
Write-Progress -Activity "Updating Mailbox Delegate" -Status "Retrieving existing delegates" -PercentComplete 50
$currentDelegates = $exchangeService.GetDelegates($EWSMailbox,$true)
#Confirm user is already a delegate
$delegateMatch = $false
if ($currentDelegates.DelegateUserResponses.Count -eq 0)
{
Write-Progress -Activity "Updating Mailbox Delegate" -Completed -Status " "
Write-Host "$ownerFirstName $ownerLastName does not have any delegates. `
Use Add-MailboxDelegate to add a new delegate."
return
}
elseif ($currentDelegates.DelegateUserResponses.Count -gt 0)
{
foreach ($currentDelegate in $currentDelegates.DelegateUserResponses)
{
if ($currentDelegate.DelegateUser.UserId.PrimarySMTPAddress -eq $mbDelegate.PrimarySMTPAddress.ToString())
{
#Modify existing delegate object instead of creating new one so existing settings
#can be preserved
$delegateUser = $currentDelegate.DelegateUser
$delegateMatch = $true
}
}
if (-not($delegateMatch))
{
Write-Progress -Activity "Updating Mailbox Delegate" -Completed -Status " "
Write-Host "$delegateFirstName $delegateLastName is not a delegate of $ownerFirstName $ownerLastName. Use Add-MailboxDelegate to add a new delegate."
return
}
}
Write-Progress -Activity "Updating Mailbox Delegate" -Status "Updating delegate" -PercentComplete 75
#Set private items if included
if ($MyInvocation.BoundParameters.ContainsKey('ViewPrivateItems'))
{
$delegateUser.ViewPrivateItems = $ViewPrivateItems
}
#Set meeting request receipt if included
if ($MyInvocation.BoundParameters.ContainsKey('ReceiveMeetingRequests'))
{
$delegateUser.ReceiveCopiesOfMeetingMessages = $ReceiveMeetingRequests
}
#Set permissions on folders
if ($InboxPermission)
{
$delegateUser.Permissions.InboxFolderPermissionLevel = Convert-StringPermissionToEnum $InboxPermission
}
if ($CalendarPermission)
{
$delegateUser.Permissions.CalendarFolderPermissionLevel = Convert-StringPermissionToEnum $CalendarPermission
}
if ($TasksPermission)
{
$delegateUser.Permissions.TasksFolderPermissionLevel = Convert-StringPermissionToEnum $TasksPermission
}
if ($ContactsPermission)
{
$delegateUser.Permissions.ContactsFolderPermissionLevel = Convert-StringPermissionToEnum $ContactsPermission
}
if ($SentItemsPermission)
{
$SIPermResponse = Set-FolderPermission $mbOwner $mbDelegate 'Sent Items' $SentItemsPermission
}
if ($DeletedItemsPermission)
{
$DIPermResponse = Set-FolderPermission $mbOwner $mbDelegate 'Deleted Items' $DeletedItemsPermission
}
#Build delegate collection object to use in EWS method
$delegateArray = New-Object Microsoft.Exchange.WebServices.Data.DelegateUser[] 1
$delegateArray[0] = $delegateUser
#Set new meeting request delivery scope if specified
if ($MeetingRequestDeliveryScope)
{
$updateResponse = $exchangeService.UpdateDelegates($EWSMailbox, (Convert-StringDeliveryScopeToEnum $MeetingRequestDeliveryScope), $delegateArray)
}
else
{
$updateResponse = $exchangeService.UpdateDelegates($EWSMailbox, $null, $delegateArray)
}
Write-Progress -Activity "Updating Mailbox Delegate" -Completed -Status " "
if ($updateResponse[0].Result -eq [Microsoft.Exchange.WebServices.Data.ServiceResult]::Success)
{
Write-Host "$delegateFirstName $delegateLastName has been updated as a delegate of $ownerFirstName $ownerLastName." -ForegroundColor Green
if ($SIPermResponse -eq $false)
{
Write-Host "An error occurred adding the delegate permission to the Sent Items folder." -ForegroundColor Yellow
}
if ($DIPermResponse -eq $false)
{
Write-Host "An error occurred adding the delegate permission to the Deleted Items folder." -ForegroundColor Yellow
}
}
else
{
Write-Host "An error occurred updating $delegateFirstName $delegateLastName as a delegate of $ownerFirstName $ownerLastName." -ForegroundColor Red
}
}
function Remove-MailboxDelegate
{
<#
.Synopsis
Remove a delegate from an owner's mailbox.
.Description
Remove a supplied mailbox delegate from a supplied owner's mailbox.
.Parameter Owner
Identity string of the user whose mailbox has the delegate.
.Parameter Delegate
Identity string of the user who is to be removed from the owner's mailbox.
.Example
Remove-MailboxDelegate user@domain.com delegate@domain.com
.Example
Remove-MailboxDelegate -Owner domain\username -Delegate
.Notes
Version: 1.01
Date: 3/5/13
#>
[CmdletBinding()]
param (
[Parameter(Position=0,Mandatory=$true)][Alias("Manager")][string]$Owner,
[Parameter(Position=1,Mandatory=$true)][string]$Delegate
)
#Validate mailboxes
Write-Progress -Activity "Removing Mailbox Delegate" -Status "Validating owner and delegate mailboxes" -PercentComplete 0
$mbOwner = Find-Mailbox $Owner
$mbDelegate = Find-Mailbox $Delegate
$ownerFirstName = (Get-User $mbOwner.Identity).FirstName
$ownerLastName = (Get-User $mbOwner.Identity).LastName
$delegateFirstName = (Get-User $mbDelegate.Identity).FirstName
$delegateLastName = (Get-User $mbDelegate.Identity).LastName
#Get EWS mailbox reference
Write-Progress -Activity "Removing Mailbox Delegate" -Status "Connecting to EWS" -PercentComplete 25
$EWSMailbox = Connect-WebServices $mbOwner.PrimarySMTPAddress.ToString()
#Get collection of delegates, without folder permissions
Write-Progress -Activity "Removing Mailbox Delegate" -Status "Retrieving delegates" -PercentComplete 50
$currentDelegates = $exchangeService.GetDelegates($EWSMailbox,$false)
if ($currentDelegates.DelegateUserResponses.Count -eq 0)
{
Write-Progress -Activity "Removing Mailbox Delegate" -Completed -Status " "
Write-Host $ownerFirstName $ownerLastName "does not have any delegates."
}
else
{
$delegateToRemove = @()
$delegateMatch = $false
Write-Progress -Activity "Removing Mailbox Delegate" -Status "Removing delegate" -PercentComplete 75
foreach ($currentDelegate in $currentDelegates.DelegateUserResponses)
{
if ($currentDelegate.DelegateUser.UserId.PrimarySMTPAddress -eq $mbDelegate.PrimarySMTPAddress.ToString())
{
#Add userid object to collection of delegates to remove
$delegateToRemove += $currentDelegate.DelegateUser.UserId
$delegateMatch = $true
}
}
if (-not($delegateMatch))
{
Write-Progress -Activity "Removing Mailbox Delegate" -Completed -Status " "
Write-Host $mbDelegate.PrimarySMTPAddress "is not a delegate of" $mbOwner.PrimarySMTPAddress "."
}
else
{
#Remove delegate from owner's mailbox
$removeResponse = $exchangeService.RemoveDelegates($EWSMailbox, $delegateToRemove)
Write-Progress -Activity "Removing Mailbox Delegate" -Completed -Status " "
if ($removeResponse[0].Result -eq [Microsoft.Exchange.WebServices.Data.ServiceResult]::Success)
{
Write-Host "$delegateFirstName $delegateLastName has been removed as a delegate of $ownerFirstName $ownerLastName." -ForegroundColor Green
}
else
{
Write-Host "An error occurred removing $delegateFirstName $delegateLastName as a delegate of $ownerFirstName $ownerLastName." -ForegroundColor Red
}
}
}
}
function Get-MailboxDelegate
{
<# .Synopsis Display a mailbox's delegates and permissions. .Description Retrieve the list of delegates for a mailbox and display the mailbox permission, folder permissions, meeting invite settings, and (optionally) whether the delegate has Send As permission. .Parameter Identity Identity string of the user whose mailbox has the delegates. Owner and Manager are valid aliases for this parameter. .Parameter Delegate Identity string of the delegate you want to retrieve. If omitted, all delegates are retrieved. .Parameter IncludeSendAs Switch to indicate that you want Send As permission to be included. .Example Get-MailboxDelegate user@domain.com -includesendas .Example Get-MailboxDelegate domain\username .Notes Version: 1.7 Date: 3/12/13 #>
param (
[Parameter(Position=0,Mandatory=$true,HelpMessage="Identity of mailbox owner",ValueFromPipelineByPropertyName=$true)]
[Alias("Owner")][Alias("Manager")][string]$Identity,
[Parameter(Position=1)][string]$Delegate,
[Alias("SA")][switch]$includeSendAs #Perform Send As lookup (takes longer)
)
process
{
#Validate owner mailbox
Write-Progress -Activity "Getting Mailbox Delegate" -Status "Validating owner mailbox" -PercentComplete 0
$mbOwner = Find-Mailbox $Identity
#Validate delegate mailbox
if ($Delegate)
{
Write-Progress -Activity "Getting Mailbox Delegate" -Status "Validating delegate mailbox" -PercentComplete 5
$mbDelegate = Find-Mailbox $Delegate
$delegateFirstName = (Get-User $mbDelegate.Identity).FirstName
$delegateLastName = (Get-User $mbDelegate.Identity).LastName
}
$ownerFirstName = (Get-User $mbOwner.Identity).FirstName
$ownerLastName = (Get-User $mbOwner.Identity).LastName
#Get EWS mailbox reference
Write-Progress -Activity "Getting Mailbox Delegate" -Status "Connecting to EWS" -PercentComplete 10
$EWSMailbox = Connect-WebServices $mbOwner.PrimarySMTPAddress.ToString()
#Get list of delegates and permissions from EWS
Write-Progress -Activity "Getting Mailbox Delegate" -Status "Retrieving delegates" -PercentComplete 20
#Get collection of delegates, with folder permissions
if ($mbDelegate)
{
#Retrieve only the specified delegate
$delegateUser = New-Object Microsoft.Exchange.WebServices.Data.UserId($mbDelegate.PrimarySMTPAddress.ToString())
$delegateArray = New-Object Microsoft.Exchange.WebServices.Data.UserId[] 1
$delegateArray[0] = $delegateUser
$currentDelegates = $exchangeService.GetDelegates($EWSMailbox,$true,$delegateArray)
}
else
{
$currentDelegates = $exchangeService.GetDelegates($EWSMailbox,$true)
}
#Get list of users with full mailbox access
Write-Progress -Activity "Getting Mailbox Delegate" -Status "Retrieving FMA list" -PercentComplete 40
$fullMailboxAccess = Get-FMA $mbOwner.Identity
$fmaSID = Get-SID $fullMailboxAccess #Convert username to SID
#Get list of users with Send As permission from AD
if ($includeSendAs)
{
Write-Progress -Activity "Getting Mailbox Delegate" -Status "Retrieving Send As List" -CurrentOperation "(This part takes the longest.)" -PercentComplete 70
$sendAs = Get-SendAs $mbOwner.Identity
$saSID = Get-SID $sendAs #Convert username to SID
}
#Get permissions for additional folders
Write-Progress -Activity "Getting Mailbox Delegate" -Status "Retrieving additional folder permissions" -PercentComplete 90
$deletedItemsPerm = Get-FolderPermission $mbOwner.Identity 'Deleted Items'
$sentItemsPerm = Get-FolderPermission $mbOwner.Identity 'Sent Items'
Write-Progress -Activity "Getting Mailbox Delegate" -Completed -Status " "
#Build output
$outputArr = New-Object System.Collections.ArrayList
#Loop through list of delegates
if ($currentDelegates.DelegateUserResponses.Count -gt 0)
{
if ($mbDelegate -and $currentDelegates.DelegateUserResponses[0].ErrorCode -eq 'ErrorNotDelegate')
{
Write-Host "$delegateFirstName $delegateLastName is not a delegate of $ownerFirstName $ownerLastName."
}
else
{
$currentDelegates.DelegateUserResponses | ForEach-Object {
#Create custom object with property names
$outputItem = "" | Select-Object Owner,Delegate,MeetingHandling,FMA,SendAs,Calendar,Inbox,Contacts,Tasks,DeletedItems,SentItems,ReceiveMeetings,ViewPrivate,Error,ErrorNote
$outputItem.Owner = $mbOwner.DisplayName
$outputItem.MeetingHandling = $currentDelegates.MeetingRequestsDeliveryScope
if ($_.ErrorMessage -eq 'The delegate does not map to a user in the Active Directory.')
{#Delegate account deleted in AD but still listed in list
$outputItem.Error = "Orphan"
$outputItem.ErrorNote = "Check NON_IPM_SUBTREE\Freebusy Data\LocalFreebusy.eml property 0x684A101E to determine orphan entry."
}
elseif ($_.ErrorMessage -eq 'Delegate is not configured properly.')
{
$outputItem.Error = "Misconfigured"
$outputItem.ErrorNote = "Missing from Freebusy Data folder or publicDelegates attribute."
}
elseif ($_.Result -eq 'Error')
{
$outputItem.Error = "UnknownError"
$outputItem.ErrorNote = $_.ErrorMessage
}
else
{
$delegateDisplayName = $_.delegateuser.userid.displayname
$outputItem.Delegate = $delegateDisplayName
if ($fmaSID -match $_.delegateuser.UserId.SID)
{
$outputItem.FMA = $true
}
else
{
$outputItem.FMA = $false
}
if ($includeSendAs)
{
if ($saSID -match $_.delegateuser.UserId.SID)
{
$outputItem.SendAs = $true
}
else
{
$outputItem.SendAs = $false
}
}
$outputItem.Calendar = $_.DelegateUser.Permissions.CalendarFolderPermissionLevel.ToString()
$outputItem.Inbox = $_.DelegateUser.Permissions.InboxFolderPermissionLevel.ToString()
$outputItem.Contacts = $_.DelegateUser.Permissions.ContactsFolderPermissionLevel.ToString()
$outputItem.Tasks = $_.DelegateUser.Permissions.TasksFolderPermissionLevel.ToString()
#Construct Deleted Items permission output
[array]$delegateDIPerm = $deletedItemsPerm | Where-Object {$_.User -eq $delegateDisplayName}
if ($delegateDIPerm.Count -eq 1)
{
$delegateDIPermValue = $delegateDIPerm[0].AccessRights[0].ToString()
}
else
{
$delegateDIPermValue = 'None'
}
$outputItem.DeletedItems = $delegateDIPermValue
#Construct Sent Items permission output
[array]$delegateSIPerm = $sentItemsPerm | Where-Object {$_.User -eq $delegateDisplayName}
if ($delegateSIPerm.Count -eq 1)
{
$delegateSIPermValue = $delegateSIPerm[0].AccessRights[0].ToString()
}
else
{
$delegateSIPermValue = 'None'
}
$outputItem.SentItems = $delegateSIPermValue
$outputItem.ReceiveMeetings = $_.delegateuser.receivecopiesofmeetingmessages
$outputItem.ViewPrivate = $_.delegateuser.viewprivateitems
$outputArr.Add($outputItem) | Out-Null
}
}
}
}
else
{
Write-Host "$ownerFirstName $ownerLastName has no delegates."
}
$outputArr
}
}
#EndRegion
Set-Alias amd Add-MailboxDelegate
Set-Alias smd Set-MailboxDelegate
Set-Alias rmd Remove-MailboxDelegate
Set-Alias gmd Get-MailboxDelegate
Export-ModuleMember -Function *-MailboxDelegate
Export-ModuleMember -Alias *