Whenever you execute or run anything in PowerShell, you’re running a “command.” A command is an informal term for executable code, which can be a built-in PowerShell cmdlet, a custom function, or even an object method.
Cmdlets are compiled executable code provided by Microsoft, created in a language like C#, compiled, and added to a PowerShell module by software developers. Functions, on the other hand, are created directly in PowerShell by users. Although functions and cmdlets are technically different, they can be thought of as similar when you’re starting out.
To demonstrate functions vs. cmdlets, let’s dig in with a short demo. Let’s find all of the available commands in the current session:
## Find all of the available command types
Get-Command | Group-Object -Property CommandType
People often interchange the terms commands, cmdlets, and functions. If this becomes confusing, remember that a “command” generally refers to either a cmdlet or a function.
The Group-Object
cmdlet groups properties, and here it provides a summary of commands by type.
You’ll see command types like aliases, cmdlets, and functions. Let’s inspect the code behind one of the cmdlets:
Get-Command -Name Get-Content | select -ExpandProperty Definition
The Definition
property contains the code for a function, and parameter sets for a cmdlet. In the case of cmdlets, you’ll only see parameter sets.
While cmdlets are more optimized for performance due to their precompiled nature, functions offer flexibility. For tasks involving custom logic or data processing, functions allow you to go beyond what cmdlets can do, providing room for creativity and problem-solving.
Now, let’s inspect a function:
Get-Command -Name Add-BitLockerKeyProtector | select -ExpandProperty Definition
You can see the actual PowerShell code for functions.
If you wish to see the module that a function resides in, you can look at the Source
property:
Get-Command -Name Add-AzADAppPermission
To locate the module, use:
Get-Module -Name BitLocker | select Path
This command will show the module’s path. For example, if the module is located in /Users/adam/.local/share/powershell/Modules/Az.Resources/7.4.0/Az.Resources.psm1
, you can open it in VS Code for further inspection.
code '/Users/adam/.local/share/powershell/Modules/Az.Resources/7.4.0/Az.Resources.psm1'
Inside the module, you’ll find several functions written in PowerShell, which you can explore and modify as needed.
It’s important to remember that although cmdlets tend to perform better, especially with large datasets, functions can be more versatile. They allow for the creation of custom workflows and logic that aren’t possible with cmdlets alone.
When deciding between using a cmdlet or a function, think about the task at hand. Cmdlets are ideal for built-in tasks that are already optimized, but if you need more control or customization, functions are your best bet. Functions can help create reusable code blocks, streamline complex tasks, and enhance overall script modularity.