Summary: Microsoft Scripting Guy, Ed Wilson, shows how to configure Windows PowerShell to return more than one instance of a command.
Hey, Scripting Guy! I have a problem. I recently upgraded to Windows 8, and now it seems that the Get-Command cmdlet does not work properly. In the past, I have used Get-Command as a replacement for Where.exe in that it is great at finding commands I need. But now in Windows 8, the Get-Command cmdlet only returns a single instance. What gives?
—MC
Hello MC,
Microsoft Scripting Guy, Ed Wilson, is here. Tomorrow we have the Windows PowerShell User Group meeting at the Charlotte, North Carolina Microsoft office. If you are in town, and do not have anything going on around 6:30 P.M., stop by. It will be loads of fun, and I can promise you will learn at least one new thing.
Using Get-Command to find commands
MC, I know it may sound strange, but I also use Get-Command to find commands. It is great at doing that. It finds Windows commands that are in my path, and it is much faster than opening Windows Explorer, and telling it to search.
For example, if I want to know if a command is available, I use Get-Command to find it for me. This is how I learned that there were two notepad.exe programs available. But when I run Get-Command in Windows 8, I am greeted with the following:
Hmm…Did we get rid of one of the Notepads in Windows 8? I don’t know, do I? It also makes me suspect that perhaps something is going on with Get-Command.
Force additional discovery in Get-Command
In Windows PowerShell 3.0, we made a change to Get-Command. When it finds a command, it returns. This is done for performance reasons, and results in faster searches. But if I am particularly interested in additional instances, I can force Get-Command to keep working. To do this, I specify a value for the TotalCount parameter. The value for TotalCount is the maximum value. So if I tell it to look for 10 instances of Notepad, it will keep trying. Of course, I only have two copies, so I am safe. Here is the command I use:
Get-Command notepad -TotalCount 10
The command and its associated output are shown here:
But where are these programs located?
To find where the programs reside, I need a bit more information. To find the additional information, I pipe the results to the Format-List cmdlet and choose all of the properties as shown here:
Get-Command notepad | Format-List *
The following image shows the command and the output associated with the command.
The path to the executable is in the Path property (no surprise, right?). Therefore, all I need to do is to select the path. I do this in the following command, and I can find where both Notepads reside.
PS C:\> Get-Command notepad -TotalCount 5 | Select-Object name, path
Name Path
---- ----
notepad.exe C:\Windows\SYSTEM32\notepad.exe
notepad.exe C:\Windows\notepad.exe
Using the Path property
Now that I know about the Path property and the way Get-Command returns the first application it finds in the search path, I might be interested in the way the commands returns. To do this, I look at the Path variable from the $env drive. I can see that first Windows\System32 is searched, and then the Windows directory. This is shown here:
PS C:\> ($env:Path -split ';')[0..1]
C:\Windows\SYSTEM32
C:\Windows
Armed with this information I can see that the Notepad from Windows\System32 returns first (I actually saw this earlier). Therefore, the application highest in the search path returns when I do not specify TotalCount.
So, now I can use the Path property from Get-Command, and I know what it will do. So if I want to look at the byte encoding of Notepad, I can use the Get-Command cmdlet to return the path to the application. I can supply that to the Get-Content cmdlet Path parameter, and I can specify Encoding Byte. I store this in the $bytes variable, and print out the first four bytes. This is shown here:
PS C:\> $bytes = Get-Content -Path (Get-Command notepad).path -Encoding Byte
PS C:\> $bytes[0..3]
77
90
144
0
MC, that is all there is to using the Get-Command cmdlet to find commands. Join me tomorrow when I will talk about more cool Windows PowerShell stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy