Powershell: Default-verb logic (implied `Get-` prefix) works when executing commands, but not with Get-Command and Get-Help

Created on 10 Jun 2017  路  6Comments  路  Source: PowerShell/PowerShell

When _invoking_ a Get-* cmdlet, the Get- prefix is optional, because Get is the default verb; E.g., Get-Content can be invoked as content.

By contrast, both Get-Command and Get-Help (as well as the common -? parameter) are unaware of this; Get-Command _fails_ (unless there happens to be a different command with that exact name), and Get-Help / -? list all topics that _contain_ the name.

_All three scenarios should treat a given command name the same._

Steps to reproduce

'hi' > t.txt; content t.txt
'---'
Get-Command content | % Name
'---'
Get-Help content | % Name
'---'
content -? | % Name

Expected behavior

hi
---
Get-Content
---
Get-Content
---
Get-Content

Actual behavior

hi
---
Get-Command : The term 'content' 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. 
....
---
Add-Content
Clear-Content
Get-Content
Set-Content
---
Add-Content
Clear-Content
Get-Content
Set-Content

Environment data

PowerShell Core v6.0.0-beta2
Windows PowerShell v5.1.14393.1198 on Microsoft Windows 10 Pro (64-bit; v10.0.14393)
Issue-Discussion WG-Engine

Most helpful comment

Note that this command lookup behavior is not limited to cmdlets - it works for any command including native commands.

It is also very expensive - we first search normally (including the PATH), and if that fails, we repeat the search prepending Get-.

Personally, I'd rather remove this misfeature than formalize it.

We could provide a handler for $ExecutionContext.InvokeCommand.CommandNotFoundAction for folks that are unwilling to fix old scripts that rely on this odd feature.

All 6 comments

Looks like someone actually included CommandDiscovery.LookupCommandInfo() (in which the Get- prefix search option is implemented) as a fallback in the Get-Command command definition but forgot to assign and return the output

Note that this command lookup behavior is not limited to cmdlets - it works for any command including native commands.

It is also very expensive - we first search normally (including the PATH), and if that fails, we repeat the search prepending Get-.

Personally, I'd rather remove this misfeature than formalize it.

We could provide a handler for $ExecutionContext.InvokeCommand.CommandNotFoundAction for folks that are unwilling to fix old scripts that rely on this odd feature.

Get-Process has an even more difficult problem to solve because process is a keyword for the process {} block, therefore executing process makes it prompt because it waits for the statement block. Maybe instead of completely removing it, apply the lookup only if the command starts with e.g. -- or some special character.
I would otherwise vote to remove optional expensive actions that get invoked when the user does not intend/want/need to. Everytime I try to tab-complete stuff when the AzureRM module is loaded, I can take a sipp of coffee...

If you want to invoke process without saying get-process, you can use & process or & "process".

Adding complexity here is unlikely good for the user experience or for performance.

If performance is unacceptable, you should open another issue with details - I don't notice performance issues when AzureRM is loaded on Windows PowerShell, but I haven't tried with PowerShell Core.

That's neat, I did not know that. But it still shows that the Get- auto completion should either always work or we should get rid of it because having to remember those exceptions is not very good.

What I noticed today is that there can be a difference between using the auto completed command or the actual command:

````powershell

(get-help).gettype()

IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object

(help).gettype()

IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array

$PSVersionTable

Name Value
---- -----
PSVersion 6.0.0-rc
PSEdition Core
GitCommitId v6.0.0-rc
OS Microsoft Windows 6.3.9600
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
````

Help is a real command that pipes through the pager like more or less.

Was this page helpful?
0 / 5 - 0 ratings