- A Go AWS SDK example - Fri, Nov 11 2022
- Getting started with Jenkins - Tue, Aug 16 2022
- Pulumi vs. Terraform - Tue, Jul 5 2022
As you probably know, PowerShell is an object-oriented programming (OOP) language. An object may contain data in the form of fields or properties and code to perform an action called a method. Properties and methods are called members.
Using the Get-Member cmdlet lets you view the structure of an object. All objects in PowerShell are wrapped around PSObject, giving us the capability to view and extend members. If you wish to extend an object, you would generally use the Add-Member cmdlet. Objects you extend with other objects are called synthetic members, named so because they are not part of the original object.
The Get-Member cmdlet allows you to view and analyze objects a command returns. The easiest way to do this is to pipe a command action to Get-Member:
Get-ChildItem -Path C:\Temp | Get-Member
You could also use the InputObject parameter on Get-Member itself:
Get-Member -InputObject (Get-ChildItem -Path C:\Temp)
PowerShell does have some hidden members, one of those being PSObject. Here's how to access these hidden members:
Get-Service -Name BITS | Get-Member -Force | Where Name -Like PS*
Now let's look at the PSObject member attached to Get-Service when looking at the Background Intelligent Transfer Service (BITS):
(Get-Service -Name BITS).PSObject
You can see it returns a whole host of information. A lot of the information Get-Member returns is from PSObject, which is very rich in detail. MemberType alone returns the following allowed values:
AliasProperty, CodeProperty, Property, NoteProperty, ScriptProperty, Properties, PropertySet, Method, CodeMethod, ScriptMethod, Methods, ParameterizedProperty, MemberSet, and All
The Definition column of Get-Member indicates the MemberType type (such as a string) and whether it's a value you can only view or change (Set).
To make this a bit clearer to follow, I've written a function called Format-Member. As the name suggests, the function is based on Get-Member, but with a formatted view. This example shows the output from the function:
Get-Service -Name BITS | Format-Member
In this screenshot, I've captured the first five objects Format-Member returned. As a rule, each member returned with over four objects changes the format from table view to list view. The format file PowerShellCore.format.ps1xml controls this (as I'm using PowerShell Core). Format-Member only returns instance members, not any static ones.
The Format-Member function returns the name, the MemberType, the type of object, and whether you are able to get and set the members. The function splits up the Definition from Get-Member to an easier format to read. What's nice is that each member returned shows the type of object it uses.
With the TypeName, you can also pipe this to Get-Member. Here's the type System.String piped to Get-Member to look at the static methods:
[System.String] | Get-Member -Static
I can see that String has a static method of join, so by getting this information from Get-Member, I now know I can do this:
[System.String]::Join(' / ','1','2')
We are really only skimming the surface here when looking at how to view and work with objects in PowerShell. Understanding how object data structure works with data fields, methods, and PowerShell integration is key. Below is the code of my Format-Member function, and you can always find the latest version on GitHub.
Subscribe to 4sysops newsletter!
function Format-Member { [CmdletBinding()] [alias("fm")] param ( [parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)] [System.Management.Automation.PSObject] $InputObject ) process { $Members = Get-Member -InputObject $InputObject '{0}: {1}' -f "TypeName", $Members.TypeName[0] $Members | ForEach-Object { $CurrentObject = $_ ; [PSCustomObject]@{ Name = $CurrentObject.Name MemberType = $CurrentObject.MemberType Type = ($CurrentObject.Where({$_.MemberType -ne 'AliasProperty'}).Definition -split '\s')[0] Getter = $CurrentObject.Where({$_.MemberType -eq 'Property' -and $_.Definition -match 'get'}) -as [bool] Setter = $CurrentObject.Where({$_.MemberType -eq 'Property' -and $_.Definition -match 'set'}) -as [bool] } } } }