MDTMonitor.psm1
$programdata = $env:programdata $Global:Current_Folder = $PSScriptRoot $Date = get-date <#.Synopsis The MDTMonitor function allows you to monitor your MDT deployment. You'll be able to list all your current installations that have been done through your MDT Deployment Share 1 / Type your Monitoring Host 2 / Choose an action - List: This option allows you to display current installations in a web report - Check a computer: This option allows you to be notified about a specific deployment 3 / If you have selected check, you will have to choose a notification type: - Cortana - Windows notification - WPF GUI .DESCRIPTION -Myhost: Allows you to type your Monitoring Host -Remember: Allows you to remember the Monitoring Host. This way, next time you'll run the mdtmonitor cmdlet you won't need to type your Monitoring Host MDTMonitor cmdlet using with all parameters MDTMonitor -myhost:MyHost -remmeber .NOTES Author: Damien VAN ROBAEYS - @syst_and_deploy - http://www.systanddeploy.com #> Function MDTMonitor { [CmdletBinding()] Param( [Parameter(Mandatory=$false,ValueFromPipeline=$true, position=1)] [string] $myHost, [Parameter(Mandatory=$False,Position=1)] [switch] $Remember ) Begin { Try { $Monitoring_Host_Txt = "$programdata\Monitoring_Host.txt" If (test-path $Monitoring_Host_Txt) { $Monitoring_Host_Content = get-content $Monitoring_Host_Txt If ($Monitoring_Host_Content -ne $null) { $myHost = $Monitoring_Host_Content $Web_Monitoring_URL = "http://" + $Monitoring_Host_Content + ":9801/MDTMonitorData/Computers/" $Data = Invoke-RestMethod $Web_Monitoring_URL } } Else { If (!($myHost)) { write-host "" [string]$myHost = read-host "Please type your monitoring host:" } If ($Remember) { If (!($Monitoring_Host_Txt)) { new-item $Monitoring_Host_Txt -force -type file } Add-content -path $Monitoring_Host_Txt -value $myHost } $Web_Monitoring_URL = "http://" + $myHost + ":9801/MDTMonitorData/Computers/" $Data = Invoke-RestMethod $Web_Monitoring_URL } } Catch { write-host "" write-host "" write-host "***********************************************" write-host " !!! Can not reach the Monitoring host" -foregroundcolor "Yellow" write-host "***********************************************" write-host "" break } } Process { $List = $False $Check = $False function Get_My_MonitoringData { $Data = Invoke-RestMethod $Web_Monitoring_URL foreach($property in ($Data.content.properties)) { $Percent = $property.PercentComplete.'#text' $Current_Steps = $property.CurrentStep.'#text' $Total_Steps = $property.TotalSteps.'#text' If ($Current_Steps -eq $Total_Steps) { If ($Percent -eq $null) { $Step_Status = "Not started" } Else { $Step_Status = "$Current_Steps / $Total_Steps" } } Else { $Step_Status = "$Current_Steps / $Total_Steps" } $Step_Name = $property.StepName If ($Percent -eq 100) { $Global:StepName = "Deployment finished" $Percent_Value = $Percent + "%" } Else { If ($Step_Name -eq "") { If ($Percent -gt 0) { $Global:StepName = "Computer restarted" $Percent_Value = $Percent + "%" } Else { $Global:StepName = "Deployment not started" $Percent_Value = "Not started" } } Else { $Global:StepName = $property.StepName $Percent_Value = $Percent + "%" } } $Deploy_Status = $property.DeploymentStatus.'#text' If (($Percent -eq 100) -and ($Step_Name -eq "") -and ($Deploy_Status -eq 1)) { $Global:StepName = "Running in PE" } $End_Time = $property.EndTime.'#text' If ($End_Time -eq $null) { If ($Percent -eq $null) { $EndTime = "Not started" $Ellapsed = "Not started" } Else { $EndTime = "Not finished" $Ellapsed = "Not finished" } } Else { $EndTime = ([datetime]$($property.EndTime.'#text')).ToLocalTime().ToString('HH:mm:ss') $Ellapsed = new-timespan -start ([datetime]$($property.starttime.'#text')).ToString('HH:mm:ss') -end ([datetime]$($property.endTime.'#text')).ToString('HH:mm:ss'); } New-Object PSObject -Property @{ "DeployID" = $($property.UniqueID.'#text'); "Computer Name" = $($property.Name); PercentNumber = $($property.PercentComplete.'#text'); "Percent Complete" = $Percent_Value; "Step Name" = $StepName; "Step status" = $Step_Status; Warnings = $($property.Warnings.'#text'); Errors = $($property.Errors.'#text'); DeployStatus = $($property.DeploymentStatus.'#text' ); "Deployment Status" = $( Switch ($property.DeploymentStatus.'#text') { 1 { "Running" } 2 { "Failed" } 3 { "Success" } 4 { "Unresponsive" } Default { "Unknown" } } ); "Date" = $($property.StartTime.'#text').split("T")[0]; "Start time" = ([datetime]$($property.StartTime.'#text')).ToLocalTime().ToString('HH:mm:ss') "End time" = $EndTime; "Ellapsed time" = $Ellapsed; } } } [int]$Task_Choice = 0 while ($Task_Choice -lt 1 -or $Task_Choice -gt 3) { Write-host "" Write-host "===================================================================================================" -foregroundcolor cyan Write-host " MDT Monitoring: Choose an action to perform from $myHost" Write-host "===================================================================================================" -foregroundcolor cyan Write-host "1. List deployment from the MDT server" Write-host "2. Check the deployment status of a specific computer, and be notified when install is finished" Write-host "3. Quit and exit" Write-host "" [Int]$Task_Choice = read-host "Please enter an option 1 to 3" Switch($Task_Choice) { 1 { $List = $True } 2 { $Check = $True } 3{exit} } } If ($List -eq $True) { $HTML_Deployment_List = "$programdata\Monitoring_List.htm" $AllDatas = Get_My_MonitoringData | Select Date, "Computer Name", "Percent Complete", PercentNumber, "Step Name", Warnings, Errors, "Start time", "End Time", "Ellapsed time", "Step status", "Deployment Status" If ($AllDatas -eq $null) { $Alert_Type = "'alert alert-warning alert-dismissible'" $Alert_Title = "Oops !!!" $Alert_Message = " There is no deployment in your monitoring history" $NB_Success = "0" $NB_Failed = "0" $NB_Runnning = "0" $Search = "" } Else { $Search = " <p> Type something like computer name, deployment status, step name...</p> <input class='form-control' id='myInput' type='text' placeholder='Search..'> " $NB_Success = ($AllDatas | Where {$_."Deployment Status" -eq "Success"}).count $NB_Failed = ($AllDatas | Where {$_."Deployment Status" -eq "Failed"}).count $NB_Runnning = ($AllDatas | Where {$_."Deployment Status" -eq "Running"}).count $NB_Unresponsive = ($AllDatas | Where {$_."Deployment Status" -eq "Unresponsive"}).count If ($NB_Success -eq $null) { $NB_Success = 0 } If ($NB_Failed -eq $null) { $NB_Failed = 0 } If ($NB_Runnning -eq $null) { $NB_Runnning = 0 } If ($NB_Unresponsive -eq $null) { $NB_Unresponsive = 0 } If (($NB_Failed -ne 0) -or ($NB_Unresponsive -ne 0)) { $Alert_Type = "'alert alert-danger alert-dismissible'" $Alert_Title = "Oops !!!" $Alert_Message = " There is an issue during one of your deployments" } ElseIf (($NB_Failed -eq 0) -and ($NB_Success -ne 0) -and ($NB_Runnning -eq 0)) { $Alert_Type = "'alert alert-success alert-dismissible'" $Alert_Title = "Congrats !!!" $Alert_Message = " All your deployments have been completed with success" } ElseIf (($NB_Failed -eq 0) -and ($NB_Success -eq 0) -and ($NB_Runnning -ne 0)) { $Alert_Type = "'alert alert-info alert-dismissible'" $Alert_Title = "Info !!!" $Alert_Message = " All your computers are currently being installed" } } $head = ' <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script> ' $Title = " <p align='center' > <img src="""" width='' height=''/> <br><br> <span class='text-primary font-weight-bold lead'>MDT deployment Status</span> <br><span class=text-success font-italic>This document has been updated on $Date</span></p> " $Badges = " <div id='demo' class='show' align='center'> <button type='button' class='btn btn-primary'> Running <span class='badge badge-light'>$NB_Runnning</span> </button> <button type='button' class='btn btn-success'> Success <span class='badge badge-light'>$NB_Success</span> </button> <button type='button' class='btn btn-danger'> Failed <span class='badge badge-light'>$NB_Failed</span> </button> <button type='button' class='btn btn-warning'> Unresponsive <span class='badge badge-light'>$NB_Unresponsive</span> </button> </div> <br> " $Alert = " <div class=$Alert_Type> <button type='button' class='close' data-dismiss='alert'>×</button> <strong>$Alert_Title</strong>$Alert_Message </div> " $Script = ' <script> $(document).ready(function(){ $("#myInput").on("keyup", function() { var value = $(this).val().toLowerCase(); $("#myTable tr").filter(function() { $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1) }); }); }); </script> ' $MyData = Get_My_MonitoringData | Select Date, "Computer Name", "Percent Complete", "Step Name", Warnings, Errors, "Start time", "End Time", "Ellapsed time", "Step status", "Deployment Status" | Sort -Property Date | ConvertTo-HTML ` -head $head -body "$title<br>$Badges<br>$Alert<br>$Search<br>$MyData<br>$Script" | ForEach { if($_ -like "*<td>Failed</td>*"){$_ -replace "<tr>", "<tr class=table-danger>"} elseif($_ -like "*<td>Success</td>*"){$_ -replace "<tr>", "<tr class=table-success>"} elseif($_ -like "*<td>Running</td>*"){$_ -replace "<tr>", "<tr class=table-primary>"} elseif(($_ -like "*<td>Unresponsive</td>*") -or ($_ -like "*<td>Unknown</td>*")){$_ -replace "<tr>", "<tr class=table-warning>"} else{$_} } > $HTML_Deployment_List $HTML = get-content $HTML_Deployment_List $HTML.replace("<table>","<table class=table>").replace("<tr><th>Date",'<thead class="thead-dark"><tr><th>Date').replace('Deployment Status</th></tr>','Deployment Status</th></tr></thead><tbody id="myTable">').replace('</td></tr></table>','</td></tr></tbody></table>') | out-file -encoding ASCII $HTML_Deployment_List Invoke-Item $HTML_Deployment_List } If ($Check) { $AllDatas = Get_My_MonitoringData | Select Date, "Computer Name", DeployID, "Percent Complete", PercentNumber, "Step Name", Warnings, Errors, "Start time", "End Time", "Ellapsed time", DeployStatus, "Deployment Status" #| where {$_.ComputerName -eq $MyComputer} If ($AllDatas -eq $null) { write-host "" Write-host "===================================================================================================" -foregroundcolor cyan write-host " !!! There is no computer in your Monitoring history" -foregroundcolor yellow Write-host "===================================================================================================" -foregroundcolor cyan write-host "" break } $Computer_Choice = @{} write-host "" Write-host "===================================================================================================" -foregroundcolor cyan write-host " MDT Monitoring: Computer selection" Write-host "===================================================================================================" -foregroundcolor cyan for ($i=1;$i -le $AllDatas.count; $i++) { Write-Host "$i. Computer name: $($AllDatas[$i-1].'Computer Name')" " - " "Status: $($AllDatas[$i-1].'Deployment Status')" " - " "Percent: $($AllDatas[$i-1].'Percent Complete')" $Computer_Choice.Add($i,($AllDatas[$i-1].DeployID)) } write-host "" [int]$ComputerToMonitor = Read-Host "Please select the computer to monitor" $MyComputerID = $Computer_Choice.Item($ComputerToMonitor) $AllDatas = $AllDatas | where {$_.deployid -eq $MyComputerID} Function AnalyzeMyComputer { Do { $Deployment_Date = $AllDatas.Date $Deployment_ComputerName = $AllDatas."Computer name" $Deployment_Status = $AllDatas.DeployStatus $Deployment_LastTime = $AllDatas.LastTime $Deployment_StepName = $AllDatas."Step Name" $Deployment_Warnings = $AllDatas.Warnings $Deployment_Errors = $AllDatas.Errors $Deployment_Percent_Complete = $AllDatas.PercentNumber $Deployment_Start_time = $AllDatas."Start time" $Deployment_End_time = $AllDatas."End Time" $Deployment_Ellapsedtime = $AllDatas."Ellapsed time" If ($Deployment_Status -eq 4) # deployment unresponsive { $Notif_Type If ($Notif_Type -eq "Mail") { $Body = "<p> <span>Hello,<br><br> Operating System deployment <strong><span style=color:red>is unresponsive</span></strong> on the computer: <span style=color:blue><strong>$Deployment_ComputerName</strong></span> - $(get-date) <br><br> <span style=color:black> See below some informations about your deployment : <br><br> <strong>Computer name: </strong>$Deployment_ComputerName <br> <strong>Start time: </strong>$Deployment_Start_time <br> <strong>Last time: </strong>$LastTime <br> <strong>Warning: </strong>$Deployment_Warnings <br> <strong>Error: </strong>$Deployment_Errors <br> <strong>Step name: </strong>$Deployment_StepName <br> <strong>Percent: </strong>$PercentNumber % <br><br> Best regards </span> </span></p> " $SecurePassword = Get-Content $File | ConvertTo-SecureString -Key $key $Global:Credential = New-Object System.Management.Automation.PSCredential ($Mail_From, $SecurePassword) write-host "" write-host "Sending the mail..." Try { send-mailmessage -To $Mail_To -From $Mail_From -smtpServer $Mail_SMTP -subject "MDT Monitoring status: Unresponsive - On $Deployment_ComputerName" -body $Body -BodyAsHtml -priority Normal -Credential $Credential -Port "587" -UseSsl write-host " The mail has been sent" -foreground "Cyan" write-host "" } Catch { write-warning "There was an error during the send of the mail" write-host "" write-warning "################################################# ISSUE REPORTED #################################################" $_.Exception.ToString() write-warning "################################################# ISSUE REPORTED #################################################" } } ElseIf ($Notif_Type -eq "Cortana") { $message = "Deployment failure. The computer $Deployment_ComputerName is unresponsive" $speak.Speak("$message") } ElseIf ($Notif_Type -eq "NotifWin") { $message = "Deployment is unresponsive on $Deployment_ComputerName.`nPlease check status of the computer." $notify.showballoontip(10,$title,$Message, ` [system.windows.forms.tooltipicon]::error) } ElseIf ($Notif_Type -eq "GUI") { $Global:Main_Text = "Deployment unresponsive" $Global:Low_Text = "$Deployment_ComputerName is unresponsive - $(get-date)" $Global:Percent_Status = $Get_Monitoring.percentcomplete powershell -sta ".\Monitoring_End_Notification.ps1" -MainText "'$global:Main_Text'" -LowText "'$global:Low_Text'" -PercentStatus "'$global:Percent_Status'" } break } ElseIf ($AllDatas.DeployStatus -eq 3) # Deployment success { If ($Notif_Type -eq "Mail") { $Body = "<p> <span>Hello,<br><br> Operating System deployment <strong><span style=color:green>completed successfully</span></strong> on the computer: <span style=color:blue><strong>$Deployment_ComputerName</strong></span> - $(get-date) <br><br> <span style=color:black> See below some informations about your deployment : <br><br> <strong>Computer name: </strong>$Deployment_ComputerName <br> <strong>Start time: </strong>$Deployment_Start_time <br> <strong>End time: </strong>$Deployment_End_time <br> <strong>Warning: </strong>$Deployment_Warnings <br> <strong>Error: </strong>$Deployment_Errors <br><br> Best regards </span> </span></p> " $SecurePassword = Get-Content $File | ConvertTo-SecureString -Key $key $Global:Credential = New-Object System.Management.Automation.PSCredential ($Mail_From, $SecurePassword) write-host "" write-host "Sending the mail..." Try { send-mailmessage -To $Mail_To -From $Mail_From -smtpServer $Mail_SMTP -subject "MDT Monitoring status: Success - On $Deployment_ComputerName" -body $Body -BodyAsHtml -priority Normal -Credential $Credential -Port "587" -UseSsl write-host " The mail has been sent" -foreground "Cyan" write-host "" } Catch { write-warning "There was an error during the send of the mail" write-host "" write-warning "################################################# ISSUE REPORTED #################################################" $_.Exception.ToString() write-warning "################################################# ISSUE REPORTED #################################################" } } ElseIf ($Notif_Type -eq "Cortana") { $message = "Deployment success on the computer $Deployment_ComputerName" $speak.Speak("$message") } ElseIf ($Notif_Type -eq "NotifWin") { $message = "Deployment success on $Deployment_ComputerName" $notify.showballoontip(10,$title,$Message, ` [system.windows.forms.tooltipicon]::info) } ElseIf ($Notif_Type -eq "GUI") { $Global:Main_Text = "Deployment completed" $Global:Low_Text = "$Deployment_ComputerName is now ready - $(get-date)" $Global:Percent_Status = "100" powershell -sta ".\Monitoring_End_Notification.ps1" -MainText "'$global:Main_Text'" -LowText "'$global:Low_Text'" -PercentStatus "'$global:Percent_Status'" } break } ElseIf ($Deployment_Status -eq 2) # Deployment failed { If ($Notif_Type -eq "Mail") { $Body = "<p> <span>Hello,<br><br> Operating System deployment <strong><span style=color:red>failed</span></strong> on the computer: <span style=color:blue><strong>$Deployment_ComputerName</strong></span> - $(get-date) <br><br> <span style=color:black> See below some informations about your deployment : <br><br> <strong>Computer name: </strong>$Deployment_ComputerName <br> <strong>Start time: </strong>$Deployment_Start_time <br> <strong>Last time: </strong>$Deployment_End_time <br> <strong>Warning: </strong>$Deployment_Warnings <br> <strong>Error: </strong>$Deployment_Errors <br> <strong>Step name: </strong>$Deployment_StepName <br> <strong>Percent: </strong>$Deployment_Percent_Complete <br><br> Best regards </span> </span></p> " $SecurePassword = Get-Content $File | ConvertTo-SecureString -Key $key $Global:Credential = New-Object System.Management.Automation.PSCredential ($Mail_From, $SecurePassword) write-host "" write-host "Sending the mail..." Try { send-mailmessage -To $Mail_To -From $Mail_From -smtpServer $Mail_SMTP -subject "MDT Monitoring status: Failed - On $Deployment_ComputerName" -body $Body -BodyAsHtml -priority Normal -Credential $Credential -Port "587" -UseSsl write-host " The mail has been sent" -foreground "Cyan" write-host "" } Catch { write-warning "There was an error during the send of the mail" write-host "" write-warning "################################################# ISSUE REPORTED #################################################" $_.Exception.ToString() write-warning "################################################# ISSUE REPORTED #################################################" } } ElseIf ($Notif_Type -eq "Cortana") { $message = "Deployment failed on the computer $Deployment_ComputerName. Please check status of the computer." $speak.Speak("$message") } ElseIf ($Notif_Type -eq "NotifWin") { $message = "Deployment failed on $Deployment_ComputerName.`nPlease check status of the computer." $notify.showballoontip(10,$title,$Message, ` [system.windows.forms.tooltipicon]::error) } ElseIf ($Notif_Type -eq "GUI") { $Global:Main_Text = "Deployment failed" $Global:Low_Text = "An error occured on $Deployment_ComputerName - $(get-date)" $Global:Percent_Status = $Get_Monitoring.PercentNumber powershell -sta ".\Monitoring_End_Notification.ps1" -MainText "'$global:Main_Text'" -LowText "'$global:Low_Text'" -PercentStatus "'$global:Percent_Status'" } break } } While ($AllDatas.PercentNumber -lt 100) } [int]$Notification_Option = 0 while ($Notification_Option -lt 1 -or $Notification_Option -gt 5) { Write-host "" Write-host "===================================================================================================" -foregroundcolor cyan Write-host " MDT Monitoring: Choose a notification type" Write-host "===================================================================================================" -foregroundcolor cyan Write-host "1. Mail" Write-host "2. Cortana" Write-host "3. Windows notification" Write-host "4. WPF GUI" Write-host "5. Quit and exit" Write-host "6. Go back" Write-host "" [Int]$Notification_Option = read-host "Please enter an option 1 to 5" Switch($Notification_Option) { 1{ # cd $Current_Folder $Global:Notif_Type = "Mail" $Mail_Config = "$current_folder\Mail_Config.xml" $Global:File = "$current_folder\MDT_Mail_Password.txt" [Byte[]] $Global:key = (1..16) $Mail_Config_Content = [xml](get-content $Mail_Config) $Global:Mail_From = $Mail_Config_Content.Config.mail_from $Global:Mail_To = $Mail_Config_Content.Config.mail_to $Global:Mail_SMTP = $Mail_Config_Content.Config.smtp_server If (($Mail_From -eq "") -or ($Mail_To -eq "") -or ($Mail_SMTP -eq "")) { write-host "" Write-host "===================================================================================================" -foregroundcolor cyan write-host " Mail configuration" -foregroundcolor yellow Write-host "===================================================================================================" -foregroundcolor cyan write-host "" [string]$Global:smtp_server = read-host " Type your SMTP server" [string]$Global:Sender_Mail = read-host " Type mail of the sender" [string]$Global:Sender_Mail_Password = read-host " Type password of the sender (Password of the mail account)" [string]$Global:Receiver_Mail = read-host " Type mail of the receiver" $Password = $Sender_Mail_Password | ConvertTo-SecureString -AsPlainText -Force $Password | ConvertFrom-SecureString -key $key | Out-File $File $Mail_Config_Content.Config.mail_from = $Sender_Mail $Mail_Config_Content.Config.Mail_To = $Receiver_Mail $Mail_Config_Content.Config.smtp_server = $smtp_server $Mail_Config_Content.Save($Mail_Config) write-host "" write-host " Sending a test mail..." $SecurePassword = Get-Content $File | ConvertTo-SecureString -Key $key $Global:Credential = New-Object System.Management.Automation.PSCredential ($Sender_Mail, $SecurePassword) Try { Send-MailMessage -To $Receiver_Mail -From $Sender_Mail -SmtpServer $smtp_server -Credential $Credential -Port "587" -UseSsl -Subject "Test mail" -Body "Test mail" -BodyAsHtml -EA SilentlyContinue write-host " The mail has been sent" -foreground "Cyan" write-host "" } Catch { write-warning "There was an error during the send of the mail" write-host "" write-warning "################################################# ISSUE REPORTED #################################################" $_.Exception.ToString() write-warning "################################################# ISSUE REPORTED #################################################" } } AnalyzeMyComputer } 2{ $Global:Notif_Type = "Cortana" Add-Type -AssemblyName System.speech $speak = New-Object System.Speech.Synthesis.SpeechSynthesizer AnalyzeMyComputer } 3{ $Global:Notif_Type = "NotifWin" [reflection.assembly]::loadwithpartialname("System.Windows.Forms") [reflection.assembly]::loadwithpartialname("System.Drawing") $path = Get-Process -id $pid | Select-Object -ExpandProperty Path $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path) $notify = new-object system.windows.forms.notifyicon $notify.icon = $icon $notify.visible = $true AnalyzeMyComputer } 4{ $Global:Notif_Type = "GUI" cd $Current_Folder AnalyzeMyComputer } 5{exit} 6{$Computer_Choice} } } } } end { } } |