Saturday, September 15, 2007

Exploring Get-Command


I removed some definition columns for readability. During Get-Command exploration I found some interesting things on my environment. Check yours :-)


To get a cmdlet syntax, not so readable


PS > get-command get-childitem -syntax

Get-ChildItem [[-Path] <String[]>] [[-Filter] <String>] [-Include <String[]>] [-Exclude <String[]>] [-Recurse] [-Force] [-Name] [-Verbose]
[-Debug] [-ErrorAction <ActionPreference>] [-ErrorVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>]
Get-ChildItem [-LiteralPath] <String[]> [[-Filter] <String>] [-Include <String[]>] [-Exclude <String[]>] [-Recurse] [-Force] [-Name] [-Verb
ose] [-Debug] [-ErrorAction <ActionPreference>] [-ErrorVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>]


Same goes here . It is better to run "get-help cmdlet-name -full"

PS C:\Scripts> get-command get-childitem -definition

CommandType  Name                     Definition
-----------          ----                        ----------
Cmdlet              Get-ChildItem         Get-ChildItem [[-Path] <String[]>] [[-Filter] <String>] [-Include <String[]>] [-Exclude <String[]>] [-Recurse]...



Get the most popular cmdlets by verb. And the winner is...

PS >  get-command | group verb

Count Name
----- ----
  134 Get
   87 Set
   60 Remove
   49 New
   17 Enable
   16 Add
   15 Disable
   15 Test
   11 Update
   10 Export
    8 Move
    7 Write
    6 Out
    6 Start
    5 Stop
    5 Suspend
    5 Resume
    5 Clear
    5 Import
    4 Format
    3 Copy



List commands were "email" appears in the command noun part

PS >  get-command -noun *email*

CommandType     Name
-----------             ----
Cmdlet                 Get-EmailAddressPolicy
Cmdlet                 New-EmailAddressPolicy
Cmdlet                 Remove-EmailAddressPolicy
Cmdlet                 Set-EmailAddressPolicy
Cmdlet                 Update-EmailAddressPolicy


The -commandType property can take one (or more of this values)




So, get all registered filters

PS > get-command -commandType Filter

