Here’s the entire script cleaned up…I hope. The variables are inside the main Try\Catch, but not in a separate function. I could move them outside the Try\Catch, which is what the errors are on.
[pre]
TRY{
VARIABLES START
*** CHANGE $Prefix FOR EACH BATCH ***
$Prefix = “HERE”
$PSTnames = (get-Item “\server1\c$\PSTs\UPload$Prefix-*”).name
*** Change the $PathRoot as needed ***
$PathRoot = “C:\scripts\import\Logs”
$D = Get-Date -Format “yyyy-MM-dd_HH-mm-ss”
sl $PSScriptRoot
These strings will be removed…
$ReplaceFileString1 = “$($Prefix)-”
$ReplaceFileString2 = “_Export_0001”
$ReplaceFileString3 = “.pst”
Log paths
$LogPath = (Join-Path $PathRoot -ChildPath “Purge_General.log”)
$ErrorLogPath = (Join-Path $PathRoot -ChildPath “Purge_ERRORS_$D.log”)
$MBstatsBeforeTagPurge = (Join-Path $PathRoot -ChildPath “Purge_MBstats-BEFORE.csv”)
$MBstatsAfterTagPurge = (Join-Path $PathRoot -ChildPath “Purge_MBstats-AFTER.csv”)
$ItemsReport = (Join-Path $PathRoot -ChildPath “Purge_Report.log”)
$TranscriptLogPath = (Join-Path $PathRoot -ChildPath “Transcripts\Purge-Transcript_$D.txt”)
Start-Transcript -Path $TranscriptLogPath -IncludeInvocationHeader -NoClobber
VARIABLES END
FUNCTION START
Function to set…
TRY{
Function TagNeverDelete ($Mailbox)
{
Set the mailbox SMTP for the Service
$service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress,$Mailbox)
Set up search criteria to find the “MaFold” and “HistItems” folders
$FolderView = new-object Microsoft.Exchange.WebServices.Data.FolderView(1)
$FolderView.Traversal = [Microsoft.Exchange.Webservices.Data.FolderTraversal]::Shallow
$SearchFilterManagedFolders = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,“MaFold”)
$SearchFilterHistItems = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,“HistItems”)
Create the properties needed to apply the personal tag: PR_POLICY_TAG [0x3019], PR_RETENTION_FLAGS [0x301D], PR_RETENTION_PERIOD [0x301A]
$PolicyTag = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x3019,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Binary);
$RetentionFlags = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x301D,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Integer);
$RetentionPeriod = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x301A,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Integer);
Set up the personal tag…
$PolicyTagGUID = new-Object Guid(“{674c6a14-3ed5-432e-9edb-c6620a8278f0}”);
######### Primary Mailbox START #########
Search for the “MaFold” folder
$FindFolderResultsPrimaryManagedFolders = $service.FindFolders([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$SearchFilterManagedFolders,$FolderView)
If the “MaFold” folder is NOT FOUND add a log entry and take no action
if ($FindFolderResultsPrimaryManagedFolders.TotalCount -eq 0)
{
Write-host “MaFold (PRIMARY) DOES NOT EXIST: $($Mailbox)”
“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”) MaFold (PRIMARY) DOES NOT EXIST: $($Mailbox)” | out-file $LogPath -Append
}
If the “MaFold” folder is FOUND look for subfolder “HistItems”
else
{
Search for subfolder “HistItems”
$FindFolderResultsPrimaryHistItems = $service.FindFolders($FindFolderResultsPrimaryManagedFolders.id,$SearchFilterHistItems,$FolderView)
If the “HistItems” folder is NOT FOUND add a log entry and take no action
if ($FindFolderResultsPrimaryHistItems.TotalCount -eq 0)
{
Write-host “HistItems (PRIMARY) DOES NOT EXIST: $($Mailbox)”
“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”) HistItems (PRIMARY) DOES NOT EXIST: $($Mailbox)” | out-file $LogPath -Append
}
If the “HistItems” folder is FOUND assign the never delete tag
Else
{
Bind to “HistItems” folder
$Folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$FindFolderResultsPrimaryHistItems.Folders[0].Id)
Set property values: PR_POLICY_TAG [0x3019], PR_RETENTION_FLAGS [0x301D], PR_RETENTION_PERIOD [0x301A]
$Folder.SetExtendedProperty($RetentionFlags, 137)
$Folder.SetExtendedProperty($RetentionPeriod, 0)
$Folder.SetExtendedProperty($PolicyTag, $PolicyTagGUID.ToByteArray())
Apply the changes to the folder
$Folder.Update()
Write-host “Retention policy stamped on HistItems (PRIMARY): $($Mailbox)”
“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”) Retention policy stamped on HistItems (PRIMARY): $($Mailbox)” | out-file $LogPath -Append
} # else Inner Primary Mailbox END
} # else Outer Primary Mailbox END
######### Primary Mailbox END #########
######### Archive Mailbox START #########
Search for the “MaFold” folder
$FindFolderResultsArchiveManagedFolders = $service.FindFolders([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::ArchiveMsgFolderRoot,$SearchFilterManagedFolders,$FolderView)
If the “MaFold” folder is NOT FOUND add a log entry and take no action
if ($FindFolderResultsArchiveManagedFolders.TotalCount -eq 0)
{
Write-host “MaFold (ARCHIVE) DOES NOT EXIST: $($Mailbox)”
“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”) MaFold (ARCHIVE) DOES NOT EXIST: $($Mailbox)” | out-file $LogPath -Append
}
If the “MaFold” folder is FOUND look for subfolder “HistItems”
else
{
Search for subfolder “HistItems”
$FindFolderResultsArchiveHistItems = $service.FindFolders($FindFolderResultsArchiveManagedFolders.id,$SearchFilterHistItems,$FolderView)
If the “HistItems” folder is NOT FOUND add a log entry and take no action
if ($FindFolderResultsArchiveHistItems.TotalCount -eq 0)
{
Write-host “HistItems (ARCHIVE) DOES NOT EXIST: $($Mailbox)”
“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”) HistItems (ARCHIVE) DOES NOT EXIST: $($Mailbox)” | out-file $LogPath -Append
}
If the “HistItems” folder is FOUND assign the never delete tag
Else
{
Bind to “HistItems” folder
$Folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$FindFolderResultsArchiveHistItems.Folders[0].Id)
Set property values: PR_POLICY_TAG [0x3019], PR_RETENTION_FLAGS [0x301D], PR_RETENTION_PERIOD [0x301A]
$Folder.SetExtendedProperty($RetentionFlags, 137)
$Folder.SetExtendedProperty($RetentionPeriod, 0)
$Folder.SetExtendedProperty($PolicyTag, $PolicyTagGUID.ToByteArray())
Apply the changes to the folder
$Folder.Update()
Write-host “Retention policy stamped on HistItems (ARCHIVE): $($Mailbox)”
“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”) Retention policy stamped on HistItems (ARCHIVE): $($Mailbox)” | out-file $LogPath -Append
} # else Inner Archive Mailbox END
} # else Outer Archive Mailbox END
######### Archive Mailbox END #########
Make sure the user is NULLed out for good measure before processing the next
$service.ImpersonatedUserId = $null
} # Function TagNeverDelete END
}CATCH{$E = $_ | select Exception;“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”) Error Function TagNeverDelete: $($E)” | out-file $ErrorLogPath -Append}
FUNCTION END
Create credential object using pass hash file previously created:
TRY{
$Username = “user@domain.com”
$Password = Get-Content “C:\HashFile.pwd” | ConvertTo-SecureString
$Credential = New-Object System.Management.Automation.PSCredential($Username,$Password)
}CATCH{$E = $_ | select Exception;“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”) Error Credential Create: $($E)” | out-file $ErrorLogPath -Append}
Connect to EXO. Import only necessary Exchange cmdlets.
#########################################################################################################################
TRY{
$SessionEXO = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $Credential -Authentication Basic -AllowRedirection
$ImportResultsEXO = Import-PSSession $SessionEXO -Prefix EXO -CommandName “Get-Mailbox”, “start-managedfolderassistant”, “Get-MailboxFolderStatistics” -DisableNameChecking
}CATCH{$E = $_ | select Exception;“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”) Error Connect Exchange EXO: $($E)” | out-file $ErrorLogPath -Append}
#########################################################################################################################
Import “Microsoft Exchange Web Services Managed API 2.2” to adjust retention properties
TRY{
Import-Module -Name “C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll”
}CATCH{$E = $_ | select Exception;“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”) Error Import WebServices Module: $($E)” | out-file $ErrorLogPath -Append}
TagNeverDelete service setup: Create the service object to access the mailboxes
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList Exchange2013_SP1
$service.Credentials = new-object Microsoft.Exchange.WebServices.Data.WebCredentials -ArgumentList $Credential.UserName, $Credential.GetNetworkCredential().Password
$service.Url= new-object Uri(“https://outlook.office365.com/EWS/Exchange.asmx”)
$service.TraceEnabled = $true
Intiate array to collect the mailbox UPNs
$UPNs = @()
For each mailbox…
foreach($PSTname in $PSTnames)
{
$UserDisplayName = $PSTname -replace (“$ReplaceFileString1”,“”) -replace (“$ReplaceFileString2”,“”) -replace (‘,’,', ') -replace (“$ReplaceFileString3”,“”)
$UserDisplayName
Get the Mailbox UPN, and add them to an array to later use to start the MFA for each mailbox
TRY{
$UPN = (Get-EXOMailbox $UserDisplayName).userprincipalname
$UPNs += $UPN
$StatsArchive = Get-EXOMailboxFolderStatistics $UPN -Archive | sort Name |
select @{n=‘DATE’;e={Get-Date -Format “yyyy-MM-dd HH:mm:ss”}},@{n=‘MBtype’;e={“Archive”}}, Identity, FolderPath, Name, DeletePolicy, ArchivePolicy, CreationTime, LastModifiedTime, FolderType, FolderSize, FolderAndSubfolderSize, ItemsInFolder, VisibleItemsInFolder, HiddenItemsInFolder, DeletedItemsInFolder, ItemsInFolderAndSubfolders, DeletedItemsInFolderAndSubfolders, FolderId
$StatsArchive | Export-Csv $MBstatsBeforeTagPurge -NoTypeInformation -Append -Force
$StatsPrimary = Get-EXOMailboxFolderStatistics $UPN | sort Name |
select @{n=‘DATE’;e={Get-Date -Format “yyyy-MM-dd HH:mm:ss”}},@{n=‘MBtype’;e={“Primary”}}, Identity, FolderPath, Name, DeletePolicy, ArchivePolicy, CreationTime, LastModifiedTime, FolderType, FolderSize, FolderAndSubfolderSize, ItemsInFolder, VisibleItemsInFolder, HiddenItemsInFolder, DeletedItemsInFolder, ItemsInFolderAndSubfolders, DeletedItemsInFolderAndSubfolders, FolderId
$StatsPrimary | Export-Csv $MBstatsBeforeTagPurge -NoTypeInformation -Append -Force
}CATCH{$E = $_ | select Exception;“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”) Error on Get-EXOMailbox for $($UPN): $($E)” | out-file $ErrorLogPath -Append}
Assign never delete to “HistItems” folder
TRY{
Write-host “`n”
“`n” | out-file $LogPath -Append
TagNeverDelete -Mailbox $UPN
Write-host “`n”
“`n” | out-file $LogPath -Append
}CATCH{$E = $_ | select Exception;“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”) Error on TagNeverDelete function for $($UPN): $($E)” | out-file $ErrorLogPath -Append}
Remove…
TRY{
“`n******” | out-file $ItemsReport -Append
“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”): -START- ItemsReport for $($UPN)” | out-file $ItemsReport -Append
“" | out-file $ItemsReport -Append
.\Remove-MessageClassItems.ps1 $UPN -ArchiveOnly -ScanAllFolders -MessageClass ‘IPM.NOTE.type1.Shortcut’ -Credentials $Credential -Impersonation -Server outlook.office365.com -Verbose -Confirm:$false <#-WhatIf:$true#> >> $ItemsReport
"`n" | out-file $ItemsReport -Append
“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”): -END- ItemsReport for $($UPN)” | out-file $ItemsReport -Append
"*****” | out-file $ItemsReport -Append
}CATCH{$E = $_ | select Exception;“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”) Error on Remove-MessageClassItems for $($UPN): $($E)” | out-file $ErrorLogPath -Append}
} # foreach($PSTname… END
sleep 20
Start Managed Folder Assistant to apply newly assigned tag
Foreach($UPN in $UPNs) #{$UPN}
{
Start Managed Folder Assistant to apply tag
TRY{
start-exomanagedfolderassistant $UPN # -WhatIf
Write-host “MaFold Assistant has been run for: $($UPN)” #-foregroundcolor $info
“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”) MaFold Assistant has been run for: $($UPN)” | out-file $LogPath -Append
}CATCH{$E = $_ | select Exception;“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”) Error on start-exomanagedfolderassistant for $($UPN): $($E)” | out-file $ErrorLogPath -Append}
} # Foreach($U… END
sleep 300
Get Mailbox Folder stats after changes
Foreach($UPN in $UPNs) #{$UPN}
{
$StatsArchive = Get-EXOMailboxFolderStatistics $UPN -Archive | sort Name |
select @{n=‘DATE’;e={Get-Date -Format “yyyy-MM-dd HH:mm:ss”}},@{n=‘MBtype’;e={“Archive”}}, Identity, FolderPath, Name, DeletePolicy, ArchivePolicy, CreationTime, LastModifiedTime, FolderType, FolderSize, FolderAndSubfolderSize, ItemsInFolder, VisibleItemsInFolder, HiddenItemsInFolder, DeletedItemsInFolder, ItemsInFolderAndSubfolders, DeletedItemsInFolderAndSubfolders, FolderId
$StatsArchive | Export-Csv $MBstatsAfterTagPurge -NoTypeInformation -Append -Force
$StatsPrimary = Get-EXOMailboxFolderStatistics $UPN | sort Name |
select @{n=‘DATE’;e={Get-Date -Format “yyyy-MM-dd HH:mm:ss”}},@{n=‘MBtype’;e={“Primary”}}, Identity, FolderPath, Name, DeletePolicy, ArchivePolicy, CreationTime, LastModifiedTime, FolderType, FolderSize, FolderAndSubfolderSize, ItemsInFolder, VisibleItemsInFolder, HiddenItemsInFolder, DeletedItemsInFolder, ItemsInFolderAndSubfolders, DeletedItemsInFolderAndSubfolders, FolderId
$StatsPrimary | Export-Csv $MBstatsAfterTagPurge -NoTypeInformation -Append -Force
} # Foreach($UPN… END
Stop-Transcript
}CATCH{$E = $_ | select Exception;“$(Get-Date -Format “yyyy-MM-dd HH:mm:ss”) Error Caught Main: $($E)” | out-file $ErrorLogPath -Append}
FINALLY
{
If(Test-Path $ErrorLogPath)
{
$FE = GC $ErrorLogPath | Out-String
Send-MailMessage -TO “who@domain.com” -From “Purge@domain.com” `
-SmtpServer server2.domain.com `
-Subject “Purge Completed with Errors: $(Get-Date -Format “yyyy-MM-dd HH:mm:ss”)” `
-body “Check Error log on server $($env:computername): `n: $($ErrorLogPath) `n $($FE)”
}
ELSE
{
Send-MailMessage -TO “who@domain.com” -From “Purge@domain.com” `
-SmtpServer server2.domain.com `
-Subject “Purge Completed without Errors: $(Get-Date -Format “yyyy-MM-dd HH:mm:ss”)” `
-body “Completed on server $($env:computername)”
}
} # FINALLY END
[/pre]