2021 Annual Petri Reader Survey - We want to know what's important to you! 2021 Annual Petri Reader Survey - We want to know what's important to you!
PowerShell

Tips and Tricks with PowerShell's Get-Member

In “Working with PowerShell’s Get-Member cmdlet,” I guided you through some additional ways to use the Get-Member cmdlet.

Because this cmdlet can expose a lot of information about an object, you might need to fine-tune your expression so that you only see what you need. Although it may not be obvious to do, you can combine parameters to help you in this task.

get-item c:\windows\notepad.exe | get-member -MemberType Properties -View Extended
Combining Get-Member parameters (Image Credit: Jeff Hicks)
Combining Get-Member parameters (Image Credit: Jeff Hicks)

This limits the output to those properties that were added through PowerShell type extensions. You can also select a single member by name.

get-item c:\windows\notepad.exe | get-member -name VersionInfo
Selecting a single member (Image Credit: Jeff Hicks)
Selecting a single member (Image Credit: Jeff Hicks)

Remember that Get-Member writes an object to the pipeline.

Getting the members from Get-Member (Image Credit: Jeff Hicks)
Getting the members from Get-Member (Image Credit: Jeff Hicks)

Because Get-Member writes an object to a pipeline, this makes it so that you can manipulate the output from Get-Member. Let’s say you want to group the results.

get-process | get-member  | group -Property MemberType
Grouping members by member type (Image Credit: Jeff Hicks)
Grouping members by member type (Image Credit: Jeff Hicks)

A better approach is to also use a hashtable.

$members = get-process | get-member -View All | group -Property MemberType -AsHashTable -AsString
Creating a hashtable of members (Image Credit: Jeff Hicks)
Creating a hashtable of members (Image Credit: Jeff Hicks)

Now, you can easily access each member type.

Referencing individual member types (Image Credit: Jeff Hicks)
Referencing individual member types (Image Credit: Jeff Hicks)

Working with method members is especially interesting.

Enumerating member methods (Image Credit: Jeff Hicks)
Enumerating member methods (Image Credit: Jeff Hicks)

Looking at this output, it might be handy to break this down further so that I can see the method name, its output type, and syntax. The information is all there, I just to break it a part from the definition. But I’m going to do more than simply parse text; I want to write a new object to the pipeline with the information I want. This doesn’t require a hashtable, so let me start over.

$members = get-process | get-member -View All -MemberType Method

Now, I have a collection of method members for process objects.

Process method members (Image Credit: Jeff Hicks)
Process method members (Image Credit: Jeff Hicks)

The Name is easy to get, but I’ll have to break down the definition. The first part should indicate the method’s output type, such as String or Boolean. Next is the syntax. But some methods are overloaded, meaning there are multiple syntax options. These are separated by commas. I could split the syntax portion on a comma, but that would mess things up for methods that take multiple parameters, which will also be separated by a comma. My solution is to use a regular expression the looks behind a comma for a closing parenthese. If it finds one, I’ll split there. Here’s the code snippet I came up with.

foreach ($method in $members) {
 $name = $method.name
 #split overloads using a look behind
 $overload = $method.definition -split "(?<=\)),"
 $overload.Trim() | foreach-object {
 #split into type and syntax
 #split on a space with no more than 2 items in the array
 $split =$_.split(" ",2)

 #create a custom object
 [pscustomobject]@{
  Name = $name
  OutputType = $split[0]
  Syntax = $split[1]
  }
 } #foreach overload

} #foreach

Extracted object methods (Image Credit: Jeff Hicks)
Extracted object methods (Image Credit: Jeff Hicks)

I don’t know about you, but I find this much easier to read. The same code doesn’t quite work for static methods.

$members = [math] | get-member -Static -MemberType Method

Using the same code above, gives me this:

Listing static methods (Image Credit: Jeff Hicks)
Listing static methods (Image Credit: Jeff Hicks)

In this case, the output type is part of the definition. My solution was to remove the ‘static’ keyword from the beginning of the definition and then split what was left to get the type and syntax.

