PowerShell Basics–Running Commands

Lets start running commands and tying in what was covered in the previous posts. As you may have guessed by now in PowerShell the cmdlets, functions, workflows and scripts are all named in a - format. This aids in classifying the functionality of them and keeps to the idea of having one specific area of functionality per command similar to Unix. To get a list of all of the Verbs we use the Get-Verb cmdlet to get the list of approved verbs for PowerShell. When we write our own we can name them anything we like but it is recommended to follow the same standard as the one present in the shell so as to maintain uniformity and ease of use. The verbs are grouped per functionality in the following groups:

  • Common
  • Data
  • Lifecycle
  • Diagnostic
  • Communications
  • Security
  • Other

In the blogpost on using the help subsystem I covered that the Get-Help cmdlet could be use to find commands on the system since it parses the help information, this could prove useful in exploring but it will also miss system commands, Dynamic Link Libraries and some time it can even be to noisy depending on what we want to find. There is a specific cmdlet in PowerShell whose whole purpose is to find all commands that are installed on the computer, including cmdlets, aliases, functions,workflows, filters, scripts, and applications. Get-Command gets the commands from Windows PowerShell modules and this is the Get-Command cmdlet. If we use the Get-Help cmdlet against the Get-Command cmdlet we get the following Syntax options:

image

We have 2 general ways we can run the cmdlet, the first one we can search by Verb or Noun and in the second one we can search by Name of the cmdlet. Lets take take the second way of running the cmdlet and look at the name option [[-Name] ] we see that it takes a string object and that we can provide it a list of string because it has the [ ] at the end of the type, we also see that -Name is between [ ] which means it is optional to. If we look at the parameter it self we will see:

PS C:\> Get-Help Get-Command -Parameter Name

-Name <String[]>
    Gets only commands with the specified name. Enter a name or name pattern. Wildcards are permitted.

    To get commands that have the same name, use the All parameter. When two commands have the same name, by default,
    Get-Command gets the command that runs when you type the command name.

    Required?                    false
    Position?                    1
    Default value                None
    Accept pipeline input?       True (ByValue, ByPropertyName)
    Accept wildcard characters?  false

NOTE: I see that is in “Accept wildcard characters?” it says false, that  is a bug that has been present since PowerShell 2.0 since I can remember, this is why I have gotten in to the habit of also reading the description of the parameters, I have only seen it happen with this cmdlet.

In the description we can see that we can use wildcard characters for looking in the names of the commands and also we see it is in position 1 so we can just pass that wildcard expression as the first argument passed to the cmdlet.  It will search for system commands in all the locations that are in the $PATH variable also. Here is an example where I show the contents of my Path environment variable and as it can be seen it includes Nmap and SQL Express installations so if I look for *nmap* and for *sql* it will show the commands for those:

PS C:\> $env:path
C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\Wind
ows System Resource Manager\bin;C:\Program Files\Microsoft Network Monitor 3\;C:\Program Files\Microsoft SQL Server\110\Tool
s\Binn\;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files (x86)\Nmap
PS C:\> get-command *nmap*

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Application     nmap.exe
Application     nmap-update.exe
Application     zenmap.exe


PS C:\> get-command *sql*

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Application     SQLCMD.EXE
Application     SqlLocalDB.exe

When using Wildcard Characters we can use any of the characters listed in the table below:

image

When it comes to parameters PowerShell also has Tab Autocomplete for parameter and they can be shorten to the minimum unique characters like we can with Cisco IOS, PowerShell does this by looking at the cmdlet it self and in the case of Function, Scripts and Workflows it will even parse the code to read this so as to provide them to AutoComplete. So we could run the Get-Service command as follows to get the information for the BITS service:

PS C:\Windows\system32> Get-Service -Name bits

Status   Name               DisplayName
------   ----               -----------
Running  bits               Background Intelligent Transfer Ser...


PS C:\Windows\system32> Get-Service -Name bits*

Status   Name               DisplayName
------   ----               -----------
Running  BITS               Background Intelligent Transfer Ser...


