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.
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
Great suggestion – done!