PS: Create-Mailbox Folder Permission Report
This script creates a html or csv file based report. Each folder within a given mailbox gets displayed within a tree view (html version).
If there are permissions set to this specific folder they get displayed below the foldername. The user needs at least "Exchange View Only" admin rights inside the exchange organisation!
Example output:
- Permission report for: John Oliva(joliva@yourdomain.com)
- Calendar
- Contacts
- Conversation Action Settings
- Deleted Items
- Drafts
- Inbox
Keith Collins :: Reviewer
Jeff Plate :: Owner- Private Stuff
Keith Collins :: Reviewer
Jeff Plate :: Owner - Subfolder
- Subfolder1
Keith Collins :: Reviewer - Subfolder2
- Subfolder1
- Private Stuff
- Journal
- Junk E-Mail
- News Feed
- Notes
- Outbox
- Quick Step Settings
- RSS Feeds
- Sent Items
- Suggested Contacts
- Tasks
Requirements
- User need "Exchange view only" admin rights in the exchange organisation.
- Powershell that allows execution of scripts... [>>KB: 10101]
Usage
Examples with a single mailbox:
- EXAMPLE1:
Create a report for the user with the SAMAccountName "John Oliva" while connecting to exchange server
"msx.yourdomain.com" in your logged on users %userhome% drive:
.Create-MailboxFolderPermissionReport.ps1 -ExchangeServer msx.yourdomain.com -MailboxName "John Oliva" - EXAMPLE2:
Create a report for the user with the SAMAccountName "John Oliva" while connecting to exchange server
"msx.yourdomain.com" to the file: "C:reportsJohnOliva.html"
.Create-MailboxFolderPermissionReport.ps1 -ExchangeServer msx.yourdomain.com -MailboxName "John Oliva" -ReportName "C:reportsJohnOliva.html"
Examples in a pipe
- EXAMPLE3:
Create a report for all mailboxes within the Exchange organization while connecting to exchange server
"msx.yourdomain.com" to the file: "C:reportsAllPermissions.html"
(Get-Mailbox -resultsize unlimited) | .Create-MailboxFolderPermissionReport.ps1 -ExchangeServer msx.yourdomain.com -ReportName "C:reportsAllPermissions.html" -AppendReport $-true - EXAMPLE4:
Create a report for all ADDS users in a given organizational unit (OU) while connecting to exchange server
"msx.yourdomain.com" to the file: "C:reportsAllPermissions.html"
HINT: Users without exchange mailboxes will be displayed as ERROR. This is normal because no mailbox attributes can be used
Import-Mobule ActiveDirectory; Get-ADUser -SearchBase "ou=MyRockBand,dc=yourdomain,dc=com" -Filter * | .Create-MailboxFolderPermissionReport.ps1 -ExchangeServer msx.yourdomain.com -ReportName "C:reportsAllPermissions.html" -AppendReport
Parameters:
- ExchangeServer
[required] the fqdn name or IP address of your exchange server. The script uses this server for remote shell. - MailboxName
[required] this one can be Alias, Distinguished name (DN), GUID, Name, Display name, LegacyExchangeDN or Email address - ReportName
can be used to specify a report file name otherwise the default name will be used - HideDefaultPermissions
can be used if the default permissions should be displayed then set it to - HideMailboxOwner
can be used if the mailbox owners permissions should be display then set it to - AppendReport
If set to the report will append to an existing file (this is useful if you want to display all reports in one file when using the script in pipe - CreateCSVReport
Creates a csv file instead of the html report. - NoProgress
Disables the progress indicator while collecting permissions of mailbox folders
Version History:
- 1.0: Initial release
- 1.1: can also be executed within an existing Exchange Management Shell (EMS). It then does not open a remote shell to Exchange.
- 1.2: This version has some bug fixes and can now be executed in a Pipe so you can run the report for several mailboxes at on time (See EXAMPLE 3 and 4)
- 1.0.3: Changed license to MIT license
- 1.0.4: Removed Error when no Folder permission was definied on a mailbox folder
- 1.0.5: Error was thrown when a folder had no permission entry defined. This is now removed
- 1.1.8: Added the ability to create csv reports; Added progress indicator when collecting folder permissions; Bug fixes with errors getting displayed with default maolbox folder permissions in some situations.
Script code:
##------------------------------------------------------------------------------------------------
##
## Create-MailboxFolderPermissionReport.ps1
##
## Version 1.1.8
##
##
## Copyright (c) 2016 Martin Mueller - www.sh-soft.com
##
## Permission is hereby granted, free of charge, to any person obtaining a copy of this software
## and associated documentation files (the "Software"), to deal in the Software without
## restriction, including without limitation the rights to use, copy, modify, merge, publish,
## distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
## Software is furnished to do so, subject to the following conditions:
##
## The above copyright notice and this permission notice shall be included in all copies or
## substantial portions of the Software.
##
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
## BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
## NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
## DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
## FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
## (The MIT License (MIT))
##
##------------------------------------------------------------------------------------------------
<#
.SYNOPSIS
Creates a tree view report for permissions on individual mailbox folders.
Creates a csv permission report of mailbox folders
.DESCRIPTION
This script creates a html based report. Each folder within a given mailbox gets displayed within a tree view.
If there a permissions set to this specific folder they get displayed below the folder name.
In addition a csv report can be created. This one can be used with the script Set-MailboxFolderPermission
The user needs at least "Exchange View Only" admin rights inside the exchange organisation!
for mor information please go to www.sh-soft.com/en/scripting/ps/ps-create-mailboxfolderpermissionreport.html
HINT: you cannot use this script directly in pipeline with the Get-Mailbox commandlet! See Examples for a workaround...
.PARAMETER ExchangeServer
[required] the fqdn name or IP address of your exchange server. The script uses this server for remote shell.
.PARAMETER MailboxName
[required] this one can be Alias, Distinguished name (DN), GUID, Name, Display name, LegacyExchangeDN or Email address
.PARAMETER ReportName
can be used to specify a report file name otherwise the default name will be used
.PARAMETER HideDefaultPermissions
can be used if the default permissions should be displayed then set it to $false
.PARAMETER HideMailboxOwner
can be used if the mailbox owners permissions should be display then set it to $false
.PARAMETER AppendReport
If set to $true the report will append to an existing file (this is useful if you want to display all reports in one file when using the script in pipe
.PARAMETER CreateCSVReport
If set to $true the report created is in CSV format and not in html
.EXAMPLE
Create a report for the user with the SAMAccountName "John Oliva" while connecting to exchange server
"msx.yourdomain.com" in your logged on users %userhome% drive:
.\Create-MailboxFolderPermissionReport.ps1 -ExchangeServer msx.yourdomain.com -MailboxName "John Oliva"
.EXAMPLE
Create a report for the user with the SAMAccountName "John Oliva" while connecting to exchange server
"msx.yourdomain.com" to the file: "C:\reports\JohnOliva.html"
.\Create-MailboxFolderPermissionReport.ps1 -ExchangeServer msx.yourdomain.com -MailboxName "John Oliva" -ReportName "C:\reports\JohnOliva.html"
.EXAMPLE
Create a report for all mailboxes within the Exchange organization while connecting to exchange server
"msx.yourdomain.com" to the file: "C:\reports\AllPermissions.html"
$AllMailboxes = Get-Mailbox -resultsize unlimited; $AllMailboxes | .\Create-MailboxFolderPermissionReport.ps1 -ExchangeServer msx.yourdomain.com -ReportName "C:\reports\AllPermissions.html" -AppendReport $true
.EXAMPLE
Create a report for all ADDS users in a given organizational unit (OU) while connecting to exchange server
"msx.yourdomain.com" to the file: "C:\reports\AllPermissions.html"
HINT: Users without exchange mailboxes will be displayed as ERROR. This is normal because no mailbox attributes can be used
Import-Mobule ActiveDirectory; Get-ADUser -SearchBase "ou=MyRockBand,dc=yourdomain,dc=com" -Filter * | .\Create-MailboxFolderPermissionReport.ps1 -ExchangeServer msx.yourdomain.com -ReportName "C:\reports\AllPermissions.html" -AppendReport $true
#>
#------------------------------------------------------------------------------------------------
# Parameter block
#------------------------------------------------------------------------------------------------
param (
[Parameter(Mandatory=$true,HelpMessage='Exchange server to connect to',Position=0)]
[string]$ExchangeServer,
[Parameter(Mandatory=$true,HelpMessage='Mailbox for which to create the report',valueFromPipeline=$true)]
[string]$MailboxName,
[Parameter(HelpMessage='Report filename')]
[string]$ReportName = $null,
[Parameter(HelpMessage='You can also enable default folder permissions to be displayed')]
[bool]$HideDefaultPermissions = $true,
[Parameter(HelpMessage='You can also enable the mailbox owner permission to be displayed')]
[bool]$HideMailboxOwner = $true,
[Parameter(HelpMessage='Append to existing file')]
[bool]$AppendReport = $false,
[Parameter(HelpMessage='Creates a CSV based report instead of the html report')]
[bool]$CreateCSVReport = $false,
[Parameter(HelpMessage='does not display a progress indicator while getting folder permissions')]
[bool]$NoProgress = $false
)
BEGIN {
#------------------------------------------------------------------------------------------------
# Connect / disconnect to the remote exchange shell for exchange command-lets...
#------------------------------------------------------------------------------------------------
$global:MyPSSession = $null
function Handle-ExchangeShell ($ExchangeServerName, $Mode) {
if ($Mode -eq "connect") {
Write-Host -ForegroundColor Green ("connecting to remote exchange shell...")
$Session = New-PSSession -ConfigurationName Microsoft.Exchange `
-ConnectionUri http://$ExchangeServerName/PowerShell/ `
-Authentication Kerberos
$global:MyPSSession = $Session.Id
$null = Import-PSSession $Session -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -DisableNameChecking -OutVariable $null
}
elseif ($Mode -eq "disconnect" -and $global:MyPSSession -ne $null) {
Write-Host -ForegroundColor Green ("disconnecting from remote exchange shell...")
Remove-PSSession -Id $global:MyPSSession
}
}
#------------------------------------------------------------------------------------------------
# Connecting to the exchange shell
#------------------------------------------------------------------------------------------------
#$Exchange
if ((Get-Command -Name Get-Mailbox -ErrorAction SilentlyContinue).Name.Length -eq $null ) {
Handle-ExchangeShell -ExchangeServerName $ExchangeServer -Mode "connect"
}
#------------------------------------------------------------------------------------------------
# Save report to file
#------------------------------------------------------------------------------------------------
function Save-Report ($ReportData, $FileName) {
try {
if ($AppendReport -or $CreateCSVReport) {
$ReportData | Out-File -FilePath $FileName -Encoding utf8 -Append
}
else {
$ReportData | Out-File -FilePath $FileName -Encoding utf8
}
}
catch {
Write-Host -ForegroundColor Red " ERROR while writing report to file: $InneFileNamerReportName"
}
}
$Global:CSVHeaderCreated = $false
}
##------------------------------------------------------------------------------------------------
## main block...
##------------------------------------------------------------------------------------------------
PROCESS {
# checking report name and apply default one if not specified
if ($ReportName -eq "") {
$TimeStamp = Get-Date -Format "yyyyMMdd.hhMMss"
if (-not $CreateCSVReport) {
$InnerReportName = Join-Path -Path (Join-Path -Path $env:HOMEDRIVE -ChildPath $env:HOMEPATH) -ChildPath "MailboxFolderPermissionReport-$TimeStamp-$MailboxName.html"
}
else {
$InnerReportName = Join-Path -Path (Join-Path -Path $env:HOMEDRIVE -ChildPath $env:HOMEPATH) -ChildPath "MailboxFolderPermissionReport-$TimeStamp-$MailboxName.csv"
}
Write-Host -ForegroundColor Yellow ("Setting reportname to: $InnerReportName")
}
else {
$InnerReportName = $ReportName
}
#------------------------------------------------------------------------------------------------
# Create CSV header once
#------------------------------------------------------------------------------------------------
if ($CreateCSVReport -and -not $Global:CSVHeaderCreated) {
Save-Report -ReportData "MailboxID;Folderpath;PermissionUser;PermissionLevel;PermissionOperator" -FileName $InnerReportName
$Global:CSVHeaderCreated = $true
}
# get mailbox
Write-Host -ForegroundColor Green ("processing mailbox: ") -NoNewline
Write-Host -ForegroundColor Yellow ($MailboxName)
$Mailbox = Get-Mailbox -Identity $MailboxName -WarningAction SilentlyContinue -ErrorAction SilentlyContinue
# check if mailbox esists
if ($Mailbox) {
Write-Host -ForegroundColor Green (" getting mailbox folders...")
#getting folders within selected mailbox
$MailboxFolders = Get-MailboxFolderStatistics -Identity $Mailbox.PrimarySmtpAddress.ToString() `
-FolderScope All | `
#Exclude system folders
Where-Object {$_.FolderType -ne "RecoverableItemsPurges" -and `
$_.FolderType -ne "RecoverableItemsVersions" -and `
$_.FolderType -ne "RecoverableItemsDeletions" -and `
$_.FolderType -ne "RecoverableItemsRoot" -and `
$_.FolderType -ne "ServerFailures" -and `
$_.FolderType -ne "LocalFailures" -and `
$_.FolderType -ne "Conflicts" -and `
$_.FolderType -ne "SyncIssues" -and `
$_.FolderType -ne "Root" -and `
$_.Name -ne "Calendar Logging"} | `
Select-Object -Property Name, FolderPath, Permissions, FolderType
# getting mailbox folder permissions
Write-Host -ForegroundColor Green (" getting mailbox folderpermissions...")
if (-not $NoProgress) {
$TotalFolder = $MailboxFolders | Measure-Object | Select-Object -ExpandProperty Count
$i=1
}
$MailboxFolders | ForEach-Object {
$MBXFolderIdentity = $Mailbox.PrimarySmtpAddress.ToString()+":"+($_.FolderPath).Replace("/", "`\")
$CurrentFolderType = $_.FolderType
#give a progress indicator...
if (-not $NoProgress) {
Write-Progress -Activity "Enumerating folder permissions" -Status "Mailbox: $MailboxName" -CurrentOperation ("Folder: "+$_.FolderPath) -PercentComplete ($i/$TotalFolder*100)
$i++
}
try {
$AllPermissions = Get-MailboxFolderPermission -Identity $MBXFolderIdentity -WarningAction SilentlyContinue -ErrorAction SilentlyContinue
}
catch {}
$runner = 0
$FilteredPermissions = New-Object System.Collections.Generic.List[System.String]
$AllPermissions | ForEach-Object {
$addThis = $true
if ($AllPermissions.Count -gt 0) {
if ($HideDefaultPermissions) {
if (($AllPermissions[$runner].AccessRights -eq "none" -and ($AllPermissions[$runner].User).ToString() -eq "Default") -or `
($AllPermissions[$runner].AccessRights -eq "none" -and ($AllPermissions[$runner].User).ToString() -eq "Anonymous")) {
$addThis = $false
}
if ($CurrentFolderType -eq "Calendar" -and $AllPermissions[$runner].AccessRights -eq "AvailabilityOnly" -and ($AllPermissions[$runner].User).ToString() -eq "Default") {
$addThis = $false
}
}
if ($HideMailboxOwner -and ($AllPermissions[$runner].User).ToString() -eq $Mailbox.DisplayName) {
$addThis = $false
}
#Add permission entry...
if ($addThis) {
$FilteredPermissions.Add(($AllPermissions[$runner].User).ToString() + "`t" + ($AllPermissions[$runner].AccessRights))
}
}
else {
#$MBXFolderIdentity
#$AllPermissions| ft
#$FilteredPermissions.Add("")
}
$runner++
}
$_.FolderPath = $_.FolderPath.SubString(1)
$_.Permissions = $FilteredPermissions.ToArray()
}
if (-not $NoProgress) {
Write-Progress -Activity "Enumerating folder permissions" -Status "done" -Completed
}
# creating html report
if (-not $CreateCSVReport) {
Write-Host -ForegroundColor Green " creating html report..."
$HTML = $null
# mailbox leaf
$HTML += ("<ul>")
$HTML += ("<li><h1>Permission report for: "+$Mailbox.DisplayName+"</h1>("+$Mailbox.PrimarySmtpAddress+")")
$global:oldlayer = 0
$MailboxFolders | ForEach-Object {
#Root Folder
$layers = ($_.FolderPath.Split("/")).Count
for ($layer=1; $layer -le $layers; $layer++) {
if ($global:oldlayer -eq $layer -and $layer -eq $layers) {
$HTML += ("</li>")
}
if ($global:oldlayer -lt $layer) {
$HTML += ("<ul>")
}
elseif ($global:oldlayer -gt $layers) {
while ($global:oldlayer -gt $layers) {
$HTML += ("</li></ul>")
$global:oldlayer--
}
if ($global:oldlayer -eq $layers) {
$HTML += ("</li>")
}
}
if ($layer -eq $layers) {
$HTML += ("<li><b>"+$_.Name+"</b>")
foreach ($entry in $_.Permissions) {
$HTML += ("<br>"+$entry.replace("`t", " :: "))
}
$global:oldlayer = $layer
}
}
}
if ($layer -gt $global:oldlayer) {
$HTML += ("</li></ul>")
}
$HTML += "</li></ul></li></ul>"
#Save report
Save-Report -ReportData $HTML -FileName $InnerReportName
}
# Create CSV file
else {
Write-Host -ForegroundColor Green " creating csv report..."
$CSV = $null
$MailboxFolders | ForEach-Object {
if ($_.Permissions.count -gt 0) {
foreach ($entry in $_.Permissions) {
$PermUser = $entry.split(' :: ')[0]
$CSV += ($MailboxName+";"+$_.FolderPath+";"+(($entry.split("`t"))[0])+";"+(($entry.split("`t"))[1])+";report`n")
}
}
else {
$CSV += ($MailboxName+";"+$_.FolderPath+";;;report`n")
}
}
# Save file
Save-Report -ReportData $CSV -FileName $InnerReportName
}
}
else {
Write-Host -ForegroundColor Red (" ERROR: Mailbox: $MailboxName could not be found!")
}
}
END {
#disconnect the exchange shell
$Global:CSVHeaderCreated = $false
Handle-ExchangeShell -ExchangeServerName $ExchangeServer -Mode "disconnect"
Write-Host -ForegroundColor Green "... Done"
}
Download the script:
>> Version 1.1.8 (current)
(MD5: c5161201f9050f89e35aeefcb9bdcc93)
(SHA1: 022a45717cab36444815f33aba1c936f66a56c6f)
>> Version 1.0.5
(MD5: 734fb9492438233dda8886d7c7192374)
(SHA1: 1629427f0bbc96522cbc596fad8d55633f3283e1)