You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过PowerShell获取SCCM客户端软件中心补丁实时安装状态

Solution: Get Real-Time SCCM Patch Status Like Software Center

Got it, I've dealt with this exact issue before—those basic WMI classes only give you post-scan status (Missing/Installed), not the real-time deployment progress you see in Software Center. The key is to use the CCM_SoftwareUpdate class in the ROOT\ccm\ClientSDK namespace, which tracks live states like downloading, installing, pending reboot, etc.

Step 1: Understand the Critical Properties

The CCM_SoftwareUpdate class has properties that map directly to Software Center's statuses:

  • InstallationState: Numeric value representing installation progress:
    • 0 = Not Installed
    • 1 = Installed
    • 2 = Failed
    • 3 = Pending Install
    • 4 = Pending Reboot
    • 5 = Pending Verification
  • DownloadState: Numeric value for download status:
    • 0 = Not Downloaded
    • 1 = Downloaded
    • 2 = Downloading
    • 3 = Download Failed
  • PercentComplete: Percentage of download/installation completed (0-100)
  • Title: Human-readable patch name (e.g., "2018-03 Cumulative Update for Windows Server 2016...")

Step 2: Modify Your Install Function

Replace your existing loop code with this block that fetches and displays real-time status for each patch. Here's the full updated function:

Function Install-SCCMPatchesAvailable {
    [CmdletBinding()]
    param(
        [Parameter(
            Position = 0,
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = "Do not reboot server after patches install")]
        [ValidateNotNullOrEmpty()]
        [switch] $DoNotReboot
    )

    begin {
        Write-Verbose "Install-SCCMPatchesAvailable: Started"
        # Create friendly state mappings to match Software Center
        $installStateMap = @{
            0 = "Not Installed"
            1 = "Installed"
            2 = "Failed"
            3 = "Pending Install"
            4 = "Pending Reboot"
            5 = "Pending Verification"
        }
        $downloadStateMap = @{
            0 = "Not Downloaded"
            1 = "Downloaded"
            2 = "Downloading"
            3 = "Download Failed"
        }
    }

    process {
        try {
            # Trigger patch installation
            $updates = Get-WmiObject -Query 'SELECT * FROM CCM_SoftwareUpdate' -namespace 'ROOT\ccm\ClientSDK'
            ([wmiclass]'ROOT\ccm\ClientSDK:CCM_SoftwareUpdatesManager').InstallUpdates([System.Management.ManagementObject[]]$updates)

            # Loop until reboot is pending (or all patches finish processing)
            while (-not((Get-WmiObject -Namespace 'ROOT\ccm\ClientSDK' -Class 'CCM_ClientUtilities' -list).DetermineIfRebootPending().RebootPending)) {
                $currentTime = (Get-Date).ToShortTimeString()
                Write-Host "`n=== Patch Status Update @ $currentTime ===" -ForegroundColor Cyan

                # Fetch real-time status for each update
                $updateStatus = Get-WmiObject -Query 'SELECT Title, InstallationState, DownloadState, PercentComplete FROM CCM_SoftwareUpdate' -namespace 'ROOT\ccm\ClientSDK'
                
                foreach ($update in $updateStatus) {
                    # Map numeric states to friendly names
                    $installStatus = $installStateMap[$update.InstallationState] ?? "Unknown State"
                    $downloadStatus = $downloadStateMap[$update.DownloadState] ?? "Unknown State"
                    $progress = if ($update.PercentComplete -ge 0) { "$($update.PercentComplete)%" } else { "N/A" }

                    # Output formatted, easy-to-read status
                    Write-Host "Patch: $($update.Title)"
                    Write-Host "  Installation Status: $installStatus"
                    Write-Host "  Download Status: $downloadStatus"
                    Write-Host "  Progress: $progress`n"
                }

                Start-Sleep -Seconds 60
            }

            # Handle reboot if needed
            if (-not $PSBoundParameters.ContainsKey('DoNotReboot')) {
                if ((Get-WmiObject -Namespace 'ROOT\ccm\ClientSDK' -Class 'CCM_ClientUtilities' -list).DetermineIfRebootPending().RebootPending) {
                    Write-Host "Reboot pending - initiating restart..." -ForegroundColor Yellow
                    (Get-WmiObject -Namespace 'ROOT\ccm\ClientSDK' -Class 'CCM_ClientUtilities' -list).RestartComputer()
                }
            }
        }
        catch {
            Write-Error -Message "Something went wrong with Install-SCCMPatchesAvailable.`n`nError.Exception.Message : $($_.Exception.Message)`nError.Exception.FullName: $($_.Exception.GetType().FullName)"
        }
    }

    end {
        Write-Verbose "Install-SCCMPatchesAvailable: Completed"
    }
}

Key Changes Explained

  • Added state mapping hashtables to convert numeric values to human-readable statuses that match what you see in Software Center
  • Replaced the generic "Still Patching" message with a detailed breakdown of each patch's download/installation state and progress
  • Added colored output for better readability during monitoring (optional but useful for quick scanning)

Quick Tips

  • If you only want to see patches actively being processed (skip already installed ones), add a filter to the WMI query: WHERE InstallationState != 1 AND DownloadState != 1
  • The PercentComplete property tracks progress for both downloads and installations, so you can see exactly how far along each patch is

内容的提问来源于stack exchange,提问作者Keith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:20:14