Name mismatch

Ever wondered why you can’t do this:

Get-ADComputer -Filter * -SearchBase 'OU=Servers,DC=Manticore,DC=org' |
Get-CimInstance -ClassName Win32_OperatingSystem

The –ComputerName parameter on get-CimInstance accepts pipeline input BUT its by property name.

PS> Get-Help Get-CimInstance -Parameter ComputerName

-ComputerName [<String[]>]
    Specifies computer on which you want to run the CIM operation. You can specify a fully qualified domain name
    (FQDN), a NetBIOS name, or an IP address.

    If you do not specify this parameter, the cmdlet performs the operation on the local computer using Component
    Object Model (COM).

    If you specify this parameter, the cmdlet creates a temporary session to the specified computer using the WsMan

    If multiple operations are being performed on the same computer, using a CIM session gives better performance.

    Required?                    false
    Position?                    named
    Default value                none
    Accept pipeline input?       True (ByPropertyName)
    Accept wildcard characters?  false

If you look at the output of Get-ADComputer it has a Name property.

PS>  Get-ADComputer -Filter * -SearchBase 'OU=Servers,DC=Manticore,DC=org'

DistinguishedName : CN=W16PWA01,OU=Servers,DC=Manticore,DC=org
DNSHostName       :
Enabled           : True
Name              : W16PWA01
ObjectClass       : computer
ObjectGUID        : 8d137004-1ced-4ff1-bcf4-f0671652fc8c
SamAccountName    : W16PWA01$
SID               : S-1-5-21-759617655-3516038109-1479587680-1322
UserPrincipalName :

So you have a Name mismatch between the property and the parameter.

There are a number of ways to deal with this.

First use foreach

Get-ADComputer -Filter * -SearchBase 'OU=Servers,DC=Manticore,DC=org' |
foreach {
  Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName $psitem.Name | 
  select CSName, Caption

Use $psitem.Name (or $_.Name) as the input to –ComputerName. Simple coding and works very nicely.

If you have a lot of computers you may want to use a foreach loop instead

$computers = Get-ADComputer -Filter * -SearchBase 'OU=Servers,DC=Manticore,DC=org' | select -ExpandProperty Name
foreach ($computer in $computers) {
  Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName $computer|
  select CSName, Caption

Create an array of computer names and iterate through them.

Second use select

Get-ADComputer -Filter * -SearchBase 'OU=Servers,DC=Manticore,DC=org' |
select @{N='ComputerName';E={$_.Name}} |
Get-CimInstance -ClassName Win32_OperatingSystem |
select CSName, Caption

In this case use select-object to create a property with the name ComputerName (case DOESN’T matter) and pipe that into Get-CimInstance.

This option is a bit more advanced as you have understand how select-object works and how to create extra properties on the object you’re passing down the pipeline. It looks cooler and should get you a few extra “ace powerShell coder” points.

The third option takes advantage of the fact that _Computername accepts an array of computer names

Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName (Get-ADComputer -Filter * -SearchBase 'OU=Servers,DC=Manticore,DC=org' | select -ExpandProperty Name) |
select CSName, Caption

You run Get-ADComputer and use select –Expand to only return the VALUE of the computer name (a string). This gives you an array of computer names. Because its in () its treated as an input object to the parameter.

Very clever and gets you maximum points.

This entry was posted in PowerShell and Active Directory, PowerShell and CIM. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s