Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Scan through mailboxes and delete folder with specific name
- <#
- .SYNOPSIS
- Uses EWS to scan Exchange mailboxes for folders with a specific name and deletes them.
- .DESCRIPTION
- This script is designed to find folders with a specific name in Exchange mailboxes. It can scan multiple mailboxes and find all the folders that fit the criteria. It will save a CSV report file with the details of each folder (Mailbox, FolderName, FolderId). It will also save a debug log. If you choose, it will also delete each found folder.
- .PARAMETER LogDirectory
- Specifies a path to a folder in which the log and report files are to be written. Paths that contain spaces must be enclosed in quotes. The default is the same folder as contains the script.
- .PARAMETER Mailbox
- Specifies the name of a mailbox to scan for items matching the size criteria. This must be in the format of an SMTP address, e.g., "user1@domain.com". Multiple mailboxes can specified, separated by commas.
- .PARAMETER InputObject
- Specifies the mailbox to scan for items matching the size criteria. This must be in the format of an object containing a PrimarySMTPAddress property, such as the Microsoft.Exchange.Data.Directory.Management.Mailbox or Microsoft.Exchange.Data.WebServices.Mailbox object types. This parameter allows the script to accept pipeline input from the Exchange Management Shell's Get-Mailbox cmdlet.
- .PARAMETER Timeout
- Specifies the Timeout parameter of the ExchangeService object, in milliseconds. Default value is 100000 (100 seconds) if not specified. See https://msdn.microsoft.com/en-us/library/office/microsoft.exchange.webservices.data.exchangeservicebase.timeout%28v=exchg.80%29.aspx
- .PARAMETER EWSUrl
- Specifies an explicit URL to Exchange Web Services (EWS). Use this if Autodiscover fails to discover the EWS URL.
- .PARAMETER RunAsAlternateUser
- Allows the user to send the EWS requests as a different user than the one who is running the PowerShell session. Use this if the PowerShell user does not have access to all the mailboxes you want to scan. This is a switch parameter which will pop up a credential prompt at the start of the script; you do not have to supply any part of the credentials on the command line.
- .PARAMETER FolderName
- This is the name of the folder you want to find and delete.
- .PARAMETER Delete
- Add this parameter to delete the found folders. Without it, the script will just generate a report.
- .EXAMPLE
- .\DeleteSpecificExchangeFolder.ps1 -Mailbox BobDole@didntwin.com -FolderName "FindMe"
- Scans the BobDole@didntwin.com mailbox and writes a report of all folders named "FindMe"
- .EXAMPLE
- .\DeleteSpecificExchangeFolder.ps1 -Mailbox AlGore@didntwin.com,JohnKerry@didntwin.com -FolderName "Skype for Business Contacts" -Delete
- Scans the mailboxes of AlGore@didntwin.com and JohnKerry@didntwin.com for all folders named "Skype for Business Contacts" and deletes them.
- .EXAMPLE
- Get-Mailbox *@didntwin.com | .\DeleteSpecificExchangeFolder.ps1 -FolderName "Skype for Business Contacts" -Delete -EWSUrl "https://mail.didntwin.com/ews/exchange.asmx" -Timeout 200000 -RunAsAlternateUser
- Scans all mailboxes returned by the Get-Mailbox cmdlet, reporting on and deleting all folders named "Skype for Business Contacts". The scan's EWS requests will use the specific URL provided (instead of relying on the Autodiscover service), they will have an extended timeout of 200 seconds, and they will be sent using a separate set of credentials entered in a secure prompt.
- #>
- Param
- (
- [Alias("o")]
- [ValidateScript({Test-Path -Path $_ -IsValid})]
- [string]
- $LogDirectory = (Split-Path -Parent $MyInvocation.MyCommand.Path)
- ,
- [Alias("m")]
- [Parameter(Mandatory=$true, ParameterSetName="typed")]
- [string]
- $Mailbox
- ,
- [Alias("f")]
- [Parameter(Mandatory=$true)]
- [string]
- $FolderName
- ,
- [Alias("d")]
- [switch]
- $Delete
- ,
- [Parameter(Mandatory=$true, ParameterSetName="piped", ValueFromPipeline=$true)]
- #[Microsoft.Exchange.Data.Directory.Management.Mailbox]
- $InputObject
- ,
- [Alias("t")]
- [int]
- $Timeout = 100000
- ,
- [Alias("ews")]
- [string]
- $EWSUrl
- ,
- [switch]
- $RunAsAlternateUser
- )
- #region Functions
- #------------------------#
- # Define our functions #
- #------------------------#
- Function Log-Line
- {
- Param ($logtext)
- Out-File -InputObject "$(Get-Date -Format HH:mm:ss.fff) $logtext" -FilePath $Logfile -Append
- Write-Verbose $logtext
- }
- Function Find-NamedFolder
- {
- Param
- (
- [string]
- $Name
- ,
- [string]
- $Mailbox
- )
- $mbx = New-Object Microsoft.Exchange.WebServices.Data.Mailbox($Mailbox)
- $TOISFolderId = New-Object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$mbx)
- $FolderFilter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,$Name)
- $FolderView = New-Object Microsoft.Exchange.WebServices.Data.FolderView(100)
- $FolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep
- $FolderPropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::IdOnly)
- $FolderPropertySet.Add([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName)
- $FolderResults = $exchService.FindFolders($TOISFolderId,$FolderFilter,$FolderView)
- Return $FolderResults
- }
- #-----------------------------#
- # End function definitions #
- #-----------------------------#
- #endregion Functions
- #-------------------#
- # Setup logging #
- #-------------------#
- # Create log file path if it does not exist
- If ((Test-Path $LogDirectory) -eq $false) {mkdir $LogDirectory | Out-Null}
- $Logfilesuffix = (Get-Date -Format yyyyMMddHHmmss) + "_" + (Get-Random).ToString().Substring(0,3)
- $Logfile = "$LogDirectory\DeleteSpecificExchangeFolder_Log_$Logfilesuffix.log"
- # Initialize new log file
- Out-File -InputObject "Delete Specific Exchange Folder Script`n`n" -FilePath $Logfile
- Log-Line "Start of script"
- # Collect start time for metrics
- $starttime = Get-Date
- #-------------------#
- # End Logging setup #
- #-------------------#
- #------------------------------#
- # Start of main script #
- #------------------------------#
- # Load Exchange dependencies
- Log-Line "Loading Exchange dependencies..."
- If (-not (Get-Module Microsoft.Exchange.WebServices)) {Import-Module -Name ".\Microsoft.Exchange.WebServices.dll" -ErrorAction Stop}
- Log-Line "Exchange dependencies loaded"
- Log-Line "Setting up Exchange objects..."
- Log-Line "Creating ExchangeService object"
- $exchService = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService
- # Get credentials for the alternate user
- if ($RunAsAlternateUser)
- {
- $psCreds = Get-Credential -Message "Type the credentials of a user with access to all mailboxes. Use DOMAIN\User format." -UserName ($env:USERDOMAIN + "\" + $env:USERNAME)
- # Convert to the format used by ExchangeService object
- $exchService.Credentials = $psCreds.GetNetworkCredential()
- }
- # Otherwise just use the credentials of whoever is running PowerShell
- else
- {$exchService.UseDefaultCredentials = $true}
- $exchService.Timeout = $Timeout
- # Get the mailboxes to process
- $mailboxes = @()
- if ($PSCmdlet.ParameterSetName -eq "typed")
- {$mailboxes += $Mailbox}
- elseif ($PSCmdlet.ParameterSetName -eq "piped")
- {
- foreach ($i in $input)
- {
- $mailboxes += $i.PrimarySmtpAddress.ToString()
- }
- }
- Log-Line "Found $($mailboxes.Count) mailboxes to process"
- $MailboxCounter = 1
- $TotalFolderCounter = 0
- $TotalDeleteCounter = 0
- :mailboxLoop foreach ($mbx in $mailboxes)
- {
- Log-Line "Processing mailbox $MailboxCounter of $($mailboxes.Count): [$mbx]"
- Write-Progress -Id 1 -Activity "Processing Mailboxes" -Status "Mailbox $MailboxCounter of $($mailboxes.Count)" -PercentComplete (($MailboxCounter/$mailboxes.Count) * 100) -CurrentOperation "[$mbx]"
- If ($EWSUrl)
- {
- Log-Line "Setting EWS virtual directory from parameter value: $EWSUrl"
- $exchService.Url = $EWSUrl
- }
- Else
- {
- Log-Line "Setting EWS virtual directory from Autodiscover for mailbox [$mbx]"
- $exchService.AutodiscoverUrl($mbx)
- }
- try
- {
- $FoldersToCheck = Find-NamedFolder -Mailbox $mbx -Name $FolderName
- Log-Line "Found $($FoldersToCheck.Count) folders in the mailbox [$mbx]"
- }
- catch
- {
- if ($_.Exception.Message.Contains("The specified object was not found in the store."))
- {
- Write-Warning "Could not enumerate folders in the mailbox [$mbx]. Are you sure you have access to this mailbox?"
- }
- Log-Line "Error reading folders in mailbox [mbx]. Error type: $($_.Exception.GetType().FullName) Error message: $($_.Exception.Message)"
- Write-Error -ErrorRecord $_
- Continue mailboxLoop
- }
- # Iterate through each folder
- $FolderCounter = 1
- :folderLoop foreach ($folder in $FoldersToCheck)
- {
- Log-Line "Processing folder $FolderCounter of $($FoldersToCheck.Count) - Name: [$($folder.DisplayName)] - FolderId: [$($folder.Id)]"
- Write-Progress -Id 2 -ParentId 1 -Activity "Processing Folders in [$mbx]" -Status "Folder $FolderCounter of $($FoldersToCheck.Count)" -PercentComplete (($FolderCounter/$FoldersToCheck.Count) * 100) -CurrentOperation "[$($folder.DisplayName)]"
- $DeletionSuccess = $false
- try
- {
- if ($Delete)
- {
- # Deletes to Recoverable Items in case you change your mind
- $folder.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::SoftDelete)
- $DeletionSuccess = $true
- $TotalDeleteCounter ++
- }
- }
- catch
- {
- }
- finally
- {
- $FolderCounter ++
- $TotalFolderCounter ++
- Log-Line "Processing complete for folder [$($folder.DisplayName)] with FolderId [$($folder.Id)]. Deletion attempted: [$Delete] Deletion completed: [$DeletionSuccess]"
- }
- } # end of folderloop
- $MailboxCounter ++
- Log-Line "Processing complete for mailbox [$mbx]"
- } # end of mailbox loop
- Log-Line "End of script processing"
- #------------------------#
- # End of main script #
- #------------------------#
- # Collect end time for metrics
- $endtime = Get-Date
- Log-Line "`n`nTotal runtime: $($endtime - $starttime)"
- Log-Line "`n`nTotal mailboxes processed: $MailboxCounter"
- Log-Line "`n`nTotal folders with name [$FolderName] found: $TotalFolderCounter"
- Log-Line "`n`nTotal folders with name [$FolderName] successfully deleted: $TotalDeleteCounter"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement