Wednesday, August 21, 2013

Get-Help vs Help - the paging/pager inconsistency

When I'm teaching PowerShell to folks, I often like to use the full name of the cmdlets - get-help instead of 'help', get-childitem instead of 'dir'. You get the idea.

I do this to help drive home the verb-noun syntax and because I can't necessarily expect everyone to know the shortcuts that I tend to use.

Well, the problem that I'm about to describe hasn't come up too much - but its annoying and I finally decided to take a minute and figure out what's going on.

The Problem (Powershell 2.0 or 3.0)

In powershell, if I issue the command:

get-help <cmdlet> -full

then I get a wall of text that is not paged (where paging is that "-- More  --" at the bottom of the screen that allows me to read a page at a time.

To be honest, I'd never really spent more than a second thinking about this annoyance because it seemed so trivial, but since I'm in the midst of putting together a curriculum for a powershell class, it got a little more important.

I had basically made the assumption that help (and man) were simply aliases to get-help. This assumption was wrong.  Have a look:

PS C:\> get-alias -Definition get-help
Get-Alias : This command cannot find a matching alias because alias with definition 'get-help' do n
ot exist.
At line:1 char:10
+ get-alias <<<<  -Definition get-help
    + CategoryInfo          : ObjectNotFound: (get-help:String) [Get-Alias], ItemNotFoundException
    + FullyQualifiedErrorId : ItemNotFoundException,Microsoft.PowerShell.Commands.GetAliasCommand

PS C:\>

That's surprising, no aliases at all for get-help? That makes me wonder what "man" is aliased to. Well as it turns out, "man" is pointing to "help".

PS C:\> get-alias man

CommandType     Name                                      Definition
-----------     ----                                      ----------
Alias           man                                       help

Alright, so what is "help" if it isn't an alias but does the exact same thing as get-help? And what's the deal with "man" aliasing to it?! Let's find out.

PS C:\> Get-Command help

CommandType     Name                                      Definition
-----------     ----                                      ----------
Function        help                                      ...

Ah ha! As we can see (highlighted for dramatic effect) - "help" is not an alias. It is a function! Let's have a look at this function.

PS C:\> cd function:
PS Function:\> dir help

CommandType     Name                                      Definition
-----------     ----                                      ----------
Function        help                                      ...

PS Function:\> Get-Content help

    [Parameter(Position=0, ValueFromPipelineByPropertyName=$true)]











      Get-Help @PSBoundParameters | more

PS Function:\>

And there we have it! The function (again, highlighted for dramatic effect) simply runs the get-help cmdlet put pipes the output to the "more" command. 

Well - that explains the different behavior, and that's good to know.

Interestingly - the "more" command is also simply a function. Output below for the sake of completeness:

PS Function:\> type more
$OutputEncoding = [System.Console]::OutputEncoding

    foreach ($file in $paths)
        Get-Content $file |
    $input |

Interesting stuff.  I hope if any of you guys wondered about this, you now have the answer and can sleep better at night. :)

No comments:

Post a Comment