Craig Forrester

The Pleasure of Finding Things Out

github linkedin email rss
Interactive PowerShell, Part 5: Object Properties
February 28, 2018
4 minutes read

In my previous post in this series, I talked about how PowerShell’s use of objects distinguishes it from other shells and what that means for how we use it. In this post, I’ll talk more about objects and their properties.

Properties

We’ve already talked a bit about PowerShell object properties, and said that properties are like the options on a particular model of a car: a car can be red, have leather interior, a navigation system, etc. Properties on objects in PowerShell are similar. They describe certain specifics about that object. Depending on what they are, we can think of them like attributes describing the object, or data that the object contains.

Let’s model what our car example would look like as a simple PowerShell Object:

# Create a new object with two properties
$car = New-Object -TypeName psobject -Property @{
       'Color'='Red';
       'Interior'='Leather';
       }

We’ve created an object1 with two special properties, which we can now view using several different techniques. Here is an example using dot notation:

PS> $car.Color
Red
PS> $car.Interior
Leather

Another way to access object properties is to pipe them to another cmdlet called Select-Object, which we often abbreviate with its alias as simply select:

PS> $car | select Color

Color
-----
Red


PS> $car | select Interior

Interior
--------
Leather

As you can see, even though we are accessing the same properties and getting more-or-less the same information, we get slightly different output. The reason for this is that the dotted notation simply outputs a string (plain text), while Select-Object actually extracts the property and wraps it up as a custom object. We’ll go into why this matters later. For now, it’s enough to know that there is more than one way to get at an object’s properties, and that we can get simple text representations of values if we want to.

Let’s see another example, this time using a native cmdlet for listing services in Windows. We’ll select a single service and then format the object output as a list, for easier reading. Note that the asterisk (*) here indicates that we want to see all of the object properties, not just the few that show in the default output:

PS> # Show Properties of the "BITS" service
PS> Get-Service -Name 'BITS' | Format-List *

Name                : BITS
RequiredServices    : {RpcSs}
CanPauseAndContinue : False
CanShutdown         : False
CanStop             : False
DisplayName         : Background Intelligent Transfer Service
DependentServices   : {}
MachineName         : .
ServiceName         : BITS
ServicesDependedOn  : {RpcSs}
ServiceHandle       :
Status              : Stopped
ServiceType         : Win32ShareProcess
StartType           : Manual
Site                :
Container           :

Note that what we’re displaying here is specific information about one service in particular. If we want to display information about this type of object — and the properties in particular — we can send the output to the Get-Member cmdlet, like this:

# Get a service and show information about the object properties
Get-Service -Name 'BITS' | Get-Member -MemberType Properties

Example Output:

PS> Get-Service -Name 'BITS' | Get-Member -MemberType Properties


   TypeName: System.ServiceProcess.ServiceController

Name                MemberType    Definition
----                ----------    ----------
Name                AliasProperty Name = ServiceName
RequiredServices    AliasProperty RequiredServices = ServicesDependedOn
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;}

As you can see, this output is not specific to the BITS service per se, but rather the type of object it is — metadata about it, if you will. Most of the properties are fairly self-explanatory. Some of the properties describe things about the service that don’t change, such as what other services BITS depends on (ServicesDependedOn) and others that show the current status of other things about the service that can change, such as whether or not it’s running (Status).

This is an important feature of object properties that you’ll want to keep in mind: object properties can change (think “dynamic”) or stay the same (think “static”). Another aspect of properties to think about is that some properties you may be able to affect or change yourself (think “mutable”), and others you may not be able to change (think “immutable”).

In my next post, we’ll talk about the other feature of objects we touched on last time — methods — and how we can use methods to affect the state and properties of objects, as well as the things they represent — like Windows Services, for example.

Additional Reading


  1. Note that this is not how you would typically see this code written. I have formatted it this way simply for the sake of legibility in the flow of this post. Often times we will place our custom object properties in their own variable first, then instantiate the object… but more on that later. [return]

Back to posts