Prof. Powershell

I'm Into That: Automation Tasks in PowerShell

It's easy to get confused when testing whether something is "in" something else or "contains" something else. Prof. PowerShell is here to clear some of the confusion.

A common automation task is testing if something is in something else. This can get tricky because you are probably thinking about a particular value and PowerShell gives you so much more. Let's start with some basic operators and examples.

In PowerShell 3.0 we can use operators –In and –Contains. They work essentially the same. An easy way to demonstrate them with an array of numbers.

PS C:\> $n = 1..100

The variable $N is the numbers 1 to 100. It is pretty simple to test membership.

PS C:\> 45 -in $n
True
PS C:\> 101 -in $n
False
PS C:\> $n -contains 77
True
PS C:\>

As with other comparison operators you get either True or False. If you need to test for the opposite, there are also –NotIn and –NotContains operators.

PS C:\> $n -notcontains 77 False
PS C:\> 200 -notin $n
True

What trips people up is that their minds are thinking one thing and PowerShell is doing something else.

PS C:\> $run = get-service | where {$_.status -eq 'running'}
PS C:\> "bits" -in $run
False
PS C:\> $run -contains "bits"
False

What I am intending is to see if the BITS service is in the list of running services. Yes, I know there are other ways to handle this particular scenario. I'm explaining a concept. So I'm looking for "bits" in the variable. But what is in $run? It is a collection of service objects, each with a number of properties. I'm asking PowerShell to test if the string "bits" is contained in the collection of service objects which will never happen.

Instead, what I can is test if "bits" is in the collection of service names. PowerShell v3 makes this pretty easy.

PS C:\> $run.name -contains "bits"
True
PS C:\> "bits" -in $run.name
True

Even though $run is a collection of objects, I can still reference a single property like Name and PowerShell will automatically expand it into a collection of names. Now the operators work. By the way, the comparison is not case sensitive.

PS C:\> "bItS" -in $run.name
True

Whether you test if something is IN something or if something CONTAINS something is really up to you and whatever makes the most semantic sense. I also haven't seen a situation where there is any difference in performance. The main thing to remember is that you are testing for values and not objects.

About the Author

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.

comments powered by Disqus
Most   Popular