SCClient.psm1

<#
 .Synopsis
  Get pending updates on the client.
 
 .Description
  You can use this commandlet to check the pending updates on the client.
 
 .Parameter ComputerName
  The computer you like to target.
 
 .Parameter Credential
  The credentials you like to use to manage the target computer.
 
 .Example
   Get-SCClientPendingUpdate
   Get all Pending updates on the local computer.
 
 .Example
   Get-SCClientPendingUpdate -ComputerName "ClientName" -Credential "CredentialObject"
   Get all Pending updates on the remote computer.
 
.Example
   Get-SCClientPendingUpdate -ComputerName "ClientName" -Credential "CredentialObject" -UpdateID "UpdateID"
   Get all Pending updates on the local computer with a specific UpdateID.
 
.Example
   Get-SCClientPendingUpdate -ComputerName "ClientName" -Credential "CredentialObject" -ArticleID "ArticleID"
   Get all Pending updates on the local computer with a specifi ArticleID.
 
.Example
   Get-SCClientPendingUpdate -ComputerName "ClientName" -Credential "CredentialObject" -UpdateID "UpdateID"
   Get all Pending updates on the remote computer with a specific UpdateID.
 
.Example
   Get-SCClientPendingUpdate -ComputerName "ClientName" -Credential "CredentialObject" -ArticleID "ArticleID"
   Get all Pending updates on the remote computer with a specifi ArticleID.
#>

function Get-SCClientPendingUpdate {
param(
    [Parameter(Mandatory=$false)]
    [string] $ComputerName="localhost",
    [Parameter(Mandatory=$false)]
    [pscredential]
    [System.Management.Automation.Credential()]
    $Credential,
    [Parameter(Mandatory=$false)]
    [string] $UpdateID="%",
    [Parameter(Mandatory=$false)]
    [string] $ArticleID="%"
    ) 

    if($(Test-Connection -ComputerName $ComputerName -Count 1 -BufferSize 10 -Quiet))
    {
        $modulepath = (Get-Module -ListAvailable SCClient).ModuleBase
        [xml]$XmlComplianceStates = Get-Content -Path $modulepath\ComplianceStateUpdates.xml
        [xml]$XmlEvaluationStates = Get-Content -Path $modulepath\EvaluationStateUpdates.xml

        if($ComputerName -eq "localhost")
        {
            $updates = Get-CimInstance -Namespace "Root\ccm\ClientSDK" -Query "SELECT * FROM CCM_SoftwareUpdate WHERE UpdateID like '$UpdateID' AND ArticleID like '$ArticleID'" -ErrorAction Stop
        }
        else
        {
            $session = New-CimSession -Credential $Credential -ComputerName $ComputerName
            $updates = Get-CimInstance -Namespace "Root\ccm\ClientSDK" -Query "SELECT * FROM CCM_SoftwareUpdate WHERE UpdateID like '$UpdateID' AND ArticleID like '$ArticleID'" -CimSession $session -ErrorAction Stop
            Remove-CimSession $session
        }
        $updatesArr = @()

        foreach($update in $updates)
        {
            $updateobj = @{}
            $updateobj.Name=$update.Name
            $updateobj.ArticleID=$update.ArticleID
            $updateobj.BulletinID=$update.BulletinID
            $updateobj.UpdateID=$update.UpdateID
            $updateobj.ExclusiveUpdate=$update.ExclusiveUpdate
            foreach($ComplianceState in $($XmlComplianceStates.states.option))
            {
                if($ComplianceState.value -eq $update.ComplianceState)
                {
                    $updateobj.ComplianceState=$ComplianceState.state
                }
            }  
            foreach($EvaluationState in $($XmlEvaluationStates.states.option))
            {
                if($EvaluationState.value -eq $update.EvaluationState)
                {
                    $updateobj.EvaluationState=$EvaluationState.state
                }
            }
            $updateobj.MaxExecutionTime = $update.MaxExecutionTime
            $updateobj.RebootOutsideServiceWindows = $update.RebootOutsideServiceWindows
            $updateobj.URL = $update.URL
            $updateobj.ErrorCode = $update.ErrorCode
            $updateobj.StartTime = $update.StartTime
            $updateobj.Publisher = $update.Publisher
            $updateobj.UserUIExperience = $update.UserUIExperience
            $object = New-Object -TypeName psobject â€“Prop $updateobj
            $updatesArr += $object
        }
        return $updatesArr|select-Object Name,Publisher,ArticleID,BulletinID,UpdateID,URL,ComplianceState,EvaluationState,ErrorCode,ExclusiveUpdate,MaxExecutionTime,RebootOutsideServiceWindows,StartTime,UserUIExperience
    }
    else
    {
        Write-Error "The computer you try to manage is offline." -Category ConnectionError
    }
}


<#
 .Synopsis
  Get installed software on the client.
 
 .Description
  You can use this commandlet to list all installed software on the client.
 
 .Parameter ComputerName
  The computer you like to target.
 
 .Parameter Credential
  The credentials you like to use to manage the target computer.
 
 .Example
   Get-SCClientInstalledSoftware
   Get all installed software on the local computer.
 
 .Example
   Get-SCClientInstalledSoftware -ComputerName "ClientName" -Credential "CredentialObject"
   Get all installed software on the remote computer.
#>

function Get-SCClientInstalledSoftware {
param(
    [Parameter(Mandatory=$false)]
    [string] $ComputerName="localhost",
    [Parameter(Mandatory=$false)]
    [pscredential] 
    [System.Management.Automation.Credential()]
    $Credential
    ) 

    if($(Test-Connection -ComputerName $ComputerName -Count 1 -BufferSize 10 -Quiet))
    {
        if($ComputerName -eq "localhost")
        {
            $InstalledApps = Get-CimInstance -Namespace "root\cimv2\sms" -Query "select * from SMS_InstalledSoftware" -ErrorAction Stop
        }
        else
        {
            $session  = New-CimSession -Credential $Credential -ComputerName $ComputerName
            $InstalledApps = Get-CimInstance -Namespace "root\cimv2\sms" -Query "select * from SMS_InstalledSoftware" -CimSession $session -ErrorAction Stop 
            Remove-CimSession $session
        }
        return $InstalledApps|Select-Object ProductName,Publisher,InstalledLocation,ProductVersion,VersionMajor,VersionMinor,ServicePack,SoftwareCode,UninstallString,LocalPackage,InstallDate
    }    
    else
    {
        Write-Error "The computer you try to manage is offline." -Category ConnectionError
    }
}


<#
 .Synopsis
  Get applications deployed to the client.
 
 .Description
  You can use this commandlet to check the applications deployed to the client.
 
 .Parameter ComputerName
  The computer you like to target.
 
 .Parameter Credential
  The credentials you like to use to manage the target computer.
 
 .Example
   Get-SCClientApplication
   Get all applications deployed to the local computer.
 
 .Example
   Get-SCClientApplication -ComputerName "ClientName" -Credential "CredentialObject"
   Get all applications deployed to the remote computer.
#>

