So, what is the difference between a command and a cmdlet in PowerShell? There is this definition "PowerShell in a Month of Lunches"
"PowerShell contains many times of executable commands. Some are called cmdlets, some are called functions, others are known as workflows, and so on. Collectively, they're all commands, and the help system works with all of them. A cmdlet is something unique to PowerShell, and many of the commands you run will be cmdlets. But we'll try to consistently use command whenever we're talking about the more general class of executable utility."
Don Jones and Jeffrey Hicks know what they're talking about so I'll probably follow their lead.
According to Microsoft's documentation they differ from commands in other command shell environments in these ways:
- Cmdlets are instances of .NET Framework classes; they are not stand-alone executables.
- Cmdlets can be created from as few as a dozen lines of code.
- Cmdlets do not generally do their own parsing, error presentation, or output formatting. Parsing, error presentation, and output formatting are handled by the Windows PowerShell runtime.
- Cmdlets process input objects from the pipeline rather than from streams of text, and cmdlets typically deliver objects as output to the pipeline.
- Cmdlets are record-oriented because they process a single object at a time.
Cmdlets perform an action and usually return an object. They can be tied together using a pipeline. There will be more on using the pipeline at a later date.
Cmdlets follow a verb-noun structure. An easy example is the Get-Command cmdlet. This does what it says on the tin. It gets all commands that are installed on the computer, including cmdlets, aliases, functions, workflows, filters, scripts, and applications.
If you type in Get-Command into the console app you get a list of available commands printed out to the screen.
This is a long list to scroll through buy you can make this list more readable by piping Get-Command into the More function. The output of this command is a paged list that you can get more results by using the Space bar.
You can see the returned table has the command type, the command name, its version and the source of the command. You can import more sources by using commands such as Import-Module or write your own.
You can add parameters after the cmdlet to add necessary details or filter results depending on the cmdlet.
Parameters are allow you to pass in arguments to a command.
There a number of common parameters for PowerShell commands like WhatIf, Confirm, Verbose, Debug, Warn, ErrorAction, ErrorVariable, OutVariable, and OutBuffer.
You can also use help parameter (-?) to get help about a command
Get-Command -? # This is equivalent to Get-Help Get-Command
There are a number of different types of parameters. They are:
Postional or Named
All cmdlet parameters are either positional or named. Positional parameters require you to type the arguments in the correct order and the system will map them to the correct parameter. Using named parameters means that you need to type the parameter name first and then the argument.
Personally, I don't used positional parameters unless I have to. They do require less typing to get the job done, especially when using aliases (more on them later too) but they make scripts less legible. The ease of the verb-noun structure makes reading scripts pretty simple.
An example of a positional parameter is using the Get-Help cmdlet to get details about another command.
An example of using a named parameter is
Get-Command -Name Get-Alias
Required or Optional
All cmdlet parameters are either required or optional. Parameters are defaulted to optional. If you try to run a cmdlet without a required parameter then it will raise an error
Switch parameters do not require an argument. It's value is automatically set to false if the parameter isn't specified. If it is then the value is set to true.
Available Nouns and Verbs
You see the Approved Verbs for Windows PowerShell Commands documentation or by running Get-Verb on the console app.
You can also run
Get-Command -Verb Get
to see all the commands that contain the Get verb.
To get all the commands using a particular noun you can use the -Noun parameter
Get-Command -Noun Alias
This returns all the commands that have the Alias noun.
This is a good article that goes through learning PowerShell names.
As you could see from the screenshot above, there are aliases available for a lot of commands. This can reduce the number of keystrokes to write a script but it makes the code less readable. They are useful when initially writing a script but if the script will be in production use, it's a good idea to use the full command name.
For instance, h is an alias for Get-History. The results are the same but the full command name is far more readable when coming back and looking at the code in the future.