Mark Stepan
Mark Stepan

Reputation: 99

Can someone explain the difference between Get-ComputerInfo -Property OSName vs (Get-ComputerInfo).OSName

I had some old code for documenting the particulars of my machines when I came across Get-ComputerInfo. So I tried to use it (unsuccessfully) and was almost ready to give up when I came across a way to get what I wanted. But now I'm wondering if anyone can help me understand WHY it works the way it does.

It's pretty simple to illustrate:

$OSName1 = Get-ComputerInfo -Property OSName

$OSName2 = (Get-ComputerInfo).OSName

Write-Host $OSName1

Write-Host $OSName2

The above yields:

@{OsName=Microsoft Windows 11 Pro}

Microsoft Windows 11 Pro

I was expecting the 2nd result from the 1st variable. So what's happening differently in those 2 variables? I was expecting them to be the same.

Thanks in advance!

Mark

Upvotes: 3

Views: 778

Answers (1)

briantist
briantist

Reputation: 47792

While the comments do explain what you're already seeing, which is that Get-ComputerInfo -Property OSName returns an object with that property, what isn't obvious is why the command would do that, instead of returning what you expected: the same thing as (Get-ComputerInfo).OSName.

The reason becomes more clear when looking at the help:

Get-Help Get-ComputerInfo
NAME
    Get-ComputerInfo

SYNTAX
    Get-ComputerInfo [[-Property] <string[]>]  [<CommonParameters>]


ALIASES
    gin

In the syntax, we can see that -Property takes a String array and not just a single string.

So you can pass an array of property names to return, like this for example:

$info = Get-ComputerInfo -Property OSName, TimeZone, OSProductType

Write-Host $info

And then get:

@{TimeZone=(UTC-05:00) Eastern Time (US & Canada); OsName=Microsoft Windows 10 Enterprise; OsProductType=WorkStation}

Now, I did it that way to match your question, but if you just output the value naturally, or via Write-Output, it would look a lot nicer:

$info
Write-Output $info
TimeZone                               OsName                          OsProductType
--------                               ------                          -------------
(UTC-05:00) Eastern Time (US & Canada) Microsoft Windows 10 Enterprise   WorkStation

Or you could format it:

$info | Format-List
TimeZone      : (UTC-05:00) Eastern Time (US & Canada)
OsName        : Microsoft Windows 10 Enterprise
OsProductType : WorkStation

So the answer why it returns an object with a single property, it's for consistency for when you request multiple properties (or request none and get them all).


This property selection works exactly the same as if you had used Select-Object:

$info = Get-ComputerInfo | Select-Object -Property TimeZone, OSName, OSProductType

It's also worth noting that Get-ComputerInfo is quite slow, and that selecting individual properties does not speed it up in any way, so there is no particular advantage to using the built-in selection vs. selecting after the fact, other than conciseness and readability.

If you need multiple properties, it's definitely not a good idea to make multiple calls to Get-ComputerInfo with different properties selected, as you're retrieving all the same info on every call and then discarding most of it that way.

If you're unsure which properties you need in the first call, just get them all, and choose them later:

$info = Get-ComputerInfo 

if ($condition1) {
    # do thing with $info.OSName
}

if ($condition2) {
    # do thing with $info.TimeZone
}

# etc.

Upvotes: 4

Related Questions