function Get-SCClientApplication {
param(
    [Parameter(Mandatory=$false)]
    [string] $ComputerName="localhost",
    [Parameter(Mandatory=$false)]
    [pscredential]
    [System.Management.Automation.Credential()]
    $Credential
    ) 

    if($(Test-Connection -ComputerName $ComputerName -Count 1 -BufferSize 10 -Quiet))
    {
        $modulepath = (Get-Module -ListAvailable SCClient).ModuleBase
        [xml]$XmlEvaluationStates = Get-Content -Path $modulepath\EvaluationStateApps.xml

        if($ComputerName -eq "localhost")
        {
            $applications = Get-CimInstance -Namespace "Root\ccm\ClientSDK" -Query "SELECT * FROM CCM_application" -ErrorAction Stop
        }
        else
        {
            $session = New-CimSession -Credential $Credential -ComputerName $ComputerName
            $applications = Get-CimInstance -CimSession $session -Namespace "Root\ccm\ClientSDK" -Query "SELECT * FROM CCM_application" -ErrorAction Stop
            Remove-CimSession $session
        }

            $applicationsArr = @()

        foreach($application in $applications)
        {
            $AppObj = @{}
            $AppObj.AllowedActions=$application.AllowedActions
            $AppObj.ApplicabilityState=$application.ApplicabilityState
            $AppObj.ConfigurationState=$application.ConfigurationState
            switch($application.EnforcePreference)
            {
                0{$AppObj.ConfigurationState="Immediate"}
                1{$AppObj.ConfigurationState="NonBusinessHours"}
                2{$AppObj.ConfigurationState="AdminSchedule"}
                default{$AppObj.ConfigurationState="Unknown"}
            }
            $AppObj.ErrorCode=$application.ErrorCode
            foreach($EvaluationState in $($XmlEvaluationStates.states.option))
            {
                if($EvaluationState.value -eq $application.EvaluationState)
                {
                    $AppObj.EvaluationState=$EvaluationState.state
                }
            } 
            $AppObj.Name=$application.Name
            $AppObj.Id=$application.Id
            $AppObj.InstallState=$application.InstallState
            $AppObj.IsMachineTarget=$application.IsMachineTarget
            $AppObj.IsPreflightOnly=$application.IsPreflightOnly
            $AppObj.LastEvalTime = $application.LastEvalTime
            $AppObj.LastInstallTime = $application.LastInstallTime
            $AppObj.Deadline = $application.Deadline
            $AppObj.NotifyUser=$application.NotifyUser
            $AppObj.OverrideServiceWindow=$application.OverrideServiceWindow
            $AppObj.PercentComplete=$application.PercentComplete
            $AppObj.Publisher=$application.Publisher
            $AppObj.RebootOutsideServiceWindow=$application.RebootOutsideServiceWindow
            $AppObj.ResolvedState=$application.ResolvedState
            $AppObj.StartTime = $application.StartTime
            $AppObj.UserUIExperience=$application.UserUIExperience
            $object = New-Object -TypeName psobject â€“Prop $AppObj
            $applicationsArr += $object
        }

        return $applicationsArr |Select-Object Name,Publisher,Id,InstallState,EvaluationState,ResolvedState,ErrorCode,ApplicabilityState,ConfigurationState,PercentComplete,AllowedActions,IsMachineTarget,IsPreflightonly,RebootOutsideServiceWindow,OverrideServiceWindow,StartTime,DeadLine,LastEvalTime,LastInstallTime,NotifyUser,UserUIExperience
    }    
    else
    {
        Write-Error "The computer you try to manage is offline." -Category ConnectionError
    }
}


<#
 .Synopsis
  Get info about last update scan.
 
 .Description
  You can use this commandlet to view details of the last update scan.
 
 .Parameter ComputerName
  The computer you like to target.
 
 .Parameter Credential
  The credentials you like to use to manage the target computer.
 
 .Example
   Get-SCClientUpdateScanHistory
   Get all Pending updates on the local computer.
 
 .Example
   Get-SCClientUpdateScanHistory -ComputerName "ClientName" -Credential "CredentialObject"
   Get all Pending updates on the remote computer.
#>

function Get-SCClientUpdateScanHistory {
param(
    [Parameter(Mandatory=$false)]
    [string] $ComputerName="localhost",
    [Parameter(Mandatory=$false)]
    [pscredential] 
    [System.Management.Automation.Credential()]
    $Credential
    ) 

    if($(Test-Connection -ComputerName $ComputerName -Count 1 -BufferSize 10 -Quiet))
    {
        if($ComputerName -eq "localhost")
        {
            $ScanHistory = Get-CimInstance -Namespace "root\ccm\scanagent" -Query "SELECT * FROM CCM_scanupdatesourcehistory" -ErrorAction Stop
        }
        else
        {
            $session = New-CimSession -Credential $Credential -ComputerName $ComputerName
            $ScanHistory = Get-CimInstance -CimSession $session -Namespace "root\ccm\scanagent" -Query "SELECT * FROM CCM_scanupdatesourcehistory" -ErrorAction Stop
            Remove-CimSession $session
        }   
        return $ScanHistory|select-Object ScanMethod,Valid,ValidTTL,UpdateSourceID,UpdateSourceVersion,LastCompletionTime
    }    
    else
    {
        Write-Error "The computer you try to manage is offline." -Category ConnectionError
    }
}


<#
 .Synopsis
  Install updates
 
 .Description
  You can use this commandlet to install a specific update or all updates.
 
 .Parameter ComputerName
  The computer you like to target.
 
 .Parameter Credential
  The credentials you like to use to manage the target computer.
 
  .Example
   Start-SCClientInstallUpdate -UpdateID "UpdateID"
   Install an update on the local computer
 
  .Example
   Start-SCClientInstallUpdate
   Install all update on the local computer
 
  .Example
   Start-SCClientInstallUpdate -ComputerName "ClientName" -Credential "CredentialObject" -UpdateID "UpdateID"
   Install an update with the specified UpdateID on the target computer
 
 .Example
   Start-SCClientInstallUpdate -ComputerName "ClientName" -Credential "CredentialObject"
   Install all updates on the target computer
#>

function Start-SCClientInstallUpdate {
param(
    [Parameter(Mandatory=$false)]
    [string] $ComputerName="localhost",
    [Parameter(Mandatory=$false)]
    [pscredential] 
    [System.Management.Automation.Credential()]
    $Credential,
    [Parameter(Mandatory=$false)]
    [string] $UpdateID="%"
    ) 

    if($(Test-Connection -ComputerName $ComputerName -Count 1 -BufferSize 10 -Quiet))
    {
        if($ComputerName -eq "localhost")
        {
            $a = get-CimInstance -query "SELECT * FROM CCM_SoftwareUpdate WHERE UpdateID like '$UpdateID'" -namespace "ROOT\ccm\ClientSDK" -ErrorAction Stop
            ([wmiclass]'ROOT\ccm\ClientSDK:CCM_SoftwareUpdatesManager').InstallUpdates($a)
        }
        else
        {
            Invoke-Command $ComputerName -ScriptBlock{
                param ([string] $arg1 = $UpdateID)
                $a = get-CimInstance -query "SELECT * FROM CCM_SoftwareUpdate WHERE UpdateID like '$arg1'" -namespace "ROOT\ccm\ClientSDK" -ErrorAction Stop
                ([wmiclass]'ROOT\ccm\ClientSDK:CCM_SoftwareUpdatesManager').InstallUpdates($a)
            } -ArgumentList $UpdateID -Credential $Credential
        }
    }    
    else
    {
        Write-Error "The computer you try to manage is offline." -Category ConnectionError
    }
}


<#
 .Synopsis
  Install updates
 
 .Description
  You can use this commandlet to install a specific update or all updates.
 
 .Parameter ComputerName
  The computer you like to target.
 
 .Parameter Credential
  The credentials you like to use to manage the target computer.
 
  .Example
   Start-SCClientInstallApplication -Id "AppId"
   Install an application with the specified Application Id on the local computer
 
  .Example
   Start-SCClientInstallApplication -ComputerName "ClientName" -Credential "CredentialObject" -Id "AppId"
   Install an application with the specified Application Id on the target computer
#>

