One of the interesting things about PowerShell is how easy it is to discover its cmdlets and parameter. In PowerShell itself or in the ISE, you can just start typing a command and then press the <TAB> key complete it.

One other interesting bit is how you can use the Get-Command cmdlet to discover all others. I covered some of this functionality and the ability to load modules in a previous blog post at http://blogs.technet.com/josebda/archive/2009/08/09/experimenting-with-powershell-cmdlets-snap-ins-and-modules.aspx

For example, Get-Command can easily help you find all the cmdlets related to the EventLogs:

PS C:\> Get-Command -Noun EventLog

CommandType     Name                                                Definition
-----------     ----                                                ----------
Cmdlet          Clear-EventLog                                      Clear-EventLog [-LogName] <String[]> [[-Computer...
Cmdlet          Get-EventLog                                        Get-EventLog [-LogName] <String> [[-InstanceId] ...
Cmdlet          Limit-EventLog                                      Limit-EventLog [-LogName] <String[]> [-ComputerN...
Cmdlet          New-EventLog                                        New-EventLog [-LogName] <String> [-Source] <Stri...
Cmdlet          Remove-EventLog                                     Remove-EventLog [-LogName] <String[]> [[-Compute...
Cmdlet          Show-EventLog                                       Show-EventLog [[-ComputerName] <String>] [-Verbo...
Cmdlet          Write-EventLog                                      Write-EventLog [-LogName] <String> [-Source] <St...


Is it also just as simple to find all cmdlets that Format the output. The next examples uses “gcm”, the alias for Get-Command:

PS C:\> gcm -Verb Format

CommandType     Name                                                Definition
-----------     ----                                                ----------
Cmdlet          Format-Custom                                       Format-Custom [[-Property] <Object[]>] [-Depth <...
Cmdlet          Format-List                                         Format-List [[-Property] <Object[]>] [-GroupBy <...
Cmdlet          Format-Table                                        Format-Table [[-Property] <Object[]>] [-AutoSize...
Cmdlet          Format-Wide                                         Format-Wide [[-Property] <Object>] [-AutoSize] [...

Now what I was looking into recently was not no much the cmdlets but the parameters you can use with them.

For instance, which cmdlets take “-ComputerName” as a parameter? That’s quite easy to answer if you look at the Definition of the command. Here’s what you can use for that:

PS C:\> Get-Command -type cmdlet | Where {$_.Definition -like "*-ComputerName*"}

CommandType     Name                                                Definition
-----------     ----                                                ----------
Cmdlet          Clear-EventLog                                      Clear-EventLog [-LogName] <String[]> [[-Computer...
Cmdlet          Connect-WSMan                                       Connect-WSMan [[-ComputerName] <String>] [-Appli...
Cmdlet          Disconnect-WSMan                                    Disconnect-WSMan [[-ComputerName] <String>] [-Ve...
Cmdlet          Enter-PSSession                                     Enter-PSSession [-ComputerName] <String> [-Crede...
Cmdlet          Get-Counter                                         Get-Counter [[-Counter] <String[]>] [-SampleInte...
Cmdlet          Get-EventLog                                        Get-EventLog [-LogName] <String> [[-InstanceId] ...
Cmdlet          Get-HotFix                                          Get-HotFix [[-Id] <String[]>] [-ComputerName <St...
Cmdlet          Get-Process                                         Get-Process [[-Name] <String[]>] [-ComputerName ...
Cmdlet          Get-PSSession                                       Get-PSSession [[-ComputerName] <String[]>] [-Ver...
Cmdlet          Get-Service                                         Get-Service [[-Name] <String[]>] [-ComputerName ...
Cmdlet          Get-WinEvent                                        Get-WinEvent [[-LogName] <String[]>] [-MaxEvents...
Cmdlet          Get-WmiObject                                       Get-WmiObject [-Class] <String> [[-Property] <St...
Cmdlet          Get-WSManInstance                                   Get-WSManInstance [-ResourceURI] <Uri> [-Applica...
Cmdlet          Invoke-Command                                      Invoke-Command [-ScriptBlock] <ScriptBlock> [-In...
Cmdlet          Invoke-WmiMethod                                    Invoke-WmiMethod [-Class] <String> [-Name] <Stri...
Cmdlet          Invoke-WSManAction                                  Invoke-WSManAction [-ResourceURI] <Uri> [-Action...
Cmdlet          Limit-EventLog                                      Limit-EventLog [-LogName] <String[]> [-ComputerN...
Cmdlet          New-EventLog                                        New-EventLog [-LogName] <String> [-Source] <Stri...
Cmdlet          New-PSSession                                       New-PSSession [[-ComputerName] <String[]>] [-Cre...
Cmdlet          New-WSManInstance                                   New-WSManInstance [-ResourceURI] <Uri> [-Selecto...
Cmdlet          Receive-Job                                         Receive-Job [-Job] <Job[]> [[-Location] <String[...
Cmdlet          Register-WmiEvent                                   Register-WmiEvent [-Class] <String> [[-SourceIde...
Cmdlet          Remove-EventLog                                     Remove-EventLog [-LogName] <String[]> [[-Compute...
Cmdlet          Remove-PSSession                                    Remove-PSSession [-Id] <Int32[]> [-Verbose] [-De...
Cmdlet          Remove-WmiObject                                    Remove-WmiObject [-Class] <String> [-AsJob] [-Im...
Cmdlet          Remove-WSManInstance                                Remove-WSManInstance [-ResourceURI] <Uri> [-Sele...
Cmdlet          Restart-Computer                                    Restart-Computer [[-ComputerName] <String[]>] [[...
Cmdlet          Set-Service                                         Set-Service [-Name] <String> [-ComputerName <Str...
Cmdlet          Set-WmiInstance                                     Set-WmiInstance [-Class] <String> [[-Arguments] ...
Cmdlet          Set-WSManInstance                                   Set-WSManInstance [-ResourceURI] <Uri> [[-Select...
Cmdlet          Show-EventLog                                       Show-EventLog [[-ComputerName] <String>] [-Verbo...
Cmdlet          Stop-Computer                                       Stop-Computer [[-ComputerName] <String[]>] [[-Cr...
Cmdlet          Test-Connection                                     Test-Connection [-ComputerName] <String[]> [[-So...
Cmdlet          Test-WSMan                                          Test-WSMan [[-ComputerName] <String>] [-Authenti...
Cmdlet          Write-EventLog                                      Write-EventLog [-LogName] <String> [-Source] <St...

For the next few examples, please start PowerShell with the option to “Import System Modules”. This is easy to do if you pin the “PowerShell” program to the taskbak and then start it with a right-click: 

Import System Modules

In that case, PowerShell will take a little longer to start, but it will load all the system modules. How many additional ones? Well, you can use Get-Command to figure out just that:

PS C:\> Get-Command -type cmdlet | Group Module | Sort Count -Desc

Count Name                      Group
----- ----                      -----
  242                           {Add-Computer, Add-Content, Add-History, Add-Member...}
   76 ActiveDirectory           {Add-ADComputerServiceAccount, Add-ADDomainControllerPasswordReplicationPolicy, Add-...
   71 WebAdministration         {Add-WebConfiguration, Add-WebConfigurationLock, Add-WebConfigurationProperty, Backu...
   69 FailoverClusters          {Add-ClusterDisk, Add-ClusterFileServerRole, Add-ClusterGenericApplicationRole, Add-...
   25 GroupPolicy               {Backup-GPO, Copy-GPO, Get-GPInheritance, Get-GPO...}
    8 BitsTransfer              {Add-BitsFile, Complete-BitsTransfer, Get-BitsTransfer, Remove-BitsTransfer...}
    5 AppLocker                 {Get-AppLockerFileInformation, Get-AppLockerPolicy, New-AppLockerPolicy, Set-AppLock...
    2 TroubleshootingPack       {Get-TroubleshootingPack, Invoke-TroubleshootingPack}

Now, with that in mind, you could also start to look into what parameters are use with the commands from each module.
For instance, you can look at which modules most implement the “-WhatIf” parameter:

PS C:\> Get-Command -type cmdlet | Where {$_.Definition -like "*-WhatIf*"} | Group Module

Count Name                      Group
----- ----                      -----
   53 ActiveDirectory           {Add-ADComputerServiceAccount, Add-ADDomainControllerPasswordReplicationPolicy, Add-...
    7 BitsTransfer              {Add-BitsFile, Complete-BitsTransfer, Remove-BitsTransfer, Resume-BitsTransfer...}
   85                           {Add-Computer, Add-Content, Clear-Content, Clear-EventLog...}
   28 WebAdministration         {Add-WebConfiguration, Add-WebConfigurationLock, Add-WebConfigurationProperty, Clear...
   17 GroupPolicy               {Backup-GPO, Copy-GPO, Import-GPO, New-GPLink...}
   14 FailoverClusters          {Block-ClusterAccess, Clear-ClusterDiskReservation, Clear-ClusterNode, Remove-Cluste...
    1 AppLocker                 {Set-AppLockerPolicy}

Or you you might want to look into which modules contain more of a specific type of verb, noun or parameter. For instance, if you’re looking for a cmdlet to manager users, you could try:

PS C:\> gcm -type cmdlet| ?{$_.Definition -like "*user*"} | Select Module, Name | Group Module | Sort Count -Desc

Count Name                      Group
----- ----                      -----
    8 ActiveDirectory           {@{Module=ActiveDirectory; Name=Get-ADUser}, @{Module=ActiveDirectory; Name=Get-ADUs...
    4 FailoverClusters          {@{Module=FailoverClusters; Name=Block-ClusterAccess}, @{Module=FailoverClusters; Na...
    3                           {@{Module=; Name=Get-EventLog}, @{Module=; Name=Invoke-Sqlcmd}, @{Module=; Name=Star...
    2 AppLocker                 {@{Module=AppLocker; Name=New-AppLockerPolicy}, @{Module=AppLocker; Name=Test-AppLoc...
    2 BitsTransfer              {@{Module=BitsTransfer; Name=Get-BitsTransfer}, @{Module=BitsTransfer; Name=Set-Bits...
    1 GroupPolicy               {@{Module=GroupPolicy; Name=Get-GPResultantSetOfPolicy}}

Now, saving the best for last, we could try to understand which parameters are used the most. This is a tricky one-liner, since we need to look into the definition itself then do some pattern matching, string splitting and comparison to isolate the parameters. We finally pass each individual one into the pipelining for further grouping and sorting, limiting to the 40 parameters most used. On the split, we split on spaces, open brackets “\[“ or close bracets “\]”, using the \ as a escape character since [ and ] are special characters for pattern matching.

PS C:\> gcm -type cmdlet | % { $d=$_.Definition -Split "[ \[\]]"; for ($c=1; $c -lt $d.count; $c++) { If ($d[$c][0] -eq "-") { $d[$c] } } } | Group | Sort Count -Desc | Select Count, Name -First 40

Count Name
----- ----
  786 -Debug
  786 -Verbose
  786 -OutBuffer
  786 -ErrorVariable
  786 -WarningAction
  786 -OutVariable
  786 -WarningVariable
  786 -ErrorAction
  318 -Confirm
  318 -WhatIf
  233 -Credential
  226 -Name
  165 -Server
  146 -Force
  142 -InputObject
  139 -PassThru
  115 -AuthType
   90 -Path
   73 -Filter
   73 -UseTransaction
   72 -Exclude
   71 -Include
   71 -Identity
   69 -ComputerName
   64 -Cluster
   49 -Authentication
   48 -Domain
   41 -Partition
   36 -PSPath
   35 -ThrottleLimit
   32 -AsJob
   31 -LiteralPath
   29 -Namespace
   28 -Value
   28 -Description
   27 -Location
   26 -DisplayName
   25 -ArgumentList
   25 -Properties
   24 –Impersonation

You can see that the “common parameters” are obvious on the top of the list, followed by a few popular ones like “-Credential”, “-Name” and “-Server”.

Hope you learned something new and have fun with PowerShell...