Getting Started (PowerShell)
Installation
Subject specific useful links are listed in the sections below, the following provide links to installers and general documentation
- Windows PowerShell V1
- Windows PowerShell V2
- http://powershell.com/cs/ - Good all-round help
- http://technet.microsoft.com/en-us/library/bb978526.aspx - TechNet!
Whilst Win2008 ships with Powershell it isn't necessarily available, to install...
- Go to Server Manager
- Go into Features, then Add Features
- Tick Windows Powershell, and then Next
Normally a restart isn't required
If you're running scripts from a machine that does not have (or has dodgy) internet access, you need to disable certificate checking
- In Internet Explorer
- Go to Internet Options, and then Advanced
- Then under Security uncheck Check for publisher's certificate revocation
Execution Policy
On the first run you need to allow Powershell to scripts (you need to run this command as an administrator, so if you're using Windows 7, for example, you'll need to start the Powershell console as an administrator, regardless of whether you're currently logged in as an admin). If you have no admin rights over the PC you're using, then you'll need to select the Suspend option rather than Yes (sets just for your current session, doesn't try to write to the registry).
Set-ExecutionPolicy RemoteSigned
It is possible to bypass the Execution Policy entirely (though you do so at your own risk, should only be used to run a script you trust where you haven't the time to fix the underlying problem, and should be reverted afterwards)...
Set-ExecutionPolicy Bypass
Installed Version
To check the main installed version use either of the following command lines...
Get-Host | Select version
$host.version
However, if you might have installed something other than the normal RTM or GA release version you'll need to the registry key HKLM\Software\Microsoft\PowerShell\1
, which will have the following values of interest...
Value | Data | Meaning |
---|---|---|
Install |
1 |
Installed (not version number - Microsoft may have intended this to be a version marker at inception, but it is not used as such) |
PID |
89383-100-0001260-04309 |
RTM (Release to Manufacturing) |
PID |
89393-100-0001260-00301 |
RC2 (Release Candidate 2) |
For more info on release version acronyms, see Software Release Life Cycle
Help Commands
Get-Help <cmd> # Provides help for CmdLets, use wildcards to broaden results.
$object | Get-Member # Provides information about an object (variable)
$object.gettype() # Provides variable type info (string, array, etc)
Conditional Operators
Comparison
Operator | Description |
---|---|
-eq |
Equal to (implied case insensitive) |
-ieq |
Equal to (case insensitive) |
-ceq |
Equal to (case sensitive) |
-lt |
Less than |
-gt |
Greater than |
-ge |
Greater than or Eqaul to |
-le |
Less than or equal to |
-ne |
Not equal to |
-match |
Match (ie string contains) anywhere within string (can be regex) |
-notmatch |
Does not match (ie string contains) (can be regex) |
-like |
Like (ie string is), stricter than match (can be regex) |
-notlike |
Not like (ie string is not) (can be regex) |
Logic
Operator | Description |
---|---|
-not |
Not |
! |
Not |
-and |
And |
-or |
Or |
Useful One-Liners
Command | Description |
---|---|
Get-Content <file-path> | Out-GridView |
Display (log)file in the nice Grid View window |
(Get-Location -PSProvider FileSystem).ProviderPath |
Current working directory |
$MyInvocation.MyCommand.Name |
Current script or function name (if in a function) |
$host.UI.RawUI.WindowTitle = "Wibble" |
Change command shell title (to Wibble) |
PowerShell Process
To get information about the current running PowerShell session process, use...
$proc = [System.Diagnostics.Process]::GetCurrentProcess()
...from which you can get all sorts of performance and other metrics such as total CPU time taken, various memory usage metrics and so forth. Which can be useful if you have a script that you want to run continuously, but you want to be able to monitor that its behaving (no excessive CPU usage or memory leaking).
The object type returned by the above is exactly the same as is returned by Get-Process
.
Process Priority
In order to change the priority of the current PowerShell process, use...
( [System.Diagnostics.Process]::GetCurrentProcess() ).PriorityClass = "NewPriority"
...where NewPriority is any of (though I'd recommend limiting to either BelowNormal or AboveNormal)...
Priority | Description |
---|---|
Idle | Only runs when system is idle, which may mean that the process never gets enough execution time to do anything useful. |
BelowNormal | Ensures that the process will yield to most other processes running on the system (good for background tasks).
By default, scheduled tasks run as Below Normal (in Win2008, and maybe others) |
Normal | Default - recommended for most tasks |
AboveNormal | Ensures that most other processes running on the system will yield to the PowerShell process (good for urgent, high priority tasks). |
High | Process will try to run immediately. Can lead to a system having constant high CPU and sluggish overall performance. |
RealTime | Process overrides all other processes (including system tasks). Can lead to an unresponsive, locked out system unless process has been specifically written to run in RealTime mode, or will only run for a very brief period. |
If you run scripts that can be CPU intensive, and/or run for a long time. This can lessen the impact on your desktop or server (wherever the script is running).
To check the current priority of your shell or script use...
( [System.Diagnostics.Process]::GetCurrentProcess() ).PriorityClass
Scripts
Include Files
In order to include another Powershell script in a parent script, use a .
and then the path to the file (there's a space between them), eg
. .\lib\include_file.ps1
Script Arguments
In order to be able to parameters to a script the $args
variable can be used. Each argument is provided within the array in order, eg
# 1st param is send yes or no
# 2nd param is email address
if ($args[0]) {
Write-Host "Email sending enabled...!"
Write-Host "Will send to" $args[1]
} else {
Write-Host "Email sending disabled."
}
So for example...
[PS > ./params.ps1 0 Email sending disabled. [PS > ./params.ps1 1 test@abc.com Email sending enabled...! Will send to test@abc.com
Logging
The easiest way to setup logging from with a script is to use the Transcript functionality which will log all output to a transcript file. Note that Write-Host
only places line feeds at the end of lines, not carriage returns, therefore Notepad will display such output as one long line. You'll need to use an editor that can handle lines only terminated by LF's (WordPad if you can't install anything, otherwise get something better, eg http://www.scintilla.org/SciTE.html).
Start-Transcript -Path C:\Users\name\Scripts\script.log -Append -NoClobber
# script
Stop-Transcript
Call External Process
Running an external executable is a bit of a faff, but it can be done...
$cmd = "rrdtool.exe update $rrd $updates"
$proc_res = &$executioncontext.InvokeCommand.NewScriptBlock($cmd)
Slow Start-Up
PowerShell isn't the fastest thing in the world to start, the fact that a basic PowerShell command prompt uses of 50MB of RAM gives some indication that its not lean and mean (but once up and running, and when running efficient script it can be very fast). However if its taking minutes rather than seconds to start then there is something going wrong.
Normally this is due to the fact that the machine you're running from has no (or limited) internet access. To workaround the problem you need to disable Certificate Revocation Checking...
- In Control Panel, open Internet Options
- Go to the Advanced tab, and scroll down to the Security section
- Untick the Check for publisher's certificate revocation
There is no increased security risk imposed by doing this on a machine with no/limited internet access, as the checks were previously timing-out and being bypassed anyway.