function Start-SCClientInstallApplication {
param(
    [Parameter(Mandatory=$false)]
    [string] $ComputerName="localhost",
    [Parameter(Mandatory=$false)]
    [pscredential] 
    [System.Management.Automation.Credential()]
    $Credential,
    [Parameter(Mandatory=$true)]
    [string] $Id
    ) 

    if($(Test-Connection -ComputerName $ComputerName -Count 1 -BufferSize 10 -Quiet))
    {
        if($ComputerName -eq "localhost")
        {
            $a = get-CimInstance -query "SELECT * FROM CCM_Application WHERE Id like '$Id'" -namespace "ROOT\ccm\ClientSDK" -ErrorAction Stop
            $RELPATH = $a.__RELPATH -split ","
            if($RELPATH[1].Contains("TRUE"))
            {
                $IsMachineTarget = $true
            }
            else
            {
                $IsMachineTarget = $false
            }
            $revision = $RELPATH[2].Substring(10)
            $revision = $revision.Substring(0,$revision.Length-1)
            ([wmiclass]'ROOT\ccm\ClientSdk:CCM_Application').Install($Id, $revision, $IsMachineTarget, 0, 'Normal', $False)
        }
        else
        {
            Invoke-Command $ComputerName -ScriptBlock{
                param ([string] $arg1 = $Id)
                $a = get-CimInstance -query "SELECT * FROM CCM_Application WHERE Id like '$arg1'" -namespace "ROOT\ccm\ClientSDK" -ErrorAction Stop
                $RELPATH = $a.__RELPATH -split ","
                if($RELPATH[1].Contains("TRUE"))
                {
                    $IsMachineTarget = $true
                }
                else
                {
                    $IsMachineTarget = $false
                }
                $revision = $RELPATH[2].Substring(10)
                $revision = $revision.Substring(0,$revision.Length-1)
                ([wmiclass]'ROOT\ccm\ClientSdk:CCM_Application').Install($arg1, $revision, $IsMachineTarget, 0, 'Normal', $False)
            } -ArgumentList $Id -Credential $Credential
        }
    }    
    else
    {
        Write-Error "The computer you try to manage is offline." -Category ConnectionError
    }
}


<#
 .Synopsis
  Start a Software Updates Assignments Evaluation Cycle
 
 .Description
  You can use this commandlet to start a Software Updates Assignments Evaluation Cycle
  or Software Update Deployment Evaluation Cycle
 
 .Parameter ComputerName
  The computer you like to target.
 
 .Parameter Credential
  The credentials you like to use to manage the target computer.
 
 .Example
   Start-SCClientUpdateDeploymentEval
   Start Software Updates Assignments Evaluation Cycle on the local computer
 
 .Example
   Start-SCClientUpdateDeploymentEval -ComputerName "ClientName" -Credential "CredentialObject"
   Start Software Updates Assignments Evaluation Cycle on the remote computer
#>

function Start-SCClientUpdateDeploymentEval {
param(
    [Parameter(Mandatory=$false)]
    [string] $ComputerName="localhost",
    [Parameter(Mandatory=$false)]
    [pscredential] 
    [System.Management.Automation.Credential()]
    $Credential
    ) 

    if($(Test-Connection -ComputerName $ComputerName -Count 1 -BufferSize 10 -Quiet))
    {
        if($ComputerName -eq "localhost")
        {
                ([wmiclass]'ROOT\ccm:SMS_Client').TriggerSchedule('{00000000-0000-0000-0000-000000000108}')
        }
        else
        {
            Invoke-Command $ComputerName -ScriptBlock{
                ([wmiclass]'ROOT\ccm:SMS_Client').TriggerSchedule('{00000000-0000-0000-0000-000000000108}')
            } -Credential $Credential
        }
    }    
    else
    {
        Write-Error "The computer you try to manage is offline." -Category ConnectionError
    }
}


<#
 .Synopsis
  Start a Software Update Scan Cycle
 
 .Description
  You can use this commandlet to start a Software Update Scan Cycle
 
 .Parameter ComputerName
  The computer you like to target.
 
 .Parameter Credential
  The credentials you like to use to manage the target computer.
 
 .Example
   Start-SCClientUpdateScan
   Start Software Update Scan Cycle on the local computer
 
 .Example
   Start-SCClientUpdateScan -ComputerName "ClientName" -Credential "CredentialObject"
   Start Software Update Scan Cycle on the remote computer
#>

