user1404390
user1404390

Reputation: 35

Simple logic statement in PowerShell using WMI

In PowerShell, I'm typing the statement:

$var = Get-WmiObject win32_product | select-object name

if ($var.name -like 'adobe') {write-host '123'}

The variable stores the list of installed products just fine; however, my if then won't catch anything. On execution I get no output or error. This works if I use something like Get-Process, but not with Get-WmiObject.

Upvotes: 2

Views: 6263

Answers (5)

JPBlanc
JPBlanc

Reputation: 72680

Another answer is that it's better to ask WMI to filter on the server, and you'll have less network traffic. Here is an example with a WMI filter:

Get-WmiObject win32_Product -Filter "name like '%adobe%'"

Upvotes: 1

Shay Levy
Shay Levy

Reputation: 126902

$var.name only works when $var contains a single object (scalar, singelton). When $var holds a collection of items, PowerShell tries to get you the Name property of the collection itself.

The collection/array doesn't have a Name property and you get nothing back. That said, $var.Name will work in PowerShell v3.

To compare to the Name property you need to loop through all objects and:

if ($var.name -like 'adobe') {write-host '123'}

If you'd extracted all values ($var contains a list of strings) then you could do:

$var = get-wmiobject win32_product | select-object -expand name

if ($var -like 'adobe') {write-host '123'}

Upvotes: 0

Andy Arismendi
Andy Arismendi

Reputation: 52689

The -like operator is a wildcard pattern matching operator. It returns things that match the expression you provide. Use * as the wildcard character. So you would use:

if ($var.name -like '*adobe*') {write-host '123'}

Update - Accessing the name property on the collection like this only worked for me in PowerShell v3. For PowerShell v2 I think you'll need to do things a little differently. I'd suggest creating a string array instead of a collection of PsCustomObjects like this (the -ExpandProperty param does the work):

$var = get-wmiobject win32_product | ? {$_.Name} | select-object -Expand name

Then do the if statement without using the name property:

if ($var -like '*adobe*') {write-host '123'}

If you have something installed with adobe in the name it will execute the IF block.

Upvotes: 1

zdan
zdan

Reputation: 29450

To add to @Zach's answer, the like operator as you've stated it:

$var.name -like 'adobe'

will only match if if he name isexactly equal to 'abobe'.

For e.g.

PS C:\> 'adobe' -like 'adobe'
True
PS C:\> 'Adobe Air' -like 'adobe'
False

However, -like is intended to be used with wildcards:

PS C:\> 'Adobe Air' -like '*adobe*'
True

and so you can do

$var | foreach{ if ( $_.name -like '*adobe*' ) { write-host '123' } }

or, in the more POSH style, use where-object

$var | where-object{ $_.name -like '*adobe*' } |  write-host '123'

Upvotes: 0

Zach Bonham
Zach Bonham

Reputation: 6827

I never realized there was a -like comparison operator? I usually use .Contains("value looking for") in that instance.

However, just noticed here that there is a -contains operator.

Mastering PowerShell, Chapter 7 Conditions

Ah, if you getting more than one result back you will need to loop through them:

$var | foreach-object { if ( $_.name -contains 'adobe' ) { write-host '123' } }

Something like that maybe?

$var is the results list, which doesn't have a property 'name', but each item in the list should.

Upvotes: 0

Related Questions