MSEndpointMgr

Use PowerShell to determine if a Task Sequence has successfully completed

Many of you probably know about Status Filter Rules and how you can configure such to run scripts when a certain status message has been sent to the site server. This method is great for e.g. running a script to email a department or person that for instance a task sequence was successfully executed. I’ve used this method before, but I wanted to know if you can determine the execution status of a task sequence by using the SMS Provider and PowerShell also. And it turns out (no big surprise really) that you can!
The scenario I was faced with at one of my customers recently, was to find a way to get a task sequence successful execution status. They were currently using a web service to accomplish this, but after upgrading their environment to ConfigMgr 2012 R2 the web service became unstable and would intermittently not return any data. So my task was to find a stable solution, and I turned to PowerShell for that.
It turns out that there’s a class called SMS_StatusMessage (you’ll find more information about that class here) where the status messages I was looking for could be located. Since this class holds alot of instances, it’s important that you try to run a query as efficient as possible. That’s why I used the -Filter option of Get-WmiObject instead of the Where-Object cmdlet in the scripts you’ll find below.

How to use the script

Since the customer was using Orchestrator together with ConfigMgr to deploy their devices, I had to build a script that would return a specific value if a task sequence for a specific device had successfully completed. I decided to use a variable called $Status to determine if the Orchestrator workflow could continue or not. The script below will check against a specified Primary Site server (or CAS if you have that), assuming that the SMS Provider is installed locally on the server, if a device has successfully completed a task sequence in the past 24 hours. In this case it was not necessary to also specify exactly what task sequence that had successfully been executed, so that’s why that’s not a part of this script. The Status Message ID that we’re using to accomplish this is 11143.
If you’d like to use this in your environment for another purpose, you could simply replace the $Status = 0 part with additional code that suit your needs.

$SiteServer = "<server_name>"
$SiteCode = "<site_code>"
$ComputerName = "<device_name>"
$TimeFrame = [System.Management.ManagementDateTimeConverter]::ToDmtfDateTime((Get-Date).AddHours(-24))
$Status = 1
$TSSummary = Get-WmiObject -Namespace "root\SMS\site_$($SiteCode)" -Class SMS_StatusMessage -ComputerName $SiteServer -Filter "(Component like 'Task Sequence Engine') AND (MachineName like '$($ComputerName)' AND (MessageID = 11143))" -ErrorAction Stop
$StatusMessageCount = ($TSSummary | Measure-Object).Count
if (($TSSummary -ne $null) -and ($StatusMessageCount -eq 1)) {
    foreach ($Object in $TSSummary) {
        if (($Object.Time -ge $TimeFrame)) {
            $Status = 0
        }
    }
}
elseif (($TSSummary -ne $null) -and ($StatusMessageCount -ge 2)) {
    foreach ($Object in $TSSummary) {
        if ($Object.Time -ge $TimeFrame) {
            $Status = 0
        }
    }
}
else {
    $Status = 1
}

Now this may not be useful for a wider range of environments, but perhaps you’d just want to run a PowerShell script from the console, providing some parameters and then get the computer name and execution success time information directly? Then save the script below as e.g. Get-TSExecutionStatusForDevice.ps1.

[CmdletBinding()]
param(

[parameter(Mandatory=$true)]

$SiteServer,

[parameter(Mandatory=$true)]

$SiteCode,

[parameter(Mandatory=$true)]

$ComputerName,

[parameter(Mandatory=$true)]

$PastHours ) $TimeFrame = [System.Management.ManagementDateTimeConverter]::ToDmtfDateTime((Get-Date).AddHours(-$PastHours)) $TSSummary = Get-WmiObject -Namespace “root\SMS\site_$($SiteCode)” -Class SMS_StatusMessage -ComputerName $SiteServer -Filter “(Component like ‘Task Sequence Engine’) AND (MachineName like ‘$($ComputerName)’ AND (MessageID = 11143))” -ErrorAction Stop $StatusMessageCount = ($TSSummary | Measure-Object).Count if (($TSSummary -ne $null) -and ($StatusMessageCount -eq 1)) { foreach ($Object in $TSSummary) { if (($Object.Time -ge $TimeFrame)) { $PSObject = New-Object -TypeName PSObject -Property @{ SuccessExecutionTime = [System.Management.ManagementDateTimeconverter]::ToDateTime($Object.Time) MachineName = $Object.MachineName } Write-Output $PSObject } } } elseif (($TSSummary -ne $null) -and ($StatusMessageCount -ge 2)) { foreach ($Object in $TSSummary) { if ($Object.Time -ge $TimeFrame) { $PSObject = New-Object -TypeName PSObject -Property @{ SuccessExecutionTime = [System.Management.ManagementDateTimeconverter]::ToDateTime($Object.Time) MachineName = $Object.MachineName } Write-Output $PSObject } } } else { Write-Output “No matches found” }

Run the following command line:

.\Get-TSExecutionStatusForDevice.ps1 -SiteServer CM01 -SiteCode PS1 -ComputerName CL01 -PastHours 24

If a match is found for what you’re searching for, the result will look something like this:
92_1
I hope you can put this to good use! If you have any questions, just drop me an email or a comment below.

Nickolaj Andersen

Chief Technical Architect and Enterprise Mobility MVP since 2016. Nickolaj has been in the IT industry for the past 10 years specializing in Enterprise Mobility and Security, Windows devices and deployments including automation. Awarded as PowerShell Hero in 2015 by the community for his script and tools contributions. Creator of ConfigMgr Prerequisites Tool, ConfigMgr OSD FrontEnd, ConfigMgr WebService to name a few. Frequent speaker at conferences such as Microsoft Ignite, NIC Conference and IT/Dev Connections including nordic user groups.

1 comment

  • I am looking for a way to get the name of the completed task sequence as well. can you please guide.

Sponsors

Categories

MSEndpointMgr.com use cookies to ensure that we give you the best experience on our website.