Effective PowerShell Item 1: The Four Cmdlets That are the Keys to Finding Your Way Around PowerShell

I have been a big fan of the Effective series of books over the years from Effective COM to Effective XML.  Without trying to be too presumptuous, I thought I would capture some of the tidbits I’ve picked up over the last couple of years using Windows PowerShell interactively and writing production build & test scripts.  This first item is pretty "basic" and I debated whether or not it belongs in an "Effective PowerShell" article.  In the end, these four cmdlets are so critical to figuring out for yourself how to make PowerShell work for you that I thought it was worth it.  Unfortunately this is a long post.  I’m going to try hard to keep my future Effective PowerShell posts much shorter than this first one. 

The following four CMDLETs are the first four that you should learn backwards and forwards.  With these four simple-to-use cmdlets you can get started using PowerShell – effectively.

#1.  Get-Command – This CMDLET is the sure cure to the blank, PowerShell prompt of death.  That is, you just installed PowerShell, fired it up and you’re left looking at this:

Now what?  Many applications suffer from the "blank screen of death" i.e. you download the app, install it and run it and now you’re presented with a blank canvas or an empty document.  Often it isn’t obvious how to get started using a foreign application.  In PowerShell, what you need to get started is Get-Command to find all the commands that are available from PowerShell.  This includes all your old console utilities, batch files, VBScript files, Perl files, etc.  Basically anything that is executable can be executed from PowerShell.  Of course, you didn’t download PowerShell just to run these old executables and scripts.  You want to see what PowerShell can do.  Try this:

PS C:\Users\Keith> get-command

