Getting Comfortable
One of the first complaints you may have against PowerShell is how much typing you have to do if you’re going to use it interactively.
Take the cmdlet used to output IP addresses on a Windows 10 system:
Get-NetIPAddress
That’s 16 characters long, as compared with the 7 character ipconfig
we all know and love. It’s even longer if you want to make the output readable in the shell:
Get-NetIPAddress | Format-Table -AutoSize
Now we can easily view the output, but we’ve increased our typing to 31 characters. You get the idea: If we are going to use any of these cmdlets on a regular basis interactively, then we’re going to need to shorten them… drastically.
Aliases
Aliases are one solution to our problem. You can think of an alias as a short “nickname” for another (usually longer) command. If you have a UNIX background, then the concept of aliases is probably familiar, but the way PowerShell handles them may be a bit confusing at first.
Using our example of the Get-NetIPAddress
cmdlet, let’s create an alias to shorten up our command:
New-Alias -Name ip -Value Get-NetIPAddress -Description "Get IP address configuration"
With our new alias created, we can now type two characters to get the same information:
ip
“Helpful,” you say, “but I still have to type | Format-Table -AutoSize
to get readable output!” True. In this case, you may be tempted to put this into the alias also, like this:
# This doesn't work like you may want it to
New-Alias -Name ip -Value Get-NetIPAddress | Format-Table -AutoSize
If you try this, it will unceremoniously take you back to the prompt and appear to have worked, but if you type your alias ip
again, you get the same output as before. Frustrating. Let’s take closer look….
New-Alias -Name ip -Value Get-NetIPAddress | Format-Table -AutoSize
# ^ End of the New-Alias command
The pipe you add into your Value
parameter is not actually being added to the alias, but is telling PowerShell to send the output of New-Alias
to
Format-Table
. “Ah, you say, I see what’s going on… I’ll wrap it in quotes!” So, you try this instead:
New-Alias -Name ip -Value "Get-NetIPAddress | Format-Table -AutoSize"
This also appears to work… Until you type ip
and get a nasty error:
ip : The term 'Get-NetIPAddress | ft -AutoSize' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ ip
+ ~~
+ CategoryInfo : ObjectNotFound: (Get-NetIPAddress | ft -AutoSize:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
So, obviously we’re doing something wrong here. As it turns out, you cannot make pipelines into aliases like we tried to do here. We also can’t add command arguments to our aliases either. So, aliases are fairly basic in what they allow us to do, but they do at least give us a way of shortening commands we commonly type interatively.
So then, how do we get around the problem with our Get-NetIPAddress
command line? Is there a way to do what we want? Yes, we can use a function instead:
function ip {
Get-NetIPAddress | Format-Table -AutoSize
}
I will cover PowerShell functions more fully in another post, but this will get you started.
Built-In Aliases
In addition to what you can create for yourself, PowerShell also has a number of built-in aliases as well. You may have used these already without even realizing it, because many of them use the names of well-known Windows or UNIX shell commands. You may have discovered this already, if you typed dir
or echo
and gotten unexpected results:
PS> dir /s
dir : Cannot find path 'C:\s' because it does not exist.
At line:1 char:1
+ dir /s
+ ~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\s:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
Or if you’re from a UNIX background:
PS> ls -l
Get-ChildItem : Missing an argument for parameter 'LiteralPath'. Specify a parameter of type 'System.String[]' and try again.
At line:1 char:4
+ ls -l
+ ~~
+ CategoryInfo : InvalidArgument: (:) [Get-ChildItem], ParameterBindingException
+ FullyQualifiedErrorId : MissingArgument,Microsoft.PowerShell.Commands.GetChildItemCommand
“What..?” It turns out both are aliases to PowerShell cmdlets:
PS> 'dir','ls','echo' | %{ Get-Alias $_ }
CommandType Name
----------- ----
Alias dir -> Get-ChildItem
Alias ls -> Get-ChildItem
Alias echo -> Write-Output
You can see some examples in the documentation, or type Get-Alias
in your shell to see them all.
Deleting Aliases
One more thing before we wrap it up. To delete an alias, you may assume you can type something like this, but you’d be wrong:
# This does not work
Remove-Alias -Name 'ip'
The solution to this is a bit odd:
# This works:
Remove-Item -Path 'Alias:\ip'
That may seem strange if you aren’t familiar with how PowerShell stores session information in “drives,” but don’t worry, we’ll cover that in a later post.
Hopefully, aliases will give your interactive productivity a little boost. Later in this series we’ll go over other aliases for more advanced cmdlets, as we cover them. In the next post, we’ll talk about how to customize our shell environment a bit to make it a little more comfortable.
Additional Reading
- Documentation: New-Alias
- Documentation: Get-Alias
- Documentation: Remove-Item