Re-running a ConfigMgr Task Sequence on Multiple Computers

Recently I deployed a very simple task sequence to all our laptop computers which installs a new WiFi profile.  However, on viewing the deployment reports I noticed a number of machines where the deployment was stuck in either the ‘running’ state, or ‘failed’.  Although the deployment is set to ‘Re-run if failed previous attempt’ it seems the task sequence will not re-run automatically, only if a new schedule is created.  I wanted a quick and easy way to simply trigger the deployment again on all the computers that needed it, so I modified a script I use for re-running a task sequence to run against all computers in a csv.

Here is the script.  You need PS remoting active in your environment.  Simply add the location of the csv that contains the computernames you want to re-run the deployment on (no header required), and the name of the task sequence, and the script will do the rest.  It’s a little crude at the moment, but it works!  After running this, my compliance figures for the deployment were immediately boosted, and only a handful of machines remained that required individual troubleshooting 🙂

$ComputerNames = Get-Content -Path C:\Script_Files\WiFi_Profile_Failures.csv
$TaskSequenceName = "WiFi Profile"

cls
foreach ($ComputerName in $ComputerNames)
{ 
# Test connectivity to the computer
if (Test-Connection -Quiet -Count 2 -ComputerName $ComputerName -ErrorAction SilentlyContinue)
{$Online = "Yes"}else{$Online = "No"}
if ($Online -eq "No")
{write-host "$ComputerName is not online!"}
if ($Online -eq "Yes")
{
 
$s = New-PSSession -ComputerName $ComputerName
Invoke-Command -Session $s -Argu $ComputerName,$TaskSequenceName -ScriptBlock `
{
param ($ComputerName,$TaskSequenceName)
write-host "Getting PackageID for '$TaskSequenceName' on $ComputerName"
 $PackageID = get-wmiobject -computername $ComputerName -query "SELECT * FROM CCM_SoftwareDistribution" -namespace "root\ccm\policy\machine\actualconfig" | where {$_.PKG_Name -like $TaskSequenceName} | Select PKG_PackageID
 $PackageID = $PackageID.PKG_PackageID
 write-host $PackageID -ForegroundColor Yellow
 write-host "Getting ScheduleID for '$TaskSequenceName' on $ComputerName"
 $ScheduleID = Get-WmiObject -computername $ComputerName -Namespace "root\ccm\scheduler" -Class ccm_scheduler_history | where {$_.ScheduleID -like "*$PackageID*"} | Select-Object ScheduleID 
 $ScheduleID = $ScheduleID.ScheduleID
 write-host $ScheduleID -ForegroundColor Yellow
 write-host "Getting AdvertisementID for '$TaskSequenceName' on $ComputerName"
 $AdvertisementID = get-wmiobject -computername $ComputerName -query "SELECT * FROM CCM_SoftwareDistribution" -namespace "root\ccm\policy\machine\actualconfig" | where {$_.PKG_Name -like $TaskSequenceName} | Select ADV_AdvertisementID
 $AdvertisementID = $AdvertisementID.ADV_AdvertisementID
 write-host $AdvertisementID -ForegroundColor Yellow
 write-host "Setting re-run behaviour"
 $a = get-wmiobject -computername $ComputerName -query "SELECT * FROM CCM_TaskSequence" -namespace "root\ccm\policy\machine\actualconfig" | Where {$_.ADV_AdvertisementID -like "*$AdvertisementID*"} 
 $a.ADV_RepeatRunBehavior='RerunAlways'
 $a.Put() | Out-Null
 write-host "Creating mandatory assignment"
 $a = get-wmiobject -computername $ComputerName -query "SELECT * FROM CCM_TaskSequence" -namespace "root\ccm\policy\machine\actualconfig" | Where {$_.ADV_AdvertisementID -like "*$AdvertisementID*"}
 $a.ADV_MandatoryAssignments=$True
 $a.Put() | Out-Null
 
 write-host "Triggering the schedule now!" -ForegroundColor Green
 Invoke-WmiMethod -ComputerName $ComputerName -Namespace ROOT\ccm -Class SMS_Client -Name TriggerSchedule -ArgumentList "$ScheduleID" | Out-Null
 }
 Remove-PSSession $s
 }
 }

Re-running a Task Sequence

What happens if your SCCM task sequence fails?  Well you troubleshoot it, fix the problem, and rerun it.  Easy to do if the task sequence is an ‘available’ deployment.  You just refresh the machine policy on the computer, go the Software Center, or Run Advertised Programs, and run it again.   And if your task sequence rerun behaviour is set to ‘Rerun if failed previous attempt’ it will run again anyway.

But what if it’s a required deployment?  There seems to be no easy ‘out-of-the-box’ way to manually rerun a task sequence.  Powershell to the rescue!

This little script will rerun the task sequence by connecting to the remote machine, deleting the TS schedule from WMI, and restarting the SMS Agent Host service.  After a few seconds, the TS will run again.

You need the Task Sequence Package ID, which you can get easily from the SCCM Console, and you should have Powershell remoting configured in your environment.  You can of course run the script on a local machine by removing the ‘PSSession’ commands.

<#
ReRunTaskSequence v1
-----------------

This script reruns a task sequence on a remote computer.

Tested on: SCCM2012R2

-Prereqs:-
> You need the PackageID of the Task Sequence which you can get from the SCCM Console
> Powershell remoting must be permitted on the remote computer
> You should have local admin rights on the remote computer to restart the ccmexec service
> Variables, enter the $ComputerName and $TSID (PackageID) variables
#>

# Enter remote computername
$ComputerName = "remotecomputer"

# Start a remote PSSession
$s = New-PSSession -ComputerName $ComputerName

# Main script
Invoke-Command -Session $s -ScriptBlock `
{
$TSID = "SMS000B1"
Get-WmiObject -Namespace "root\ccm\scheduler" -Class ccm_scheduler_history | where {$_.ScheduleID -like "*$TSID*"} | ft ScheduleID # Outputs the Schedule ID
Get-WmiObject -Namespace "root\ccm\scheduler" -Class ccm_scheduler_history | where {$_.ScheduleID -like "*$TSID*"} | Remove-WmiObject # Deletes the Schedule
Get-WmiObject -Namespace "root\ccm\scheduler" -Class ccm_scheduler_history | where {$_.ScheduleID -like "*$TSID*"} | ft ScheduleID # No output confirms the deletion
Get-Service | where {$_.Name -eq "CCMExec"} | Restart-Service # Restart the SMS Agent Host service
}
Remove-PSSession $s

More info:

http://www.scconfigmgr.com/2012/11/21/re-run-task-sequence-with-powershell/
http://blogs.msdn.com/b/steverac/archive/2009/11/06/sccm-forcing-a-task-sequence-to-rerun.aspx