foreach ($method in $members) {
 $name = $method.name
 #split overloads using a look behind
 $overloads = $method.definition -split "(?<=\)),"
 foreach ($overload in $overloads) {
  #trim and remove Static
  $m = $overload.Trim().remove(0,7)
  #split into type and syntax
  $split =$m.split(" ",2)
  #create a custom object
  [pscustomobject]@{
    Name = $name
    OutputType = $split[0]
    Syntax = $split[1]
  }
 } #foreach overload
} #foreach

Revised static member listing (Image Credit: Jeff Hicks)
Revised static member listing (Image Credit: Jeff Hicks)

After experimenting with all of this, I decided to go ahead and write a function to easily display an object’s methods.

#Requires -version 4.0

Function Get-Method {
[cmdletbinding()]
Param(
[Parameter(Position=0,Mandatory,ValueFromPipeline)]
[ValidateNotNullorEmpty()]
[object]$InputObject,
[switch]$Static,
[ValidateNotNullorEmpty()]
[System.Management.Automation.PSMemberViewTypes]$View = "All"
)
Begin {
    Write-Verbose "Starting: $($MyInvocation.Mycommand)"
    #Add MemberType
    $PSBoundParameters.Add("MemberType","Method")
    Write-Verbose "PSBoundParameters $($PSBoundParameters | Out-string)"
    #initialize an array
    $in = @()  
} #begin

Process {
 
  #add each input object
  $in+=$InputObject

  
} #process

End {
    If ($Static) {
        Write-Verbose "Analyzing static methods for object type $($in[0].Fullname)"
    }
    else {
       Write-Verbose "Analyzing methods for object type $($in[0].GetType().Fullname)"
    }
    Try {
        #only need to process one object
        $PSBoundParameters.InputObject = $in[0]
        $members = Get-Member @PSBoundParameters -ErrorAction Stop
                
        foreach ($method in $members) {
        $name = $method.name

        #split overloads
        #use a regex look behind to split on ), but keep the )
        $overloads = $method.definition -split "(?<=\)),"
            Foreach ($overload in $overloads) {
            $overload = $overload.Trim()
            if ($Static) {
                #trim and remove 'Static'
                $overload = $overload.Trim().remove(0,7)
            }
            
            #split into type and syntax
            $split =$overload.split(" ",2)
            #create a custom object
            [pscustomobject]@{
            Name = $name
            OutputType = $split[0]
            Syntax = $split[1]
            }
        } #foreach overload

        } #foreach
  } #Try
  Catch {
    Throw $_
  } #Catch

    Write-Verbose "Ending: $($MyInvocation.Mycommand)"
} #end
} #end Get-Method

The function is essentially a wrapper for Get-Member, so it uses the same parameters. This makes it easy to splat the bound parameters (i.e. $PSBoundParameters) to Get-Member. This function works for single objects:

Listing methods for a single object (Image Credit: Jeff Hicks)
Listing methods for a single object (Image Credit: Jeff Hicks)

You can use a cmdlet:

Extracting methods from cmdlet output (Image Credit: Jeff Hicks)
Extracting methods from cmdlet output (Image Credit: Jeff Hicks)

As well as static classes, as long as you remember to use the Static parameter.

[convert] | get-method -Static | out-gridview -title "Convert methods"
Convert static methods (Image Credit: Jeff Hicks)
Convert static methods (Image Credit: Jeff Hicks)

I find this especially helpful with WMI classes.

Listing WMI class methods (Image Credit: Jeff Hicks)
Listing WMI class methods (Image Credit: Jeff Hicks)

All of this came about because I took the time to see what else I could do with Get-Member. Of course, I hope you will play around with Get-Member and other PowerShell cmdlets and let me know what you find.

Related Topics:

BECOME A PETRI MEMBER:

Don't have a login but want to join the conversation? Sign up for a Petri Account

Register
Comments (0)

Leave a Reply

Register for the Hybrid Identity Protection (HIP) Europe Conference!

Hybrid Identity Protection (HIP) Europe 2021 - Virtual Conference

Mobile workforces, cloud applications, and digitalization are changing every aspect of the modern enterprise. And with radical transformation come new business risks. Hybrid Identity Protection (HIP) is the premier educational forum for identity-centric practitioners. At the inaugural HIP Europe, join your local IAM experts and Microsoft MVPs to learn all the latest from the Hybrid Identity world.