PowerShell: Modify Source Location for SCCM Drivers

I recently ran into an issue where eh hmm.. someone (not sure who but his initials are WB) imported a new set of drivers from a UNC path that was named incorrectly.¬† ūüėź

To be exact, the directory was named “\\DFS\NameSpace\Share$\OSD\Win7\x64\DriverSrc\Lenovo S32_x64_R01” when in reality it was supposed to be “\\DFS\NameSpace\Share$\OSD\Win7\x64\DriverSrc\Lenovo E32_x64_R01″.

There are quite a few drivers that were imported for this particular model and there is no way in the console to bulk change the source path so after renaming the source folder to E32, off to PowerShell I went.

As you might guess I opened the PowerShell (x86) Console from the SCCM Admin Console (Still on Sp1 CU3 so no x64 PowerShell for me yet).

First I need to retrieve the driver objects that have the invalid path:
$Drivers = Get-CMDriver | Where-Object ($_.ContentSourcePath -like “*S32_x64*”}

This process takes a while as I have a lot of drivers.  If your really bored you can watch the SMSProv.log instead of stare at the PowerShell console waiting for the command to end.

Once the command completes I  have a new variable ($Drivers ) filled with all the driver objects I need to target to fix this mishap created by whoever that attention deficit admin was.  (*cough*).  For sanity sake I echo the contents out to the screen to validate I have only what I need in the variable:

$Drivers | Select-Object ContentSourcePath

I now know I have all the desired drivers that I need to modify.  My goal is to simply replace S32 with E32 in the existing path.  The command I used:

foreach ($driver in $xBackupDrivers) {$oldPath = $driver.ContentSourcePath; Write-Host “OLDPATH: $oldPath”; $NewPath = $driver.ContentSourcePath -replace “S32″,”E32”; Write-Host “NEWPATH: $NewPath”; Set-CMDriver -Id $driver.CI_ID -DriverSource $NewPath}

An easier way to read this:

foreach ($driver in $xBackupDrivers) {
    $oldPath = $driver.ContentSourcePath
¬†¬†¬† Write-Host “OLDPATH: $oldPath”
¬†¬†¬† $NewPath = $driver.ContentSourcePath -replace “S32″,”E32”
¬†¬†¬† Write-Host “NEWPATH: $NewPath”
    Set-CMDriver -Id $driver.CI_ID -DriverSource $NewPath

I have highlighted the commands that are doing the actual work.¬† I simply replace the text into a new variable and pass that to the “Set-CMDriver” cmdlet (Along with the driver CI_ID).

About¬†30 seconds¬†later the drivers have the correct source path.¬†¬†I’m now off¬†to reprimand that SCCM Admin!



PowerShell: Get logged on user remotely

Ever need to determine who is logged in to a remote computer?¬† I found myself frequently using¬†the Sysinternals “psloggedon” utility.¬† Nothing wrong with this utility and it continues to work on modern OS’s however a single line of PowerShell code can accomplish the same task: (Of course this command requires administrative rights on the remote computer.¬† ;-))

Get-WmiObject Win32_ComputerSystem -ComputerName ComputerName | select username



Check out the Sysinternal TechNet site.  Still some handy tools:  http://technet.microsoft.com/en-us/sysinternals/



Managing “If Null” for Published Data in Orchestrator

Anyone who has ever created a script knows that If statements are a cornerstone for error checking and decision points. You can easily check for a null value and redefine the variable with a specific value.

Fast forward to Orchestrator Runbooks.  As you have likely seen already or will see at some point, this same logic doesn’t translate natively to Runbook activities.

Consider this scenario:

You create Runbook activity to retrieve an attribute from an AD User.¬† In our example we’ll use the “Get Object Property Values” Activity from the ‚ÄúSCORCH Dev – Active Directory‚ÄĚ IP (available on CodePlex) to retrieve the “DisplayName” property of a User:

If that attribute contains a value you’re golden! The value can be retrieved from the databus for future activities:


What if that attribute does not contain a value? What if you would like to check for a Null value and create a new Published Data entry for DisplayName that has a value of ‚ÄúUnknown‚ÄĚ for example? You could certainly use a link condition to determine if the value was Null, but then what?

There is a fairly simple solution to this utilizing the Run .NET Script activity and Powershell.

Using 2 simple lines of code you simply check the Property Value, if null you set a Powershell variable with your own value:


You then publish the Powershell variable to the Databus using the Published Data tab


Snippet of what the Runbook looks like:


Very simple solution to check for Null values and redefine as needed ensuring you have a value on the databus for future activities.¬† ūüėȬ† Would love to hear from others in the comments to see how they accomplish this.

Hope this info provides useful for others!