function Start-SCClientUpdateScan {
param(
    [Parameter(Mandatory=$false)]
    [string] $ComputerName="localhost",
    [Parameter(Mandatory=$false)]
    [pscredential] 
    [System.Management.Automation.Credential()]
    $Credential
    ) 

    if($(Test-Connection -ComputerName $ComputerName -Count 1 -BufferSize 10 -Quiet))
    {
        if($ComputerName -eq "localhost")
        {
                ([wmiclass]'ROOT\ccm:SMS_Client').TriggerSchedule('{00000000-0000-0000-0000-000000000113}')
        }
        else
        {
            Invoke-Command $ComputerName -ScriptBlock{
                ([wmiclass]'ROOT\ccm:SMS_Client').TriggerSchedule('{00000000-0000-0000-0000-000000000113}')
            } -Credential $Credential
        }
    }    
    else
    {
        Write-Error "The computer you try to manage is offline." -Category ConnectionError
    }
}


<#
 .Synopsis
  Start a Machine Policy Retrieval and Evaluation Cycle.
 
 .Description
  You can use this commandlet to start a Machine Policy Retrieval and Evaluation Cycle.
 
 .Parameter ComputerName
  The computer you like to target.
 
 .Parameter Credential
  The credentials you like to use to manage the target computer.
 
 .Example
   Start-SCClientMachinePolicyEval
   Start Machine Policy Retrieval and Evaluation Cycle on the local computer
 
 .Example
   Start-SCClientMachinePolicyEval -ComputerName "ClientName" -Credential "CredentialObject"
   Start Machine Policy Retrieval and Evaluation Cycle on the remote computer
#>

function Start-SCClientMachinePolicyEval {
param(
    [Parameter(Mandatory=$false)]
    [string] $ComputerName="localhost",
    [Parameter(Mandatory=$false)]
    [pscredential] 
    [System.Management.Automation.Credential()]
    $Credential
    ) 

    if($(Test-Connection -ComputerName $ComputerName -Count 1 -BufferSize 10 -Quiet))
    {
        if($ComputerName -eq "localhost")
        {
                ([wmiclass]'ROOT\ccm:SMS_Client').TriggerSchedule('{00000000-0000-0000-0000-000000000021}')
                ([wmiclass]'ROOT\ccm:SMS_Client').TriggerSchedule('{00000000-0000-0000-0000-000000000022}')
        }
        else
        {
            Invoke-Command $ComputerName -ScriptBlock{
                ([wmiclass]'ROOT\ccm:SMS_Client').TriggerSchedule('{00000000-0000-0000-0000-000000000021}')
                ([wmiclass]'ROOT\ccm:SMS_Client').TriggerSchedule('{00000000-0000-0000-0000-000000000022}')
            } -Credential $Credential
        }
    }    
    else
    {
        Write-Error "The computer you try to manage is offline." -Category ConnectionError
    }
}


<#
 .Synopsis
  Start a Application Deployment Evaluation Cycle.
 
 .Description
  You can use this commandlet to start a Application Deployment Evaluation Cycle.
 
 .Parameter ComputerName
  The computer you like to target.
 
 .Parameter Credential
  The credentials you like to use to manage the target computer.
 
 .Example
   Start-SCClientApplicationEval
   Start Application Deployment Evaluation Cycle on the local computer
 
 .Example
   Start-SCClientApplicationEval -ComputerName "ClientName" -Credential "CredentialObject"
   Start Application Deployment Evaluation Cycle on the remote computer
#>

function Start-SCClientApplicationEval {
param(
    [Parameter(Mandatory=$false)]
    [string] $ComputerName="localhost",
    [Parameter(Mandatory=$false)]
    [pscredential] 
    [System.Management.Automation.Credential()]
    $Credential
    ) 

    if($(Test-Connection -ComputerName $ComputerName -Count 1 -BufferSize 10 -Quiet))
    {
        if($ComputerName -eq "localhost")
        {
                ([wmiclass]'ROOT\ccm:SMS_Client').TriggerSchedule('{00000000-0000-0000-0000-000000000121}')
        }
        else
        {
            Invoke-Command $ComputerName -ScriptBlock{
                ([wmiclass]'ROOT\ccm:SMS_Client').TriggerSchedule('{00000000-0000-0000-0000-000000000121}')
            } -Credential $Credential
        }
    }    
    else
    {
        Write-Error "The computer you try to manage is offline." -Category ConnectionError
    }
}