Forum Discussion

NAN2019's avatar
NAN2019
Copper Contributor
Oct 20, 2020

Calculate Percent on Compliance SCCM Powershell by Device collection

 

I have a function that pulls compliance status of a software update deployment (assignment ID). I want to configure this to calculate percent of the status types (Success, Error, In Progress, Unknown) and I would also like to pull compliance status based on device collection name instead of the deployment ID as it is shown below.

 

What I want to accomplish is automatically take a list of device collection names and run a software update deployment which organizes each collection by compliance percent (for each status), and then receive it by email every morning. 

 

I have several locations based on device collection, and I want to be able to differentiate which locations and devices are the problematic ones. 

 

This method makes tracking and reporting much easier and SCCM console will not have to be launched each individual time to get reporting. 

 

 

function Get-SCCMSoftwareUpdateStatus {

 

    [CmdletBinding()]

 

    param(

        [Parameter()]

        [switch]  $DeploymentIDFromGUI,

 

        [Parameter(Mandatory = $false)]

        [Alias('ID', 'AssignmentID')]

        [string]   $DeploymentID,

         

        [Parameter(Mandatory = $false)]

        [ValidateSet('Success', 'InProgress', 'Error', 'Unknown')]

        [Alias('Filter')]

        [string]  $Status

 

 

    )

 

    BEGIN {

        $Site_Code   = 'ABC'

        $Site_Server = 'SYSTEMCENTERSERVERNAME'

        $HasErrors   = $False

 

        if ($Status -eq 'Success') {

            $StatusType = 1

        }

 

        if ($Status -eq 'InProgress') {

            $StatusType = 2

        }

 

        if ($Status -eq 'Unknown') {

            $StatusType = 4

        }

 

        if ($Status -eq 'Error') {

            $StatusType = 5

        }

 

    }

 

    PROCESS {

        try {

            if ($DeploymentID -and $DeploymentIDFromGUI) {

                Write-Error "Select the DeploymentIDFromGUI or DeploymentID Parameter. Not Both"

                $HasErrors   = $True

                throw

            }

 

            if ($DeploymentIDFromGUI) {

                $ShellLocation = Get-Location

                Import-Module (Join-Path $(Split-Path $env:SMS_ADMIN_UI_PATH) ConfigurationManager.psd1)

                 

                #Checking to see if module has been imported. If not abort.

                if (Get-Module ConfigurationManager) {

                        Set-Location "$($Site_Code):\"

                        $DeploymentID = Get-CMSoftwareUpdateDeployment | select AssignmentID, AssignmentName | Out-GridView -OutputMode Single -Title "Select a Deployment and Click OK" | Select -ExpandProperty AssignmentID

                        Set-Location $ShellLocation

                    } else {

                        Write-Error "The SCCM Module wasn't imported successfully. Aborting."

                        $HasErrors   = $True

                        throw

                }

            }

 

            if ($DeploymentID) {

                    $DeploymentNameWithID = Get-WMIObject -ComputerName $Site_Server -Namespace root\sms\site_$Site_Code -class SMS_SUMDeploymentAssetDetails -Filter "AssignmentID = $DeploymentID" | select AssignmentID, AssignmentName

                    $DeploymentName = $DeploymentNameWithID.AssignmentName | select -Unique

                } else {

                    Write-Error "A Deployment ID was not specified. Aborting."

                    $HasErrors   = $True

                    throw  

            }

 

            if ($Status) {

                   $Output = Get-WMIObject -ComputerName $Site_Server -Namespace root\sms\site_$Site_Code -class SMS_SUMDeploymentAssetDetails -Filter "AssignmentID = $DeploymentID and StatusType = $StatusType" | `

                    select DeviceName, CollectionName, @{Name = 'StatusTime'; Expression = {$_.ConvertToDateTime($_.StatusTime) }}, @{Name = 'Status' ; Expression = {if ($_.StatusType -eq 1) {'Success'} elseif ($_.StatusType -eq 2) {'InProgress'} elseif ($_.StatusType -eq 5) {'Error'} elseif ($_.StatusType -eq 4) {'Unknown'}  }}

 

                } else {      

                    $Output = Get-WMIObject -ComputerName $Site_Server -Namespace root\sms\site_$Site_Code -class SMS_SUMDeploymentAssetDetails -Filter "AssignmentID = $DeploymentID" | `

                    select DeviceName, CollectionName, @{Name = 'StatusTime'; Expression = {$_.ConvertToDateTime($_.StatusTime) }}, @{Name = 'Status' ; Expression = {if ($_.StatusType -eq 1) {'Success'} elseif ($_.StatusType -eq 2) {'InProgress'} elseif ($_.StatusType -eq 5) {'Error'} elseif ($_.StatusType -eq 4) {'Unknown'}  }}

            }

 

            if (-not $Output) {

                Write-Error "A Deployment with ID: $($DeploymentID) is not valid. Aborting"

                $HasErrors   = $True

                throw

                 

            }

 

        } catch {

             

         

        } finally {

            if (($HasErrors -eq $false) -and ($Output)) {

                Write-Output ""

                Write-Output "Deployment Name: $DeploymentName"

                Write-Output "Deployment ID:   $DeploymentID"

                Write-Output ""

                Write-Output $Output | Sort-Object Status

            }

        }

    }

 

    END {}

 

}

