header image

Jobs, WMI, CIM and more jobs

Posted by: | September 27, 2012 | No Comment |

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 Smile

under: PowerShell and WMI, PowerShell V3