Exchange Server Export Mailboxes of Disabled Users
I was asked the other day to get a list of all the mailboxes connected to users disabled on Active Directory.
I fired up Powershell ISE, loaded the Active Directory module and the Exchange snap-ins and started to work on my script.
First of all, I had to get a list of all the users in Active Directory that were disabled. This is very easy to implement using the Get-ADUser cmdlet and the Filter parameter. The company's Identity Management System though when disabling a user, it also moves the object to specific OU named "Disabled". To get those users I used the Get-ADUser cmdlet with the SearchBase and filter paramaters:
Just to make sure that I do not include any active users, I piped the output to a Where-Object cmdlet.
Now that I have all the users I had to check if they had a mailbox. Since the identity of the mailbox may be different that the user's samaccount name, I used the Get-Mailbox cmdlet and the Filter parameter:
I used a variable called "samaccountname" because the engine behind the filter of the Get-Mailbox will not accept the syntax $u.samaccountname. It may work with single and double quotes but I have not tested it...
Since I now have all the mailboxes, what about some statistics? Lets get the size of each mailbox!
In my case, I had to export those mailboxes to a file share as PSTs so I was two cmdlets away.
First I will create the export requests using New-MailboxExportRequest
Depending on the size of the mailboxes, their number and the load on your Exchange servers, you may have to do them in batches.
Since the requests will take some time to finish, you can easily check their status using the Get-MailboxExportRequest cmdlet.
When all requests were completed, I disconnected the mailboxes and removed the requests.
Although the mailboxes will remain in the Exchange Databases for the mailbox retention period defined for each database, I always check the size of the pst files after the export.
In case you want your script to be more robust, you should add try/catch statements to handle any exceptions that my rise.
I fired up Powershell ISE, loaded the Active Directory module and the Exchange snap-ins and started to work on my script.
First of all, I had to get a list of all the users in Active Directory that were disabled. This is very easy to implement using the Get-ADUser cmdlet and the Filter parameter. The company's Identity Management System though when disabling a user, it also moves the object to specific OU named "Disabled". To get those users I used the Get-ADUser cmdlet with the SearchBase and filter paramaters:
1 2 | $users = Get-ADUser -SearchBase "OU=DISABLED, DC=LAB, DC=LOCAL" -Filter * -Properties * | Where-Object {$_.enabled -eq $false} |
Just to make sure that I do not include any active users, I piped the output to a Where-Object cmdlet.
Now that I have all the users I had to check if they had a mailbox. Since the identity of the mailbox may be different that the user's samaccount name, I used the Get-Mailbox cmdlet and the Filter parameter:
1 2 3 4 5 6 7 | $mailboxes = @() foreach($u in $users) { $samaccountname = $u.samaccountname $mailbox = Get-Mailbox -Filter {samaccountname -eq $samaccountname} $mailboxes += $mailbox } |
I used a variable called "samaccountname" because the engine behind the filter of the Get-Mailbox will not accept the syntax $u.samaccountname. It may work with single and double quotes but I have not tested it...
Since I now have all the mailboxes, what about some statistics? Lets get the size of each mailbox!
1 2 3 4 5 6 7 8 9 10 11 12 | $statistics = @() foreach($m in $mailboxes) { $obj = New-Object psobject $obj | Add-Member -MemberType NoteProperty -Name Name -Value $m.name $obj | Add-Member -MemberType NoteProperty -Name Alias -Value $m.alias $obj | Add-Member -MemberType NoteProperty -Name Identity -Value $m.identity $size = (Get-MailboxStatistics -Identity $m.identity).TotalItemSize.Value.ToMB() $obj | Add-Member -MemberType NoteProperty -Name Size -Value $size $statistics += $obj } |
In my case, I had to export those mailboxes to a file share as PSTs so I was two cmdlets away.
First I will create the export requests using New-MailboxExportRequest
1 2 3 4 | foreach($s in $newstatistics) { New-MailboxExportRequest -Mailbox $s.alias -FilePath ("\\FileServer\Share\" + $s.alias + ".pst") -Name $s.alias } |
Depending on the size of the mailboxes, their number and the load on your Exchange servers, you may have to do them in batches.
Since the requests will take some time to finish, you can easily check their status using the Get-MailboxExportRequest cmdlet.
1 2 | Get-MailboxExportRequest | Where-Object {$_.status -ne "Completed"} |
When all requests were completed, I disconnected the mailboxes and removed the requests.
1 2 3 4 5 6 7 | $requests = Get-MailboxExportRequest foreach($r in $requests) { Disable-Mailbox $r.name -Confirm:$false } $requests | Remove-MailboxExportRequest -Confirm:$false |
Although the mailboxes will remain in the Exchange Databases for the mailbox retention period defined for each database, I always check the size of the pst files after the export.
In case you want your script to be more robust, you should add try/catch statements to handle any exceptions that my rise.