Get PowerShell Parameter Aliases

magnifying-glass During a recent PowerShell training class we naturally covered aliases. An alias is simply an alternate name, often something that is shorter to type, or maybe even more meaningful. There are aliases for commands, properties and parameters. Discovering aliases for commands is pretty easy with Get-Alias. Property aliases are discoverable using Get-Member. But, discovering parameter aliases is a bit more difficult. The information is there, but doesn’t surface very well. It would be terrific if help showed parameter aliases but it rarely does. So here are some ways you might find parameter aliases.

One way is to use Get-Help.

But you need to use Get-Help. If you use the Help function it won’t work. In the command I filtered out parameters that didn’t have aliases. You can also pipe Get-Command to Get-Help.

But for some reason, this doesn’t always work. There are aliases for Get-Service, but these same commands fail to show it.

I know there are aliases because Get-Command shows me, although it takes a little work to extract this information.

Plus I can verify at the prompt:

Since it appears I can always get the information from Get-Command, I wrote a function called Get-ParameterAlias.

The function can take a command name or you can pipe something from Get-Command.

Because parameter information from Get-Command includes common parameters such as -ErrorAction, I’ve skipped those by default, unless you use the -IncludeCommon parameter.

Now it is easy to discover parameter aliases for say a module.

get-parameteralias

Knowing parameter aliases can make you more efficient in the console. But remember, when committing PowerShell to a script use the full parameter name as some of these aliases can be a bit cryptic.

As always, I hope you’ll let me know what you think.

Create an HTML PowerShell Help Page

Yesterday I posted an article about getting the online url for a cmdlet help topic. Today I want to demonstrate how we might take advantage of this piece of information.

Since the link is already in the form of a URL, wouldn’t it make sense to put this in an HTML document? At first glance, you might take the command from yesterday and pipe it to ConvertTo-HTML.


Get-Command -CommandType cmdlet | Get-Help |
Select Name,Synopsis,@{Name="URI";Expression={
($_.RelatedLinks | select -ExpandProperty NavigationLink | where {$_.uri}).uri}} |
Where {$_.URI} | ConvertTo-HTML -Title "Help Links" | Out-File c:\work\pshelp.htm

This code will work just fine. But if you look at the resulting file, we don’t have a link. I suppose it would be nice if ConvertTo-HTML could auto-detect URLs and automatically add a link, but it looks like we’ll have to do it. We could probably use a custom hash table to insert the HTML Anchor tags so here’s the first attempt:


Get-Command -CommandType cmdlet | Get-Help | Where {$_.RelatedLinks} |
Select Name,Synopsis,@{Name="URI";Expression={
#add the link tags as part of the output!
$link=$_.RelatedLinks | select -ExpandProperty NavigationLink | where {$_.uri}
if ($link.uri) {
$uri=$link.uri
Write "$uri"
}
else {
#no link so write a null
write $Null
}
}} | Where {$_.URI} | ConvertTo-HTML -Title "Help Links" |
Out-File c:\work\pshelp.htm

One additional change I made was to filter out cmdlets with no related links. Then in the expression scriptblock I can create a new value based on the URI value if it exists. But there is a problem with this, which you’ll see immediately if you run this code. ConvertTo-HTML sees the value of my new URI property and escapes the < and > characters.

That doesn’t help. But this is where the fact that ConvertTo-HTML only creates HTML code because we can parse the code and do a simple replace. Let me jump ahead and pull part of the finished dessert from the oven.


Function Convert-HTMLEscape {

<# convert < and > to < and >
It is assumed that these will be in pairs
#>

[cmdletbinding()]

Param (
[Parameter(Position=0,ValueFromPipeline=$True)]
[string[]]$Text
)

Process {
foreach ($item in $text) {
if ($item -match "<") {
<# replace codes with actual symbols This line is a shortcut to do two replacements with one line of code. The code in the first set of parentheses revised text with "<". This normally gets written to the pipeline. By wrapping it in parentheses it tells PowerShell to treat it as an object so I can then call the Replace() method again and add the >.
#>
($item.Replace("<","<")).Replace(">",">")
}
else {
#otherwise just write the line to the pipeline
$item
}
}
} #close process

} #close function

This function takes string input, presumably from ConvertTo-HTML and replaces the HTML escapes with the “real” characters. This I can use to write to the file.


...| Where {$_.URI} | ConvertTo-HTML -Title "Help Links" | Convert-HTMLEscape | Out-File c:\work\pshelp.htm

One of the reasons I put this in a function is to make it re-usable for future projects where I might need to escape these characters again. We’re getting closer. One last thing before we ice the final dessert: I have been using an expression to get all cmdlet help. But I like flexibility. What if tomorrow I only want a page with New* cmdlets from PowerCLI? So once again, I took my code that works just fine from a prompt into a more flexible and re-usable function.

Function Get-HelpUri {

[cmdletbinding()]

Param(
[Parameter(Position=0,Mandatory=$True,HelpMessage="Enter a cmdlet name",
ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)]
[ValidateNotNullorEmpty()]
[string]$Name
)

Process {
Write-Verbose "Processing $name"
Get-Help $name | Where {$_.RelatedLinks} |
Select Name,Synopsis,@{Name="URI";Expression={
#add the link tags as part of the output!
$link=$_.RelatedLinks | select -ExpandProperty NavigationLink | where {$_.uri}
if ($link.uri) {
$uri=$link.uri
Write "$uri"
}
else {
#no link so write a null
write $Null
}
}}
} #close process

} #close function

