Figured I would share a few scriptlets I’ve written recently. Hopefully some of you may find them useful at some point at least.
Scriptlet 1
Find out all users who live on a specific mailbox without having to type the entire mailbox database name:
get-mailbox -database $(get-mailboxdatabase | where-object {$_.name -like "*Database1*"}) | Format-Table Name,Database -wrap -autosizeScriptlet 2
Get statistics on a specific user without knowing the entire name or if you’d want to find out statistics on all users who have the first name John or last name Doe:
Get-MailboxStatistics -server serverhere | Where-Object {$_.DisplayName -like "*MailboxUserName*"} | Format-Table DisplayName,ItemCount,TotalItemSizeScriptlet 3
When you are in an environment with multiple Mailbox Servers, it may be annoying to find what disconnected mailbox lives on which server since the Exchange Management Console will only connect to one server at a time and when connected, it’ll only show disconnected mailboxes for that specific server. This scriptlet will cycle through all mailbox servers and report back all disconnected mailbox servers and which disconnected mailbox lives on which mailbox server.
$mbx = Get-ExchangeServer | Where-Object {$_.IsMailboxserver -eq $true}
foreach ($server in $mbx) {
Get-Mailboxstatistics -Server $Server | Where-Object { $_.DisconnectDate -ne $null } | Format-Table DisplayName,ItemCount,OriginatingServer -wrap
}Scriptlet 4
Based on a CSV file, export users contacts that were created after a certain start date to a PST file. A copy of how the CSV should be formatted is located here. While the CSV contains multiple columns, the script only utilizes the Account Name column by default. If you want to modify what columns it uses, you can change the line below that starts with $AdName =. After the script pulls the name in the Account Name field, it finds the mailbox using the Get-Mailbox command with the name that was specified in the Account Name field.
$file = "pstusers.csv"
$PSTLocation = "C:\PSTs"
$StartDate = "03/20/2009"
############################################
####### Don't modify below this line #######
############################################
$erroractionpreference = "SilentlyContinue"
if (!(Test-Path -path $PSTLocation)) {
Write-Host "Creating the Directory $PSTLocation" -ForegroundColor Yellow
New-Item -ItemType "Directory" -Path $PSTlocation
}
if (Test-Path $file) {
$excel = Import-CSV $file
foreach ($line in $excel) {
$AdName = $line."Account Name"
$Mailbox = Get-Mailbox $AdName
if ($Mailbox) {
Write-Host "$AdName is being exported to $PSTLocation"
$Mailbox | Export-Mailbox -PSTFolderPath $PSTLocation -StartDate $StartDate -ExcludeFolders "\Inbox","\Deleted Items","\Drafts","\Junk E-mail","\Outbox","\Sent Items","\Journal","\Calendar","\Notes","\Tasks"
}
else { Write-Warning "$ADName Mailbox Does not Exist" }
}
}
else {
Write-Warning "The file $file does not exist"
}Scriptlet 5
If you are familiar with Quest Notes Migrator for Exchange, you may have had the chance to migrate data to a PST file. What you will see, is that the PST gets migrated with the Display Name of the user. For example, we if migrated the Notes mailbox of Elan Shudnow to a PST, the PST file name would be Elan Shudnow.PST. A lot of people won’t want to migrate the PST directly from Quest NME to a user’s home share because that user’s home share may be located in a remote site and opening a PST file across a network isn’t really a good idea; especially over long distances.
So I wrote a script so you can migrate all the PST files locally and then it’ll check the Display Name portion of the PST file and use that display name to find a matching user in AD and then find their home directory and then copy that PST file to that home share.
# Set Location to where the PST files are started
Set-Location "E:\"
$pstData = Get-ChildItem -recurse | Where-Object {$_.Name -like "*.pst"}
function Get-HomeDirectory ($displayName) {
$ads = New-Object System.DirectoryServices.DirectorySearcher([ADSI]'')
$ads.filter = "(&(objectClass=Person)(displayName=$displayName))"
$s = $ads.FindOne()
return $s.GetDirectoryEntry().homeDirectory
}
foreach ($pstUser in $pstData) {
$PSTName = $pstUser.Name
$PSTDisplayName = $pstUser.Name.split(".")[0]
$PSTDisplayName = $PSTDisplayName.split("-")[0]
$Path = $PSTUser.DirectoryName + "\" + $PSTUser.Name
$Directory = Get-HomeDirectory $PSTDisplayName
Copy-Item $Path $Directory
}

I added your blog to favorites Looking for more update.
Thank you for the cool scripts. :)
Could you please add one script or command line ,where we can use both Get-mailbox and Get-MailboxStatistics?
for script 3 how can i get it to either:_a. output in alphabetical order_or_b. output to a spreadsheet like excel so i can sort the order alphabetically_the script is great but having them out of order i have to constantly watch the screen and we have hundreds to go through sometimes.
Change this line:
Get-Mailboxstatistics -Server $Server | Where-Object { $_.DisconnectDate -ne $null } | Select-Object DisplayName,ItemCount,OriginatingServer | Export-CSV C:\file.csv -notypeinformation
Basically, the Format-Table is Powershell Formatting only. Select-Object is agnostic and allows you to pipe the results using Export-CSV.
Do you know how to script the sharing of the calendar for a shared mailbox
Use exfolders for Exchange 2010 and PFDAVAdmin for Exchange 2003/2007.
Hi Elan
Could you please add one script or command line ,where we can use both Get-mailbox and Get-MailboxStatistics?
I have one example ,but its trhrowing error
"MailboxDisplayName,SAMAccount,EmployeeID,Department,ServerName/StoreName,Size,TotalItems,LastLoggedOnUserAccount,LastLogoffTime,LastLogonTime"| out-file GMS.csv;Get-Mailbox -resultsize unlimited -server st-excl21 | Get-MailboxStatistics -server st-excl21 | ForEach{$a = $_.DisplayName;$b=$_.Alias;$c=$_.CustomAttribute12;$d=$_.CustomAttribute4;$e=$_.database;$f=$_.TotalItemSize.Value.ToMB();$g=$_.itemcount;$h=$_.LastLoggedOnUserAccount;$i=$_.LastLogoffTime;$j=$_.LastLogonTime;"$a,$b,$c,$d,$e,$f,$g,$h,$i,$j"} | out-file GMS.csv -Append
Please help
Can’t believe I didn’t know that! *slaps self* Thanks Shay.
Hi Elan,
Scriptlet 1: Get-MailboxDatabase Identity parameter accept wildcard characters so you could skip Where-Object and do:
Get-MailboxDatabase -Identity *Database1* | Format-Table Name,Database -wrap -autosize