PowerShell Basics - Filtering and Selecting

Author by Mitchell Grande

The next topic in the PowerShell Basics series is focused on filtering and selecting PowerShell objects using the Where-Object and Select-Object commands.  Using these commands allows you to precisely define what items are displayed or acted on.

Review of PowerShell Objects and the Pipeline

To learn how to use the Where-Object and Select-Object commands, it's important to understand the concepts we covered in past articles.  First, PowerShell is based on objects.  Nearly every command will output an object with multiple properties that can be viewed and filtered on individually.  For example, the Get-Process command will return multiple separate pieces of information about running Windows processes, such as the EXE path, start time, and current memory usage.  Each of these are stored as properties within a Process object.  Additionally, PowerShell commands can be chained together with the Pipe character: |.  When doing so, you are passing the results of the commands on the left of the pipe into the commands on the right of it.  If you pipe Get-Process to Stop-Process, as in Get-Process | Stop-Process, the processes selected by the Get-Process command will be stopped.  With no filtering in place, this would attempt to stop all of the running processes on the system.

Where-Object

The Where-Object command is used to filter objects based on any of their properties.  Where-Object follows a consistent pattern that looks like:

Where-Object {$_.PropertyName -ComparisonType FilterValue}

The PropertyName is the name of the object's property that you are filtering.  ComparisonType is a short keyword for what type of comparison you are doing.  Some examples are "eq" for equals, "gt" for greater than, "lt" for less than, and "like" for a wildcard search.  Finally, the FilterValue is the value you are comparing the object's property against.  For example, the Get-Process command contains a property called "WorkingSet" which represents the amount of memory used by the process.  We can use the Where-Object command, combined with Get-Process, to find all running processes using more than 100MB of memory.  In this example, we'll use WorkingSet for the property name, gt for the comparison operator (which stands for greater than), and 100000000 for the value to compare to (which is approximately 100MB):

Get-Process | Where-Object {$_.WorkingSet -gt 100000000}

For another example, we can find all Windows services that contain "dns" in their name.  The like operator in this example allows you use asterisks as wildcards in your search:

Get-Service | Where-Object {$_.Name -like "*dns*"}

Finally, we can also pipe the results of Where-Object to another command to actually take action on the results.  For example, we can stop all services that are set to manual start with this command:

Get-Service | Where-Object {$_.StartType -eq "Manual"} | Stop-Service

Getting Property Names

In each of the above examples, we filtered our results using the names of properties that we already knew.  If you don't know what properties an object contains, or you need some examples of values, you can use the Format-List command to list out the entire object.  For example, we can find out all of the properties of Windows services by running:

Get-Service | Format-List *

The "Format-List *" command will output all properties and their values of the object passed in on the pipeline.  You can use the result of that command to help you build your filter.  Note that the asterisk (*) after the Format-List command is important to include.  If you don't include that, you may not see all of the available properties.

Select-Object

The other command to learn about is Select-Object.  This command is used to limit or modify the results of other commands.  There are many different ways to use it, but a common one is to select the first N results of another command.  For example, we may want to see just the first 5 files in a folder:

Get-ChildItem | Select-Object -First 5

Conversely, you may want to see just the last 5:

Get-ChildItem | Select-Object -Last 5

Finally, this command can also be used to choose which properties are retrieved and displayed.  This example will return the name and PID of all processes running on the system:

Get-Process | Select-Object -Property Name, Id

Using the Where-Object and Select-Object commands allows you to easily control which items you are working on in PowerShell.  You can use these commands to either filter the data you are viewing or to limit actions (such as stopping services or removing files) to those that match the filters you define.  The next article will be the final one in this series.  We'll be looking at looping through groups of objects to perform more complex tasks on a set of items. 

Author

Mitchell Grande

Systems Engineer

Tags in this Article