So… I have a situation, and I’m not really sure what’s going on.  I think this is a two-fold problem:

Problem 1: Variable and Alias – Odd Things – There’s a Ghost in the (Power)Shell

To set the picture, I’m running Windows PowerShell 5.0 on Windows 10, but we also saw this on Windows PowerShell 2.0 in Windows Server 2008 R2.  When I type alias, it outputs contents as if it were running Get-Alias.

alias1-20151103

My instinct tells me this should be an alias.  So let’s see:

alias5-20151103

Nope… not an alias.  Is this a variable?

alias2-20151103

Nope… not a variable.  Is this a command?

alias3-20151103

Nope…. not a command. Is this a function?

alias4-20151103

Nope.  Is this an executable that cmd can run?

cmdexe-20151103

Nope.  We also see this phantom listing (for lack of a better term) with variable.

So… problem 1 – what are these things if they aren’t commands, aliases, variables, or  functions?  June and I tested these with PowerShell v2.0 on Windows Server 2008 R2 and PowerShell v5.0 on Windows 10, natively.  We also tested it in versions 2.0, 3.0, 4.0, and 5.0 side-by-side.

Problem 2. The Shadow of the Phantom (not the Opera)

So piggybacking off of #1, I have an odder situation.  I have a custom PS module that I’ve created for teaching – originally used in 2011 and repurposed for Coding 101 this past October.  June changed my line #1 to include -Name and -Value (but this doesn’t make a difference).  I have an issue with the alias scenario above, coming from a Linux background.  The command alias by itself is used for creating aliases, so I like to fix the alias with the proper usage:

alias6-20151103

PowerShell is not auto-loading this module, but we can load it with Import-Module and the alias alias works as expected.

Is our phantom friend from #1 shadowing my module, preventing it from auto-loading?  If so, is this a bug?  Or is this possibly an undocumented feature?  (What…?!? I’m a dev. I had to put it that way. 🙂 )

UPDATE – The Mysterious 2nd Pass

So I asked about this on Twitter, and I got responses from the PowerShell community – thanks to Bruce Payette, Boe Prox, and Lee Holmes.  Basically, as Bruce Payette explained it, since PowerShell v1.0, when a command is executed, PowerShell does a 2-pass find:  first it looks for the command by name, and if that fails, then it does a second pass with Get- prepended to it.  So…

  1. alias is looked for but not found.
  2. Get-Alias is looked for, found, and executed.

Boe Prox  blogged about this behavior and how he sniffed it out with the Trace-Command cmdlet.

Lee Holmes explained that auto-loading a module happens if CommandNotFound is about to get thrown.  However, because of this second pass, CommandNotFound doesn’t get thrown, so the module does not auto-load.

And this… this is why I love the PowerShell community.  They’re super helpful and can shed light on issues even with 140 character limits on Twitter. 🙂  Thanks, guys!