Monday, November 19, 2007

Help vs. Get-Help

Help text for any command-let in PowerShell can be viewed by executing "help cmdletName" or "get-help cmdletName". At first glance there's no difference between the two, both emits the relevant help to PowerShell's console, but under the cover they are completely different command types:


PS > (help get-command).gettype().fullname
System.Object[]

PS > (get-help get-command).gettype().fullname
System.Management.Automation.PSCustomObject

 

All members type of 'help get-command' are strings, while 'get-help get-command' returns rich PSCustomObject:

 

PS > (help get-command) | foreach {$_.gettype()}

IsPublic IsSerial Name                                    BaseType
-------- -------- ----                                         --------
True     True     String                                   System.Object
True     True     String                                   System.Object
...

 

PS > (get-help get-command) | foreach {$_.gettype()}

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                          --------
True     False    PSCustomObject                     System.Object

 

Now with Get-Member, which returns different type names:

PS > (help get-command) | gm
TypeName: System.String

PS > (get-help get-command) | gm
TypeName: MamlCommandHelpInfo

 

One might think (as I did) that "help" is a built-in alias for get-help:

PS > Get-Alias -name h* | format-table -auto

CommandType  Name     Definition
----------- ----    ------      ----
Alias                 h           Get-History
Alias                 history   Get-History
 

There is no such alias for get-help. Another test:

PS > get-alias | where {$_.Definition -match "Get-Help"}

No output. Typing help or get-help separately shows different output formats. Executing "Help" emits a list of PowerShell's built-in aliases, cmdlets, providers and about help files. It also supports paging (one screen at a time). On the other hand get-help outputs the help for the get-help cmdlet with no paging support.

 

So, what is "help"? Lets try get-command:

PS > get-command help  | ft -auto

CommandType   Name        Definition
----------- ----     -----          -----
Function             help         param([string]$Name,[string[]]$Category=@('All')...
Application         help.exe   C:\WINDOWS\system32\help.exe

 

Ah.. help is a function while get-help is a cmdlet. To view the source of the help function (edited):

PS > (dir function:\help).definition
(...)

if ($Detailed)
{
      #Detailed and #Full are in different sets..let get-help cmdlet handle the error
      get-help $Name -Full -Detailed  | more.com
  return;
}

if ($Examples)
{
      #Examples and #Full are in different sets..let get-help cmdlet handle the error
      get-help $Name -Full -Examples  | more.com
  return;
}
(...)

 

You can see that behind the scenes, the help function is kind of a proxy command. It pipes the typed help command and parameters to get-help and then pipes the result to more.com to support paging.

Moreover, when you want to access certain member (like examples) to display a specific code example:

PS > (get-help get-command).examples.example[0]

-------------------------- EXAMPLE 1 --------------------------

C:\PS>get-command

This command retrieves information about all of the Windows PowerShell cmdlets....

 

Try the same with help and you'll get an error:

PS > (help get-command).examples.example[0]
Cannot index into a null array.
At line:1 char:37
+ (help get-command).examples.example[0 <<<< ]

 

So, if you need access to specific members of a certain cmdlet using the above examples use get-help. If you know other differences, please post them in the comments box.

1 comment:

Harkamal Singh said...

Hello.

there's a nice link to generate html documentation for cmdlets by using output from Get-Help which spits rich object.

Script could then call and create html tags...
CMDLET.Name
CMDLET.Synopsis
CMDLET.Examples.Examples[0]

How ever if i create similar help text files as same format of Get-Help files. The format is String type not of MAML. So I cannot use CMDLET.Name
CMDLET.Synopsis type code to generate help for my script files.

Your article helped understand why. Is there a way around ?

http://blogs.vmware.com/vipowershell/2007/09/new-htmlhelp.html

Thanks
Harkamal