Use Edit-Command to discover the code behind built-in cmdlets

Did you know that there are a lot of built-in cmdlets which are written entirely in PowerShell? Did you also know that you can view the source of those cmdlets? Well, you can. Get-Command shows all the details we need. When you run Get-Command you get all kinds of details about the commands you are looking for. One of the properties in the output is called ScriptBlock. Thats where the code is, if its written in PowerShell.

Lets take a quick example. First check how many commands are available, and then how many of those have a scriptblock attached to them.
PS C:\> (Get-Command).count
1861

PS C:\> (Get-Command | ? scriptblock).count
955
In this system I have a total of 1861 commands, and 955 of those are written in PowerShell. Thats cool. Get-Verb is one of those commands. Lets have a look at that and expand the scriptblock property.
PS C:\> Get-Command -Name Get-Verb | Select-Object -ExpandProperty scriptblock

param(
    [Parameter(ValueFromPipeline=$true)]
    [string[]]
    $verb = '*'
)
begin {
    $allVerbs = 
[System.Reflection.IntrospectionExtensions]::GetTypeInfo([PSObject]).Assembly.ExportedTypes 
|
        Microsoft.PowerShell.Core\Where-Object {$_.Name -match '^Verbs.'} |
        Microsoft.PowerShell.Utility\Get-Member -type Properties -static |
        Microsoft.PowerShell.Utility\Select-Object @{
            Name='Verb'
            Expression = {$_.Name}
        }, @{
            Name='Group'
            Expression = {
                $str = "$($_.TypeName)"
                $str.Substring($str.LastIndexOf('Verbs') + 5)
            }
        }
}
process {
    foreach ($v in $verb) {
        $allVerbs | Microsoft.PowerShell.Core\Where-Object { $_.Verb -like $v }
    }
}
# .Link
# http://go.microsoft.com/fwlink/?LinkID=160712
# .ExternalHelp System.Management.Automation.dll-help.xml
But why not add the result to a new tab in the PowerShell ISE? I wrote a simple cmdlet for that, called Edit-Command. When you run Edit-Command it will check if the command have a scriptblock and in that case open a new tab in ISE with the content from the scriptblock. In the top of the new tab it will add some meta data about the command, like name, type, version and source.
PS C:\> Edit-Command -Name Get-Verb
Pretty neat. Below is the code for Edit-Command if you want to try it yourself.

Edit-Command

function Edit-Command {
 
    [CmdletBinding()]
    [OutputType([void])]
   
    param (
        [validatenotnullorempty()]
        [string]$Name
    )

    Process
    {
        try {
            $command = Get-Command -Name $Name -ErrorAction Stop
        } catch {
            Throw $Error[0].Exception
        }

        if ( $command -is [array]) {
            throw 'Multiple commands found. You need to be more specific.'
        }

        if (-not ($scriptblock = $command.ScriptBlock) ) {
            $exception = "The command does not have a scriptblock available."
            Throw $exception
        }

        $code = New-Object -TypeName System.Text.StringBuilder

        $code.Append("# Command: $($command.Name)`n") | Out-Null
        $code.Append("# Type: $($command.CommandType)`n") | Out-Null
        $code.Append("# Version: $($command.Version)`n") | Out-Null
        $code.Append("# Source: $($command.Source)`n") | Out-Null
        $code.Append($scriptblock) | Out-Null

        OpenTab -code $code
        
    }
}

function OpenTab {
    param ( [System.Text.StringBuilder]$code )

    $displayname = $psISE.CurrentPowerShellTab.Files.Add().DisplayName
    $openfile = $psISE.PowerShellTabs.files | 
        Where-Object DisplayName -eq $displayname | 
        Select-Object -First 1 
        
    $openfile.Editor.Text += $code 
    $openfile.Editor.SetCaretPosition(1,1)

}
This code is also available on GitHub.

No comments

Post a Comment