This will write a custom object with the cmdlet name, synopsis and URI property with the HTML code. I still need to convert to HTML and then fix the tags but I can verify it works.


PS C:\> get-command new-object | get-helpuri | ConvertTo-Html |Convert-HTMLEscape



HTML TABLE

Name Synopsis URI
New-Object Creates an instance of a Microsoft .NET Framework or COM object. http://go.microsoft.com/fwlink/?LinkID=11335
5


The icing is to include some style via a CSS file. Here’s a short script on how I might build a file for all of the cmdlets in my current session.


Write-Host "Building cmdlet help report" -ForegroundColor Green

#the file to create
$file="c:\work\cmdletonline.htm"

#be sure to change the path to the CSS file if you want to use it
$cssPath="c:\scripts\blue.css"

#optional image
$imagePath="c:\work\talkbubble.gif"

#some pre content
[email protected]"



Cmdlet Online Help




"@

#some post content
[email protected]"

Help for cmdlets found on $env:computername on $(Get-Date)
"@

#a title for the report
$Title="Cmdlet Help"

<# Get all cmdlets in the current session, send them to the Get-HelpURI function to parse out help URLS, filter out those without a link, pass the remaining to the Convertto-HTML to generate HTML code which is piped to my function to replace < with > and the final HTML code is piped to
a file.
#>
Get-Command -CommandType cmdlet | Get-HelpURI | Where {$_.URI} |
ConvertTo-Html -PreContent $PreContent -PostContent $postContent -Title $Title -cssUri $cssPath |
Convert-HTMLEscape | Out-File -FilePath $file -Encoding ASCII

Write-Host "Finished. See $file for the results" -ForegroundColor Green

And here’s the final result in Internet Explorer.

Ok, maybe you don’t have a compelling need for this exact script, but I hope you picked up on the importance of writing code for re-use and taking advantage of the pipeline.

If you’d like to try my code out for yourself, including the graphic and CSS file, download this zip file.

Get Cmdlet Help URL

I was toying around with PowerShell help this morning and as usually happens one thing leads to another. When you run Get-Help, or use the wrapper function Help, you are actually getting an object: MamlCommandHelpInfo. This object has properties that you are use to seeing like name and synopsis.


PS C:\> get-help get-service | Select Name,Syntax,RelatedLinks

Name syntax relatedLinks
---- ------ ------------
Get-Service @{syntaxItem=System.Man... @{navigationLink=Syste...

As you can see, some of these properties are nested objects.


PS C:\> get-help get-service | Select RelatedLinks | get-member

TypeName: Selected.System.Management.Automation.PSCustomObject

Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
relatedLinks NoteProperty MamlCommandHelpInfo#relatedLinks [email protected]{na...

I wanted to try something with related links, specifically those links which PowerShell uses for online help.


PS C:\> get-help get-service | Select -expandproperty RelatedLinks

Online version: http://go.microsoft.com/fwlink/?LinkID=113332
Start-Service
Stop-Service
Restart-Service
Resume-Service
Suspend-Service
Set-Service
New-Service

It is easy to forget, that these are still objects.


PS C:\> get-help get-service | Select -expandproperty RelatedLinks | get-member

TypeName: MamlCommandHelpInfo#relatedLinks

Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
navigationLink NoteProperty System.Management.Automation.PSObject[] navigati...

I see that these related link objects have a NavigationLink property so I’ll expand it:


PS C:\> get-help get-service | Select -expandproperty RelatedLinks | select -e
xpand navigationlink

linkText uri
-------- ---
Online version: http://go.microsoft.com/fwlink/?Link...
Start-Service
Stop-Service
Restart-Service
Resume-Service
Suspend-Service
Set-Service
New-Service

Now we’re getting somewhere. All I want is the link with a URI value.


PS C:\> get-help get-service | Select -expandproperty RelatedLinks | select -expandproperty navigationlink | where {$_.uri}

linkText uri
-------- ---
Online version: http://go.microsoft.com/fwlink/?Link...

Very cool. Now that I have the basic concept down for a single cmdlet, I can modify my expression to pull this value out of the nested objects and bring it “up”.


Get-Help get-service |
Select Name,Synopsis,@{Name="URI";Expression={
($_.RelatedLinks | select -ExpandProperty NavigationLink | where {$_.uri}).uri}} |
Where {$_.URI}

I’m using a hash table to define a custom property called URI that pulls the URI property, if found “up”. When I run this code and pipe it to Format-List to make it easier to read I get a result like this:


Name : Get-Service
Synopsis : Gets the services on a local or remote computer.
URI : http://go.microsoft.com/fwlink/?LinkID=113332

Beautiful. All I need to do now is modify my code to work with more cmdlets.


Get-Command -CommandType cmdlet | Get-Help | Select Name,Synopsis,@{Name="URI";Expression={
($_.RelatedLinks | select -ExpandProperty NavigationLink | where {$_.uri}).uri}} | Where {$_.URI}

This one line command will get all cmdlets in my current PowerShell session and display the cmdlet name, synopsis and help URL if found. The PowerCLI cmdlets include online help, but not all of them so when I run this command in a session with them loaded I’ll only get those cmdlets with an online help link.

What I really wanted to show here is discovering an object’s details, especially if there are nested object properties. PowerShell is all about objects in the pipeline and once you get a hold of that concept you can do some amazing things with very little effort. I’ll be back tomorrow to take this one more step.