Monitor-MoveRequest.ps1 v1.8

#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