Invoke Run Script via PowerShell and Collect the Result

I'm a big fan of the Run Script feature in ConfigMgr, since it allows me to run a PowerShell script on any ConfigMgr client without having to worry about remote PowerShell being enabled, or having any special permissions on the target machine itself.

Here is an example on how to invoke a run script via PowerShell on a single machine, and collect the result. It is not very pretty, but it works 🙂 For multiple results, like when targeting a collection of devices, you're better off returning the Run Script result as JSON and then read it. But that's for another day.

In this example the Run Script used retrieved the .NET Framework version on the client, and If you have any ideas for improvements, please let me know in the comments below. Also, you can find the "Get .NET Framework Version" Run Script used here:

Sample output from the script

The InvokeRunScriptOnDevice.ps1 script

# Run a script on device via Run Script, and collect the result

# Parameters
$ScriptName = "Get .NET Framework Version"
$ComputerName = "CHI-W10PEER-008"
$ProviderMachineName = ""
$SiteCode = "PS1"

# Import the ConfigurationManager.psd1 module 
if((Get-Module ConfigurationManager) -eq $null) {
    Import-Module "$($ENV:SMS_ADMIN_UI_PATH)\..\ConfigurationManager.psd1"

# Connect to the site's drive if it is not already present
if((Get-PSDrive -Name $SiteCode -PSProvider CMSite -ErrorAction SilentlyContinue) -eq $null) {
    New-PSDrive -Name $SiteCode -PSProvider CMSite -Root $ProviderMachineName 

# Set the current location to be the site code.
Set-Location "$($SiteCode):\" 

# Main code
$ScriptGuid = (Get-CMScript -ScriptName $ScriptName -Fast).ScriptGuid
If (!($ScriptGuid)){
    Write-Warning "Could not find a Run Script named $ScriptName, aborting..."

$CMDevice = Get-CMDevice -Name $ComputerName
$OperationID = (Invoke-CMScript -ScriptGuid $ScriptGuid -Device $CMDevice -PassThru).OperationID

# Get script output, wait a maximum of five minuters
$NumberOfLoops = 30
$LoopInterval = 10 #Seconds
$i = 1
[System.Collections.ArrayList]$VMList = @()
do {

    $Operation = Get-CimInstance -Namespace root\SMS\Site_$SiteCode -ClassName SMS_ScriptsExecutionStatus -Filter "ClientOperationID = '$OperationID'" 
    If ($Operation){
        # Got the status, time to exit loop
    Start-Sleep -Seconds $LoopInterval
while ($i -le $NumberOfLoops)

# Script output
About the author

Johan Arwidmark

5 1 vote
Article Rating
Notify of
Inline Feedbacks
View all comments