Windows PowerShell Workshop

An introduction workshop to Windows PowerShell 2.0
created by on 2012-04-30

Agenda


Disclaimer

I am not a PowerShell expert.

Please take everything you’ll see in this document with a grain of salt 😉


Introduction to PowerShell


What is PowerShell?

Screenshot of the Windows PowerShell Console 2.0

Screenshot of the Windows PowerShell Console 2.0


Terminology


Shell- vs. Scripting-Languages

(Command-Line) Shell

Scripting Languages


Common features of command-line shells


Examples of command-line shells


Examples: UNIX Shells


Examples: Windows Shells (1)

Screenshot of the Windows Command-Line cmd.exe


Examples: Windows Shells (2)

Screenshot of the Cygwin GNU Bash


Examples: Browser Shells

Screenshot of the Google Chrome Developer Tools Console

Screenshot of the Firebug Command-Line for Firefox


Why PowerShell?


PowerShell Version History


The Future of PowerShell


Links


What is so special about PowerShell?


Getting Started with PowerShell


Online Resources about PowerShell


Installation & Startup


PowerShell Command-Line (1)

If you are running a recent version of Windows you will have PowerShell already installed:

Start > Accessories > Windows PowerShell

Screenshot of the PowerShell tool in the Windows Start menu under Start>Accessories>Windows PowerShell


PowerShell Command-Line (2)

Screenshot of the Windows PowerShell Console 2.0


PowerShell ISE / Debugger (1)

If don’t have the PowerShell debugger installed you can add it via the Windows Features dialog:

Server Management > Features > Add Feature > “Windows Integrated Scripting Environment (ISE)”

Screenshot of the Server Managment Feature Dialog for installing the Windows PowerShell Integrated Scripting Environment / Debugger on Windows Server 2008 R2 64bit


PowerShell ISE / Debugger (2)

Screenshot of the Windows PowerShell Integrated Scripting Environment (ISE) - The PowerShell Debugger.


PowerShell Installation Directory

The PowerShell executables are located in the folder:

%windir%\System32\WindowsPowerShell\v1.0

Screenshot of the Windows PowerShell installation directory under %windir%\System32\WindowsPowerShell\v1.0


PowerShell Security Settings (1)

By default, PowerShell will not allow you to run scripts. Not external ones and not even your own scripts.

“The execution policy is part of the security strategy of Windows PowerShell. It determines whether you can load configuration files (including your Windows PowerShell profile) and run scripts, and it determines which scripts, if any, must be digitally signed before they will run.”

In order to overcome this restriction we must change PowerShells security policy (“execution policy”).

Screenshot of a PowerShell window displaying a security warning


PowerShell Security Settings (2)

In order to be able to run (unsigned) PowerShell scripts and configuration files you need to set the ExecutionPolicy to “RemoteSigned”:

PS> Get-ExecutionPolicy

PS> Set-ExecutionPolicy RemoteSigned

Screenshot of a Windows PowerShell window where the execution policy has been changed from Restricted to RemoteSigned

Links


Workshop Preparations


Configuring Mercurial

For this workshop we are going to use Mercurial to distribute the course material and in order to track and exchange changes.

Start PowerShell (Start > Accessories > Windows PowerShell) and enter the following command:

PS> notepad $Home\Mercurial.ini

Then enter the following text and then save the changes:

[ui]
username = Your Name <[email protected]>
verbose  = True

[Extensions]
purge =

Screenshot of the Mercurial profile with a set set username


Fetching the workshop material

In order to get a copy of the PowerShell workshop material please clone my mercurial repository and create a branch that is named after you.

Start PowerShell

PS> mkdir $Home\Desktop\dev | Set-Location
PS> hg clone http://andyk.dyndns-server.com:8000 PowerShell-Workshop
PS> Set-Location PowerShell-Workshop
PS> hg branch "YourName"
PS> hg push --new-branch

Core Elements of PowerShell


Key Points about PowerShell


Features of the PowerShell console (1)

The PowerShell console is based on cmd.exe and has basically the same features, but also some that cmd.exe and other shells are missing:

Tab Completion: Enter a command partially and then hit the TAB-key in order to let PowerShell complete the command


Features of the PowerShell console (2)

Evaluation of basic expressions

Screenshot of expression evaluation feature of the PowerShell console

F7 Command History: As in cmd.exe the key pops up a command history window

Screenshot of the PowerShell command history feature which is displayed when the user hits th F7 key


PowerShell Syntax


PowerShell Command Structure

A PowerShell command consists of:

PowerShell Command Structure: Command Name, Switch Parameter(s), Command Parameter(s) and Command Argument(s)


PowerShell Command Syntax

PowerShell commands, called cmdlets [speak: command-lets], use verb*-noun pairs in order to be self-descriptive.

Note: Windows PowerShell uses the term verb to describe a word that implies an action even if that word is not a standard verb in the English language. For example, the term New is a valid Windows PowerShell verb name because it implies an action even though it is not a verb in the English language.

