#MSExchange #PowerShell
I know, I know I’m a slacker .. w h a t e v e r
So here is the in final script in a my 3 part Exchange 2010 move mailbox process. Change the bits that say “<CHANGE THIS>” .. let me know what you think
<#
.NOTES
NAME: Monitor-MoveRequest.ps1
AUTHOR: Paul Flaherty
Last Edit: v1.8 [30 March 2011]
v1.0 sometime : A script it born
v1.1 09 Jun 2011 : Added more Move-Request status checking
v1.2 16 Jun 2011 : Changed the loop ot use email address instead of name
v1.3 21 Jun 2011 : Updated to collect overall duration properly
v1.4 30 Jul 2011 : Updated with last item in report
v1.5 4 Aug 2011 : Updated so Moverequest report is generated and emailed
v1.6 22 Nov 2011 : Updated the output to put the summary at the top
: Updated with colours on output
v1.7 23 Nov 2011 : Update summary to include GB Transferred
v1.7 30 Mar 2012 : Cleaned up screen output
.LINK
blogs.flaphead.com
.SYNOPSIS
This script performs some preflight checks for mailboxes moves
and should be run before a mailbox move
.DESCRIPTION
This script Monitors Exchange Server 2010 move-requests by generating a webpage
and sending an email once it is complete.
.OUTPUTS
None
.EXAMPLE
Monitor-MoveRequest.ps1
Run the checks using the default csv file
#>
##########################################################################################
PARAM([String]$BatchName = $args[0],
[String]$HTMLOutFolder = "E:PsMonHTML",
[String]$Mailbox="")
$Error.Clear()
#########################################################################################
$AppName = "Monitor-MoveRequest.ps1"
$AppVer = "v1.8 [30 March 2011]"
$Today = Get-Date
$ServerName = hostname
$RunUser = ([System.Security.Principal.WindowsIdentity]::GetCurrent()).Name
##########################################################################################
#Display script name and version
##########################################################################################
CLS
Write-host " " $AppName -NoNewLine -foregroundcolor Green
Write-Host ": " $AppVer -foregroundcolor Green
Write-host "`n Run on $ServerName at $Today by $RunUser" -foregroundcolor Yellow
Write-Host "|——————————————————————-|`n"
##########################################################################################
$xPsCheck = Get-PSSnapin | Select Name | Where {$_.Name -Like "*Exchange*"}
If ($xPsCheck -eq $Null) {Add-PsSnapin Microsoft.Exchange.Management.PowerShell.e2010}
$xBatchName =$BatchName
If ($xBatchName -eq ""){
#Check Environment Variables
Write-Host "Checking Environment Variables .. " -NoNewLine
$envBatchName = [environment]::GetEnvironmentVariable(‘BatchName’,’User’)
Write-Host $envBatchName -Foregroundcolor Green
$xBatchName = $envBatchName
}
Write-Host "Batch Name:….."$xBatchName
Write-Host "Mailbox:…….."$Mailbox
Write-Host "Output Folder:.."$HTMLOutFolder
$xHTMLoutFolder = $HTMLOutFolder
$UserList = @()
$users2Migrate = @()
$htmlHeader = "
<META HTTP-EQUIV=’refresh’ CONTENT=’60’>
<Style>
TABLE{border-width: 1px;padding: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TD{border-width: 1px;padding: 1px;border-style: solid;border-color: black;}
TH{font-family:’Arial’;font-size:12px;border-width: 1px;padding: 1px;border-style: solid;border-color: black;background-color:peachpuff;}
TR{font-family:’Arial’;font-size:10px}
P{font-family:’Arial’;}
</Style>"
$x="<META HTTP-EQUIV=’refresh’ CONTENT=’300′><Style>TABLE{font-family:VERDANA;font-size: 10pt; border-width: 1px;padding: 1px;border-style: solid;border-color: black;border-collapse: collapse;}TD{border-width: 1px;padding: 1px;border-style: solid;border-color: black;}TH{border-width: 1px;padding: 1px;border-style: solid;border-color: black;background-color:peachpuff;}</Style>";
If ($xBatchName -ne ""){
Write-Host "Batch Name: " $xBatchName
Write-Host "`nGetting users from move request " -noNewLine
$GMR = Get-MoveRequest -BatchName $xBatchName -ResultSize unlimited
$msgSubject1 = "From Batch $xBatchName"
$xattachdir = $xBatchname
} #If ($xBatchName -ne "")
If ($Mailbox -ne ""){
Write-Host "Mailbox Name: " $Mailbox
Write-Host "`nGetting users from move request " -noNewLine
$GMR = Get-MoveRequest $Mailbox -ResultSize unlimited
$msgSubject1 = "for $Mailbox "
$xattachdir = $Mailbox
} #If ($Mailbox -ne "")
IF ($GMR -eq $Null){
Write-Host "No Users in BatchName, Exiting" -foregroundcolor red
Exit
}ELSE{
Write-Host $GMR.count "Found" -Foregroundcolor Green
} #IF ($GMR -eq $Null)
Write-Host "Getting mailbox information for users"
$GMBX = $GMR | Get-Mailbox
$GMBX | ForEach{
$xUser = "" | Select Email
$xUser.EMail+= $_.PrimarySmtpAddress.ToString()
$users2Migrate += $xUser
} #ForEach
Write-Host "Checking Users .."
ForEach($xUser in $Users2Migrate){
$tmpemail = $xUser.email
Write-Host "-" $tmpemail
$xUser = "" | Select Name, Email, IsValid, MoveStatus, ActualStatus, Pct, Duration, MailboxSize, ItemCount, ItemDone, BadItemsEncountered, SourceDatabase, TargetDatabase, MRSServerName, Transferred, TransferredPerMinute, PiQ, Message, Status
#Check User is Valid
$tmpmbx = Get-Mailbox $tmpemail
$xUser.Name = $tmpmbx.name
$xUser.Email = $tmpemail
$xUser.IsValid = $tmpmbx.isvalid
if ($tmpmbx.isvalid -eq $True){$xUser.MoveStatus = "Unknown"}ELSE{$xUser.MoveStatus = "ERR";$xUser.IsValid = $False}
$UserList += $xUser
} #ForEach($xUser
$tmpLoop = $true
$tmpcount = $UserList.count
$position = $host.ui.rawui.cursorposition
While ($tmploop){
$now = Get-Date;
$host.ui.rawui.cursorposition=$position;
Write-Host "–> REFRESH " -Foregroundcolor Green
For($i=0;$i -le $TmpCount-1;$i++){
$tmpname
= $UserList[$i].email #v1.2 <- $UserList[$i].name
$tmpgmr = Get-MoveRequestStatistics $tmpname -IncludeReport
$tmpstatus = $tmpgmr.Status
$UserList[$i].ActualStatus = $tmpstatus
$UserList[$i].Pct = $tmpgmr.PercentComplete
switch ($tmpstatus) {
"AutoSuspended" {$UserList[$i].MoveStatus = $tmpstatus}
"Completed" {$UserList[$i].MoveStatus = $tmpstatus}
"CompletedWithWarning" {$UserList[$i].MoveStatus = $tmpstatus}
"Failed" {$UserList[$i].MoveStatus = $tmpstatus}
"Suspended" {$UserList[$i].MoveStatus = $tmpstatus}
default {$UserList[$i].MoveStatus = "Unknown"}
} #Switch
$tmpDur = $tmpgmr | select OverallDuration
$UserList[$i].Duration = $tmpDur.OverallDuration.ToString()
$UserList[$i].BadItemsEncountered = $tmpgmr.BadItemsEncountered
$UserList[$i].ItemDone = $tmpgmr.ItemsTransferred
$UserList[$i].MailboxSize = $tmpgmr.TotalMailboxSize
$UserList[$i].ItemCount = $tmpgmr.TotalMailboxItemCount
$UserList[$i].SourceDatabase = $tmpgmr.SourceDatabase
$UserList[$i].TargetDatabase = $tmpgmr.TargetDatabase
$UserList[$i].MRSServerName = $tmpgmr.MRSServerName
$UserList[$i].Transferred = $tmpgmr.BytesTransferred
$UserList[$i].TransferredPerMinute = $tmpgmr.BytesTransferredPerMinute
$UserList[$i].Message = $tmpgmr.Message
$tmpPiQ = ($tmpgmr.PositionInQueue).ToString()
$tmpLog = $tmpgmr.report.Entries | ForEach{$_.ToString()}
$UserList[$i].Status = $tmpLog[-1]
$UserList[$i].PiQ = ($tmpPiQ.Split(" "))[0]
} #UserList
$host.ui.rawui.cursorposition=$position;
Write-Host "–> " -Foregroundcolor Green
$tmpchk = 0
$UserList | where{$_.MoveStatus -eq "Unknown"} | ForEach {$tmpchk ++}
$xsumHTML = $UserList | group ActualStatus | Select @{Expression={$Now};Label="Now"}, Name, @{Expression={"!AR!" + $_.Count};Label="Count"}, @{Expression={"!AR!" + (($_.Group | Measure-Object Transferred -Sum).sum/1024/1024).ToString("n")};Label="MBTransferred"}, @{Expression={"!AR!" + (($_.Group | Measure-Object MailboxSize -Sum).sum/1024/1024).ToString("n")};Label="TotalMB"} | Sort Name
$xsum = $UserList | group ActualStatus | Select @{Expression={$Now};Label="Now"}, Name, Count, @{Expression={(($_.Group | Measure-Object Transferred -Sum).sum/1024/1024).ToString("n")};Label="MBTransferred"}, @{Expression={ (($_.Group | Measure-Object MailboxSize -Sum).sum/1024/1024).ToString("n")};Label="TotalMB"}
$xsum | ft *
Write-host "<– WAITING: <–" -Foregroundcolor Red
$position=$host.ui.rawui.cursorposition
$position.y = $position.y -1
$xhtml += "
<hr><Style>
TABLE{border-width: 1px;padding: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TD{border-width: 1px;padding: 1px;border-style: solid;border-color: black;}
TH{font-family:’Arial’;font-size:12px;border-width: 1px;padding: 1px;border-style: solid;border-color: black;background-color:peachpuff;}
TR{font-family:’Arial’;font-size:10px}
P{font-family:’Arial’;}
</Style>"
$xhtml2 = $xsumHTML | ConvertTo-Html -Fragment
$today = Get-Date
$z="<B><FONT size=’2′ face=’VERDANA’>Move Requests ($xBatchName)</B></FONT><BR><FONT size=’1′ face=’VERDANA’>Last updated: $today</FONT></FONT><HR size=6 color=Green>[INSERTHERE]<br>"
$xhtml = $userlist | Select Name, Email, IsValid, MoveStatus, ActualStatus, Pct, MailboxSize, ItemCount, ItemDone, SourceDatabase, TargetDatabase, MRSServerName, Transferred, TransferredPerMinute, @{Expression={$_.BadItemsEncountered};Label="BadItems"}, PiQ, Status | sort @{Expression="ActualStatus";Descending=$False}, @{Expression="Pct";Descending=$True}, Name | ConvertTo-Html -head $HtmlHeader -Title "Move Requests" -body $z
#Colour the HTML table up
$txtFAILED = @()
$i=0; $xHTML | foreach{IF ($_ -like "*<td>Failed*"){ $txtFAILED+= $i}; $i++}
$txtFAILED | ForEach{$xHTML[$_] = $xHTML[$_].Replace("<tr>","<tr bgcolor=Red>")}
$txtINPROGRESS = @()
$i=0; $xHTML | foreach{IF ($_ -like "*<td>InProgress*"){ $txtINPROGRESS += $i}; $i++}
$txtINPROGRESS | ForEach{$xHTML[$_] = $xHTML[$_].Replace("<tr>","<tr bgcolor=ORANGE>")}
$txtCOMPLETED = @()
$i=0; $xHTML | foreach{IF ($_ -like "*<td>Completed*"){ $txtCOMPLETED += $i}; $i++}
$txtCOMPLETED | ForEach{$xHTML[$_] = $xHTML[$_].Replace("<tr>","<tr bgcolor=Lime>")}
$txtCOMPLETION = @()
$i=0; $xHTML | foreach{IF ($_ -like "*<td>CompletionInProgress*"){ $txtCOMPLETION += $i}; $i++}
$txtCOMPLETION | ForEach{$xHTML[$_] = $xHTML[$_].Replace("<tr>","<tr bgcolor=Yellow>")}
#Colour the Summary HTML table up
$txtFAILED = @()
$i=0; $xhtml2 | foreach{IF ($_ -like "*<td>Failed*"){ $txtFAILED+= $i}; $i++}
$txtFAILED | ForEach{$xHTML2[$_] = $xHTML2[$_].Replace("<tr>","<tr bgcolor=Red>")}
$txtINPROGRESS = @()
$i=0; $xHTML2 | foreach{IF ($_ -like "*<td>InProgress*"){ $txtINPROGRESS += $i}; $i++}
$txtINPROGRESS | ForEach{$xHTML2[$_] = $xHTML2[$_].Replace("<tr>","<tr bgcolor=ORANGE>")}
$txtCOMPLETED = @()
$i=0; $xHTML2 | foreach{IF ($_ -like "*<td>Completed*"){ $txtCOMPLETED += $i}; $i++}
$txtCOMPLETED | ForEach{$xHTML2[$_] = $xHTML2[$_].Replace("<tr>","<tr bgcolor=Li
me>")}
$txtCOMPLETION = @()
$i=0; $xHTML2 | foreach{IF ($_ -like "*<td>CompletionInProgress*"){ $txtCOMPLETION += $i}; $i++}
$txtCOMPLETION | ForEach{$xHTML2[$_] = $xHTML2[$_].Replace("<tr>","<tr bgcolor=Yellow>")}
$txtAR = @()
$i=0; $xHTML2 | foreach{IF ($_ -like "*>!AR!*"){ $txtAR += $i;}; $i++}
$txtAR | ForEach{$xHTML2[$_] = $xHTML2[$_].Replace(">!AR!"," align=right>")}
$tmpHere = @()
$i=0; $xHTML | foreach{IF ($_ -like "*[INSERTHERE]*"){ $tmpHere += $i}; $i++}
$tmpHere | ForEach{$xHTML[$_] = $xHTML[$_].Replace("[INSERTHERE]",$xhtml2)}
$xhtml| Out-File $xHTMLoutFolderMoveRequestinProgress.html
$tmpPosition = $position;
$tmpPosition.x = $tmpPosition.x + 12
If($tmpChk -eq 0){
$tmpLoop = $False
}ELSE{
FOR($i=0;$i -le 10;$i++){
Sleep 2
$host.ui.rawui.cursorposition=$tmpposition;
Write-Host "#" -foregroundcolor Red
$tmpPosition.x = $tmpPosition.x + 1
} #FOR($i=0;$i -le 10;$i++)
} #If($tmpChk -eq 0)
} #While ($tmploop)
$xsum = $UserList | group ActualStatus | Select Name, Count, @{Expression={(($_.Group | Measure-Object Transferred -Sum).sum/1024/1024/1024).ToString("n")};Label="GB Transferred"}
$xhtml2 = $xsum | ConvertTo-Html -Fragment
$today = Get-Date; $z="<B><FONT size=’2′ face=’VERDANA’>Move Requests ($xBatchName)</B></FONT><BR><FONT size=’1′ face=’VERDANA’>Last updated: $today</FONT></FONT><HR size=6 color=Green>" + $xhtml2 + "<br>"
$OutHTML = $UserList | Select Name, Email, IsValid, MoveStatus, ActualStatus, Pct, Duration, MailboxSize, ItemCount, BadItemsEncountered, SourceDatabase, TargetDatabase, MRSServerName, message | ConvertTo-Html -head $HtmlHeader -Title "Move Requests" -body $z
$xEnd = get-Date
$OutHTML += "
<HR size=6 color=Green>
<FONT size=’1′ face=’VERDANA’>Run by $CurrentUser. Script Completed: $xEnd</FONT>
</FONT><BR></BODY>
</HTML>
"
$OutHTML | Out-File $xHTMLoutFolderMoveRequestinProgress.html
$txtRED = @()
$i=0; $OutHTML | foreach{IF ($_ -like "*<td>Failed*"){ $txtRED += $i}; $i++}
$txtRED | ForEach{$OutHTML[$_] = $OutHTML[$_].Replace("<tr>","<tr bgcolor=Red>")}
$logfiles=@()
ForEach($yUser in $UserList){
$logfile = $Datefolder+""+$xBatchname+"_MoveRequestReport_" + $yuser.email + ".txt"
$movereport=(Get-MoveRequestStatistics $yUser.email -IncludeReport).report
$log = $movereport.Entries | ForEach{$_.ToString()}
$log | Out-File $logfile
$logfiles += $logfile
}
Write-Host "`nSending Email" -Foregroundcolor Red
$emailTo = "<CHANGE THIS>"
$emailFrom = "<CHANGE THIS>"
$SMTPServer = "<CHANGE THIS>"
$msgsubject = "PSM: Move Request Information " + $msgSubject1
$message = New-Object Net.Mail.MailMessage($emailFrom, $emailTo, $msgsubject, $outHTML)
$message.IsBodyHTML = $True
Write-Host "- Adding log attachments" -Foregroundcolor Green
$logfiles | ForEach{
$_
$attachment = New-Object System.Net.Mail.Attachment $_
$message.Attachments.Add($attachment)
}
$smtp = New-Object Net.Mail.SmtpClient($SMTPServer)
$smtp.Send($message)
[environment]::SetEnvironmentVariable(‘BatchName’, ”,’User’)
#End