Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is "date"? "Get-Command date" throws CommandNotFoundException

Tags:

powershell

date working:

PS> date

Saturday, June 10, 2017 9:10:11 AM

But Get-Command date throws exception:

PS> Get-Command date
Get-Command : The term 'date' 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
+ Get-Command date
+ ~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (date:String) [Get-Command], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand

Also Get-Alias date throws exception:

PS> Get-Alias date
Get-Alias : This command cannot find a matching alias because an alias with the name 'date' does not exist.
At line:1 char:1
+ Get-Alias date
+ ~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (date:String) [Get-Alias], ItemNotFoundException
    + FullyQualifiedErrorId : ItemNotFoundException,Microsoft.PowerShell.Commands.GetAliasCommand

$PSVersionTable.PSVersion is "5.1.15063.296" on Windows 10.

The date seems not to be a cmdlet, function, script file, operable program or alias. So, what is the date?

like image 909
matt9 Avatar asked Jun 10 '17 17:06

matt9


2 Answers

The PowerShell CommandDiscovery API uses the following precedence order to resolve command names to commands:

  1. Alias
  2. Function
  3. Cmdlet
  4. Native Windows commands

If the command name does not contain a dash or a slash, and no command has been found after exhausting the last option in the list above, it'll try again, but with Get- prepended.

For this reason, the Get verb is also known as the default command verb.

This works for any Get-* command for which there's no collision with existing alias, function or cmdlet names, or native executable in $env:path, like:

Alias
Item
ChildItem

... and so on.


If you ever again wonder why a command get's resolved in a certain way, you can use the Trace-Command cmdlet to get debug-level information from the powershell engine:

Trace-Command -Expression { date } -Name Command* -Option All -PSHost

Command* will, in this context, match the CommandSearch and CommandDiscovery routines and show you exactly which steps powershell takes to resolve the command name date

like image 176
Mathias R. Jessen Avatar answered Oct 14 '22 02:10

Mathias R. Jessen


To complement Mathias R. Jessen's helpful answer, which explains the command-discovery process well:

That Get-Command is unaware of the default-verb logic and therefore doesn't report the same command that is actually executed when the given command name is used is an inconsistency that should be fixed, because that is its very purpose when given a command name.

  • As an aside: The -All option allows you to see additional commands of the same name with lower precedence, but even wit -All date isn't found (and, if it were, it should be listed first, in line with reporting it as the effective command, without -All).

Similarly, Get-Help and -? are also unaware of the default-verb logic:

  • date -? and Get-Help date do not return Get-Date's help; instead, they list help topics that contain the word date.

I've created an issue in the PowerShell GitHub repository.

like image 8
mklement0 Avatar answered Oct 14 '22 01:10

mklement0