November 22, 2014

Powershell storage analysis

So on a daily basis we have a report emailed to us with the current total storage and a percentage of that storage that is free.
It’s definitely easier than logging into servers and calculating the amount of storage on every mount point.

The powershell script works in 2 ways.
1) The powershell script itself (storagereport.ps1) and the server list (serverlist.txt) that it references. If you are adding or subtracting servers from the environment, just add or subtract them from the serverlist.txt and save the file in the same directory as the powershell script.

I suggest creating a folder on the server that this report will run from and putting in a text file with a list of servers, then referencing this list in your script.

Script (storagereport.ps1)
$TotalGB = @{Name="Capacity(GB)";expression={[math]::round(($_.Capacity/ 1073741824),2)}}
$FreeGB = @{Name="FreeSpace(GB)";expression={[math]::round(($_.FreeSpace / 1073741824),2)}}
$FreePerc = @{Name="Free(%)";expression={[math]::round(((($_.FreeSpace / 1073741824)/($_.Capacity / 1073741824)) *


function get-mountpoints {
$volumes =Get-WmiObject -computer $server win32_volume | Where-object {$_.DriveLetter -eq $null -and $ -like

"*Indexvol*" }
$volumes | Select SystemName, Label, $TotalGB, $FreeGB, $FreePerc |ConvertTo-HTML -head $a | add-content



remove-item C:\<user>\<ServerStorage>.htm
$servers = (Get-Content c:\<user>\serverlist.txt)

foreach ($server in $servers){
Invoke-Expression C:\<user>\<ServerStorage>.htm

# Send email as a HTML body.
$smtpServer = "smtp.<domain>.com"
$mailto = "<username>@<domain>.com,"

$msg = new-object Net.Mail.MailMessage  
$smtp = new-object Net.Mail.SmtpClient($smtpServer) 
$msg.From = $MailFrom
$msg.IsBodyHTML = $true
$msg.Subject = "My exchange Storage Report."
$MailTextT =  Get-Content  -Path C:\<user>\<ServerStorage>.htm
$msg.Body = $MailTextT

Server list (serverlist.txt)

As you add and remove servers from your environment, update the serverlist.txt to ensure it will appear on your report.

To add/remove recipients to the email report, amend the $mailto = section in the script to reflect your new addition (eg),,

# Send email as a HTML body.
$smtpServer = "smtp.<domain>.com"
$mailto = "<username>@<domain>.com,"

Once all have been configured. Create a scheduled task to run the report daily. This will automatically send the report out via email daily as a result.

November 21, 2014

Moving mass Mailboxes from Exchange 2003 to Exchange 2010

Assuming you already have Exchange 2003 and Exchange 2010 working in co-existence in your large single forest environment. These are the following steps you need to take when moving mailboxes in bulk from exchange 2003 to exchange 2010.

1) You need to take a look at your .config file on your target Exchange 2010 CAS server. By default the maximum number of mailboxes you can move at a given time is 2. If you are moving mailboxes in bulk you will need to increase it to your desired number of mailbox moves, in this example, we'll make it 50.

In a normal installation of exchange, you will find the .config file located here to edit in notepad:

C:\Program Files\Microsoft\ExchangeServer\V14\Bin\MSExchangeMailboxReplication.exe.config

MaxActiveMovesPerSourceMDB = "50"
MaxActiveMovesPerTargetMDB = "50"
MaxActiveMovesPerSourceServer = "50"
MaxActiveMovesPerTargetServer = "50"

After making the above changes, you will need to restart Microsoft Exchange Mailbox Replication service. 

Note: I recommend making these changes afterhours in any environment. Restarting this service will not disrupt mailflow during the business day but it is ideal practise to make these changes after hours in your environment.

2) Create a .csv file having the Alias or Displayname in the format below and save it as batchusers.csv


Then you need to run the command from the Exchange Management Shell on your Exchange 2010 server.

Import-CSV "C:\Batchusers.csv" | foreach {New-MoveRequest -Identity $_.alias -TargetDatabase $_.TargetDatabase}

With a baditemlimit parameter in there as well:

Import-CSV "C:\Batchusers.csv" | foreach {New-MoveRequest -Identity $_.alias -TargetDatabase $_.TargetDatabase -BadItemLimit 100}

You can also use the Get-Content switch to move mailboxes in bulk. Some may say this is easier. Using the Display Name or alias of Users and in notepad, save the notepad file as a .txt file like batchusers.txt
In Exchange Management Shell type this command:

Get-Content -Path C:\MoveMailbox\batchusers.txt | New-MoveRequest -TargetDatabase "NameOfMailboxDatabase"