Saturday, June 14, 2014

PowerShell Revisited - Running Commands

Running PowerShell Commands
The command Get-Verb is an example of a cmdlet (pronounced "command-let"). Cmdlets are structured verb-noun, where the noun is singular.
Below we will get a list of approved verbs in PowerShell, then format the results to fill the screen from left to right:
PS C:\> Get-Verb | Format-Wide -AutoSize
Add           Clear         Close         Copy         Enter        Exit         Find         Format       Get
Hide          Join          Lock          Move         New          Open         Optimize     Pop          Push
Redo          Remove        Rename        Reset        Resize       Search       Select       Set          Show
Skip          Split         Step          Switch       Undo         Unlock       Watch        Backup       Checkpoint
Compare       Compress      Convert       ConvertFrom  ConvertTo    Dismount     Edit         Expand       Export
Group         Import        Initialize    Limit        Merge        Mount        Out          Publish      Restore
Save          Sync          Unpublish     Update       Approve      Assert       Complete     Confirm      Deny
Disable       Enable        Install       Invoke       Register     Request      Restart      Resume       Start
Stop          Submit        Suspend       Uninstall    Unregister   Wait         Debug        Measure      Ping
Repair        Resolve       Test          Trace        Connect      Disconnect   Read         Receive      Send
Write         Block         Grant         Protect      Revoke       Unblock      Unprotect    Use

Microsoft has provided a nice page on the verb naming rules which can be found here.
The commands you use in cmd.exe can also be used within PowerShell since they are either aliased, new functions, or the external executable is called.
  • dir is an alias for Get-ChildItem
  • md is an alias for mkdir which is a function for New-Item
  • rmdir is an alias for Remove-Item
Some easy commands that just work:
  • Get-Process
  • Get-Service
  • Get-Date
  • Get-HotFix
  • Get-History
  • Start-Transcript, Stop-Transcript
  • Get-ChildItem
Now you may be wondering why the names seem so generic. The idea is that if the names are consistent then you can easily discover new commands. In addition, some commands can be reused in multiple areas such as managing the registry and filesystem. Here is a good example with Get-PSDrive:
PS C:\> Get-PSDrive

Name           Used (GB)     Free (GB) Provider      Root                                               CurrentLocation
----           ---------     --------- --------      ----                                               ---------------
Alias                                  Alias
C                  81.37        151.42 FileSystem    C:\
Cert                                   Certificate   \
E                                      FileSystem    E:\
Env                                    Environment
Function                               Function
HKCU                                   Registry      HKEY_CURRENT_USER
HKLM                                   Registry      HKEY_LOCAL_MACHINE
I                1112.16        305.87 FileSystem    \\chs-fs01_users\Users\Michael.West
Variable                               Variable
WSMan                                  WSMan
Y                   8.88          3.12 FileSystem    \\chs\data

PowerShell uses a variety of providers such as those for connecting to the file system and the registry. This design allows one to use for example, the Remove-Item command to delete a file or delete a registry key. Sweet!
PS C:\> $item = New-Object -TypeName PSObject -Property @{Name="Michael";Height=73;}
PS C:\> $item | Format-List

Height : 73
Name   : Michael

Here I created a new PSObject to contains some details about my name and height. Let's see the member information.
PS C:\> $item | Get-Member

   TypeName: System.Management.Automation.PSCustomObject

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
Height      NoteProperty System.Int32 Height=73
Name        NoteProperty System.String Name=Michael

As you can see, the TypeName is "System.Management.Automation.PSCustomObject" and the new properties "Name" and "Height" are listed. The object type will be relevant to whatever object is piped in to Get-Member.

Gets the Windows PowerShell drives in the current session.
# Displays details about the local disk C.
Get-PSDrive C
Random fact:
Try this: (Get-PSDrive)[0].Name <# Returns the name of the first object. #>
Try this: (Get-PSDrive)[0].GetType() <# Returns the type of the first object. #>
Sets the current working location to a specified location.
# Changes the location to the registry hive HKEY_LOCAL_MACHINE. The colon is required.
Set-Location HKLM:

PS C:\> Set-Location HKLM:
PS HKLM:\> Set-Location C:
PS C:\> Set-Location Alias:
PS Alias:\> dir | more

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Alias           % -> ForEach-Object
Alias           ? -> Where-Object
Alias           ac -> Add-Content
Alias           asnp -> Add-PSSnapin
Alias           cat -> Get-Content
Alias           cd -> Set-Location
Alias           chdir -> Set-Location
Alias           clc -> Clear-Content
Alias           clear -> Clear-Host
Alias           clhy -> Clear-History
Alias           cli -> Clear-Item
As you can see in the image above, I changed to the registry, then the C drive, then to Alias. In all of these locations, you can run the standard commands such as dirlscd and so on. In the image you can also see that cd is an alias for Set-Location.
Below are some command aliases common in other environments.
Copy-Itemcpi, cp, copy
ForEach-Objectforeach, %
Get-ChildItemdir, ls
Get-Contentgc, type, cat
Get-Locationgl, pwd
Move-Itemmi, mv, move
Rename-Itemrni, ren
Set-Locationcd, chdir
Where-Objectwhere, ?
Remove-Itemri, rd, del, rm, rmdir
Random fact:
To count the number of items return, use Measure-Object. Use additional switch parameters such as -Sum and -Average.
Try this: Get-Process | Measure-Object <# Returns a table with the results of Measure-Object. #>
Try this: (Get-Process | Measure-Object).Count <# Returns the count value. #>
Gets the content of the item at the specified location.
# Reads the entire contents of the file.
Get-Content -Path C:\log.txt
Adds content to the specified items, such as adding words to a file.
# Appends the text to the file log.txt.
Add-Content -Path C:\log.txt -Value "The quick brown fox jumps over the lazy dog."
Sends output to a file.
# The first command takes a snapshot of all the running processes. 
# The list passed through pipeline to Out-File which is then written to log.txt.
Get-Process | Out-File -FilePath C:\log.txt
Writes customized output to a host. The information is not kept in the pipeline.
# The text is written to the console window.
Write-Host "This text is written to the host, such as the console window."
Sends the specified objects to the next command in the pipeline. If the command is the last command in the pipeline, the objects are displayed in the console.
# The snapshot of running processes is saved into the variable p. The variable p is then written to the console window.
$p = Get-Process; Write-Output -InputObject $p
The text is written to the verbose message stream. This is commonly used in PowerShell scripts.
# The text is written to the verbose stream. If the switch -Verbose is used, the text will be written to the console window.
Write-Verbose -Message "The quick brown fox jumps over the lazy dog."

Creates a new item. The item can be a new registry key, file, directory, etc. The type of item created depends on which provider you are connected to.
# A new file is created with the specified text.
New-Item -Path C:\ -Name log.txt -ItemType "file"
New-Item -Path C:\log.txt -ItemType "file" -Value "The quick brown fox jumps over the lazy dog."