Enable-EXOLitigationHold.ps1
#Requires -Version 5.1 <#PSScriptInfo .VERSION 1.0.0 .GUID 6294d02e-207f-411b-a76e-1485011e98c5 .AUTHOR June Castillote .COMPANYNAME lazyexchangeadmin.com .COPYRIGHT Copyright (c) 2019 June Castillote .TAGS .LICENSEURI .PROJECTURI https://github.com/junecastillote/Enable-EXOLitigationHold .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES .PRIVATEDATA #> <# .DESCRIPTION Script to enable litigation hold for all mailbox with ExchangeOnlineEnterprise Mailbox Plan #> [cmdletbinding()] Param( [parameter()] [switch]$UseSSL, [parameter()] [switch]$SendEmail, [parameter()] [mailaddress]$From, [parameter()] [mailaddress[]]$To, [parameter()] [pscredential]$Credential, [parameter()] [string]$smtpServer, [parameter()] [int]$Port, [parameter()] [switch]$ListOnly, [parameter()] [string]$ReportDirectory = ($env:windir + '\temp'), [parameter()] [ValidateSet('CSV', 'HTML', 'ALL')] [string]$ReportType = 'ALL', [parameter()] [switch]$AttachCSVWhenPossible ) if ($ListOnly) { Write-Output '[TEST MODE]' } if ($SendEmail) { if (!$From) { Write-Output "From address is missing." } if (!$To) { Write-Output "To address is missing." } if (!$smtpServer) { Write-Output "SMTP Server address is missing." } if (!$Port) { Write-Output "SMTP Server Port is missing." } } $ScriptInfo = (Test-ScriptFileInfo -Path "$($PSScriptRoot)\$($MyInvocation.MyCommand.Name)") Write-Output "....................................." Write-Output "Name : $($ScriptInfo.Name)" Write-Output "Version : $($ScriptInfo.Version)" Write-Output "....................................." $tz = ([System.TimeZoneInfo]::Local).DisplayName.ToString().Split(" ")[0] $today = Get-Date -Format "MMMM dd, yyyy hh:mm tt" if (!(Test-Path $ReportDirectory)) { $null = New-Item -ItemType Directory -Path $ReportDirectory -Force } "Last Run: $today" | Out-File ($ReportDirectory + "\Remediate-Exchange-Online-Litigation-Hold.txt") try { $OrgInfo = Get-OrganizationConfig -Erroraction stop $Organization = $OrgInfo.DisplayName } catch { Write-Output "Remote Exchange Online PowerShell Session is required." break } $css_string = @' #tbl { font-family:"Tahoma"; width:auto; border-collapse:collapse; } #tbl td, #tbl th { font-size:13px; border-bottom: 1px solid #ccc; padding-top:10px; padding-bottom:10px; padding-left:10px; padding-right:10px; } #tbl td.head { font-size:14px; border: none; padding-top:10px; padding-bottom:10px; padding-left:10px; padding-right:10px; } #tbl th { font-size:14px; background-color:#fff; text-align:left; vertical-align:top; color: #7a7a52; } #tbl th.section { font-family:"Tahoma"; font-weight: bold; font-size:26px; text-align:left; padding-top:10px; padding-bottom:10px; padding-left:10px; padding-right:10px; background-color:#fff; color:#000; vertical-align:center; border: none; } #tbl td { text-align:left; vertical-align:top; font-weight: lighter; color: #7a7a52; width: fit-content } #tbl td.wrap { word-break: break-all; } #legend { font-family:"Tahoma"; width: auto; border-collapse:collapse; font-size:10px; text-align: center; } #legend td { font-size:10px; border: none; padding-top:5px; padding-bottom:5px; padding-left:5px; padding-right:5px; } #settings { font-family:"Tahoma"; width: auto; border-collapse:collapse; font-size:10px; text-align: left; } #settings td { border: none; padding-top:0px; padding-bottom:0px; padding-left:0px; padding-right:0px; color: #7a7a52; } .red { background-color: red; color: #fff; } .green { background-color: green; color: #fff; } .gray { background-color: gray; color: #fff; } '@ $subject = "Exchange Online Litigation Hold Remediation Report" if ($ListOnly) { $subject = ('[TEST MODE] ' + $subject) } $fileSuffix = "{0:yyyy_MM_dd}" -f [datetime]$today $outputCsvFile = ($ReportDirectory + "\$($Organization)-LitigationHold_Remediation_Report-$($fileSuffix).csv").Replace(" ", "_") $outputHTMLFile = ($ReportDirectory + "\$($Organization)-LitigationHold_Remediation_Report-$($fileSuffix).html").Replace(" ", "_") if (Test-Path $outputCsvFile) { $null = Remove-Item -Path $outputCsvFile -Force -Confirm:$false } if (Test-Path $outputHTMLFile) { $null = Remove-Item -Path $outputHTMLFile -Force -Confirm:$false } Write-Output 'Getting mailbox list with E3, E5 or Plan 2 License..' ## 1. Get all mailbox with plan $mailboxList = Get-Mailbox -ResultSize Unlimited -Filter 'mailboxplan -ne $null -and litigationholdenabled -eq $false' ## 2. Get all mailbox with "ExchangeOnlineEnterprise*" plan $mailboxList = $mailboxList | Where-Object { $_.MailboxPlan -like "ExchangeOnlineEnterprise*" } Write-Output "Found $([int]$mailboxList.count) mailbox with disabled litigation hold" ## 3. Enable Litigation Hold if ($mailboxList.count -gt 0) { if (!$ListOnly) { try { foreach ($mailbox in $mailboxList) { Set-Mailbox -Identity $mailbox.SamAccountName -LitigationHoldEnabled $true -WarningAction SilentlyContinue -ErrorAction STOP Write-Output "Enable Litigation Hold for Mailbox: $($Mailbox.Name) - SUCCESS" } } catch { Write-Output "Enable Litigation Hold for Mailbox: $($Mailbox.Name) - FAIL" Write-Output $_.Exception.Message } } } else { break } #Reset mailboxList and get updated values. if (!$ListOnly) { Write-Output 'Getting updated values. Please wait...' $mailboxList = @($mailboxList | ForEach-Object { Get-Mailbox -Identity $_.Identity }) } #if ($mailboxList.count -gt 0) { Write-Output 'Writing report..' ## Create CSV report if ($ReportType -eq 'CSV' -or $ReportType -eq 'ALL') { $mailboxList | Select-Object Name, UserPrincipalName, SamAccountName, @{Name = 'WhenMailboxCreated'; Expression = { '{0:dd/MMM/yyyy}' -f $_.WhenMailboxCreated } }, LitigationHoldEnabled, LitigationHoldDate, LitigationHoldDuration, LitigationHoldOwner | Export-CSV -NoTypeInformation $outputCsvFile } ## create the HTML report ## html title $html = "<html><head><title>[$($Organization)] $($subject)</title><meta http-equiv=""Content-Type"" content=""text/html; charset=ISO-8859-1"" />" $html += '<style type="text/css">' $html += $css_string $html += '</style></head><body>' ## heading $html += '<table id="tbl">' $html += '<tr><td class="head"> </td></tr>' $html += '<tr><th class="section">' + $subject + '</th></tr>' $html += '<tr><td class="head"><b>' + $Organization + '</b><br>' + $today + ' ' + $tz + '</td></tr>' $html += '<tr><td class="head"> </td></tr>' $html += '</table>' $html += '<table id="tbl">' if ($ReportType -ne 'CSV') { $html += '<tr><th>Name</th><th>UPN</th><th>Created</th><th>Enabled</th><th>When</th><th>Duration</th><th>Owner</th></tr>' foreach ($mailbox in $mailboxList) { $WhenMailboxCreated = '{0:dd-MMM-yyyy}' -f $mailbox.WhenMailboxCreated $LitigationHoldDate = '{0:dd-MMM-yyyy}' -f $mailbox.LitigationHoldDate ## data values $html += "<tr><td>$($mailbox.Name)</td><td>$($mailbox.UserPrincipalName)</td><td>$($WhenMailboxCreated)</td>" $html += "<td>$($mailbox.LitigationHoldEnabled)</td><td>$($LitigationHoldDate)</td>" $html += "<td>$($mailbox.LitigationHoldDuration)</td><td>$($mailbox.LitigationHoldOwner)</td></tr>" # if (!$ListOnly) { # Set-Mailbox -Identity $mailbox.SamAccountName -LitigationHoldEnabled $true -WarningAction SilentlyContinue # } } $html += '</table>' } elseif ($ReportType -ne 'HTML') { $html += '<tr><th>Please see attached CSV file</th></tr>' $html += '</table>' } $html += '<table id="tbl">' $html += '<tr><td class="head"> </td></tr>' $html += '<tr><td class="head"> </td></tdr>' $html += '<tr><td class="head">Source: ' + $env:COMPUTERNAME + '<br>' $html += 'Script Directory: ' + (Resolve-Path $PSScriptRoot).Path + '<br>' $html += 'Report Directory: ' + (Resolve-Path $ReportDirectory).Path + '<br>' $html += '<a href="' + $ScriptInfo.ProjectURI.ToString() + '">' + $ScriptInfo.Name.ToString() + ' v' + $ScriptInfo.Version.ToString() + ' </a><br>' $html += '<tr><td class="head"> </td></tr>' $html += '</table>' $html += '</html>' $html | Out-File $outputHTMLFile -Encoding UTF8 Write-Output "Report saved in $ReportDirectory" if ($sendEmail -eq $true) { Write-Output 'Sending email..' [string]$html = Get-Content $outputHTMLFile -Raw -Encoding UTF8 $mailParams = @{ SmtpServer = $smtpServer Port = $Port To = $To From = $From Subject = "[$($Organization)] $subject" DeliveryNotificationOption = 'OnFailure' BodyAsHTML = $true Body = (Get-Content $outputHTMLFile -Raw -Encoding UTF8) } if ($Credential) { $mailParams += @{Credential = $Credential } } if ($UseSSL) { $mailParams += @{UseSSL = $true } } ## if ReportType is CSV only, attach the CSV file. if ($ReportType -ne 'HTML' -or $AttachCSVWhenPossible) { if (Test-Path $outputCsvFile) { $mailParams += @{Attachments = $outputCsvFile } } } # ## if AttachCSVWhenPossible and ReportType is CSV or ALL # if ($AttachCSVWhenPossible -and ($ReportType -eq 'All' -or $ReportType -eq 'CSV')) { # $mailParams += @{Attachments = $outputCsvFile } # } ## Send email try { Send-MailMessage @mailParams -ErrorAction STOP } catch { Write-Output $_.Exception.Message } } ## if CSV only, delete HTML file if ($ReportType -eq 'CSV') { Remove-Item -Path $outputHTMLFile -Confirm:$false -Force } #} |