I'm currently learning Powershell 101 using PowerShell 7.4, and I'm interested in inpecting the type of some expressions, for example by executing
[Powershell] | gm
I get:
TypeName: System.RuntimeType
or by executing
[Powershell].getType()
I get
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
False False RuntimeType System.Reflection.TypeInfo
However, I can't get the type of a Cmdlet since it's executed automatically, for example :
get-help | gm
this command give the members of the returned object, rather than the members of the Cmdlet itself.
I tried executing:
(Get-Command Get-Help).GetType()
I got:
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False CmdletInfo System.Management.Automation.CommandInfo
So I think that the Get-Command
Cmdlet does not return an object of type Cmdlet
, instead, it gives a CmdletInfo
object.
According to the Powershell SDK 7.4.0, the class of a Cmdlet is System.Management.Automation.Cmdlet
[System.Management.Automation.Cmdlet]
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False Cmdlet System.Management.Automation.Internal.InternalCommand
So how can I refer to a Cmdlet itself in Powershell instead of executing it to play with its features?
Use the .ImplementingType
property of the System.Management.Automation.CmdletInfo
instance returned by Get-Command
:
(Get-Command Get-Help).ImplementingType
This directly returns a System.Type
-derived instance that represents the .NET type that implements the Get-Help
cmdlet, namely Microsoft.PowerShell.Commands.GetHelpCommand
.
Every time you call Get-Help
from PowerShell code, an instance of Microsoft.PowerShell.Commands.GetHelpCommand
is created behind the scenes.
As you note, all cmdlets must derive from the System.Management.Automation.Cmdlet
base class; the System.Management.Automation.PSCmdlet
class (which itself derives from the former) is more typically used as the base class, as it provides better integration with the PowerShell runtime.
While you can directly obtain an instance of a cmdlet-implementing type as follows in order to inspect its properties, note that you won't be able to call .Invoke()
on instances of PSCmdlet
-derived types, which the majority of the built-in cmdlets are:
# Create an instance of the class that implements the `Get-Help` cmdlet.
$cmdletInstance =
(Get-Command Get-Help).ImplementingType::new()
# Ditto, using the type directly:
$cmdletInstance =
[Microsoft.PowerShell.Commands.GetHelpCommand]::new()
A - rare - example of where calling .Invoke()
does work is the Cmdlet
-derived Get-Date
:
# Same as calling `Get-Date`
(Get-Command Get-Date).ImplementingType::new().Invoke()