This project is read-only.

Get-Command <TAB> doesn't show scripts that are in $Env:Path


I have some scripts that normally show up in tab completion, but don't show up in Get-Command <TAB>. I think externalscript needs to be added to have it get those as well. I'll probably look at it a little later and see if I can find it.


JasonMArcher wrote Sep 6, 2010 at 11:04 PM

I did that because Get-Command does not default to scripts. If you specify -CommandType ExternalScript it will work. (Actually, I just noticed a bug I need to fix.

StephenMills wrote Sep 7, 2010 at 12:20 AM

True, I realize it doesn't show them by default. However, if you specify one or include a wildcard, it will get the command (or script in this case.).

A bigger issue I found when trying to implement this, is that it takes a long time for Get-Command to get all the scripts in $Env:Path. Not sure why that is since I can parse $Env:Path, do a dir of each one for *.ps1, pull out the name of the scripts, and still have it take a lot less time than "Get-Command -CommandType ExternalScript". I thought it might be because it needs to find parameters, but I can get the contents of each script and still have it be faster then Get-Command. On my system, with a drive with paths on a WiFi network, it takes about 10 seconds to do a "Get-Command -CommandType Alias, Function, Filter, Cmdlet, ExternalScript", whereas if I take the "ExternalScript" part out, it takes under 1 second. My custom one that includes the output from the version without "ExternalScript", but with everything else, takes about 1 second more to manually find scripts.

I frequently do a "gcm <script>" to get parameters, verify a script is in the path.... It would be nice to have the scripts show up there, but I guess it might not be worth it.

JasonMArcher wrote Sep 9, 2010 at 5:27 PM

This is a use case I don't have a lot of experience with, I don't use scripts on the path. Right now you have two options to find a script named "script.ps1".

gcm -c e<TAB> script<TAB>
script%<TAB> ## This one is slow if your search string has lots of matches

StephenMills wrote Sep 11, 2010 at 5:27 PM

It actually isn't as simple as Get-Command not defaulting to ExternalScript. It actually doesn't have a default value for CommandType.
For Example, create a script and a function of the same name
Function: Get-MyTest
Script: Get-MyTest.ps1

Now try
GetCommand Get-MyTest | % { $_.Name }

Or if you try:
Get-Command Get-My* | % { $_.Name }

It also looks for any "Application" that matches what is passed to Get-Command.

But I was saying it doesn't have a default CommandType, in fact if you give it a CommandType, it will then ONLY show those items.

Get-Command Get-My* -CommandType Function | % { $_.Name }

Because of how odd it works and that I really liked the idea of getting scripts in there as well, I've added this functionality to my fork.
As part of this change I've also added a new function Get-CommandName which is much faster than Get-Command for ExternalScripts, but get's all commands.

StephenMills wrote Sep 14, 2010 at 5:24 PM

Oops. Ignore the changeset I posted. I'm not sure why it worked for me before, but now it just gives me an error. I need to track down why it isn't seeing the function I declared.

StephenMills wrote Sep 16, 2010 at 6:18 AM

Ok, I looked into it and am if I export the function Get-CommandName, then it works fine. Since this makes it visible to everyone, I'm not sure it's the best solution. But in any case here's the recent change that includes that.

StephenMills wrote Nov 23, 2010 at 6:18 PM

Any chance of having this addressed? Most of my scripts are written like a cmdlet "Verb-Noun" even though they are scripts and I use them more like cmdlets.

I addressed the slowness issue you mentioned by creating a Get-CommandName function that is much faster than Get-Command for finding scripts. It doesn't very much information compared with Get-Command, but if all you are looking for is a name, then it works good. If you don't have a lot of scripts in your path, it should slow you down much if at all. Get-CommandName uses a filter of "*.ps1" so it can find the script files faster. It also has CommandType parameter that accepts "Executable" which duplicates some functionality elsewhere in PowerTab ("## Native commands / scripts in path").