PowerShell for Windows Admins

Dec 21 2015   3:36PM GMT

New-CimInstance cmdlet and the–Key parameter

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Tags:
CIM
Powershell
WMI

I was asked a question about the –Key parameter on New-CimInstance today. I wasn’t sure of the answer so I’ve done some experimentation.

I tend to avoid New-CimInstance if I can preferring to use the Create method on the CIM class – however not all CIM classes have a create method so need to fall back on New-CimInstance.

I started by looking at the documentation. The help file for New-CimInstance says:

-Key<String[]>

Specifies the properties that are used as keys. CimSession and ComputerName cannot be used when Key is specified.

That then leads to the question how do I discover the Key or Keys of a CIM class.  You can’t use the –Qualifier parameter in Get-CimClass because that works at the class level and Key is a property qualifier.  Means you need to use some code

function Get-CimClassKey {

param (

[string]$CIMnamespace = ‘ROOT/cimv2’,

[string]$CIMclass

)

$class = Get-CimClass -Namespace $CIMnamespace -ClassName $CIMclass

foreach ($property in $class.CimClassProperties) {

$property | Select-Object -ExpandProperty Qualifiers |
foreach {
if ($_.Name -eq ‘key’){
$property
}
}

}
}

The Key property of a class HAS to be given a value when a new instance of the class is created.

The New-CimInstance help file shows an example using Win32_Environment.  Adapring the example:

PS> New-CimInstance -ClassName Win32_Environment @{Name=’RStest1′; VariableValue=’test1′; UserName=’RSSURFACEPRO2\Richard’}

Name             UserName                                            VariableValue
—-             ——–                                            ————-
RStest1          RSSURFACEPRO2\Richard                               test1

Using our function to discover the Keys of Win32_Environment

PS> Get-CimClassKey -CIMclass Win32_Environment
Name               : Name
Value              :
CimType            : String
Flags              : Property, Key, NullValue
Qualifiers         : {read, key, MappingStrings, Override…}
ReferenceClassName :

Name               : UserName
Value              :
CimType            : String
Flags              : Property, Key, ReadOnly, NullValue
Qualifiers         : {key, MappingStrings, MaxLen, read}
ReferenceClassName :

Adding the –Key parameter

PS> New-CimInstance -ClassName Win32_Environment @{Name=’RStest2′; VariableValue=’test2′; UserName=’RSSURFACEPRO2\Richard’} -Key ‘Name’, ‘UserName’

Name             UserName                                            VariableValue
—-             ——–                                            ————-
RStest2          RSSURFACEPRO2\Richard                               test2

Using Win32_Environment you can use the Key parameter, or not, as long as you define values for the Name and Username properties.

Another example in the New-CimInstance help file uses the Win32_Process class.  The key for that class is the Handle property

PS> Get-CimClassKey -CIMclass Win32_process
Name               : Handle
Value              :
CimType            : String
Flags              : Property, Key, ReadOnly, NullValue
Qualifiers         : {key, MaxLen, read}
ReferenceClassName :

the Handle is appears to be identical to the ProcessId in value as far as I can determine

This now gets  messy:

Just the Handle.  BTW exmple 3 in the documentation has an error as Handle is a string not an integer

PS> New-CimInstance -ClassName Win32_Process -Property @{Handle=’0′}
New-CimInstance : Provider is not capable of the attempted operation
At line:1 char:1
+ New-CimInstance -ClassName Win32_Process -Property @{Handle=’0′}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (Win32_Process:CimInstance) [New-CimInstance], CimException
+ FullyQualifiedErrorId : HRESULT 0x80041024,Microsoft.Management.Infrastructure.CimCmdlets.NewCimInstanceCommand

Add the Key parameter

PS> New-CimInstance -ClassName Win32_Process -Property @{Handle=’0′} -Key Handle
New-CimInstance : Provider is not capable of the attempted operation
At line:1 char:1
+ New-CimInstance -ClassName Win32_Process -Property @{Handle=’0′} -Key …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (Win32_Process (Handle = “0”):CimInstance) [New-CimInstance], CimException
+ FullyQualifiedErrorId : HRESULT 0x80041024,Microsoft.Management.Infrastructure.CimCmdlets.NewCimInstanceCommand

The only way it works is if you use –ClientOnly to make an in memory CIM instance that only exists in your PowerShell session

PS> New-CimInstance -ClassName Win32_Process -Property @{Handle=’0′} -Key Handle -ClientOnly

Handle PSComputerName
—— ————–
0

You can remove the –Key parameter

PS> New-CimInstance -ClassName Win32_Process -Property @{Handle=’0′} -ClientOnly

Handle PSComputerName
—— ————–
0

Win32_Process has a Create method that takes these parameters

PS> $class.CimClassMethods[‘Create’].Parameters

Name                       CimType Qualifiers                                 ReferenceClassName
—-                                 ——- ———-                                 ——————
CommandLine                 String {ID, In, MappingStrings}
CurrentDirectory            String {ID, In, MappingStrings}
ProcessStartupInformation Instance {EmbeddedInstance, ID, In, MappingStrings}
ProcessId                   UInt32 {ID, MappingStrings, Out}

Using Invoke-CimMethod

PS> Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine=’notepad.exe’}

ProcessId ReturnValue PSComputerName
——— ———– ————–
2648           0

Now trying New-CimInstance

PS> New-CimInstance -ClassName Win32_Process -Property @{Handle=’0′; CommandLine=’notepad.exe’} -Key Handle
New-CimInstance : Provider is not capable of the attempted operation
At line:1 char:1
+ New-CimInstance -ClassName Win32_Process -Property @{Handle=’0′; Comm …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (Win32_Process (Handle = “0”):CimInstance) [New-CimInstance], CimException
+ FullyQualifiedErrorId : HRESULT 0x80041024,Microsoft.Management.Infrastructure.CimCmdlets.NewCimInstanceCommand

Other variants of not including the Handle property and changing the handle value all fail with same error

Botton line is that New-CimInstance is a bit of a mess to use – with or without the –Key parameter (which doesn’t seem to do much).

If the CIM class has a create method Id recommend that you use that as a lot of CIm classes (or their providers) don’t work with New-cimInstance. In reality given that many of the CIM classes are effectively read only – you can’t create a new instance of Win32_ComputerSystem for example – it probably doesn’t matter.

 Comment on this Post

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when other members comment.

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

Share this item with your network: