2014-12-05

Breaking into PowerShell

 
Notes for climbing the steep PowerShell learning curve...


Commonly used cmdlets (use Get-Alias to get the list of all aliases):
  • Get-ChildItem. Aliases: ls, dir, and gci
  • Get-Content. Aliases: cat, gc, and type
  • Get-Help. Using the option -full will output examples of use for the cmdlet in question.
  • Get-WmiObject. Alias: gwmi. In PowerShell 1.0 it was largely the only way to access remote computers.
  • Format-List. Effectively reverse rows and columns (in output).
  • Get-Location. Aliases: pwd and gl
  • Get-Member. Alias: gm
  • Get-Process. Aliases: gps and ps
  • Group-Object. Alias: group
  • Measure-Command. For timing.
  • Measure-Object. Alias: measure
  • New-Item. Alias: ni (and mkdir with parameter -ItemType "Directory"). For instance, create a new file, new folder or registry entry.
  • New-Object.
  • Out-GridView. Open GUI window with the fields as columns and objects as rows. The columns can be interactively sorted and the clipboard works with the usual shortcut Ctrl + C, including disjoint selected rows!. Alias: ogv 
  • Select-Object. Effectively choose another subset of fields from an object than the default (e.g. for the ultimate goal of an output). Alias: select
  • Set-Location. Sets the current working location. Aliases cd, chdir, and sl
  • Sort-Object. Alias: sort
  • Test-Path. Test if the syntax for a path is correct. Useful when dealing with user input.
  • Where-Object. Used to filter (get a subset of piped objects). A common idiom is Where-Object {$_ -match '\d{3}[-|\s]\d{3}[-|\s]\d{3}$'}, where what is between the two single quotes is a regular expression. Aliases: where and ?
  • Write-Output. If the command is the last command in the pipeline, the objects are displayed in the console. Aliases: echo and write

wc

Equivalent to Linux' wc (used on a directory listing in this example):


  Get-ChildItem | Measure-Object | Select-Object -ExpandProperty Count

Using aliases:

  dir | measure | select -ExpandProperty Count


Example: get desired information from the running processes on the computer

Get-Process returns a (very long) list of running processes on the computer. Assume we are interested in the processes that take up a lot of memory and that are potentially leaking (Private Bytes is the proper quantity for this). First explore the different kind of values with Get-Member:

  Get-Process | Get-Member

The field "PrivateMemorySize" seems to be what is called "Private Bytes".

Use Where-Object to only get the subset of processes that take up more than about 1 MB:

  Get-Process | Where-Object {$_.PrivateMemorySize -gt 1000000}

This returns some processes with eight different kinds of fields (or at least that is how it appears in the output on the screen), but not private bytes. Say we still want the process ID and process name, but also private bytes and the full path to the executable. Use Select-Object to get those four fields instead of the eight defaults (the four names are from the output of Get-Member, above):

  Get-Process | Where-Object {$_.PrivateMemorySize -gt 1000000} | Select-Object Id, PrivateMemorySize, Name, Path

We can sort by any of the four fields:

  Get-Process | Where-Object {$_.PrivateMemorySize -gt 1000000} | Select-Object Id, PrivateMemorySize, Name, Path | Sort-Object -Property PrivateMemorySize

When this is output to the screen, it is way too wide. To get more readable output we can effectively reverse rows and columns with Format-List:

  Get-Process | Where-Object {$_.PrivateMemorySize -gt 1000000} | Select-Object Id, PrivateMemorySize, Name, Path | Sort-Object -Property PrivateMemorySize | Format-List

Alternatively, we can get the output into a GUI window using cmdlet Out-GridView:

  Get-Process | Where-Object {$_.PrivateMemorySize -gt 1000000} | Select-Object Id, PrivateMemorySize, Name, Path | Sort-Object -Property PrivateMemorySize | Out-GridView

The GUI window is quite sophisticated. For instance, using Add criteria, all instances of svchost can be excluded from the displayed processes.


Using aliases and the fact that the parameter to Sort-Object is positional, it can be shortened to:

  ps | where {$_.PrivateMemorySize -gt 1000000} | select Id, PrivateMemorySize, Name, Path | sort PrivateMemorySize | Format-List

and

  ps | where {$_.PrivateMemorySize -gt 1000000} | select Id, PrivateMemorySize, Name, Path | sort PrivateMemorySize | ogv

, respectively.
 
On my system the last items in the output was:

Id                : 448
PrivateMemorySize : 56143872
Name              : powershell
Path              : C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe

Id                : 3636
PrivateMemorySize : 90882048
Name              : CCC
Path              : C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static\ccc.exe

Id                : 4952
PrivateMemorySize : 349118464
Name              : opera
Path              : D:\Program Files (x86)\Opera1051\opera.exe

Id                : 2648
PrivateMemorySize : 630624256
Name              : firefox
Path              : D:\Program Files (x86)\Mozilla Firefox27\firefox.exe

Firefox took up 601 MB, the Opera web browser 332 MB, some videodisplay thingy 87 MB and PowerShell itself 54 MB.