As of the 1802 release of Microsoft System Center Configuration Manager (ConfigMgr) the feature is still pre-release. Don’t hesitate to share your feedback through the Feedback Hub to help shape this feature. If you haven't read our introduction blog into this feature check it out as this post is a continuation as we dig deeper into server group patching, leveraging the pre and post scripts as part of your more complex control for server patching.
As of the 1802 release there have been no published updates to this feature. However, with this post we dig deeper into how the pre/post scripts. Specifically, we’ll look at how Drain/Resume scripts work.
Under the covers in the UpdateDeployments.log you will see the following error (0x87d00666 -Software updates cannot be installed outside service window):
Essentially the updates cannot be installed until a lock is available, and Software Center is not going to tell you.
To address this, you should implement a flag file with a timestamp to prevent the Drain script from running over-and-over in rapid succession. Something to the following would work:
$f = "$env:TEMP\patch.flg"
#// Test for flag file to see if recently ran
If (Test-Path $f) {
$fl = gci $f
If ($fl.LastWriteTime -gt (Get-Date).AddMinutes(-1)) {
Write-Host "Recently run"
Exit 0
}
}
Write-Host "Haven't run recently"
#// Create Flag
$Null | Out-File $f -Force
The Write-Host in the sample script are not necessary. They are added when testing to highlight the functionality.
In the previous blog we provided sample Drain/Resume scripts which called a script from a network share to work around the 512 character limit. The revised sample script is revised for better error handling and ensuring that we return a failure exit code that can be interpreted by the ConfigMgr client.
The revised script can be used for both the Drain/Resume Node script, simply change out the $m variable to specify the mode to run the parent script. Your Patch.ps1 script will need to have a mode parameter and take the appropriate actions for the server for either the drain or resume mode.
Replace the SERVER place holder with the name for your server. The below example script is exactly 502 characters, so if your server name adds any more than 10 characters you will need to trim the script down.
The biggest improvement in this version is that it wraps your network script in a try catch, and appends the output to the Patch.txt in the temp folder and returns a failure exit code to the ConfigMgr client.
$l = 'C:\windows\temp\patch.txt'
$m = 'DRAIN'
"$m|Start $(Get-Date)"|Out-File $l -append
$s = '\\SERVER\patch\Patch.ps1'
If (Test-Path ($s)) {
$c = "$s"+" -mode '$m'"
Try {
Invoke-Expression $c
} Catch {
$e = $_.Exception.HResult
"ERROR [$e] $($_.Exception.Message) ($($_.InvocationInfo.ScriptLineNumber)"|Out-File $l -append
Exit $e
}
} Else {
"Not found $s"|Out-File $l -append
Exit 404
}
"$m|Stop $(Get-Date)"|Out-File $l -append