PS C:\Windows\system32> Get-Service -Na bits*

Status   Name               DisplayName
------   ----               -----------
Running  BITS               Background Intelligent Transfer Ser...


PS C:\Windows\system32> Get-Service bits*

Status   Name               DisplayName
------   ----               -----------
Running  BITS               Background Intelligent Transfer Ser...

This provides great flexibility for running cmdlets, Functions and Workflows but it also adds the power of discoverability, we can just type a –<Tab> and keep hitting the Tab key to discover the parameter we want.

On PowerShell v3 the autocompleting is further expanded to include predefined lists or those that can be calculated and deduced by the command like list of processes, list of services, error actions ..etc.

Expansion for services as they are enumerated for autocomplete:

image

Expansion of predefine options:

image

in the none ISE Terminal one can cycle thru them by just keep hitting the <Tab> Key

PowerShell v3 added a graphical way to also explore PowerShell specific commands and build the command in the GUI and execute it in the GUI also using the Show-Command cmdlet

image

image

PowerShell just like other Unix shells allows the use of Aliases for commands, this allows for less typing. Now a word of advice, since PowerShell allows the shortening of parameters or use of the values of such can produce very hard to read code when scripting with PowerShell so for interactive shell this is perfect so as to allow for fast use but when sharing command strings or scripts get in to the habit of expanding the command alias and the parameters.

We can use the Get-Command cmdlet to search for all the cmdlets for managing Aliases:

PS C:\> Get-Command *alias*

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Cmdlet          Export-Alias                                       Microsoft.PowerShell.Utility
Cmdlet          Get-Alias                                          Microsoft.PowerShell.Utility
Cmdlet          Import-Alias                                       Microsoft.PowerShell.Utility
Cmdlet          New-Alias                                          Microsoft.PowerShell.Utility
Cmdlet          Set-Alias                                          Microsoft.PowerShell.Utility

The use of the <verb>-<noun> format makes the identification of the purpose of the cmdlets quite simple. To get a list of the aliases on the current sessions we would use the Get-Alias cmdlet. We can create new cmdlets with New-Alias and Set-Alias, to modify an Alias the Set-Alias cmdlet is used.

To get the definition of a specific alias:

PS C:\> Get-Alias -Name ls

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Alias           ls -> Get-ChildItem

To get what aliases are for a specific cmdlet

PS C:\> Get-Alias -Definition Get-ChildItem

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Alias           dir -> Get-ChildItem
Alias           gci -> Get-ChildItem
Alias           ls -> Get-ChildItem

To create a new alias

PS C:\> New-Alias -Name ll -Value Get-ChildItem
PS C:\> ll


    Directory: C:\


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----         8/16/2012   5:14 PM            inetpub
d----         7/26/2012   3:33 AM            PerfLogs
d-r--         1/18/2013  10:03 PM            Program Files
d-r--         1/13/2013   8:33 AM            Program Files (x86)
d----        10/30/2012  10:02 PM            SQLEXPRESS
d-r--         8/15/2012   8:35 PM            Users
d----         1/12/2013  10:56 PM            Windows

Sadly the aliases we create are not permanent and are lost once we close the session. We can export the aliases we create to a file and load them in to any session or autoload them with the use of profiles files (More on this on a later blogpost), to export them we use the Export-Alias cmdlet.

PS C:\> export-alias -path alias.csv

This will generate a a list in to a CSV File

image

It an also be exported as a Script

PS C:\> Export-Alias -Path .\alias.ps1 -as script

image

To import the aliases that where exported we use the Import-Alias.

PS C:\> Import-Alias -Path .\alias.csv -ErrorAction SilentlyContinue

Conclusion

As always I hope you found this blogpost useful and I invite you to read more on the subject covered by looking at the following conceptual help information inside of PowerShell using the Get-Help cmdlet (Yes it is homework):

  • about_CommonParameters
  • about_Parameters
  • about_Parameters_Default_Values
  • about_Core_Commands
  • about_Command_Syntax
  • about_Command_Precedence
  • about_Aliases