user4317867
user4317867

Reputation: 2448

PowerShell install SCCM updates and display Write-Progress

I've put together some (borrowed) powershell that will install all SCCM missing updates on a remote server. Now I'm trying to get Write-Progress to work and haven't had much success. The code below displays a progress bar but throws errors when the argument for PercentComplete increments past 100.

I know this could be resolved using a ForEach loop and incrementing a counter but I'm not even sure how to attempt that since I'm using the InstallUpdates method. I know there's an InstallUpdate method but am not sure how to wrap up everything.

# Get the number of missing updates
[System.Management.ManagementObject[]] $CMMissingUpdates = @(GWMI -ComputerName $server -query "SELECT * FROM CCM_SoftwareUpdate WHERE ComplianceState = '0'" -namespace "ROOT\ccm\ClientSDK") #End Get update count.
$result.UpdateCountBefore = "The number of missing updates is $($CMMissingUpdates.count)"
#Install missing updates.
If ($CMMissingUpdates.count) {
#$result.UpdateCountBefore = "The number of missing updates is $($CMMissingUpdates.count)"
$CMInstallMissingUpdates = (GWMI -ComputerName $server -Namespace "root\ccm\clientsdk" -Class "CCM_SoftwareUpdatesManager" -List).InstallUpdates($CMMissingUpdates)
#Set the missing updates to variable for progress indicator.
$updates = $CMMissingUpdates.Count
$Increment = 100 / $updates
$Percent = 0
Do {
Start-Sleep -Seconds 15
[array]$CMInstallPendingUpdates = @(GWMI -ComputerName $server -query "SELECT * FROM CCM_SoftwareUpdate WHERE EvaluationState = 6 or EvaluationState = 7" -namespace "ROOT\ccm\ClientSDK")
#Not 100% sure $result.UpdateCountBefore is needed below.
$result.UpdateCountBefore = "The number of pending updates for installation is: $($CMInstallPendingUpdates.count)"
Write-Progress -Activity "Updates are installing..." -PercentComplete $Percent -Status "Working..."
$Percent = $Percent + $Increment
}
While(($CMInstallPendingUpdates.count -ne 0) -and ((New-TimeSpan -Start $StartTime -End $(Get-Date)) -lt "00:55:00"))
Write-Progress -Activity "Updates Installed" -Status "Done" -Completed

Upvotes: 1

Views: 6620

Answers (1)

xXhRQ8sD2L7Z
xXhRQ8sD2L7Z

Reputation: 1716

I think I've fixed up the progress bar's percent complete problem. As you mentioned, the For loop is used. There is a lot of things I can't test like the WMI queries and SCCM methods, but the Write-Progress should be ok.

You can include the pendingupdates test and timespan test in the for loop condition if you want, but this is a little easier on the eyes.

Update: I checked the code in your link. The progress bar would never update until the inner loop was complete - meaning the progress would go from 0% to 100%. So I removed the outer For loop, break checks and sleep command and moved Write-Progress to inside the Do loop:

# Get the number of missing updates
[System.Management.ManagementObject[]] $CMMissingUpdates = @(GWMI -ComputerName $server -query "SELECT * FROM CCM_SoftwareUpdate WHERE ComplianceState = '0'" -namespace "ROOT\ccm\ClientSDK") #End Get update count.
$result.UpdateCountBefore = "The number of missing updates is $($CMMissingUpdates.count)"

$updates = $CMMissingUpdates.count

If ($updates) {
   #Install the missing updates.
   $CMInstallMissingUpdates = (GWMI -ComputerName $server -Namespace "root\ccm\clientsdk" -Class "CCM_SoftwareUpdatesManager" -List).InstallUpdates($CMMissingUpdates)
   Do {
      Start-Sleep -Seconds 15
      [array]$CMInstallPendingUpdates = @(GWMI -ComputerName $server -query "SELECT * FROM CCM_SoftwareUpdate WHERE EvaluationState = 6 or EvaluationState = 7" -namespace "ROOT\ccm\ClientSDK")
      Write-Progress -Activity "Updates are installing..." -PercentComplete (($CMInstallPendingUpdates.count/$updates)*100)
   } While (($CMInstallPendingUpdates.count -gt 0) -and ((New-TimeSpan -Start $StartTime -End $(Get-Date)) -lt "00:55:00"))
} Else {
   $result.UpdateCountAfter = "There are no missing updates."
}

Upvotes: 2

Related Questions