Background jobs were one of the most undervalued aspects of PowerShell v2. With the introduction of PowerShell v3 we get ways to schedule those jobs. In this post though I want to look at the new CIM cmdlets and jobs.
Using the WMI cmdlets most PowerShell users have done something like this:
PS> Get-WmiObject -Class Win32_ComputerSystem
Domain : WORKGROUP
Manufacturer : Hewlett-Packard
Model : HP G60 Notebook PC
Name : RSLAPTOP01
PrimaryOwnerName : richard_siddaway@hotmail.com
TotalPhysicalMemory : 2951135232
The WMI cmdlets have the ability to be run as a background job by using the –AsJob parameter:
PS> Get-WmiObject -Class Win32_ComputerSystem -AsJob
Id Name PSJobTypeName State HasMoreData Location
– —- ————- —– ———– ——–
4 Job4 WmiJob Running True localhost
PS> Receive-Job -Id 4 -Keep
Domain : WORKGROUP
Manufacturer : Hewlett-Packard
Model : HP G60 Notebook PC
Name : RSLAPTOP01
PrimaryOwnerName : richard_siddaway@hotmail.com
TotalPhysicalMemory : 2951135232
Notice the job type – WMI job
A number of other cmdlets have an –AsJob parameter:
PS> Get-Help * -Parameter *ASJob*
Name
—-
Get-NetConnectionProfile
Set-NetConnectionProfile
Invoke-Command
Get-WmiObject
Invoke-WmiMethod
Remove-WmiObject
Restart-Computer
Set-WmiInstance
Stop-Computer
Test-Connection
Notice that the list doesn’t include the CIM cmdlets. If you want to run those as jobs you need to use the standard job cmdlets.
PS> Start-Job -ScriptBlock {Get-CimInstance -ClassName Win32_ComputerSystem}
PS> Get-Job
Id Name PSJobTypeName State
– —- ————- —–
4 Job4 WmiJob Completed
6 Job6 BackgroundJob Completed
In this case the job type is Background job not WMI job.
One of the big things with the CIM cmdlets is CIM sessions – these are analogous to remoting sessions and also work over WSMAN
PS> $sw = New-CimSession -ComputerName $env:COMPUTERNAME
PS> Start-Job -ScriptBlock {Get-CimInstance -ClassName Win32_ComputerSystem -CimSession $sw}
PS> Get-Job
Id Name PSJobTypeName
– —- ————-
4 Job4 WmiJob
6 Job6 BackgroundJob
8 Job8 BackgroundJob
PS> Receive-Job -Id 8 -Keep
Cannot bind argument to parameter ‘CimSession’ because it is null.
+ CategoryInfo : InvalidData: (:) [Get-CimInstance], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.Management.Infrastructure.CimCm
dlets.GetCimInstanceCommand
+ PSComputerName : localhost
Oops – what happened.
The problem is that back ground jobs run in their own PowerShell process. That’s why you get the prompt back so quick. That process doesn’t contain the CIM session. The way round it is to create the CIM session as part of the job.
PS> $sb ={
>> $sw2 = New-CimSession -ComputerName $env:COMPUTERNAME
>> $sw2
>> Get-CimInstance -ClassName Win32_ComputerSystem -CimSession $sw2
>> }
>>
PS> Start-Job -ScriptBlock $sb
You then get a job that completes and gives you data you can use.
Just remember that if you want to use CIM sessions in a job then create them as part of the job. You should also put in a line to remove them