Craig Forrester

The Pleasure of Finding Things Out

github linkedin email rss
Interactive PowerShell, Part 2: Aliases
February 14, 2018
5 minutes read

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


Back to posts