Craig Forrester

The Pleasure of Finding Things Out

github linkedin email rss
Interactive PowerShell, Part 4: Objects
February 23, 2018
6 minutes read

In my previous post in this series, I discussed how to set up your PowerShell profile so that you could start collecting shortcuts and tools into it that will make working with PowerShell interactively much, much easier. In this post, I’d like to take a step back and talk about what distinguishes PowerShell from other shells and what that means for how we use it. This leads to a good question:

What makes PowerShell different from other shells?

To answer this question, we have to first take a look at how most command shells have traditionally done their work.

Text Pipelines

Traditionally, shells have relied on text — text for input and text for output. If you had command in the Command Prompt that you need to filter for specific information, you would send the output of that command to another one whose job it was to look only for a particular sequence of characters.

:: Findstr outputs lines matching either SERVICE NAME or RUNNING
:: in the output of the SC command
sc query | findstr "SERVICE_NAME RUNNING"
::       ^ Pipe character tells shell to pass 'sc' output to 'findstr'

The basic unit of operation for most shells is text characters. The shell passes a stream of text from one command to another. Each command in the pipeline operates in turn on sets of the characters it gets from the previous command — perhaps delimiting them by word boundaries with spaces or tabs, or treating each line as a distinct item to work with by using line breaks. It manipulates those characters, or groups of them, and passes it changes on down the pipeline to the next command. This is a bit of an oversimplification, but it should suffice to say that text is lingua franca of most command shells.

Object Pipelines

What makes PowerShell unique is that its basic unit of operation is objects. We could quibble over the details of that statement, but from the perspective of a PowerShell user, they are working with objects, not text.

Take, for example, the PowerShell implementation of the sc command line I showed you above:

gsv | ?{ $_.Status -eq 'Running' }

This cryptic command line does pretty much the same thing as the previous example with sc, but it is actually working with objects.

“But wait,” you say, “Isn’t it just filtering through text output like findstr does?

Actually, no, it’s not, and that is what makes PowerShell so powerful, and so easy to work with…

The gsv command is an alias for Get-Service and ? is an alias for Where-Object. If we were to expand that last command out and reconstruct it a bit, it would look like this:

Get-Service | Where-Object -Property Status -EQ -Value Running

Get-Service is actually passing objects to the Where-Object cmdlet, which looks at the properties of those objects and only returns (passes on down the pipeline) those whose value is equal to “Running”.

This notion of “Properties” lets us do things like this:

Get-Service | Sort-Object -Property Status

This kind of filtering and sorting in text based shells is much more cumbersome. If, for example, the commands themselves do not natively support it, sort on a “column” of text can require a lot of extra work. PowerShell lets us do this with ease, because it’s using objects.

What is an Object anyway?

If you’ve used PowerShell for any time at all, you’ve likely stumbled over a reference to objects — and if you haven’t yet, you will. But what exactly is an “object” and why does it matter?

It’s a bit academic, but once we understand what an “object” is, and how PowerShell stitches them together in a “pipeline”, we will far more efficient using PowerShell, interactively and when we create scripts.

An object is a container for data and code.

That’s my personal definition. It’s short and to the point, and it drives to the two key aspects of what most PowerShell output objects have in them. You can compare objects to cars, for example:

Container Object Car
Data Property Option
Code Method Feature

An object’s data is accessed through its properties, which are like the options on a car — for example, its color being red. An object’s code is accessed through its methods, which are like the features of a car — for example, the ability to accelerate, stop, or engage all-wheel drive.

So, here’s an example of what that might look like for either:

Object Windows Service Car Mustang
Property ServiceName Option Leather Interior
Method Start Feature Set Cruise Control

Now, obviously a car has thousands of options and features, and objects have only a few, but another way that you can think of the distinctions between properties and methods is that properties are something, and methods do something. Or, if you like language, properties are nouns, methods are verbs:

Object Car Thing Word
Property Option Is Noun
Method Feature Does Verb

We can explore what various objects are and do inside PowerShell with the Get-Member cmdlet:

Get-Service | Get-Member

Sample output:

   TypeName: System.ServiceProcess.ServiceController

   Name                      MemberType    Definition
   ----                      ----------    ----------
   Name                      AliasProperty Name = ServiceName
   RequiredServices          AliasProperty RequiredServices = ServicesDependedOn
   Disposed                  Event         System.EventHandler Disposed(System.Object, System.EventArgs)
   Close                     Method        void Close()
   Continue                  Method        void Continue()
   CreateObjRef              Method        System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
   Dispose                   Method        void Dispose(), void IDisposable.Dispose()
   Equals                    Method        bool Equals(System.Object obj)
   ExecuteCommand            Method        void ExecuteCommand(int command)
   GetHashCode               Method        int GetHashCode()
   GetLifetimeService        Method        System.Object GetLifetimeService()
   GetType                   Method        type GetType()
   InitializeLifetimeService Method        System.Object InitializeLifetimeService()
   Pause                     Method        void Pause()
   Refresh                   Method        void Refresh()
   Start                     Method        void Start(), void Start(string[] args)
   Stop                      Method        void Stop()
   WaitForStatus             Method        void WaitForStatus(System.ServiceProcess.ServiceControllerStatus desiredStatus), ...
   CanPauseAndContinue       Property      bool CanPauseAndContinue {get;}
   CanShutdown               Property      bool CanShutdown {get;}
   CanStop                   Property      bool CanStop {get;}
   Container                 Property      System.ComponentModel.IContainer Container {get;}
   DependentServices         Property      System.ServiceProcess.ServiceController[] DependentServices {get;}
   DisplayName               Property      string DisplayName {get;set;}
   MachineName               Property      string MachineName {get;set;}
   ServiceHandle             Property      System.Runtime.InteropServices.SafeHandle ServiceHandle {get;}
   ServiceName               Property      string ServiceName {get;set;}
   ServicesDependedOn        Property      System.ServiceProcess.ServiceController[] ServicesDependedOn {get;}
   ServiceType               Property      System.ServiceProcess.ServiceType ServiceType {get;}
   Site                      Property      System.ComponentModel.ISite Site {get;set;}
   StartType                 Property      System.ServiceProcess.ServiceStartMode StartType {get;}
   Status                    Property      System.ServiceProcess.ServiceControllerStatus Status {get;}
   ToString                  ScriptMethod  System.Object ToString();

My hope is that we took some of the mystery, or even anxiety, out of objects for you, and make working with them, and PowerShell, a lot clearer and more straightforward. In my next post in this series, I’ll talk more about objects and how we can make use of their properties and methods.

Additional Reading

Back to posts