---
title: Use Edit-Command to discover the code behind built-in cmdlets
date: 2017-02-22 14:14:00 +0200 +0200
draft: false
author: John Roos
----

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. That’s 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 script block 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. That’s cool. Get-Verb is one of those commands. Lets have a look at that and expand the script block 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 script block and in that case open a new tab in ISE with the content from the script block. 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.