Basics of Cmdlets
Cmdlets are at the core of PowerShell. As already noted in The object-oriented model, a cmdlet is a specialised .NET object, with output formatting that makes sense to an administrator.
In this article, we discuss the following:
Getting help information for a cmdlet
Let us pick a common cmdlet: Get-ChildItem
, a simple, useful cmdlet. Its job is to just list out the contents of a given location. PowerShell doesn’t see just the disk drives as drives, but also the registry and other such logical containers. Therefore, Get-ChildItem
(or gci
or dir
or ls
) can essentially list out more than just files and folders. But in this article, we go by the route most commonly picked: Get-ChildItem
at a filesystem location.
To know what the cmdlet does, and what kinds of input and parameters it accepts, we run Get-Help
on it:
Get-Help Get-ChildItem
The output that it shows is concise and helpful. However, if you would like more information, you could always use -Examples
or -Full
along with Get-Help
.
Parameter sets
What you may have noticed when running Get-Help for a cmdlet is the parameter sets in SYNTAX
. Parameter sets are groups of parameters you can use together. There are some instances—for example, where you are doing a Set
operation: Set
means change, which could mean add or remove. But it wouldn’t make sense, in most cases, to use -Add
and -Remove
at the same time, because it could give rise to a conflict.
New-Burger 'AwesomeQuinoa'
Set-Burger -Burger 'AwesomeQuinoa' -Sauce Barbecue -Add -Remove
It would not make sense to add and remove the barbecue sauce in a burger, both at the same time. So when you’re running a cmdlet, ensure to read the parameter sets. In most cases, if you’re using tab-complete or IntelliSense—which I recommend—PowerShell would not let you use conflicting parameters. If you’re not using either of them, PowerShell would simply spit out an error indicating that you used two or more incompatible parameters.
As a side-note, read the errors. They help you understand what the issue is. When we’re beginners, we just see the red text as “an error”, rather than considering it a pointer to a specific issue. They are usually highly technical—Microsoft is infamous for that—but they point us in the right direction. Use the FullyQualifiedErrorId
property of the error to look for help online; this is common across languages, so, there hardly a chance that an error isn’t discussed about in the forums.
Positional parameters
It is common to spot commands like Restart-Computer 'MyDesktop'
, and there is a good chance you saw someone writing Restart-Computer -ComputerName 'MyDesktop'
as well. It may make us wonder what the difference between the two commands is.
Functionally, there’s no difference. However, the visual difference is that the latter uses what we call a Named Parameter.
PowerShell understood in the first case, that we were referring to the computer name by saying, Restart-Compuer 'MyDesktop'
. But how?
This is because of what we call Positional Parameters. Positional parameters help you write a PowerShell cmdlet that understands a certain sequence of parameters, without requiring the administrator to name them every time.
So if you were to write a cmdlet to boil something to a temperature of 80°C, you could simply say, Boil-Content water 80
, instead of Boil-Content -Content 'water' -TemperatureInC 80
. In this case, PowerShell simply understood the content type and the temperature, because the cmdlet was programmed to understand the input that way. The cmdlet has been told, ‘The first word after the cmdlet is supposed to be the content, and the second, the temperature in degree Celsius’.
But why would someone use a named parameter when positional parameters are easier?
Named parameters ensure that PowerShell is specifically told what is what, and that there’s no room for confusion. Positional parameters just make the job easier. Both have their advantages and disadvantages. While named parameters make you type more, positional parameters introduce a chance of confusion.
Also, positional parameters require that the sequence is maintained, while named parameters don’t. Therefore, you could say:
Boil-Content -TemperatureInC 80 -Content 'water'
While creating PowerShell scripts, it is recommended to use named parameters. This way, debugging becomes easier, and the others who are using or contributing to your scripts can understand easily, how you’ve used each of the cmdlets or functions. You can apply the same rule of thumb I mentioned about, in using aliases—strike a balance: positional parameters on the CLI and named parameters in scripts.
Also, like I’ve mentioned already, tab-completion is a great boon in PowerShell. It works with completing parameter names (and in many cases, even with parameter values), along with completing cmdlets.
Help on specific parameters
If you would like to get help on a specific parameter, use the -Parameter
parameter of Get-Help
and pass the name of the parameter to it. For example:
Get-Help Get-ChildItem -Parameter Path
This shows you what the Path
parameter does, and what kinds of values it accepts. You can see that the parameter accepts a string array as input, that its default value is the current directory, and that its position is 1.
Positions are zero-indexed in PowerShell. Therefore, if a parameter’s position is 0, the value right after the cmdlet would be assigned to this parameter. However, there is a chance that a certain cmdlet has a parameter whose position is 1, but no parameter at position 0. In this case, the parameter with the lowest index number would be the one that gets the value that appears after the cmdlet.
For instance, the Sauce
parameter
-BurgerName <String>
Specifies the burger name.
Required? true
Positions 1
DefaultValue null
AcceptPipelineInput? false
AcceptWildcardCharacters? false
Let us say, Set-Burger does not have a parameter at position 0. Then, Set-Burger AwesomeQuinoa
automatically becomes Set-Burger -BurgerName AwesomeQuinoa
.
Assigning values to a parameter
Finally, to the very important part of parameters. In short, any value that follows the name of the parameter is the value assigned to it. In most cases, we don’t use an operator to assign values to the parameter, except some special situations.
In cases where the parameters accept an array as input, separate the values with a comma, and optionally, a space. For instance, if you would like to create three new files, you would do it the following way:
New-Item -Path file-1, file-2, file-3 -ItemType File
Notice the values passed to -Path
—we use commas to separate file-1
, file-2
and file-3
.
If you would like to have spaces in the file names, enclose the names in quotes—preferably single quotes. Otherwise, you would receive an error from PowerShell stating that it did not find a parameter that accepted the input. Let me explain why. Say you want three files, file 1
, file 2
and file 3
, and you type:
New-Item -Path file 1, file 2, file 3 -ItemType File
PowerShell will think that the path you mentioned was file
and you were trying to pass 1
and file
to a parameter at the second position (and 2
and file
to a parameter at the third position and 3
to a parameter at the fourth position).
In some special situations, we use a different type of assignment of values to a parameter. One such situation is turning off confirmation prompts:
Get-ChildItem . -Recurse | Remove-Item -Confirm:false
Here we pass false
to -Confirm
using a colon. However, know that the situations in which you would have to use an operator to assign a value to a parameter is extremely rare.
That brings us to the end of this article. You should now be comfortable running cmdlets, and working with different kinds of parameters. You should be able to understand how parameter sets work, why they exist, how to pass values to parameters, including leveraging their positional configuration and how to find out this information about the parameters.