Examples

Links


Common Verbs and their meaning (1)

Here is a list of the most common verbs used for PowerShell commands:

VerbDescriptionCounterpart
AddAdds a resource to a container, or attaches an item to another item.Remove
ClearRemoves all resources from a container but does not delete the container.
CloseChanges the state of a resource to make it inaccessible, unavailable, or unusable.
CopyCopies a resource to another container.
EnterSpecifies an action that allows the user to move into a resource.Exit
ExitSets the current environment or context to most recently used context.Enter
FindLooks for an object in a container that is unknown, implied, optional, or specified.
FormatArranges objects in a specified form or layout.
GetSpecifies an action that retrieves a resource.Set
HideMakes a resource undetectable.Show
JoinCombines resources into one resource.Split
LockSecures a resources.Unlock
NewCreates a resource.
OpenChanges the state of a resource to make it accessible, available, or usable.Close
PopRemoves an item from the top of a stack.Push
PushAdds an item to the top of a stack.Pop

Common Verbs and their meaning (2)

VerbDescriptionCounterpart
RedoResets a resource to the state that was undone.
RemoveDeletes a resource from a container.Add
RenameChanges the name of a resource.
ResetSets a resource back to its original state.
SearchCreates a reference to a resource in a container.
SelectLocates a resouces in a container.
SetReplaces data on an existing resource or creates a resources that contains some data.Get
ShowMakes a resource visible to the user.Hide
SkipBypasses one or more resources or points in a sequence.
SplitSeperates parts of a resource.Join
StepMoves to the next point or resources in a sequence.
SwitchSpecifies an action that alternates between two resources, such as to change between two locations, responsibilities, or states.
UndoSets a resource to its previous state.
UnlockReleases a resource that was locked.Lock
WatchContinually inspects or monitors a resource for changes.

For more examples and PowerShell development guidelines please refer to the MSDN documentation:


Variables

Variables defined by a leading dollar sign ($):

PS> $someVariable = "Some Content"

All variables can be accessed through a PowerShell provider/drive called “variable:”

PS> cd variable:
PS> dir
PS> get-item someVariable

Screenshot of a PowerShell Console window which defined a new variable and accesses it through the variable: PowerShell drive provider


Quotes (1)

Text in PowerShell is marked by ‘single’- or “double”-quotes. If a command name or argument contains whitespace or other special characters, you must wrap the value in single or double quotes. Otherwise the command-interpreter cannot bind the parameters and arguments correctly.

Missing Quotes

Missing quotes might lead to errors if the command argument contains whitespace characters:

PS> Set-Location .\Program Files (x86)

Screenshot of a PowerShell console where the correct quoting is missing for a set-location command


Quotes (2)

Single Quotes

PS> Set-Location '.\Program Files (x86)'

Screenshot of a PowerShell console using single quotes for the set-location command

Double Quotes

PS> Set-Location ".\Program Files (x86)"

Screenshot of a PowerShell console using double quotes for the set-location command


Backtick Escape Character (1)

Since PowerShell is a Shell that needs to support Windows-style file systems, it cannot use the usual backslash () for escaping characters with a special meaning, but uses the backtick character instead (`):

Escape SequenceCorresponding Special Character
`nNewline
`rReturn
`tTab
`aAlert
`b<Backspace>
`'Single Quote (')
`"Double Quote (")
`0Null
``A single backtick (`)

Example: New-Line

PS> Write-Host "Line1`nLine2"

Screenshot of the PowerShell console using the new-line escape sequence for the Write-Host command


Backtick Escape Character (2)

Example: Tab

PS> Write-Host "Key:`tvalue"

Screenshot of the PowerShell console using the tab escape sequence for the Write-Host command

Example: Double Quotes

PS> $value = "Lorem Ipsum"
PS> Write-Host "Key:`"$value`""

Screenshot of the PowerShell console using the double quote escape sequence for the Write-Host command


Statement Termination (1)

PowerShell has two statement termination characters: the semicolon (;) and sometimes the newline (\r\n). If the previous text is a syntactically complete statement, a newline is considered to be a statement termination. If it isn’t complete, the newline is simply treated like any other whitespace.

Example: Defining an array accross multiple lines

PS> $someArrayContainingNumbers = @(1,2,
PS> 3,
PS> 4,
PS> 5,6
PS> ,7
PS> ,8,
PS> 9,0)
PS>

Screenshot showing array which spreads several lines in the PowerShell console


Statement Termination (2)

Example: Foreach loop

PS> foreach ($number in $someArrayContainingNumbers) {
PS>    Write-Host "The Number is: $number"
PS> }
PS>

Screenshot showing a foreach loop which spreads several lines in the PowerShell console


Statement Termination (3)

Example: Using expressions and semicolons for multi-line statements

PS> $a = (1 + 2) *
PS> 3
PS> $b = 4;
PS> $a + $b
PS>

Screenshot showing the use of expressions and semicolons for multi-line statements in the PowerShell console


Statement Termination (4)

Example: Using double quotes to start a multi-line statement

PS> Write-Host "Multi-Line:
PS> Line 1
PS> Line 2
PS> Line 3"
PS>

Screenshot showing the use of double quotes for multi-line statements in the PowerShell console


Statement Termination (5)

Example: Using the backtick character (`) for bypassing the statement termination