CommandType     Name                         Definition
———–     —-                         ———-
Cmdlet          Add-Content                  Add-Content [-Path] <Stri…
Cmdlet          Add-History                  Add-History [[-InputObjec…
Cmdlet          Add-Member                   Add-Member [-MemberType] …
Cmdlet          Add-PSSnapin                 Add-PSSnapin [-Name] <Str…
Cmdlet          Clear-Content                Clear-Content [-Path] <St…
Cmdlet          Clear-Item                   Clear-Item [-Path] <Strin…
Cmdlet          Clear-ItemProperty           Clear-ItemProperty [-Path…
Cmdlet          Clear-Variable               Clear-Variable [-Name] <S…
Cmdlet          Compare-Object               Compare-Object [-Referenc…

Cmdlet          Get-Command                  Get-Command [[-ArgumentLi…

By default, get-command list all the CMDLETs that PowerShell provides.  Notice that Get-Command is one of those CMDLETs.  Get-Command can list more information but how would you figure that out?  This brings us to the second command you need to know and will be using frequently in PowerShell.

#2. Get-Help – This CMDLET will provide information on what a CMDLET does, what parameters it takes and usually it will include examples of how to use the command.  It will also provide help on general PowerShell topics like globbing and providers like Registry and FileSystem.  Say you want to know what *all* the help topics are in PowerShell – easy – just do this:

PS C:\Users\Keith> get-help *

Name                     Category                 Synopsis
—-                     ——–                 ——–
ac                       Alias                    Add-Content
asnp                     Alias                    Add-PSSnapin

Get-Command              Cmdlet                   Gets basic informati…
Get-Help                 Cmdlet                   Displays information…

Alias                    Provider                 Provides access to t…
Environment              Provider                 Provides access to t…
FileSystem               Provider                 The PowerShell Provi…
Function                 Provider                 Provides access to t…
Registry                 Provider                 Provides access to t…
Variable                 Provider                 Provides access to t…
Certificate              Provider                 Provides access to X…

about_Globbing           HelpFile                 See Wildcard
about_History            HelpFile                 Retrieving commands …
about_If                 HelpFile                 A language command f…
about_Line_Editing       HelpFile                 Editing commands at …
about_Location           HelpFile                 Accessing items from…
about_logical_Operator   HelpFile                 Operators that can b…

And if you only want to see the "about" help topics try this:

PS C:\Users\Keith> get-help about*

Name                     Category                 Synopsis
—-                     ——–                 ——–
about_Alias              HelpFile                 Using alternate name…
about_Arithmetic_Oper… HelpFile                 Operators that can b…
about_Array              HelpFile                 A compact data struc…

Now, let’s try Get-Help on Get-Command and see what else we can do with Get-Command:

PS C:\Users\Keith> get-help get-command -detailed

NAME
    Get-Command

SYNOPSIS
    Gets basic information about cmdlets and about other elements of Wind
    ows PowerShell commands.

PARAMETERS
    -name <string[]>
        Gets information only about the cmdlets or command elements with
        the specified name. <String> represents all or part of the name o
        f the cmdlet or command element. Wildcards are permitted.

    -verb <string[]>
        Gets information about cmdlets with names that include the specif
        ied verb. <String> represents one or more verbs or verb patterns,
         such as "remove" or *et". Wildcards are permitted.

    -noun <string[]>
        Gets cmdlets with names that include the specified noun. <String>
         represents one or more nouns or noun patterns, such as "process"
         or "*item*". Wildcards are permitted.

    -commandType <CommandTypes>
        Gets only the specified types of command objects. Valid values fo
        r <CommandTypes> are:
                  Alias                  ExternalScript
                  All                    Filter
                  Application            Function
                  Cmdlet (default)       Script

TIP: you will want to use the -Detailed parameter with Get-Help otherwise you get very minimal parameter information.  Hopefully in PowerShell v.next they will fix the "default view" of CMDLET help topics to be a bit more informative.  There’s a couple things to learn from the help topic.  First, you can pass Get-Command a commandType to list other types of commands.  Let’s try this to see what PowerShell functions are available by default:

PS C:\Users\Keith> get-command -commandType function

CommandType     Name                         Definition
———–     —-                         ———-
Function        A:                           Set-Location A:
Function        B:                           Set-Location B:
Function        C:                           Set-Location C:
Function        Clear-Host                   $spaceType = [System.Mana…
Function        D:                           Set-Location D:
Function        E:                           Set-Location E:
Function        F:                           Set-Location F:
Function        G:                           Set-Location G:
Function        H:                           Set-Location H:
Function        help                         param([string]$Name,[stri…
Function        I:                           Set-Location I:
Function        J:                           Set-Location J:
Function        K:                           Set-Location K:
Function        L:                           Set-Location L:
Function        M:                           Set-Location M:
Function        man                          param([string]$Name,[stri…
Function        md                           param([string[]]$paths); …
Function        mkdir                        param([string[]]$paths); …
Function        more                         param([string[]]$paths); …
Function        N:                           Set-Location N:
Function        O:                           Set-Location O:
Function        P:                           Set-Location P:
Function        prompt                       ‘PS ‘ + $(Get-Location) +…
Function        Q:                           Set-Location Q:
Function        R:                           Set-Location R:
Function        S:                           Set-Location S:
Function        T:                           Set-Location T:
Function        TabExpansion                 …
Function        U:                           Set-Location U:
Function        V:                           Set-Location V:
Function        W:                           Set-Location W:
Function        X:                           Set-Location X:
Function        Y:                           Set-Location Y:
Function        Z:                           Set-Location Z:

Excellent.  We could do the same for filters, aliases, applications, etc.  Also note that Get-Command allows you search for CMDLETs based on either a Noun or a Verb.  There’s a more compact form that most of the PowerShell regulars use instead of these parameters though:

PS C:\Users\Keith> get-command write-*

CommandType     Name                         Definition
———–     —-                         ———-
Cmdlet          Write-Debug                  Write-Debug [-Message] <S…
Cmdlet          Write-Error                  Write-Error [-Message] <S…
Cmdlet          Write-Host                   Write-Host [[-Object] <Ob…
Cmdlet          Write-Output                 Write-Output [-InputObjec…
Cmdlet          Write-Progress               Write-Progress [-Activity…
Cmdlet          Write-Verbose                Write-Verbose [-Message] …
Cmdlet          Write-Warning                Write-Warning [-Message] …

You can swap the wildcard char to find all verbs associated with a particular noun (usually the more useful search):

PS C:\Users\Keith> get-command *-object

CommandType     Name                         Definition
———–     —-                         ———-
Cmdlet          Compare-Object               Compare-Object [-Referenc…
Cmdlet          ForEach-Object               ForEach-Object [-Process]…
Cmdlet          Group-Object                 Group-Object [[-Property]…
Cmdlet          Measure-Object               Measure-Object [[-Propert…
Cmdlet          New-Object                   New-Object [-TypeName] <S…
Cmdlet          Select-Object                Select-Object [[-Property…
Cmdlet          Sort-Object                  Sort-Object [[-Property] …
Cmdlet          Tee-Object                   Tee-Object [-FilePath] <S…
Cmdlet          Where-Object                 Where-Object [-FilterScri…

Finally, we can pass a name to Get-Command to find out if this name will be interpreted as a command and if so, what type of command: cmdlet, function, filter, alias, externalscript, script or application.  In this usage, Get-Command is like the Unix ‘which’ command on steriods.  Let me show you what I mean:

PS C:\Users\Keith> get-command more

CommandType     Name                         Definition
———–     —-                         ———-
Function        more                         param([string[]]$paths); …
Application     more.com                     C:\Windows\system32\more.com

Note that PowerShell tells me not only the location of applications like more.com, it also tells me what type of command each is (function vs application) as well as the functions defintion and the priority order of the commands. In this case, PowerShell will execute its ‘more’ function if you were to use the command ‘more’.  [Update 11/16/07: The output order is does *not* indicate the priority order in which PowerShell will execute commands with the same name.  This is disappointing].  If you wanted to use the Windows executable, you would need to use the command ‘more.com’.  However there is even more information to be found here that meets the eye.  This brings us to our third and final important cmdlet to become familiar with.

#3. Get-Member – The single biggest concept that takes a while to sink in with most people using PowerShell for the first time is that just about *everything* is (or can be) a .NET object.  That means when you pipe information from one CMDLET to another it quite often isn’t text and if it is, it is still an object.  To be specific, it is a System.String object.  However, quite often it is some other type of object and being new to PowerShell, quite often you won’t know what type of object it is or what you can do with that object.  Let’s take a further look at what information (ie objects) Get-Command outputs.  In order to do this, we will use Get-Member like so:

PS C:\Users\Keith> get-command more.com | get-member

   TypeName: System.Management.Automation.ApplicationInfo

Name            MemberType     Definition
—-            ———-     ———-
Equals          Method         System.Boolean Equals(Object obj)
GetHashCode     Method         System.Int32 GetHashCode()
GetType         Method         System.Type GetType()
get_CommandType Method         System.Management.Automation.CommandTyp…
get_Definition  Method         System.String get_Definition()
get_Extension   Method         System.String get_Extension()
get_Name        Method         System.String get_Name()
get_Path        Method         System.String get_Path()
ToString        Method         System.String ToString()
CommandType     Property       System.Management.Automation.CommandTyp…
Definition      Property       System.String Definition {get;}
Extension       Property       System.String Extension {get;}
Name            Property       System.String Name {get;}
Path            Property       System.String Path {get;}
FileVersionInfo ScriptProperty System.Object FileVersionInfo {get=[Sys…

Well now, isn’t this interesting.  Unlike the Unix ‘which’ command that only gives us the path to the application, here we get a bit more information.  Let’s examine the FileVersionInfo on this command:

PS C:\Users\Keith> get-command more.com | foreach {$_.FileVersionInfo}

ProductVersion   FileVersion      FileName
————–   ———–      ——–
6.0.6000.16386   6.0.6000.1638… C:\Windows\system32\more.com

This is just an inkling of the power of being able to access objects instead of unstructured information like plain text.  Get-Member is also very handy for discovery what properties and methods are available on .NET classes.

PS C:\Users\Keith> get-date | get-member

   TypeName: System.DateTime

Name                 MemberType     Definition
—-                 ———-     ———-
Add                  Method         System.DateTime Add(TimeSpan value)
AddDays              Method         System.DateTime AddDays(Double value)
AddHours             Method         System.DateTime AddHours(Double va…
AddMilliseconds      Method         System.DateTime AddMilliseconds(Do…
AddMinutes           Method         System.DateTime AddMinutes(Double …

You can also find out information about static properties and methods like so:

PS C:\Users\Keith> [System.Math] | get-member -static

   TypeName: System.Math

Name            MemberType Definition
—-            ———- ———-
Abs             Method     static System.Single Abs(Single value), sta…
Acos            Method     static System.Double Acos(Double d)
Asin            Method     static System.Double Asin(Double d)
Atan            Method     static System.Double Atan(Double d)
Atan2           Method     static System.Double Atan2(Double y, Double x)
BigMul          Method     static System.Int64 BigMul(Int32 a, Int32 b)

#4 Get-PSDrive – Next to "everything is an object" the next biggest notion to digest in PowerShell is that the file system is one of many stores than can be manipulated by many of the same cmdlets you use to manipulate the file system.  First, how do you find out which drives are available in PowerShell?  Why use the Get-PSDrive command:

PS C:\> Get-PSDrive

Name       Provider      Root                                   CurrentLocation
—-       ——–      —-                                   —————
Alias      Alias
C          FileSystem    C:\
cert       Certificate   \
D          FileSystem    D:\
E          FileSystem    E:\
Env        Environment
Function   Function
G          FileSystem    G:\
H          FileSystem    H:\
HKCU       Registry      HKEY_CURRENT_USER
HKLM       Registry      HKEY_LOCAL_MACHINE
M          FileSystem    M:\
Variable   Variable

All these drives can be manipulating using same cmdlets you use to manipulate the file system.  What are those?  Use Get-Command *-Item* to find out:

PS C:\> Get-Command *-Item*

CommandType     Name                            Definition
———–     —-                            ———-
Cmdlet          Clear-Item                      Clear-Item [-Path] <String[]…
Cmdlet          Clear-ItemProperty              Clear-ItemProperty [-Path] <…
Cmdlet          Copy-Item                       Copy-Item [-Path] <String[]>…
Cmdlet          Copy-ItemProperty               Copy-ItemProperty [-Path] <S…
Cmdlet          Get-Item                        Get-Item [-Path] <String[]> …
Cmdlet          Get-ItemProperty                Get-ItemProperty [-Path] <St…
Cmdlet          Invoke-Item                     Invoke-Item [-Path] <String[…
Cmdlet          Move-Item                       Move-Item [-Path] <String[]>…
Cmdlet          Move-ItemProperty               Move-ItemProperty [-Path] <S…
Cmdlet          New-Item                        New-Item [-Path] <String[]> …
Cmdlet          New-ItemProperty                New-ItemProperty [-Path] <St…
Cmdlet          Remove-Item                     Remove-Item [-Path] <String[…
Cmdlet          Remove-ItemProperty             Remove-ItemProperty [-Path] …
Cmdlet          Rename-Item                     Rename-Item [-Path] <String>…
Cmdlet          Rename-ItemProperty             Rename-ItemProperty [-Path] …
Cmdlet          Set-Item                        Set-Item [-Path] <String[]> …
Cmdlet          Set-ItemProperty                Set-ItemProperty [-Path] <St…

There you have it.  The four CMDLETS that you *need* to know to really find your way around Windows PowerShell.  Get-Command to find out what commands/functionality is available.  Get-Help to find out how to use that functionality.  Get-Member to figure out what information and functionality is available on those .NET objects you’ll be dealing with in PowerShell.  And Get-PSDrive to find out which stores you can operate on besides the obvious one (the file system).  Comments are welcome.

Update: Added Get-PSDrive based on Jeffrey’s comment.

This entry was posted in Effective PowerShell. Bookmark the permalink.

2 Responses to Effective PowerShell Item 1: The Four Cmdlets That are the Keys to Finding Your Way Around PowerShell

  1. Jeffrey says:

    I would have added GET-PSDRIVE to the list.
     
    Jeffrey Snover [MSFT]Windows Management Partner ArchitectVisit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShellVisit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx 

  2. Keith says:

    Great suggestion – done! 

Leave a comment