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
    • 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"

Create-MailboxFolderPermissionReport

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

Create-MailboxFolderPermissionReport

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)


>> syntax highlighting powered by highlight.js