PS> Get-ChildItem `
PS> -Path .\Users\Administrator `
PS> -Filter *.ini
PS>

Screenshot showing the use of the backtick (`) character for bypassing the statement termination in the PowerShell console


PowerShell’s Built-in Help


The Get-Help Command (1)

PowerShell has a built-in help command that can provide a lot of information and about the different PowerShell commands and the scripting language itself - just like the Unix man pages.

CommandDescription
get-help *Display all available help topics
get-help get-*Display all help topics that begin with "get-"
get-help *SomeString*Display topics with "SomeString" in the name
get-help set-locationDisplays help about the "set-location" cmdlet
get-help set-location -examplesDisplays examples on how to use the "set-location" cmdlet
get-help set-location -detailedDisplay additional information about a cmdlet, including descriptions of the parameters and examples of using the cmdlet.
get-help set-location -fullDisplay the entire help file for a cmdlet, including technical information about the parameters.
get-help about*Display conceptual help topics
get-help about_functionsDisplays conceptual help about "functions"
get-help about_switchDisplay conceptual help about "switch" statements

The Get-Help Command (2)

PS> get-help

Screenshot of the PowerShell console displaying the result of the get-help command


The Get-Help Command (3)

Using the get-help command together with the “-examples” switch to display some example usages of the “set-location” cmdlet:

PS> get-help set-location -examples

Screenshot of the PowerShell console displaying the results of the get-help set-location -examples command


The Get-Help Command (4)

The PowerShell Get-Help cmdlets returns objects not just plain text, but full help objects on which you can access any property you like:

PS> (get-help set-location) | Get-Member

Screenshot of the PowerShell console displaying the properties of a help object


The Get-Help Command (5)

Using the “syntax” property of an help object to display only the syntax section of a help result:

PS> (get-help set-location).Syntax

Screenshot of the PowerShell console displaying the results of the (get-help set-location).Syntax command


PowerShell Commands


Command Types

There are four kinds of command Windows PowerShell can execute:

  1. Cmdlets [command-lets]

    .NET programs that are designed for PowerShell
  2. Scripts (*.ps1)

    Scripts/Functions that live on the disk
  3. Functions

    Scripts/Function that live only in memory
  4. Executables

    All executable programs that are accesible through the PATH) variable (e.g. notepad.exe)

Common Commands/Cmdlets

The most common commands/cmdlets are the ones you would also use to in your classical Windows cmd.exe command line:


Retrieving a list of Commands (1)

In order to to get full list of all available comands you can use the “get-command” cmdlet:

PS> get-command

Screenshot of the PowerShell console displaying the result of the get-command cmdlet


Retrieving a list of Commands (2)

You can also use wildcards to search for commands for specific commands.

Get all commands that start with “write-”:

PS> get-command write-*

Screenshot of the PowerShell console displaying the result of the get-command write-* command


Retrieving a list of Commands (3)

Get all commands that have the term “item” in the name:

PS> get-command *item*

Screenshot of the PowerShell console displaying the result of the get-command write-* command


Command Aliases


Command Aliases (1)

Since most of these command name are all following the verb-noun syntax, they are self-explanatory but also kind of verbose.

Examples of verbose commands:

And thats why PowerShells comes with a large set of predefined aliases.


Command Aliases (2)

Comand aliases are concise shortcuts to existing commands that enable you


Command Aliases (3)

These are some of the alias that are used frequently:

AliasCommandAlias Type
cdSet-LocationTransitional (Windows)
dirGet-ChildItemTransitional (Windows)
lsGet-ChildItemTransitional (UNIX)
clsClear-HostTransitional (Windows)
gcGet-ContentConvenience
typeGet-ContentTransitional (Windows)
catGet-ContentTransitional (UNIX)
mkdirNew-Item -type directoryTransitional (Windows)
rmRemove-ItemConvenience
delRemove-ItemTransitional (Windows)
rmdirRemove-ItemTransitional (Windows)
copyCopy-ItemTransitional (Windows)
cpCopy-ItemTransitional (Unix)
fmFormat-ListConvenience
gmGet-MemberConvenience
foreachForeach-ObjectConvenience
whereWhere-ObjectConvenience

Command Aliases (4)

To get a full list of all aliases use the get-alias command:

PS> get-alias

Screenshot of the PowerShell console displaying the result of the get-alias command


Command Aliases (5)

For getting all aliases for a specific command use the definition-parameter for the get-alias command:

PS> get-alias -definition Remove-Item

Screenshot of the PowerShell console displaying the result of the get-alias -definition command for the remove-item command

If you need more background information about PowerShell aliases, please refer to the PowerShell online help:

PS> get-help about_aliases

PS> get-help get-alias

Command Aliases (6)

Elastic Syntax

The idea of the command aliases is that PowerShell can be terse when needed and descriptive when appropriate.
The syntax is concise for simple cases and can be stretched like an elastic band for larger problems.

This is important in a language that is both a command-line tool and a scripting language.

**Rules for using command aliases **


PowerShell Providers


PowerShell Providers (1)

PowerShell providers are .NET programs that make serialized data available through a filesystem-drive like format.
These drives are called PowerShell Drives or short PSDrives.

Screenshot of a Windows PowerShell console displaying the use of the IIS PowerShell Provider/Drive


PowerShell Providers (2)

Windows PowerShell comes with a number of built-in providers / PowerShell drives that you can use to access many different types of data stores.

ProviderDriveData Store
AliasAlias:Windows PowerShell aliases
CertificateCert:x509 certificates for digital signatures
EnvironmentEnv:Windows environment variables
FileSystemC:, D:, ...File system drives, directories, and files
FunctionFunction:Windows PowerShell functions
VariableVariable:Windows PowerShell variables
RegistryHKLM:, HKCUWindows registry

Example: Navigation to the “Variable”-drive

PS C:\Users\Administrator> cd variable:
PS Variable:\> dir

Screenshot of a Windows PowerShell console displaying the use of the variable: PowerShell drive


PowerShell Providers (3)

You can retrieve a list of all available PowerShell providers with the Get-PSProvider command:

PS> get-psprovider

Screenshot of a Windows PowerShell console displaying the result of the get-psprovider command


PowerShell Providers (4)

You can retrieve a list of all available PowerShell drives with the Get-PSDrive command:

PS> get-psdrive

Screenshot of a Windows PowerShell console displaying the result of the get-psdrive command


PowerShell Providers (5)

These are the cmdlets that will work for any PowerShell provider / drive.


Pipelines


Pipelines (1)

A pipeline is a series of commands connected by pipeline operators (|).
Each pipeline operator sends the results of the preceding command to the next command.

Send the objects that are returned by one command to be used as input to another command:

PS> Command-1 | Command-2 | Command-3

Each command in the pipeline receives an object from the previous command, performs some operation on
it, and then passes it along to the next command in the pipeline.

Anatomy of a PowerShell pipeline (source: Payette, Bruce; PowerShell in Action)


Pipelines (2)

Example: Formatting the results of the Get-ChildItem cmdlet

Sending the results of the dir/get-childitem command directly to the format-table command - displaying only the file name and the directory of the found files.

PS> dir -Recurse -Filter *.ps1 | Format-Table Name,Directory

Screenshot of a PowerShell console showing the result of a PowerShell command pipeline: dir -Recurse -Filter *.ps1 | Format-Table Name,Directory


Pipelines (3)

Example: Filtering the result of the Get-Process cmdlet

Using the Where-Object cmdlet to display only the process with the desired name (e.g. “chrome”).

PS> Get-Process | Where-Object { $_.ProcessName -eq "chrome" }

Screenshot of a PowerShell console showing the result of a PowerShell command pipeline: Get-Process | Where-Object { $_.ProcessName -eq chrome }


Output Redirection


Output Redirection

By default, Windows PowerShell sends all output to the console, but like all shell languages PowerShell has the ability to direct the output to a text file instead.


Output Redirection Example


Output Redirection: Example (1)

Content of myScript.ps1

Screenshot showing the content of the someScript.ps1 PowerShell script

$fileName = "test.txt"


"Fetching file (`$fileName = $fileName)."
if (!(Test-Path $fileName))
{
    "This will cause an error, because a file with the
    name '$fileName' does not exist in the current folder"
}

Get-Item $fileName

Output Redirection: Example (2)

PS> .\myScript.ps1

Screenshot showing the result of the someScript.ps1 PowerShell script

When you execute the script “someScript.ps1” you will get a result which looks something like you can see in the screenshot above:

  1. The message “Fetching file …”
  2. The message “This will cause an error …” because the file “test.txt” does not exist
  3. An error caused by the get-item command

Output Redirection: Example (3)

Now you can redirect the output of the script to a file with the “>” operator:

PS> .\someScript.ps1 > ..\output-of-someScript.txt

Screenshot showing the output of the someScript.ps1 PowerShell script which is redirected to a text file whereas the errors are printed to the console window


Error Redirection Example


Error Redirection: Example (1)

In order to redirect only the error messages to a file you can use the “2>” operator:

PS> .\someScript.ps1 2> ..\output-of-someScript.txt

Screenshot showing the result of the someScript.ps1 PowerShell script in the console window whereas the error is redirected to a text file


Error Redirection: Example (2)

With the “2>&1” operator you can force PowerShell to redirect error messages to the normal success-output-stream.

PS> .\someScript.ps1 > ..\output.txt

Screenshot showing the result of the


Error Redirection: Example (3)

Output that would normally be redirected to the console window (error stream) is now treated as if it was normal output and is sent to the success stream (output.txt):

PS> .\someScript.ps1 > ..\output.txt 2>&1

Screenshot showing the result of the


Output Redirection vs. Pipelines

Whats is the difference between Pipelining and Output Redirection?

Pipeline equivalent for the > Operator

PS> someScript.ps1 > output.txt

PS> someScript.ps1 | Out-File -Path output.txt

Pipeline equivalent for the >> Operator

PS> someScript.ps1 >> output.txt

PS> someScript.ps1 | Out-File -Path output.txt -Append

Output Redirection: Resources

Resources about output- and error-redirection and pipelines:


Variables


Variables: Overview (1)

A variable is a unit of memory in which values are stored.


Variables: Overview (2)


User-created variables

Screenshot showing user-created variables from the PowerShell profile in a PowerShell session via the get-variable cmdlet



Automatic Variables

Automatic variables are created by Windows PowerShell and are used to store its state.

Variable Description
$$ Contains the last token in the last line received by the session.
$? Contains the execution status of the last operation. It contains TRUE if the last operation succeeded and FALSE if it failed.
$^ Contains the first token in the last line received by the session.
$_ Contains the current object in the pipeline object.
$Args Contains an array of the undeclared parameters and/or parameter values that are passed to a function, script, or script block.
$Error Contains an array of error objects that represent the most recent errors.
$False Contains FALSE.
$ForEach Contains the enumerator of a ForEach-Object loop.
$Home Contains the full path of the user's home directory.
$Host Contains an object that represents the current host application for Windows PowerShell.
$LastExitCode Contains the exit code of the last Windows-based program that was run.
$Matches The $Matches variable works with the -match and -not match operators.
$MyInvocation Contains an object with information about the current command, such as a script, function, or script block.
$NULL Contains a NULL or empty value.
$PID Contains the process identifier (PID) of the process that is hosting the current Windows PowerShell session.
$Profile Contains the full path of the Windows PowerShell profile for the current user and the current host application.
$PsHome Contains the full path of the installation directory for Windows PowerShell, typically, %windir%\System32\WindowsPowerShell\v1.0.
$Pwd Contains a path object that represents the full path of the current directory.
$This In a script block that defines a script property or script method, the $This variable refers to the object that is being extended.
$True Contains TRUE. You can use this variable to represent TRUE in commands and scripts.

Preference Variables

Windows PowerShell includes a set of variables that enable you to customize its behavior. These “preference variables” work like the options in GUI-based systems.

Example: $OFS - The Default Space Character

By default the $OFS variable is set to a single whitespace character (” “):

PS> $data = 1,2,3,4,5,6,7,8,9
PS> [string] $data
1 2 3 4 5 6 7 8 9

But you can change the value if you like:

PS> $OFS = ","
PS> $data = 1,2,3,4,5,6,7,8,9
PS> [string] $data
1,2,3,4,5,6,7,8,9

For more information about preference variables use the PowerShell help:

PS> get-help about_Preference_Variables

Working with Variables (1)

Use the get-variable cmdlet to get a list of all variables in your current PowerShell session:

PS> get-variable

Screenshot showing the results of the get-variable command


Working with Variables (2)

Use wildcards for the get-variable cmdlet to search for variables:

PS> get-variable p*

Screenshot showing the results of the get-variable p* command with wildcards

PS> get-variable -Name p* -Exclude ps*

Screenshot showing the results of the get-variable -Name p* -Exclude Ps* command with wildcards


Working with Variables (3)

Use can use the Variable PowerShell Provider to access variables.

PS C:\Users\Administrator> set-location variable:
PS Variable:\> dir

Screenshot of a PowerShell console displaying the contents of the Variable: PowerShell drive


Working with Variables (4)

You can use the Environment PowerShell Provider to access the variables from the $env scope:

PS C:\Users\Administrator> set-location Env:
PS Env:\> dir

Screenhot of a PowerShell console displaying the content of the Env: PowerShell drive


Working with Variables (5)

Or you can access environment variables with their scope modifier “$env:”.

PS C:\Users\Administrator> set-location $env:SystemRoot
PS C:\Windows\>

Sample usage of the $env:SystemRoot environment variable


Variables: Resources


Operators


Arithmetic Operators

Screenshot showing the use of arithmetic operators in the PowerShell console


Assignment Operators

PowerShell supports all the compound operators that are found in C-based languages such as C#.


Comparion Operators

These are the comparison operators that are supported by PowerShell.

By default, all of these operators are case insensitive. But there is also and case sensitive versions for each operator.
For more information please refer to the help section:


Pattern Matching Operators

Wildcards

Regular Expression Matching

Regular Expression Replacement


Flow Control


Flow Control: If/Else Statement

The syntax of the PowerShell if-statement based on the C-syntax:

if (<condition>)
{
    <statement list>
}
elseif (<condition>)
{
    <statement list>
}
else
{
    <statement list>
}

Which two exceptions:


Flow Control: Switch Statement

The switch statement is the most powerful statement in the PowerShell language.

It combines

all into a single control structure.

Syntax

switch -option (value)
{
    <pattern>
    {
        <statement list>
    }

    default
    {
        <statement list>
    }
}

Flow Control: While Loop

Again, the while loop has the same syntax as in most C-based languages:

while (condition)
{
    <statement list>
}

Example

$index = 0
while($val -ne 3)
{
    $index++
    write-host "The number is $index"
}

Screenshot of a simple while loop in the PowerShell console


Flow Control: Do-While Loop

The do-while loop follows the same structure like the while loop:

do
{
    <statement list>
}
while (condition)

Example

$index = 0
do
{
    $index++
    write-host "The number is $index"
}
while ($val -ne 3)

Screenshot of a simple do-while loop in the PowerShell console


Flow Control: For-Loop

The for loop is the basic counting loop in PowerShell. It’s typically used to step though a collection of objects.

It’s not used as often in PowerShell as in other languages because there are frequently better ways of processing a collection (see: foreach).

Syntax

for (<initialization pipeline>; <test pipeline>; <increment pipeline>)
{
    <statement list>
}

Example

$numbers = 1..10
for ($index = 0; $index -lt $numbers.Length; $index++)
{
    Write-Host "$numbers[$index]"
}

Screenshot of a simple for loop in the PowerShell console


Flow Control: Foreach Loop

This statement of the PowerShell foreach loop is syntactically identical to the C# foreach loop with the exception that you don’t have to declare the type of the loop variable.

Syntax

foreach (<variable> in <collection>)
{
    <statement list>
}

Example

$numbers = 1..10
foreach ($entry in $numbers)
{
    Write-Host $entry
}

Screenshot of a simple foreach loop in the PowerShell console


Fuctions


Functions (1): Syntax

Functions are one of the four command types supported by PowerShell.

Syntax

function <name> (<parameter list>)
{
    <statement list>
}

Calling Functions

Functions are called like cmdlets.

PS> SampleFunction -ParameterName1 Value1 -ParameterName2 Value2

Functions (2): Example

Example

function Hello ($Name = "World")
{
    "Hello $name"
}

PS> Hello -Name PowerShell
Hello PowerShell

PS> Hello
Hello World

Screenshot of the Hello Sample function


Functions (3): Function Provider

Function PowerShell Provider

You can access all function in your current PowerShell session via the Function-provider.

PS C:\Users\Administrator> set-location function:
PS Function:\> dir

Screenshot of a PowerShell console showing the contents of the Function: PowerShell Drive


Functions (4): Named Parameters

There are two ways of specifying parameters for functions.

Using the Braces:

function SayHallo-To ($name)
{
    "Hallo $name"
}

Using the Param keyword:

function SayHallo-To
{
    param($name)

    "Hallo $name"
}

Both ways are fine. You can use the syntax that you prefer. I prefer the latter.


Functions (5): Parameter Types

By default you don’t have to specify the types of parameters in PowerShell, but it can be useful sometimes.

function DaysTillBirthday([DateTime] $Birthdate)
{
    $now = [DateTime]::Now
    $thisYearsBirthday = [DateTime] "$($now.Year)-$($Birthdate.Month)-$($Birthdate.Day)"

    $timespan = $thisYearsBirthday - $now

    if ($timespan.Days -gt 0)
    {
        "$($timespan.Days) days to go"
    }
    else
    {
        "It's been $($timespan.Days) days ago"
    }
}

DaysTillBirthday -Birthdate "1983-05-13"

Functions (6): Parameter Default Values

PowerShell allows you to specify default values for parameters.

function dayOfWeek ([DateTime] $date = $(get-date))
{
    $date.dayofweek
}

PS> dayOfWeek -date "2012-05-07"
Monday

If you don’t specify the date parameter the function will use the result of the “get-date” cmdlet:

PS> dayOfWeek
Tuesday

Screenshot of PowerShell function making use of default values for function parameters


Functions (6): Switch Parameters

A switch is a parameter that does not require a value and is either $true or $false.

function game ([switch] $on)
{
    if ($on) {
        "Game on!"
    }
    else {
        "Car"
    }
}

PS> game -on

Screenshot of simple function showing the use of a Powershell switch parameter

Game On


Functions (7): Positional Parameters

Positional Paramters are parameters withour a parameter name. You can access them using the $args array.

function implode
{
    [string]::join(",", $args)
}

PS> implode 1 2 3 4 5

Screenshot of a function making use of positional arguments


Functions (8): Return Values

Unlike other programming languages, PowerShell does not require a return statement in its functions.
A PowerShell function will automatically return the results of every statement that isn’t captured.

Example: A function which returns a text

function Sample
{
    "This is the result of the Sample function"
}

Functions (9): Return Values

Example: A function which uses the return statement to exit early

function Sample ([switch] $noReturnValuePlease)
{
    if ($noReturnValuePlease) {
        return
    }

    "This is the result of the Sample function"
}