10 Replies

  • farismalaeb's avatar
    farismalaeb
    Iron Contributor

    NAN2019 

    Hi,

    I had a small question just to confirm that I understand your question, so what you need is to get the result for all the deployment packages which listed in the following line

    $DeploymentID = Get-CMSoftwareUpdateDeployment | select AssignmentID, AssignmentName | Out-GridView -OutputMode Single -Title "Select a Deployment and Click OK" | Select -ExpandProperty AssignmentID

     and get the percentage of how many deployment was success, failure ...etc

    so the output will look like

    Success: 40%

    Error: 2%

    Unknown: 50%

    and so on, Yes?!

    • NAN2019's avatar
      NAN2019
      Copper Contributor

      farismalaeb 

       

      1) Yes. I would like to show a clear percentage of each status (for example: Success 12% , 40% failed), for the Software update deployment. 

       

      2) The 2nd request was to take the specific software update deployment and run it against device collection names. Maybe the device collection could either be in a for-each statement or if its possible to take the device collection name itself and do it. So in a sense I would have: 

       

      Chicago - 75% success, 25% failed, 0% In progress, 0% failed

      Cleveland - 25% success, 25% failed, 50% In progress, 0% failed

      Houston - 75% success, 25% failed, 0% In progress, 0% failed

      Miami - 0% success, 25% failed, 25% In progress, 50% failed

       

      And I would like it to be in a csv as well as in the txt body of an email sent every morning. 

      • farismalaeb's avatar
        farismalaeb
        Iron Contributor

        NAN2019 

         

        I wrote a quick update for script, review the change and test it, I don't have a big SCCM env, but this seems to be as you want.

        Function Get-AllPackages{
        $AllPack = Get-CMSoftwareUpdateDeployment | select AssignmentID, AssignmentName
        return $AllPack
        } 
        
        $Packages= Get-AllPackages
        
        foreach ($SinglePack in $Packages) {
        Write-Host "--------------"
            Write-Host $SinglePack.AssignmentName
            $packinfo=Get-SCCMSoftwareUpdateStatus -DeploymentID $SinglePack.AssignmentID 
                $Status=$packinfo.status | Get-Unique
                foreach ($sinlgestatus in $Status){
                Write-Host "The Status of $($sinlgestatus) for $($SinglePack.AssignmentName)" 
                    ((($packinfo | where {$_.status -like $sinlgestatus})).status.count / ($packinfo.Count -4)).tostring("P")
                
        
                    }
        } 

         

        There is no change on the main function, I added extra function and some foreach loop to get the status. 

        Hope it helps

         

         

        ---------------

        If the above reply answers your question, please don't forget to click on Best Response.

         

Resources