PowerShell Pipeline

Exploring PowerShell, Part 1: Using Get-Command

Here's how to retrieve the information you're looking for with one powerful command.

The amazing thing about PowerShell is that you are able to explore around the shell and find all sorts of cool things that it can do. Someone starting out with PowerShell might not be sure what the first step is other than looking at someone's code and determining what is going on or hitting the internet to find out how to accomplish a goal that perhaps someone else has already done so they can learn from that example.  Without searching the Internet or reviewing someone else's code, you will be amazed at just how much information you can find with just a few commands! One such command is Get-Command, which based on its name, gets a single or multiple commands based on what it has been given.

Let's take a look at just what we can do with this cmdlet.

[Click on image for larger view.]  Figure 1. Possible parameters with Get-Command.

We can see that there are multiple parameters which can be used to narrow down the scope of the results. For instance, if I only want to look for cmdlets, I can use the –CommandType parameter and specify Cmdlet.

[Click on image for larger view.]  Figure 2. Multiple possible CommandType arguments.

Notice in the ISE that the intellisense shows that I have much more than just Cmdlet as a possible argument for the parameter. We can not only just pick cmdlet, but we can also add function as well to see all of these results.

Get-Command -CommandType  Cmdlet,Function 
[Click on image for larger view.]  Figure 3. Lots of Functions and Cmdlets returned.

I decided to group the results by CommandType just to show you how many functions and cmdlets are available (I'm using Windows 2012 R2 as my OS) to look at.

Need to know what commands are in a module? No problem! Just use the –Module parameter and specify the name of the module. But what if we only want the commands that use Get as its verb? We can specify –Verb with Get as its argument and we have our information!

Get-Command -Module  NetAdapter -Verb  Get 
[Click on image for larger view.]  Figure 4. Results of looking at the NetAdapter module for Get- commands.

You can find any command that you are looking for with just a few parameters and even if you are not quite sure of what the command might be, the parameter for –Name accepts wildcards which allows you get a little closer to finding what you are looking for.

Each time you use Get-Command, it outputs an object type of System.Management.Automation.CmdletInfo which has multiple properties that we can use to see more parts of the command metadata.

If you are curious as to what all of the parameters are in a command, we can look at the parameters property and start exploring all of the properties.

We can use Get-Process as an example. Let's dig into some of the parameters to learn a little more about what they are:

$Command = Get-Command -Name Get-Process
[Click on image for larger view.]  Figure 5. All of the available parameters for Get-Process as a hash table.

The results when viewing the parameters are a hash table with each parameter name being mapped to its value. We can look at the Name parameter name and see what its metadata is.

[Click on image for larger view.]  Figure 6. Looking at the metadata of the Name parameter of Get-Process.

Here we can see that there is a lot of great information residing under the parameter metadata. Here we see that the parameter type supports a collection of strings ([string[]]) while there are also 2 possible parameter sets called Name and NameWithUserName. The attributes property looks pretty interesting, so let's dive deeper into that and see what we can find.

We actually have four attributes which help to make up this parameter:

$Command.Parameters['Name'].Attributes |  ForEach {
Write-Verbose $_.GetType().FullName -Verbose
[Click on image for larger view.]  Figure 7. Parameter attributes.

Note how there are two System.Management.Automation.ParameterAttribute for each parameter set that this parameter is a part of (note the ParameterSetName property). We can also see what the position is of the parameter a well as if it supports the pipeline. Also listed is the alias type of the parameter as well as other parameter attributes which might be used such as the [ValidateNotNullOrEmpty()] attribute.

Jumping back to Get-Command itself, we can actually filter for commands that match a specific parameter name and/or parameter type that is expected using –Parametername and –ParameterType.

Let's look for all cmdlets that have the capability to use the –Computername parameter to support remote actions and see what we get.

Get-Command -ParameterName  Computername
[Click on image for larger view.]  Figure 8. Commands with a Computername parameter.

These are only the cmdlets which have had the modules loaded, so there are possible more commands available which have a Computername parameter available to use.

If you have ever been curious as to what commands might just happened to take a hashtable as an argument, you can run the following command:

Get-Command -ParameterType  [hashtable] 
[Click on image for larger view.]  Figure 9. Commands that have parameter which takes a hash table.

For one last fun thing, we can take a look and see exactly what those parameters are that are hashtables (or similar like a collecton of hashtables: [hashtable[]] or System.Collections.IDictionary) using the following code:

Get-Command -CommandType  Cmdlet -ParameterType  [hashtable] |  ForEach {
$Command = $_.Name
$_.Parameters.GetEnumerator()| ForEach {
$Parameter = $_.Key
Switch ($_.value.ParameterType) {
{$_ -eq [hashtable]} {
$Type = 'Hashtable'
{$_ -eq [System.Collections.IDictionary]} {
$Type = 'System.Collections.IDictionary'
{$_ -eq [hashtable[]]} {
$Type = 'Hashtable[]'
Default {
$Skip = $True
If (-Not $Skip) {
Name = $Command
Parameter = $Parameter
Type = $Type
$Skip = $False
[Click on image for larger view.]  Figure 10. List of parameters that utilize a hashtable as an argument.

With that, we have taken a look at how we can use Get-Command to locate various commands such as cmdlets or functions as well as being able to further filter our findings by parameter name and/or type. With this knowledge, you can quickly find the command that you need to accomplish a task!

We will be continuing our trek into PowerShell by looking at the help system in the next article. See you then!

About the Author

Boe Prox is a Microsoft MVP in Windows PowerShell and a Senior Windows System Administrator. He has worked in the IT field since 2003, and he supports a variety of different platforms. He is a contributing author in PowerShell Deep Dives with chapters about WSUS and TCP communication. He is a moderator on the Hey, Scripting Guy! forum, and he has been a judge for the Scripting Games. He has presented talks on the topics of WSUS and PowerShell as well as runspaces to PowerShell user groups. He is an Honorary Scripting Guy, and he has submitted a number of posts as a to Microsoft's Hey, Scripting Guy! He also has a number of open source projects available on Codeplex and GitHub. His personal blog is at http://learn-powershell.net.

comments powered by Disqus
Most   Popular