Screenshot of a function that makes use of the return statement to exit the function early


Functions (10): Resources


Types


Basic Types


Arrays

Arrays in PowerShell are simply defined by using a comma (,).

PS> $arrayOfNumbers = 1,2,3,4,5

They are origin-zero:

PS> $arrayOfStrings = "Value 1", "Value 2", "Value 3"
PS> $arrayOfStrings[0]
"Value 1"

The size can be determined using the Length property:

PS> $letters = "a", "b", "c"
PS> $number.Length
3

Empty arrays can be specified like this:

PS> $emptyArray = @()
PS> $emptyArray.Length
0

Hashtables (1)

PowerShell Hashtables relate to the .NET System.Collections.Hashtable type.

You can create them using hash literals:

PS> $keyvaluestore = @{ Key1 = "Value1"; Key2 = "Value "; Key3 = "Value 3" }
$keyvaluestore

Screenshot of a simple PowerShell Hashtable

You can get a list of all the key in a hashtable by using the “Keys” collection:

PS> $keyvaluestore.Keys

Using the Keys property of a hashtable


Hashtables (2)

You can also iterate over all the values of a hashtable using the “Values” collection:

PS> $keyvaluestore.Values

Using the Values property of a hashtable

And of course you can use the indexer notation to access a single value:

PS> $keyvaluestore["Key1"]

Using indexer notation to access a single value of a hashtable


Hashtables (3)

And you can also set the values of hashtable:

PS> $keyvaluestore["Key1"] = "New Value"
PS> $keyvaluestore["Key4"] = "Value4"
PS> $keyvaluestore.Key5 = "Value 5"

Modifing the contents of an existing hashtable


Using .NET Types

PowerShell allows you to use any .NET type that is available in your GAC.

Example:

PS> (new-object System.Net.WebClient).DownloadString("http://www.google.com")

Scripts


PowerShell Scripts

You can execute PowerShell Scripts from your command line like this:

PS> .\someScript.ps1

You can pass arguments to a PowerShell script in the same way you do it for functions.

Positional script arguments

PS> .\someScript.ps1 Argument1 Argument2

Named script arguments

PS> .\someScript.ps1 -ParameterName1 "Parameter Value 1"

Lessons


Debugging with PowerShell ISE

Live-Demo

Screenshot of a debugging session with PowerShell ISE


PowerShell Community Extensions


Installing the Community Extensions (1)

The PowerShell Community extensions (PSCX) are a PowerShell module that adds a lot of useful cmdlets to PowerShell:

and many more …


Installing the Community Extensions (2)

Instructions

  1. Create a PowerShell Profile if you don’t have one yet

    if ((Test-Path $Profile) -eq $false)
    {
    New-Item $Profile -Type file -Force | Out-Null
    }

    explorer (Split-Path $profile -parent)

  2. Extract the PSCX archive (“Pscx-2.0.0.1.zip”) into your PowerShell Profile Directory

    C:\Users\Administrator\Documents\WindowsPowerShell\Modules

  3. Add an import statement to your PowerShell profile

    Import-Module Pscx -arg “$(Split-Path $profile -parent)\Modules\Pscx\Pscx.UserPreferences.ps1”

  4. Restart PowerShell


Installing the Community Extensions (3)

Take the PowerShell Community Extension for a spin:

Links


Reading/Writing XML with PowerShell (1)

PowerShell supports XML documents as a primitive data type.

Sample XML

<Settings>
    <Entry id="1">Value 1</Entry>
    <Entry id="2">Value 2</Entry>
    <Entry id="3">Value 3</Entry>
</Settings>

Reading XML

[xml] $xml = Get-Content sample.xml
foreach ($setting in $xml.Settings.Entry)
{
    Write-Host "$($setting.psbase.InnerText) (Id: $($setting.Id))"
}

Screenshot of the PowerShell console executing the reading-xml.ps1 script


Reading/Writing XML with PowerShell (2)

Writing XML

# Read XML
[xml] $xml = Get-Content sample.xml

# Create new node
$newEntry = $xml.CreateElement("Entry")
$newEntry.psbase.InnerText = "Value 4"

# Create new node attribute
$idAttribute = $xml.CreateAttribute("id")
$idAttribute.psbase.Value = "4"

# Assign new attribute to new node
$newEntry.SetAttributeNode($idAttribute)

# Append new node
$xml.Settings.AppendChild($newEntry)

# Save XML (Note: Use absolute paths for XML.Save())
$targetFile = Join-Path "$(Get-Location)" "sample-extended.xml"
$xml.save($targetFile)

Reading/Writing XML with PowerShell (3)

Screenshot of the PowerShell console executing the writing-xml.ps1 script


Customizing the PowerShell Console


Customizing the PowerShell Console (1)

Since PowerShell is hosted in the same console windows as the good old cmd.exe, it will look exactly like good old cmd.exe if you start it using the PowerShell.exe.

Screenshot of an un-customized PowerShell console window


