Behind the PowerShell Pipeline logo

Behind the PowerShell Pipeline

Subscribe
Archives
February 21, 2025

Are You My Type?

Even though PowerShell is built on the .NET Framework, you have never been required to be a .NET developer to use PowerShell. Microsoft designed PowerShell for IT Pros to get work done quickly and easily. This is possible because PowerShell abstracts the complexity of .NET and provides a simplified interface for working with objects. Instead of having to know about the Kill() method of the Process class and how to invoke it, you can simply use the Stop-Process cmdlet. Instead of being forced to know about the ServicesDependedOn property of System.Service.ServiceController class in order to see required services, PowerShell abstracts that complexity in the way it presents service objects to you.

Meet the ETS

Here's what I'm talking about. This is a typical PowerShell operation.

PS C:\> Get-Process -id $pid | Select-Object -Property ID,Name,WS,CommandLine,Product

Id          : 35012
Name        : pwsh
WS          : 123248640
CommandLine : pwsh.exe -NoLogo -NoProfile
Product     : PowerShell

Get something and display some properties. But where do these properties come from? Start by asking Get-Member.

PS C:\> Get-Process -id $pid | Get-Member -Name ID,Name,WS,CommandLine,Product

   TypeName: System.Diagnostics.Process

Name        MemberType     Definition
----        ----------     ----------
Id          Property       int Id {get;}
Name        AliasProperty  Name = ProcessName
WS          AliasProperty  WS = WorkingSet64
CommandLine ScriptProperty System.Object CommandLine {get=...
Product     ScriptProperty System.Object Product {get=$this.Mainmodule.FileVersionInfo.Pr...

ID is an actual property of the System.Diagnostics.Process class. If you were to look up the documentation on this .NET class, you would find ID as a property.However, you won't find the other properties listed. PowerShell added them to make working with process objects easier. The alias properties are defined so that you can useName instead of ProcessName and WS instead of WorkingSet64. A .NET developer would know to use ProcessName and WorkingSet64, but PowerShell abstracts that complexity for you and simplifies things so you can use Name and WS.

By the way, a script property is a way of getting a property value from a script block. The .NET class doesn't have a CommandLine property. But PowerShell can run a code snippet to get a value. We'll dig into this in a bit.

All of these properties are added automatically by PowerShell's extensible type system (ETS). That's why you are encouraged to use Get-Member to explore objects. Another way to discover if an object has been extended is to use Get-TypeData. All you need to know is the object type name which you can get from Get-Member.

PS C:\> $td = Get-TypeData System.Diagnostics.Process
PS C:\> $td.Members

Key            Value
---            -----
Name           System.Management.Automation.Runspaces.AliasPropertyData
SI             System.Management.Automation.Runspaces.AliasPropertyData
Handles        System.Management.Automation.Runspaces.AliasPropertyData
VM             System.Management.Automation.Runspaces.AliasPropertyData
WS             System.Management.Automation.Runspaces.AliasPropertyData
PM             System.Management.Automation.Runspaces.AliasPropertyData
NPM            System.Management.Automation.Runspaces.AliasPropertyData
Path           System.Management.Automation.Runspaces.ScriptPropertyData
CommandLine    System.Management.Automation.Runspaces.ScriptPropertyData
Parent         System.Management.Automation.Runspaces.CodePropertyData
Company        System.Management.Automation.Runspaces.ScriptPropertyData
CPU            System.Management.Automation.Runspaces.ScriptPropertyData
FileVersion    System.Management.Automation.Runspaces.ScriptPropertyData
ProductVersion System.Management.Automation.Runspaces.ScriptPropertyData
Description    System.Management.Automation.Runspaces.ScriptPropertyData
Product        System.Management.Automation.Runspaces.ScriptPropertyData
__NounName     System.Management.Automation.Runspaces.NotePropertyData

This is a list of type extensions for process objects. The value indicates the type of property. Let's look at these with Get-Member.

PS C:\> Get-Process -id $pid | Get-Member -name $($td.Members.keys)

   TypeName: System.Diagnostics.Process

Name           MemberType     Definition
----           ----------     ----------
Name           AliasProperty  Name = ProcessName
SI             AliasProperty  SI = SessionId
Handles        AliasProperty  Handles = Handlecount
VM             AliasProperty  VM = VirtualMemorySize64
WS             AliasProperty  WS = WorkingSet64
PM             AliasProperty  PM = PagedMemorySize64
NPM            AliasProperty  NPM = NonpagedSystemMemorySize64
Path           ScriptProperty System.Object Path {get=$this.Mainmodule.FileName…
CommandLine    ScriptProperty System.Object CommandLine {get=…
Parent         CodeProperty   System.Object Parent{get=GetParentProcess;}
Company        ScriptProperty System.Object Company {get=$this.Mainmodule.FileV…
CPU            ScriptProperty System.Object CPU {get=$this.TotalProcessorTime.T…
FileVersion    ScriptProperty System.Object FileVersion {get=$this.Mainmodule.F…
ProductVersion ScriptProperty System.Object ProductVersion {get=$this.Mainmodul…
Description    ScriptProperty System.Object Description {get=$this.Mainmodule.F…
Product        ScriptProperty System.Object Product {get=$this.Mainmodule.FileV…
__NounName     NoteProperty   string __NounName=Process

A CodeProperty is similar to a ScriptProperty, except that the value is derived from invoking compiled code. A NoteProperty is a simple property that typically has a fixed value for all objects.

PS C:\> Get-Process | Get-Random -count 5 |
Select-Object -Property ID,Name,__NounName

   Id Name                             __NounName
   -- ----                             ----------
 6088 pia-service                      Process
12392 vmmem                            Process
27216 wsl                              Process
21056 Code                             Process
17532 IntelSoftwareAssetManagerService Process
Want to read the full issue?
GitHub Bluesky LinkedIn About Jeff
Powered by Buttondown, the easiest way to start and grow your newsletter.