Sunday, July 22, 2007

What's *dat* parameter?


When you want to find out how things are working in PowerShell, the first command to check is the get-help command. The help cmdlet can be used in various ways:

help <command>
man <command>
<command> -?
help about*

and there are a few more ways to achieve the same thing.


You can ask PowerShell to view different sections of the help by adding some switches like -detailed, -full or even
-examples to get the examples section of the command.

There is also the parameters section that lists all parameters a cmdlet supports. To list
all accepted parameters, type:

get-help <command> -parameter *


PowerShell also supports a shortened notation of parameters. If a cmdlet has a parameter
named -include, then you can type -i as long as there is no additional parameter
that starts with "i". In the case of multiple parameters that start with the
same characters, you need to distinguish the parameter by adding another character, something like:

Select-String -inc # -include 
Select-String -inp # -inputObject


Most of the time typing get-help to discover parameters results in a few help pages,
and navigating them to find what you need can be a very long process, not to mention how your console looks like
when you want to see the last commands you have typed.

Another issue is commands written with abbreviated parameters. something like:

Set-Content -l "argument" -pas "argument" -fi "argument" -l "argument" -fo


which you need to decipher by yourself. Although you can guess the parameter objective
by its argument, it can be quite a deciphering process.

This is where this utility function comes in hand. I wrote it as a learning tool for parameters.
It will print out three columns for the given cmdlet (you can add more):
1.      parameter name
2.      Alias, new column which calculates the distinguished part of the parameter.
3.      positioned column



So, to get all params for select-string cmdlet

PS C:\Scripts>get-params select-string

- select-string -

name                alias    position   Type
----                   -----     --------     ----
caseSensitive     -c        named    SwitchParameter
exclude              -e       named    string[]
include               -inc     named    string[]
inputObject        -inp     named    psobject
list                     -l        named    SwitchParameter
path                   -path   2           string[]
pattern              -patt    1            string[]
quiet                 -q        named    SwitchParameter
simpleMatch       -s        named    SwitchParameter
text                    -t        2            string[]


Looking good, now get only parameters starting with i*

PS C:\Scripts> get-params select-string i*

- Select-String -

name                alias    position   Type
----                   -----     --------     ----

include               -inc     named    string[]
inputObject        -inp     named    psobject



Generate a "cheat-sheet" for all cmdlets:

Get-Command | % {get-params $} >  c:\AbbreviatedParameters.txt


Some command-lets do not support the parameters property (or globbing) and will render an error:

Get-Help : No parameter matches criteria *.
At line:1 char:9
+ get-help  <<<< Get-AuthenticodeSignature -param *



One last thing, PowerShell maintains a short notation for its common parameters:

Verbose       {vb}
Debug         {db}
ErrorAction   {ea}
ErrorVariable {ev}
OutVariable   {ov}
OutBuffer     {ob}



Here is the code for get-params:

function get-params{
                [string]$cmd = $(throw "Please specify cmdlet name"),
        $ErrorActionPreference = "SilentlyContinue";
        # check the existence of the command-lets.
        $check = get-command | ? {$_.CommandType -eq "Cmdlet" -and $ -eq $cmd}
        if($check -eq $null){
                write-warning "No such command [$cmd]";

        # some command-lets do not support the parametrs property.
        $check = @(get-help $cmd -parameter * -ea silentlyContinue).count
        if($check -eq $null -or $check -eq 0){
                write-warning "No parameters found for [$cmd]";

        $obj = get-help $cmd -parameter $pat;

        $obj | add-Member -memberType noteProperty -name alias -value "" -force;       
        $params = $obj | % {$}

        for($i=0;$i -le $obj.length;$i++){

                [bool]$exitFlag = $false;

                for($x=0;$x -le $params[$i].length -and !($exitFlag);$x++){            
                        $regex = "^" + $params[$i].substring(0,$x);            
                        if(($params -match $regex).count -eq 1){
                                $obj[$i].alias = ("-"+$regex.substring(1,$regex.length-1)).tolower();

        "-" * $len ; "- $cmd -" ; "-" * $len;
        $obj | select Name,Alias,Position,@{n="Type";e={$}}| sort name | ft -auto





Kiron said...

Thanks Shay, the parameter 'short' name generator is great.
Get-Help is a good source of information on each parameter, be aware that some commonly used Cmdlets' help contents are missing parameters.

PowerShell's scalar/array treatment --as in your PowerShell's NewsGroup CSV post-- seems to be the reason why your function doesn't support Cmdlets that have one or zero regular parameter, but all support common parameters. Get-Command's Definition property will list all functional parameters, except the -Debugger for Set-TraceSource, Trace-Command.

$hay@israel said...

Cheers Kiron. Well said and done ;)