Powershell – Understanding Select-Object

Understanding how “Select-Object” works, can differentiate an average from a good Powershell user. So lets dedicate some time in understanding how Select-Object works.

Select-Object is mainly used to override the default display of the cmdlets. Example:

select

When you run the Get-Service cmdlet, the output displays the Status, Name and DisplayName. By piping the output of Get-Service to Select-Object, you can override the default display for that object type.

(Piping the Get-Service output to Get-Member, allows you to understand what other properties can be used with the Select-Object)

Select-Object changes the object type

Notice the below two examples and observe the TypeName in both the case.

Get-Service | gm

get-service

Get-Service | Select-Object name | gm

get-service-select

From the above two outputs, you can clearly see that the Select-Object is changing the object from System.ServiceProcess.ServiceController to Selected.System.ServiceProcess.ServiceController. That, it is “Selecting” only few properties from the “original” service object. Now, you will not be able to treat the new object as a service object. Hence you cannot run the operations that you were running on the good-old service object. Hence, the Select-Object HAS to be the last cmdlet in the pipeline.

Selecting subset of objects

Select-Object allows us to choose a subset of objects either from the beginning, from the end, or a chunk of object from a random range. Powershell provides, “First”, “Last” and “Skip” parameters just for these operations.

We are running the below three cmdlets as a demonstration:

Get-Service | Sort-Object name | Select-Object -first 5

Get-Service | Sort-Object name | Select-Object -last 5

Get-Service | Sort-Object name | Select-Object -first 3 -Skip 2

subset

Note: No matter in which order you are specifying the parameters to the Select-Object. If you have specified -Skip, it will ALWAYS execute first, and then -First or -Last (if you have specified along with skip).

Select-Object allows Custom Properties

Custom Properties are the ones which do not come pre-loaded with Powershell. instead they are dynamically created by the user on the go.

Example:

Get-Process | select name, id, @{label='TotalMemory';expression={($_.pm + $_.vm)/ 1MB -as [int]}}

custom properties

What did we just do?

  • We wanted to calculate the TotalMemory of a service. Since we do not have a default parameter that provides us this value. We decided to create a custom property of our own.
  • The structure starting with ‘@‘ sign is called a hash table. A Hash Table contains entries in the form of a name-value pair. Custom Properties comes with two pairs. Each pair is separated by a semi-colon.
  • The first key is called as “Label” or “Name“. The value for this key is what you want to appear in the column header of your custom property.
  • The second key is called the “Expression“. The value for this key,  is the code for the powershell to run/execute to create the resulting row in the custom property.
  • The $_ holder is a place holder for the current object in the pipeline. This can be replaced by $PSItem, both have same meaning.
  • Each @ structure represents a single custom property. You can have as many custom property as you like.

Expanding Properties

Imagine a situation, you want to grab process from the computers [dc=company, dc=pri] in your Active Directory.

You are sure that the below command will fetch the desired computers from the Active Directory.

Get-AdComputer -Filter * -SearchBase "dc=company, dc=pri"

And you also know that the Get-Process has a -ComputerName as a parameter. So you go ahead an happily run the below command:

Get-Process -ComputerName (Get-AdComputer -Filter * -SearchBase "dc=company, dc=pri")

To your surprise the command does not generate the desired result. This is because the Get-AdComputer is generating ADComputer objects. However, the -ComputerName parameter in the Get-Process cmdlet is asking for String[] type input. This is where the -ExpandProperty parameter of the Select-Object shines.

Have a look at this command:

Get-Process -ComputerName (Get-AdComputer -Filter * -SearchBase "dc=company, dc=pri" | Select-Object -ExpandProperty Name)

When Powershell executes this command, it is fetching the desired computers and then expanding the Name property. This has an effect of writing a collection of string to the pipeline, instead of bunch of objects.

-ExpandProperty is a handy technique when you want to save property value to variable.

bits1

As shown above, the Select-Object wrote a ServiceController object into the variable. Hence we need to use a sub-expression to fetch the display name.

bits2

In this case, the Select-Object wrote a String into the variable. This way, it is very easy to access the display name. You can expand single property or a bunch or properties.

From Powershell v3, we have a shortcut way to implicitly expand a property:

(Get-Process).name

implicit

Confirming that the output were String objects:

(Get-Process).name | gm

implicit 2

Some properties are collection of other objects. Example:

expanding1

We can use the -ExpandProperty to “expand” them into their stand-alone objects.

expanding2

We can also use the shortcut trick to get the same results.

expanding3

2 comments

  1. ManJunath: Thank you for this post. I have enjoyed it immensely ! I continue to study it!
    This particular post I have read multiple times and I’m currently running small Shell experiments dissecting your words of wisdom.

    Please post more as your time permits. Your efforts are NOT wasted.
    Especially for those of us who are new to PS.

    For me currently, gaining a deeper understanding of how Cmdlets manipulate Classes and objects is very important, such studies are on going.

    As part of my PS research, I have been trying to keep special notes for personal documentation.
    I thought of keeping such notes public and easily available. So I decided on WordPress.
    Now mind you, I had never used WordPress before.

    So I created a free account. I encountered some formatting and structuring issues with the free tools provided. was wondering if you would be so kind as to tell me ( or point me in the correct direction) which tools you are utilizing for your WordPress blog.

    Thank you
    Sergacity@gmail.com

    Like

    1. Hello sergacity, Thank you for your love and support. I will definitely spend more time to write interesting contents about Azure and Powershell. Coming to the WordPress, I have purchased a domain and been using the basic tools.

      Like

Leave a comment