Introduction to Microsoft PowerShell– Basics of Running Cmdlets
PowerShell Cmdlets
You will notice that for the PowerShell commands I use the word Cmdlet, that is how Microsoft calls and spells the word. In a PowerShell shell you can execute regular windows commands in addition to the cmdlets and most work without any problem some may experience problems depending on the parameters used since PowerShell uses space as a delimiter so do keep this in mind when you are running local exe files.
PowerShell cmdlets are in the form of a <verb>-<noun>, you will see common verbs like set, get, clear, write and stop to name a few and each belong to a group of actions, you can get an updated list of verbs at the TechNet site http://social.technet.microsoft.com/wiki/contents/articles/4537.powershell-approved-verbs-en-us.aspx do keep this list handy because if you create any module, cmdlet or function you should follow the naming so as to not confuse users and not get warnings from PowerShell when loading modules or cmdlets. To get a list of cmdlets on PS we use the Get-Command cmdlet:
When ran with no options we get a list of all cmdlet, functions and Aliases we have available. Just like on a Unix shell you will notice you have functions and aliases at your disposal to call. Aliases are mainly for saving time when entering commands and to make others more familiar when ran in a shell like the ls or the cat commands:
PS C:\Users\Carlos Perez> lsDirectory: C:\Users\Carlos PerezMode LastWriteTime Length Name---- ------------- ------ ----d-r-- 2/16/2012 3:03 PM Contactsd-r-- 3/26/2012 11:23 PM Desktopd-r-- 2/16/2012 3:03 PM Documentsd-r-- 3/8/2012 3:52 PM Downloadsd-r-- 2/16/2012 3:03 PM Favoritesd-r-- 2/16/2012 3:03 PM Linksd-r-- 2/16/2012 3:03 PM Musicd-r-- 2/16/2012 3:03 PM Picturesd-r-- 2/16/2012 3:03 PM Saved Gamesd-r-- 2/16/2012 3:03 PM Searchesd-r-- 2/16/2012 3:03 PM Videos-a--- 3/28/2012 8:16 PM 28 hello.txtPS C:\Users\Carlos Perez> cat .\hello.txthello worldPS C:\Users\Carlos Perez> rm .\hello.txtPS C:\Users\Carlos Perez> lsDirectory: C:\Users\Carlos PerezMode LastWriteTime Length Name---- ------------- ------ ----d-r-- 2/16/2012 3:03 PM Contactsd-r-- 3/26/2012 11:23 PM Desktopd-r-- 2/16/2012 3:03 PM Documentsd-r-- 3/8/2012 3:52 PM Downloadsd-r-- 2/16/2012 3:03 PM Favoritesd-r-- 2/16/2012 3:03 PM Linksd-r-- 2/16/2012 3:03 PM Musicd-r-- 2/16/2012 3:03 PM Picturesd-r-- 2/16/2012 3:03 PM Saved Gamesd-r-- 2/16/2012 3:03 PM Searchesd-r-- 2/16/2012 3:03 PM Videos
As we can see the aliases makes the shell behave similar to a Unix/Linux shell, but do keep in mind it is only similar, the parameters are not the same.
One can use the tab key to auto complete PSDrive Paths (More on this on another blog post), File Paths, Functions, Cmdlets, Function Options, Cmdlets Parameters, Variables and regular Windows Commands. So one can so Get-<tab> and keep hitting tab to cycle through the cmdlets available with the verb Get, the same can be done to find a cmdlet parameter like Get-Service –<tab>
The Get-Command also allow us to filter using wildcards:
PS C:\Users\Carlos Perez> Get-Command -Name *service* -CommandType cmdletCommandType Name Definition----------- ---- ----------Cmdlet Get-Service Get-Service [[-Name] <String[]>] [-ComputerName ...Cmdlet New-Service New-Service [-Name] <String> [-BinaryPathName] <...Cmdlet New-WebServiceProxy New-WebServiceProxy [-Uri] <Uri> [[-Class] <Stri...Cmdlet Restart-Service Restart-Service [-Name] <String[]> [-Force] [-Pa...Cmdlet Resume-Service Resume-Service [-Name] <String[]> [-PassThru] [-...Cmdlet Set-Service Set-Service [-Name] <String> [-ComputerName <Str...Cmdlet Start-Service Start-Service [-Name] <String[]> [-PassThru] [-I...Cmdlet Stop-Service Stop-Service [-Name] <String[]> [-Force] [-PassT...Cmdlet Suspend-Service Suspend-Service [-Name] <String[]> [-PassThru] [...
On Windows 8 in PowerShell v3 we have the the Show-Command cmdlet that will bring a GUI Interface for exploring the cmdlet and it options allowing us to copy the command we build or run the command:
When we want to get specific help on any cmdlet we can use the get-help cmdlet or it’s alias help:
This will provide us with a base help for the cmdlet where we can see:
- Name
- Synopsis
- Syntax
- Description
- Related Links
- Remarks
We can use the –detail option to get more details on the options, their types and position in the command arguments if we pass each value without an option, we can also use the –examples to get example on how to use the cmdlet and a brief description of what the command is doing and we can get a with –full the entire content of the help message. You can consider help/Get-Help as the man command in Unix/Linux. When you look at the Syntax section the options you can quickly determine what values you can provide to them. When we see the message we will see that each optional Parameter we can pass is between [ ], if a parameter is not optional it will not be enclosed in [ ], some options do not require values those are just –<Parametername> other will take a value, for those that take a value PS will let you know the value type if it is a string, integer, object ..etc between <>, some can take a list of values and you will notice those will be in the format of <type[]> and those that have a predefined list of options that can be given to a parameter will be in the format of < option1 | option2 | option3>. I highly recommend that when starting with a cmdlet for the first time to use the –full parameter when getting help. The full help message will provide us additional information for each parameter as shown bellow:
-Name <string[]>Specifies the service names of services to be retrieved. Wildcards are permitted. By default, Get-Service getsall of the services on the computer.Required? falsePosition? 1Default valueAccept pipeline input? true (ByValue, ByPropertyName)Accept wildcard characters? true-RequiredServices [<SwitchParameter>]Gets only the services that this service requires.This parameter gets the value of the ServicesDependedOn property of the service. By default, Get-Service gets all services.Required? falsePosition? namedDefault value FalseAccept pipeline input? falseAccept wildcard characters? false
As it can be seen for the –Name parameter we can see additional information like if it is required or not, the position when calling the cmdlet, this means that the cmdlet will take the first thing given to it an use it as the value for this parameter when the parameter is not given, we can also see it accepts inputs from the pipeline and that this can be a value or a property. In the case of the RequiredServices parameter the position is named, that means that the name of the parameter must be specified with the value.
If the computer you are running PowerShell on has internet connectivity you can give the parameter–online to the Get-Help cmdlet to open a browser window with the latest help information for it.
Let take a look at the Get-Service cmdlet:
As we can see we in syntax we can call the cmdlet in 3 different ways, one where we start by providing the name or names of the service, another where we provide Display Names and a third where we pass service controller objects (Remember PowerShell cmdlets output objects). Let look at the first one:
Get-Service [[-Name] <string[]>] [-ComputerName <string[]>] [-DependentServices] [-Exclude <string[]>] [-Include <string[]>] [-RequiredServices] [<CommonParameters>]
As we can see the –Name parameter takes a list of strings. Lets get the state of several services:
PS C:\Users\Carlos Perez> Get-Service -Name BITS, VSS
Status Name DisplayName------ ---- -----------Running BITS Background Intelligent Transfer Ser...
Stopped VSS Volume Shadow Copy
Now we ask for a full help for the command we will see for the name option that it accepts wildcard characters for the parameter of -Name and for the parameter of –DisplayName so we can search for any service with the word WMI in its Display Name:
PS C:\Users\Carlos Perez> Get-Service -DisplayName *WMI*Status Name DisplayName------ ---- -----------Stopped wmiApSrv WMI Performance Adapter
The Wildcard Characters that can be used are shown in the table bellow:
Wildcard Character | Description | Example |
---|---|---|
* |
Matches zero or more characters, starting at the specified position |
a* |
? |
Matches any character at the specified position |
?n |
[ ] |
Matches a range of characters |
[a-l]name |
[ ] |
Matches the specified characters |
[bc]name |
In PowerShell one can use parameter abbreviation, similar to what one can do with commands on Cisco IOS we only need to enter enough of the parameter name that is is unique against the other. In the Get-Process cmdlet the only parameter that starts with the letter N is Name so we can shorten it to only this letter:
PS C:\Users\Carlos Perez> Get-Process -N *vm*Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName------- ------ ----- ----- ----- ------ -- -----------270 20 8956 7708 87 1392 vmtoolsd289 23 15252 14388 145 113.97 2544 vmtoolsd68 9 3444 3148 68 0.55 2532 VMwareTray
As we play with parameters and comandlets one of the things we can do is to maintain a transcript. We can do this with the Start-Transcript cmdlet, this will save all of our commands and output to a file and when we issue the cmdlet Stop-Transcript it will stop recording our action, we can even append to an existing file by giving it the –Append parameter. One thing to note is that you can not use it on ISE.
PS C:\Windows\system32> Start-Transcript C:\windows\Temp\testtranscript.txtTranscript started, output file is C:\windows\Temp\testtranscript.txtPS C:\Windows\system32> Get-Service | select -first 1Status Name DisplayName------ ---- -----------Stopped AeLookupSvc Application ExperiencePS C:\Windows\system32> Get-process | select -first 1Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName------- ------ ----- ----- ----- ------ -- -----------23 4 2128 1460 38 0.09 408 cmdLogName: PS C:\Windows\system32> Stop-TranscriptTranscript stopped, output file is C:\windows\Temp\testtranscript.txt
Now as mentioned before PowerShell cmdlets return objects and we can pipe this objects to other cmdlets. We can illustrate by saving an object in to a variable and looking at what we have available. In PowerShell variables start with with $ In this example we will look at the object for the BITS service:
PS C:\Windows\system32> $srv = Get-Service -Name BITS
PS C:\Windows\system32> $srvStatus Name DisplayName------ ---- -----------Running BITS Background Intelligent Transfer Ser...
If we want to know it’s type we can use the .Net method of gettype()
PS C:\Windows\system32> $srv.GetType().fullnameSystem.ServiceProcess.ServiceController
If we want to look at the methods (actions that can be taken) and Properties (Information) of an object we can use the Get-Members cmdlet.
PS C:\Windows\system32> Get-Member -InputObject $srvTypeName: System.ServiceProcess.ServiceControllerName MemberType Definition---- ---------- ----------Name AliasProperty Name = ServiceNameRequiredServices AliasProperty RequiredServices = ServicesDependedOnDisposed Event System.EventHandler Disposed(System.Object, System.EventArgs)Close Method System.Void Close()Continue Method System.Void Continue()CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)Dispose Method System.Void Dispose()Equals Method bool Equals(System.Object obj)ExecuteCommand Method System.Void ExecuteCommand(int command)GetHashCode Method int GetHashCode()GetLifetimeService Method System.Object GetLifetimeService()GetType Method type GetType()InitializeLifetimeService Method System.Object InitializeLifetimeService()Pause Method System.Void Pause()Refresh Method System.Void Refresh()Start Method System.Void Start(), System.Void Start(string[] args)Stop Method System.Void Stop()ToString Method string ToString()WaitForStatus Method System.Void WaitForStatus(System.ServiceProcess.ServiceControllerStatus desi...CanPauseAndContinue Property System.Boolean CanPauseAndContinue {get;}CanShutdown Property System.Boolean CanShutdown {get;}CanStop Property System.Boolean CanStop {get;}Container Property System.ComponentModel.IContainer Container {get;}DependentServices Property System.ServiceProcess.ServiceController[] DependentServices {get;}DisplayName Property System.String DisplayName {get;set;}MachineName Property System.String MachineName {get;set;}ServiceHandle Property System.Runtime.InteropServices.SafeHandle ServiceHandle {get;}ServiceName Property System.String ServiceName {get;set;}ServicesDependedOn Property System.ServiceProcess.ServiceController[] ServicesDependedOn {get;}ServiceType Property System.ServiceProcess.ServiceType ServiceType {get;}Site Property System.ComponentModel.ISite Site {get;set;}Status Property System.ServiceProcess.ServiceControllerStatus Status {get;}
We can also pipe the contents of the variable to the the cmdlet like so $srv | Get-Members as we can see we can get information like status, type, dependencies and we can take actions like pause , start and stop. we can also use tab completion to cycle thru the methods and properties of an object when it is in a variable.
Lets stop the service and get it’s status before and after:
PS C:\Windows\system32> (Get-Service -Name BITS).status
StoppedPS C:\Windows\system32> (Get-Service -Name BITS).start()
PS C:\Windows\system32> (Get-Service -Name BITS).status
Running
You will notice that methods are always called with ( ) in the end since a methods takes parameters, properties we can call directly and they are the state of when the object was created that is why we execute the command and work with the object directly by running the command between parenthesis.
Also properties and the results from methods can have methods and more properties beneath them, we can chain this to get the value or results we want.
PS C:\Windows\system32> $srv.Status.GetType()IsPublic IsSerial Name BaseType-------- -------- ---- --------True True ServiceControllerStatus System.Enum
Another way would be to use the refresh method:
PS C:\Windows\system32> $srv.StatusRunningPS C:\Windows\system32> $srv.Stop()PS C:\Windows\system32> $srv.Refresh()PS C:\Windows\system32> $srv.StatusStopped
As you can see one of the main advantages of PowerShell is the is the advantage to manipulate the data as objects and not as text. In the next post I will cover more on how to work with several objects, how to modify the objects and piping.
As always I hope you find this post informative and useful.