In part I of Put the Alias Description Property to Work, I showed and explained how to add a description property to each of my personal, profile script-created aliases. This allowed me to use a basic function, that filtered the Get-Alias
results to return only my aliases. In this post, we will take this one step further and we will add descriptions to the built-in aliases in PowerShell. If you remember, we determined that most of the built-in aliases do not include a source
property. Therefore, sorting or filtering on that property is of little value.
The source
property is not a settable property, meaning that no matter how hard I try, I cannot edit it. The Description
property, as we learned, is open for me to make changes. This is also true with built-in aliases and not just the aliases I create. Here is what we are going to do. All the aliases resolve to a command, and all but four of those commands have a source
property. We are going to acquire a command’s source and set it as the description of its alias. This might make more sense with some examples, so let’s start there.
But before we do, let’s look at the default properties returned by Get-Alias.
Get-Alias | Get-Random
CommandType Name Version Source ----------- ---- ------- ------ Alias pwd -> Get-Location
Get-Alias
returns CommandType
, Name
, Version
, and Source
. Kind of. Name is really a property called DisplayName
. It may be better to know that now. In the first, real example, we are also going to use Get-Random
to randomly select an alias for us. Then, we will return its ResolvedCommandName
, DisplayName
, Description
, and Options
properties.
$Alias = Get-Alias | Get-Random Get-Alias -Name $Alias | Select-Object ResolvedCommandName,DisplayName,Description,Options
ResolvedCommandName DisplayName Description Options ------------------- ----------- ----------- ------- Connect-PSSession cnsn -> Connect-PSSession ReadOnly
Notice that currently, its Description
property is blank. In the next example, we will use the value stored in $Alias
and run it through a ForEach-Object
loop. Take a look at the PowerShell now, and I will do that recently experimented with, line-by-line explanation further below.
Get-Alias -Name $Alias | ForEach-Object { if ($_.Description -eq '') { $Params = @{ Name = $_.Name Value = $_.ResolvedCommandName Description = if ((Get-Command -Name $_.ResolvedCommandName).Source) { ((Get-Command -Name $_.ResolvedCommandName).Source) } else {'None'} Option = $_.Options Force = $true } Set-Alias @Params -Verbose } } VERBOSE: Performing the operation "Set Alias" on target "Name: cnsn Value: Connect-PSSession".
Line 1: Pipe our single alias into a ForEach-Object
loop.
Line 2: Continue into an if
construct if the alias’ description is empty. If it is not, we would move on to the next alias if there were more than just one.
Line 3: Create a hash table and store it in the $Params
variable.
Line 4, 5: Add the name and the resolved command name into the Name
and Value
keys, respectively.
Line 6 – 8: Add a description to the Description
key based on whether or not there is a source. If there is a source, add it, if there is not a source add the string None
.
Line 9, 10: Add the options and $true
value into the Option
and Force
keys, respectively.
Line 12: Invoke the Set-Alias
command, splatting the $Params
hash table as parameters and associated parameter values.
Let’s rerun the command we did just a minute ago.
Get-Alias -Name $Alias | Select-Object ResolvedCommandName,DisplayName,Description,Options
ResolvedCommandName DisplayName Description Options ------------------- ----------- ----------- ------- Connect-PSSession cnsn -> Connect-PSSession Microsoft.PowerShell.Core ReadOnly
We have taken the source of the command Connect-PSSession
and placed its value into the description of an alias that resolves to Connect-PSSession
. It is not genius, but it is something!
Moving on, the next command pipes out all the known aliases and the values in each of the included properties. I will only include the first ten, as there are almost 150.
Get-Alias | Select-Object ResolvedCommandName,DisplayName,Description,Options
ResolvedCommandName DisplayName Description Options ------------------- ----------- ----------- ------- Where-Object ? -> Where-Object ReadOnly, AllScope ForEach-Object % -> ForEach-Object ReadOnly, AllScope Add-Content ac -> Add-Content ReadOnly Clear-Host c -> Clear-Host tommymaynard None Get-Content cat -> Get-Content None Set-Location cd -> Set-Location AllScope Set-Location chdir -> Set-Location None Clear-Content clc -> Clear-Content ReadOnly Clear-Host clear -> Clear-Host None Clear-History clhy -> Clear-History ReadOnly
This should look familiar. There are a couple of differences in this code block compared to the one above. One, we are piping in all of the aliases (not just one), and two, there is no Verbose
parameter included when the Set-Alias
command is invoked. We do not need to output the change made to each alias. Yeah, no thanks.
Get-Alias | ForEach-Object { if ($_.Description -eq '') { $Params = @{ Name = $_.Name Value = $_.ResolvedCommandName Description = if ((Get-Command -Name $_.ResolvedCommandName).Source) { ((Get-Command -Name $_.ResolvedCommandName).Source) } else {'None'} Option = $_.Options Force = $true } Set-Alias @Params } }
This is the same command we saw earlier. I have only included the first ten here, as well. Notice the changes made to the Description
property for each alias. Now I can easily see which alias goes with which source.
Get-Alias | Select-Object ResolvedCommandName,DisplayName,Description,Options
ResolvedCommandName DisplayName Description Options ------------------- ----------- ----------- ------- Where-Object ? -> Where-Object Microsoft.PowerShell.Core ReadOnly, AllScope ForEach-Object % -> ForEach-Object Microsoft.PowerShell.Core ReadOnly, AllScope Add-Content ac -> Add-Content Microsoft.PowerShell.Management ReadOnly Clear-Host c -> Clear-Host tommymaynard None Get-Content cat -> Get-Content Microsoft.PowerShell.Management None Set-Location cd -> Set-Location Microsoft.PowerShell.Management AllScope Set-Location chdir -> Set-Location Microsoft.PowerShell.Management None Clear-Content clc -> Clear-Content Microsoft.PowerShell.Management ReadOnly Clear-Host clear -> Clear-Host None None Clear-History clhy -> Clear-History Microsoft.PowerShell.Core ReadOnly
Like all worthy PowerShell code, I am going to wrap this in a function, and for the foreseeable future, copy this into my profile script. There is one change in this version that should be mentioned. The Scope
parameter is now being included inside the $Params
hash table with the Global
value. Like the other parameters and parameters values in this hash table, it will be splatted onto the Set-Alias
cmdlet when it is invoked. While the Scope
parameter is not required with Get-Alias
, it absolutely is with Set-Alias
. We want the aliases that exist outside the function to be the ones we modify.
function Set-AliasDescription Get-Alias | ForEach-Object { if ($_.Description -eq '') { $Params = @{ Name = $_.Name Value = $_.ResolvedCommandName Description = if ((Get-Command -Name $_.ResolvedCommandName).Source) { ((Get-Command -Name $_.ResolvedCommandName).Source) } else {'None'} Option = $_.Options Force = $true Scope = 'Global' } Set-Alias @Params } } Set-AliasDescription
With the descriptions set, we can filter such as in the next two examples. Remember, the Get-Alias
Description
property is not displayed by default.
Get-Alias | Where-Object -Property Description -eq 'None'
CommandType Name Version Source ----------- ---- ------- ------ Alias clear -> Clear-Host Alias cls -> Clear-Host Alias man -> help Alias md -> mkdir
Get-Alias | Where-Object -Property Description -like '*core'
CommandType Name Version Source ----------- ---- ------- ------ Alias ? -> Where-Object Alias % -> ForEach-Object Alias clhy -> Clear-History Alias cnsn -> Connect-PSSession Alias dnsn -> Disconnect-PSSession Alias etsn -> Enter-PSSession Alias exsn -> Exit-PSSession Alias foreach -> ForEach-Object Alias gcm -> Get-Command Alias ghy -> Get-History Alias gjb -> Get-Job Alias gmo -> Get-Module Alias gsn -> Get-PSSession Alias h -> Get-History Alias history -> Get-History Alias icm -> Invoke-Command Alias ihy -> Invoke-History Alias ipmo -> Import-Module Alias nmo -> New-Module Alias nsn -> New-PSSession Alias oh -> Out-Host Alias r -> Invoke-History Alias rcjb -> Receive-Job Alias rcsn -> Receive-PSSession Alias rjb -> Remove-Job Alias rmo -> Remove-Module Alias rsn -> Remove-PSSession Alias sajb -> Start-Job Alias spjb -> Stop-Job Alias where -> Where-Object Alias wjb -> Wait-Job