CommandType Name                       Definition
-----------         ----                          ----------
Function          A:                            Set-Location A:
Function          B:                            Set-Location B:
Function          backup-profile          copy-item $PROFILE "C:\Scripts\PoSH Profile" -force;...
Function          C:                            Set-Location C:
Function          Clear-Host                $spaceType = [System.Management.Automation...
Function          Clear-Temp              remove-item -r -fo $env:temp\* -ea 0;...
Function          D:                            Set-Location D:
Function          e                              & "explorer.exe" $args[0];
Function          E:                             Set-Location E:
Function        echo-args                   for($i=0;$i -lt $args.length;$i++){...
Function        edit-profile                 & $textpad $PROFILE;
Function        F:                               Set-Location F:
Function        G:                                Set-Location G:
Function        get-def                        ($args[0] | gm $args[1]).definition.split(',');...
Function        Get-Params                  param(...
Function        Get-RemoteEventLog    [System.Diagnostics.Eventlog]::GetEventLogs(...
Function        Get-RemoteProcess      [System.Diagnostics.Process]::GetProcesses(...
Function        Get-RemoteService       [void][System.Reflection.Assembly]::LoadWithPartial...


To return all scripts that are found in your PATH environment variable. Interesting ... I installed the Exchange 2007 management pack and it registered some scripts:


PS > get-command -commandType ExternalScript

CommandType    Name                                  
-----------            ----                                  
ExternalScript     AddReplicaToPFRecursive.ps1           
ExternalScript     AddUsersToPFRecursive.ps1             
ExternalScript     CheckInvalidRecipients.ps1            
ExternalScript     ConfigureAdam.ps1                     
ExternalScript     configure-SMBIPsec.ps1                
ExternalScript     enable-CrossForestConnector.ps1       
ExternalScript     Exchange.ps1                          


-CommandType can also get multiple types, separated by a comma


PS C:\Scripts> Get-Command -commandType Filter,ExternalScript

CommandType     Name
-----------             ----
Function              A:
ExternalScript     AddReplicaToPFRecursive.ps1
ExternalScript     AddUsersToPFRecursive.ps1
Function             B:
Function             backup-profile
Function            C:
ExternalScript    CheckInvalidRecipients.ps1
Function           Clear-Host
Function           Clear-Temp
ExternalScript   ConfigureAdam.ps1
ExternalScript  configure-SMBIPsec.ps1
Function          D:
Function          e
Function          E:
Function          echo-args



Now, Get ExternalScript file paths:

PS > get-command -commandType ExternalScript | foreach {$_.path}

C:\Program Files\Microsoft\Exchange Server\Scripts\AddReplicaToPFRecursive.ps1
C:\Program Files\Microsoft\Exchange Server\Scripts\AddUsersToPFRecursive.ps1
C:\Program Files\Microsoft\Exchange Server\Scripts\CheckInvalidRecipients.ps1
C:\Program Files\Microsoft\Exchange Server\Scripts\ConfigureAdam.ps1
C:\Program Files\Microsoft\Exchange Server\Scripts\configure-SMBIPsec.ps1



To add your own scripts directory type (e.g., c:\scripts)

PS > $env:path+=";c:\scripts"


Now you can execute all scripts in your scripts directory, typing only its name (with/out .ps1 extension) and you don't need to be in the scripts working directory. I'll introduce Get-WorldClock on my next blog post :-) 


PS D:\> Get-WorldClock

Place                  Time
-----                   ----
Addis Ababa       Sat 4:19 PM
Adelaide            Sat 10:49 PM
Aden                 Sat 4:19 PM
Algiers              Sat 2:19 PM
Amman             Sat 4:19 PM
Amsterdam       Sat 3:19 PM
Anadyr              Sun 2:19 AM
Anchorage        Sat 5:19 AM
Ankara             Sat 4:19 PM
Antananarivo    Sat 4:19 PM
Asuncion           Sat 9:19 AM
Athens              Sat 4:19 PM
Atlanta             Sat 9:19 AM
Auckland          Sun 1:19 AM


Group all commndlets by its PSSnapIn property

PS > get-command | where {$_.CommandType -eq "Cmdlet"} | group PSSnapIn | select count,name

Count  Name
-----    ----
  381   Microsoft.Exchange.Management.PowerShell.Admin
   47   Microsoft.PowerShell.Management
   12   Microsoft.PowerShell.Core
   58   Microsoft.PowerShell.Utility
   10   Microsoft.PowerShell.Security
    2   Microsoft.PowerShell.Host


Another way to list only Exchange 2007 command-lets

PS > get-command | where {$ -match "exchange"}

CommandType     Name
-----------             ----
Cmdlet                Add-ADPermission
Cmdlet                Add-AvailabilityAddressSpace
Cmdlet                Add-ContentFilterPhrase
Cmdlet                Add-DistributionGroupMember
Cmdlet                Add-ExchangeAdministrator
Cmdlet                Add-IPAllowListEntry
Cmdlet                Add-IPAllowListProvider
Cmdlet               Add-IPBlockListEntry
Cmdlet               Add-IPBlockListProvider
Cmdlet               Add-MailboxPermission


Or even better, filter with the pssnapin parameter 

PS > get-command -pssnapin Microsoft.Exchange.Management.PowerShell.Admin

CommandType     Name
-----------             ----
Cmdlet          Add-ADPermission
Cmdlet          Add-AvailabilityAddressSpace
Cmdlet          Add-ContentFilterPhrase
Cmdlet          Add-DistributionGroupMember
Cmdlet          Add-ExchangeAdministrator
Cmdlet          Add-IPAllowListEntry
Cmdlet          Add-IPAllowListProvider
Cmdlet          Add-IPBlockListEntry
Cmdlet          Add-IPBlockListProvider
Cmdlet          Add-MailboxPermission



Get all properties for a command-let

PS > (get-command select-string).parametersets[0].parameters | select name,ParameterType,aliases


Name               ParameterType                                                     Aliases
----                   -------------                                                          -------
InputObject       System.Management.Automation.PSObject              {}
Pattern             System.String[]                                                       {}
SimpleMatch     System.Management.Automation.SwitchParameter   {}
CaseSensitive   System.Management.Automation.SwitchParameter   {}
Quiet               System.Management.Automation.SwitchParameter   {}
List                  System.Management.Automation.SwitchParameter   {}
Include             System.String[]                                                       {}
Exclude            System.String[]                                                       {}
Verbose           System.Management.Automation.SwitchParameter   {vb}
Debug              System.Management.Automation.SwitchParameter  {db}
ErrorAction      System.Management.Automation.ActionPreference  {ea}
ErrorVariable    System.String                                                         {ev}
OutVariable      System.String                                                         {ov}
OutBuffer         System.Int32                                                          {ob}



I also wrote a function Get-Params which takes a cmdlet name and calculates the
shortest alias name for each cmdlet parameter. Very useful when typing commands interactively. It also emits some additional important columns.


>> Get-Params select-string


- select-string -

Name               Alias        Position     Type
----                  -----         --------       ----
caseSensitive   -c            named        SwitchParameter
exclude            -e            named        string[]
include             -inc         named        string[]
inputObject      -inp        named         psobject
list                   -l           named         SwitchParameter
path                 -path      2                string[]
pattern             -patt      1                string[]
quiet                -q          named        SwitchParameter
simpleMatch     -s          named        SwitchParameter
text                  -t          2                string[]

No comments: