2021-07-13 18:14:20 +05:30
<#
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2023-09-28 12:41:10 +05:30
Name : Export Office 365 Mailbox Holds Report
Description : This script exports hold enabled mailboxes to CSV
2021-07-13 18:14:20 +05:30
Version : 1.0
2023-09-28 12:41:10 +05:30
Website : o365reports . com
Script Highlights :
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
1 . Generates 4 different mailbox holds reports .
2 . Automatically installs the Exchange Online module upon your confirmation when it is not available in your machine .
3 . Shows list of the mailboxes with all the active holds information for each mailbox .
4 . Shows the mailboxes with litigation hold enabled along with hold duration and other details .
5 . Displays in-place hold applied mailboxes .
6 . Lists mailboxes that are placed on retention hold and their retention policy .
7 . Supports both MFA and Non-MFA accounts .
8 . Exports the report in CSV format .
9 . Scheduler-friendly . You can automate the report generation upon passing credentials as parameters .
For detailed Script execution : http : / / o365reports . com / 2021 / 06 / 29 / export-office - 365 -mailbox -holds -report -using -powershell
2021-07-13 18:14:20 +05:30
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
#>
param (
[ string ] $UserName = $null ,
[ string ] $Password = $null ,
[ Switch ] $LitigationHoldsOnly ,
[ Switch ] $InPlaceHoldsOnly ,
[ Switch ] $RetentionHoldsOnly
)
Function GetBasicData {
$global:ExportedMailbox = $global:ExportedMailbox + 1
$global:MailboxName = $_ . Name
$global:RecipientTypeDetails = $_ . RecipientTypeDetails
$global:UPN = $_ . UserPrincipalName
}
Function RetrieveAllHolds {
if ( $LitigationHoldsOnly . IsPresent ) {
$global:ExportCSVFileName = " LitigationHoldsReport " + ( ( Get-Date -format " MMM-dd hh-mm-ss tt " ) . ToString ( ) ) + " .csv "
Get-mailbox -IncludeInactiveMailbox -ResultSize Unlimited | Where-Object { $_ . LitigationHoldEnabled -eq $True } | foreach-object {
$CurrLitigationHold = $_
GetLitigationHoldsReport
}
}
elseif ( $InPlaceHoldsOnly . IsPresent ) {
$global:ExportCSVFileName = " InPlaceHoldsReport " + ( ( Get-Date -format " MMM-dd hh-mm-ss tt " ) . ToString ( ) ) + " .csv "
Get-mailbox -IncludeInactiveMailbox -ResultSize Unlimited | Where-Object { $_ . InPlaceHolds -ne $Empty } | foreach-object {
$CurrInPlaceHold = $_
GetInPlaceHoldsReport
}
}
elseif ( $RetentionHoldsOnly . IsPresent ) {
$global:ExportCSVFileName = " RetentionHoldsReport " + ( ( Get-Date -format " MMM-dd hh-mm-ss tt " ) . ToString ( ) ) + " .csv "
Get-mailbox -IncludeInactiveMailbox -ResultSize Unlimited | Where-Object { $_ . RetentionHoldEnabled -eq $True } | foreach-object {
$CurrRetentionHold = $_
GetRetentionHoldsReport
}
}
else {
$global:ExportCSVFileName = " AllActiveHoldsReport " + ( ( Get-Date -format " MMM-dd hh-mm-ss tt " ) . ToString ( ) ) + " .csv "
Get-mailbox -IncludeInactiveMailbox -ResultSize Unlimited | Where-Object { $_ . LitigationHoldEnabled -eq $True -or $_ . RetentionHoldEnabled -eq $True -or $_ . InPlaceHolds -ne $Empty -or $_ . ComplianceTagHoldApplied -eq $True } | foreach-object {
$CurrMailbox = $_
GetDefaultReport
}
}
}
Function GetInPlaceHoldType($HoldGuidList ) {
$HoldTypes = @ ( )
$InPlaceHoldCount = 0
$HoldGuidList | ForEach-Object {
$InPlaceHoldCount = $InPlaceHoldCount + 1
if ( $_ -match " UniH " ) {
$HoldTypes + = " eDiscovery Case "
}
elseif ( $_ -match " ^mbx " ) {
$HoldTypes + = " Specific Location Retention Policy "
}
elseif ( $_ -match " ^\-mbx " ) {
$HoldTypes + = " Mailbox Excluded Retention Policy "
}
elseif ( $_ -match " skp " ) {
$HoldTypes + = " Retention Policy on Skype "
}
else {
$HoldTypes + = " In-Place Hold "
}
}
return ( $HoldTypes -join " , " ) , $InPlaceHoldCount
}
Function GetLitigationHoldsReport {
GetBasicData
$LitigationOwner = $CurrLitigationHold . LitigationHoldOwner
if ( $null -ne $CurrLitigationHold . LitigationHoldDate ) {
$LitigationHoldDate = ( $CurrLitigationHold . LitigationHoldDate ) . ToString ( ) . Split ( " " ) | Select-Object -Index 0
}
$LitigationDuration = $CurrLitigationHold . LitigationHoldDuration
if ( $LitigationDuration -ne " Unlimited " ) {
$LitigationDuration = ( $LitigationDuration ) . split ( " . " ) | Select-Object -Index 0
}
Write-Progress " Retrieving the Litigation Hold Information for the User: $global:MailboxName " " Processed Mailboxes Count: $global:ExportedMailbox "
#ExportResult
$ExportResult = @ { 'Mailbox Name' = $global:MailboxName ; 'Mailbox Type' = $global:RecipientTypeDetails ; 'UPN' = $global:UPN ; 'Litigation Owner' = $LitigationOwner ; 'Litigation Duration' = $LitigationDuration ; 'Litigation Hold Date' = $LitigationHoldDate }
$ExportResults = New-Object PSObject -Property $ExportResult
$ExportResults | Select-object 'Mailbox Name' , 'UPN' , 'Mailbox Type' , 'Litigation Owner' , 'Litigation Duration' , 'Litigation Hold Date' | Export-csv -path $global:ExportCSVFileName -NoType -Append -Force
}
Function GetInPlaceHoldsReport {
GetBasicData
$InPlaceHoldInfo = GetInPlaceHoldType ( $CurrInPlaceHold . InPlaceHolds )
$InPlaceHoldType = $InPlaceHoldInfo [ 0 ]
$NumberOfHolds = $InPlaceHoldInfo [ 1 ]
Write-Progress " Retrieving the In-Place Hold Information for the User: $global:MailboxName " " Processed Mailboxes Count: $global:ExportedMailbox "
#Export Results
$ExportResult = @ { 'Mailbox Name' = $global:MailboxName ; 'Mailbox Type' = $global:RecipientTypeDetails ; 'UPN' = $global:UPN ; 'Configured InPlace Hold Count' = $NumberOfHolds ; 'InPlace Hold Type' = $InPlaceHoldType }
$ExportResults = New-Object PSObject -Property $ExportResult
$ExportResults | Select-object 'Mailbox Name' , 'UPN' , 'Mailbox Type' , 'Configured InPlace Hold Count' , 'InPlace Hold Type' | Export-csv -path $global:ExportCSVFileName -NoType -Append -Force
}
Function GetRetentionHoldsReport {
GetBasicData
$RetentionPolicy = $CurrRetentionHold . RetentionPolicy
$RetentionPolicyTag = ( ( Get-RetentionPolicy -Identity $RetentionPolicy ) . RetentionPolicyTagLinks ) -join " , "
if ( ( $CurrRetentionHold . StartDateForRetentionHold ) -ne $Empy ) {
$StartDateForRetentionHold = ( $CurrRetentionHold . StartDateForRetentionHold ) . ToString ( ) . split ( " " ) | Select-Object -Index 0
}
else {
$StartDateForRetentionHold = " - "
}
if ( ( $CurrRetentionHold . EndDateForRetentionHold ) -ne $Empy ) {
$EndDateForRetentionHold = ( $CurrRetentionHold . EndDateForRetentionHold ) . ToString ( ) . split ( " " ) | Select-Object -Index 0
}
else {
$EndDateForRetentionHold = " - "
}
Write-Progress " Retrieving the Retention Hold Information for the User: $global:MailboxName " " Processed Mailboxes Count: $global:ExportedMailbox "
#ExportResult
$ExportResult = @ { 'Mailbox Name' = $global:MailboxName ; 'Mailbox Type' = $global:RecipientTypeDetails ; 'UPN' = $global:UPN ; 'Retention Policy Name' = $RetentionPolicy ; 'Start Date for Retention Hold' = $StartDateForRetentionHold ; 'End Date for Retention Hold' = $EndDateForRetentionHold ; 'Retention Policy Tag' = $RetentionPolicyTag }
$ExportResults = New-Object PSObject -Property $ExportResult
$ExportResults | Select-object 'Mailbox Name' , 'UPN' , 'Mailbox Type' , 'Retention Policy Name' , 'Start Date for Retention Hold' , 'End Date for Retention Hold' , 'Retention Policy Tag' | Export-csv -path $global:ExportCSVFileName -NoType -Append -Force
}
Function GetDefaultReport {
GetBasicData
$LitigationHold = $CurrMailbox . LitigationHoldEnabled
$ComplianceTag = $CurrMailbox . ComplianceTagHoldApplied
$RetentionHold = $CurrMailbox . RetentionHoldEnabled
$ArchiveStatus = $CurrMailbox . ArchiveStatus
$RetentionPolicy = $CurrMailbox . RetentionPolicy
$LitigationDuration = $CurrMailbox . LitigationHoldDuration
if ( $LitigationDuration -ne " Unlimited " ) {
$LitigationDuration = ( $LitigationDuration ) . split ( " . " ) | Select-Object -Index 0
}
$InPlaceHold = $CurrMailbox . InPlaceHolds
if ( $InPlaceHold -ne $Empty ) {
$InPlaceHold = " Enabled "
}
else {
$InPlaceHold = " Disabled "
}
Write-Progress " Retrieving All Active Holds Applied on the User: $global:MailboxName " " Processed Mailboxes Count: $global:ExportedMailbox "
#ExportResult
$ExportResult = @ { 'Mailbox Name' = $global:MailboxName ; 'Mailbox Type' = $global:RecipientTypeDetails ; 'UPN' = $global:UPN ; 'Archive Status' = $ArchiveStatus ; 'Litigation Hold Enabled' = $LitigationHold ; 'Compliance Tag Hold Enabled' = $ComplianceTag ; 'Retention Hold Enabled' = $RetentionHold ; 'Litigation Duration' = $LitigationDuration ; 'In-Place Hold Status' = $InPlaceHold ; 'Retention Policy Name' = $RetentionPolicy }
$ExportResults = New-Object PSObject -Property $ExportResult
$ExportResults | Select-object 'Mailbox Name' , 'UPN' , 'Mailbox Type' , 'Archive Status' , 'Litigation Hold Enabled' , 'In-Place Hold Status' , 'Retention Hold Enabled' , 'Compliance Tag Hold Enabled' , 'Litigation Duration' , 'Retention Policy Name' | Export-csv -path $global:ExportCSVFileName -NoType -Append -Force
}
Function ConnectToExchange {
$Exchange = ( get-module ExchangeOnlineManagement -ListAvailable ) . Name
if ( $Exchange -eq $null ) {
Write-host " Important: ExchangeOnline PowerShell module is unavailable. It is mandatory to have this module installed in the system to run the script successfully. "
$confirm = Read-Host Are you sure you want to install module ? [ Y] Yes [N ] No
if ( $confirm -match " [yY] " ) {
Write-host " Installing ExchangeOnlineManagement "
Install-Module ExchangeOnlineManagement -Repository PSGallery -AllowClobber -Force
Write-host " ExchangeOnline PowerShell module is installed in the machine successfully. "
}
elseif ( $confirm -cnotmatch " [yY] " ) {
Write-host " Exiting. `n Note: ExchangeOnline PowerShell module must be available in your system to run the script. "
Exit
}
}
#Storing credential in script for scheduling purpose/Passing credential as parameter
if ( ( $UserName -ne " " ) -and ( $Password -ne " " ) ) {
$SecuredPassword = ConvertTo-SecureString -AsPlainText $Password -Force
$Credential = New-Object System . Management . Automation . PSCredential $UserName , $SecuredPassword
Connect-ExchangeOnline -Credential $Credential -ShowProgress $false | Out-Null
}
else {
Connect-ExchangeOnline | Out-Null
}
Write-Host " ExchangeOnline PowerShell module is connected successfully "
#End of Connecting Exchange Online
}
ConnectToExchange
$global:ExportedMailbox = 0
RetrieveAllHolds
if ( ( Test-Path -Path $global:ExportCSVFileName ) -eq " True " ) {
2023-09-28 12:41:10 +05:30
Write-Host ` n " The output file available in: " -NoNewline -ForegroundColor Yellow
Write-Host . \ $global:ExportCSVFileName
Write-Host " "
Write-host " There are $global:ExportedMailbox mailboxes records in the output file " ` n
2021-07-13 18:14:20 +05:30
$prompt = New-Object -ComObject wscript . shell
$userInput = $prompt . popup ( " Do you want to open output file? " , 0 , " Open Output File " , 4 )
If ( $userInput -eq 6 ) {
Invoke-Item " $global:ExportCSVFileName "
}
}
else {
Write-Host " No data found with the specified criteria "
}
Disconnect-ExchangeOnline -Confirm: $false -InformationAction Ignore -ErrorAction SilentlyContinue
Write-Host " Disconnected active ExchangeOnline session "
2023-09-28 12:41:10 +05:30
Write-Host ` n ~ ~ Script prepared by AdminDroid Community ~ ~ ` n -ForegroundColor Green
Write-Host " ~~ Check out " -NoNewline -ForegroundColor Green ; Write-Host " admindroid.com " -ForegroundColor Yellow -NoNewline ; Write-Host " to get access to 1800+ Microsoft 365 reports. ~~ " -ForegroundColor Green ` n ` n