Customizing the PowerShell Console (2)

If you want the same look and feel you get, if you open the PowerShell from a shortcut or your Windows start menu …

Screenshot of an PowerShell console window with the classic PowerShell look

… you can assign your desired console window style in your personal PowerShell profile.


Customizing the PowerShell Console (3)

Open your PowerShell profile in a text editor:

PS> notepad $profile

Then add the following code to your PowerShell profile:

$consoleUi = (Get-Host).UI.RawUI

# Set Colors
$consoleUi.BackgroundColor = "DarkBlue"
$consoleUi.ForegroundColor = "White"

# Set Window Size
$width = 120
$height = 50

$consoleBufferSize = $consoleUi.BufferSize
$consoleBufferSize.Width = $width + 10
$consoleBufferSize.Height = $height * 10
$consoleUi.BufferSize = $consoleBufferSize

$consoleWindowSize = $consoleUi.WindowSize
$consoleWindowSize.Width = $width
$consoleWindowSize.Height = $height
$consoleUi.WindowSize = $consoleWindowSize

# Set Window Title
$consoleUi.WindowTitle = "PowerShell"

# Apply Changes
Clear-Host

Customizing the PowerShell Console (4)

Screenshot showing the how the PowerShell customization code can be added to the PowerShell profile


Customizing the PowerShell Console (5)

Screenshot showing a customized PowerShell console


Filesystem Watcher


Creating a file-system watcher (1)

You can easily create a file-system watcher utilizing existing .NET functionality:

$currentDirectory = (Get-Item $MyInvocation.InvocationName).Directory.FullName
$watchFolder = Join-Path $Home "Desktop"
$filter = "*.*"

$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = $watchFolder
$watcher.IncludeSubdirectories = $false
$watcher.EnableRaisingEvents = $true
$watcher.Filter = $filter

$changed = Register-ObjectEvent $watcher "Changed" -Action {
    $pathOfChangedFile = ($eventArgs.FullPath)
    $fileNameOfChangedFile = (Get-Item $pathOfChangedFile).Name
    $fileNameOfChangedFileWithoutExtension = (Get-Item $pathOfChangedFile).BaseName
    $folder = (Get-Item $pathOfChangedFile).Directory.FullName

    Write-Host "$fileNameOfChangedFile just changed"
}

Creating a file-system watcher (2)

Every time the content of an file on the users Desktop changed the script will write the message:

"file-xy.txt just changed"

Screenshot of the PowerShell file-changed watcher in action


Creating functions for accessing the Clipboard


Clipboard access (1)

In this lesson we are going to extend your personal PowerShell profile with function for reading and writing from and to the clipboard.

What it the PowerShell Profile

The Windows PowerShell profile is simply a script file that runs when you start Windows PowerShell. All functions defined in this script will be automatically available in your new PowerShell session.
The location of your PowerShell profile is stored in the $PROFILE variable:

PS> $profile
C:\Users\Administrator\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

Screenshot of Windows PowerShell Console displaying the content of the $profile variable


Clipboard access (2)

You can edit your profile script by entering:

PS> notepad $profile

In case you don’t have a profile script you will get a message like this:

$profile does not exist


Clipboard access (3)

In order to create the profile script and open it with notepad enter this command:

PS> notepad (New-Item $PROFILE -Type file -force)

Create a PowerShell Profile and edit it with notepad

Everything that you add to this script will be executed when you launch a new instance of PowerShell.


Clipboard access (4)

In order to open the directory of the profile script you can enter:

PS> explorer (Get-Item $PROFILE).Directory

PowerShell command for opening the PowerShell $profile directory in the Windows Explorer


Clipboard access (5)

Now you can add the functions for reading and writing to and from the Windows Clipboard to your personal PowerShell profile:

new-alias Out-Clipboard $env:SystemRoot\system32\clip.exe

function Get-ClipboardText()
{
    Add-Type -AssemblyName System.Windows.Forms
    $tb = New-Object System.Windows.Forms.TextBox
    $tb.Multiline = $true
    $tb.Paste()
    $tb.Text
}

Start a new instance of PowerShell and verify that your functions have been applied correctly:

PS> Get-Command *Clipboard*

Screenshot of a PowerShell console displaying the two new functions for reading and writing from and to the Windows Clipboard: Get-ClipboardText and Out-Clipboard


Clipboard access (6)

And now you can take your new functions “Get-ClipboardText” and “Out-Clipboard” out for a spin:

PS> Get-Content $Profile | Out-Clipboard
PS> dir | Out-Clipboard
PS> Get-Process | Out-Clipboard

Links


Working with files and folders

tbd


Parsing Text Files

e.g. parsing log files


Accessing SQL Databases

tbd


Using the Web Administration Module


Writing a custom Cmdlet

tbd


Creating a customer PowerShell Drive

tbd


Using .NET DLLs


Signing PowerShell Scripts

tbd


Creating a custom open-folder command

tbd

Shortlink:
Tags:
Fork allmark on GitHub