0% found this document useful (0 votes)
74 views488 pages

PSITP v4 Part2 v1.4

Uploaded by

affy1977
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
74 views488 pages

PSITP v4 Part2 v1.4

Uploaded by

affy1977
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 488

PowerShell v4.

0 for the IT
Professional
Part 2
Meet your trainer
<Trainer Name>
<Position, Location>
<[email protected]>
<other links>

Microsoft Confidential Microsoft Confidential 2


Introductions About You

• Name

• Company Affiliation

• Title/Function/Area of Responsibility

• Product experience

• Expectations for this Course

Microsoft Confidential Microsoft Confidential 3


Workshop Schedule Workshop Duration: 3 Days

Start: 9:00am

Break: As Needed

Lunch: Target Noon

Break: As Needed

End: 5:00pm

Microsoft Confidential Microsoft Confidential 4


Agenda

Module 1: Review of Part 1 Concepts


Day 1 Module 2: Remoting
Module 3: Advanced Functions 1
Module 4: Advanced Functions 2
Day 2 Module 5: Regular Expressions (Regex)
Module 6: Error Handling
Module 7: Debugging
Day 3 Module 8: Introduction to Desired State Configuration (DSC)
Module 9: Introduction to Workflow

Microsoft Confidential 5
2012R2-DC 2012R2-MS WIN8-WS

Lab Windows Server 2012 R2 Windows Server 2012 R2 Windows 8.1

Environment Core

Domain Controller Domain Member Domain Member


Server Workstation

10.0.1.200 10.0.1.210 10.0.1.220

Domain Name Contoso.com


Domain NetBIOS Name Contoso

Admin Account Username Administrator User Account Username DanPark


Password PowerShell4 Password PowerShell4

Microsoft Confidential
Conditions and Terms of Use
Microsoft Confidential
This training package is proprietary and confidential, and is intended only for uses described in the training materials. Content and software is provided to you under a
Non-Disclosure Agreement and cannot be distributed. Copying or disclosing all or any portion of the content and/or software included in such packages is strictly
prohibited.
The contents of this package are for informational and training purposes only and are provided "as is" without warranty of any kind, whether express or implied,
including but not limited to the implied warranties of merchantability, fitness for a particular purpose, and non-infringement.
Training package content, including URLs and other Internet website references, is subject to change without notice. Because Microsoft must respond to changing
market conditions, the content should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information
presented after the date of publication. Unless otherwise noted, the companies, organizations, products, domain names, e-mail addresses, logos, people, places, and
events depicted herein are fictitious, and no association with any real company, organization, product, domain name, e-mail address, logo, person, place, or event is
intended or should be inferred.

Copyright and Trademarks


© 2013 Microsoft Corporation. All rights reserved.
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as
expressly provided in written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights,
or other intellectual property.
Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced,
stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any
purpose, without the express written permission of Microsoft Corporation.
For more information, see Use of Microsoft Copyrighted Content at
http://www.microsoft.com/about/legal/permissions/
Microsoft®, Internet Explorer®, Outlook®, OneDrive®, Windows Vista®, Zune®, Xbox 360®, DirectX®, Windows Server® and Windows® are either registered
trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. Other Microsoft products mentioned herein may be either registered
trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. All other trademarks are property of their respective owners.
Agenda

Module 1: Review of Part 1 Concepts


Module 2: Remoting
Module 3: Advanced Functions 1
Module 4: Advanced Functions 2
Module 5: Regular Expressions (Regex)
Module 6: Error Handling
Module 7: Debugging
Module 8: Introduction to Desired State Configuration (DSC)
Module 9: Introduction to Workflow

Microsoft Confidential 8
Module 1: Review of Part 1
Concepts

Module Overview

Microsoft Confidential 9
Windows PowerShell Introduction

Task-based command-line shell and scripting language, built on the .NET framework,
designed especially for system administration

Helps IT professionals and power users control and automate the administration of the
Windows operating system and applications that run on Windows.

Has an interactive console & and Integrated Scripting Environment (ISE)

Microsoft Confidential 10
PowerShell Versions
No 1.0 1.0 as Update 2.0 2.0 as 3.0 3.0 as 4.0 4.0 as
PowerShell Update Update Update
(WMF) (WMF) (WMF)
XP
2003
Vista
2008
2008R2
Win7
Win8
2012
Win8.1
2012R2

WMF: Windows Management Framework


Grouping of several management related tools such as PowerShell, BITS, and the WinRM service
Microsoft Confidential 11
PowerShell Commands

PowerShell can run external commands/built-in cmdlets


Cmdlet syntax is made of
• Command name
• Required parameters and values
• Optional parameters and/or values

Stop-Service -Name Spooler -Force

Command Command
Name Parameters

Microsoft Confidential 12
PowerShell Commands Cont.

Every cmdlet has common parameters PowerShell provides.


Example: -Outvariable, -ErrorAction, -Verbose
-WhatIf & -Confirm switch parameters are present on many cmdlets
Get-Command shows you external & PowerShell commands
Get-Help assists with cmdlets, concepts, examples, etc.
Aliases save time typing & help transition

Microsoft Confidential 13
PowerShell Commands Continued

Scriptblocks are statements in braces

{Get-Process}

Functions are reusable, named scriptblocks

function GetEveryProcess
{
Get-Process
}
Microsoft Confidential 14
PowerShell Remoting Basics
Allows running commands against remote machine(s)
Types of remoting:
• Temporary
Invoke-Command -ComputerName 2012R2-DC `
–Credential contoso\administrator `
-ScriptBlock {Get-Culture}

• Persistent
New-PSSession -ComputerName 2012R2-DC –OutVariable ps
Invoke-Command –Session $ps -ScriptBlock {Get-Culture}

• Interactive:
Enter-PSSession -ComputerName 2012R2-DC

Microsoft Confidential 15
PowerShell Pipeline
The pipeline is a chain of cmdlets that passes objects

Initial pipeline input provided by:


• Get-* & Import-* cmdlets, text files & external commands

Pipeline objects are manipulated using:


• Sort-*, Select-*, Group-*, Measure-Object, cmdlets & more

Pipeline output via:


• Format-* cmdlets (should always be last)
• Export-* cmdlets
• Out-* cmdlets
• Variables
Microsoft Confidential 16
PowerShell Pipeline Continued
$_ or $PSItem refer to the current pipeline object
Get-ChildItem | Where-Object { $psitem.Length –gt 1MB }

Alternatively, create a custom pipeline variable using –PipelineVariable


Get-Process -PipelineVariable CurrentProcess |
Where-Object {$CurrentProcess.ws -gt 100MB}

Where-Object has a simple syntax (new to v3)


Get-ChildItem | Where-Object { $_.Length –gt 1MB }
Get-ChildItem | Where-Object Length -gt 1MB

Individual parameters can take pipeline input by value/property name

Microsoft Confidential 17
Scripts

A collection of statements or expressions within a text file with a .ps1 extension

Scripts can be run in either the Windows PowerShell console, ISE or launched
externally from cmd.exe

The Param() statement enables the script to accept input parameters

Microsoft Confidential 18
Scripts (Continued)

Execution Policy defines permissions for running scripts

The default execution policy restricts Windows PowerShell from running any scripts
• Restricted
• Unrestricted
• AllSigned
• RemoteSigned
• Bypass

Policy can be applied at five separate scopes:


• GPO (User or Computer), Process, Registry (current user or all users)

Microsoft Confidential 19
Scripts (Continued)
Comments are extra annotation added purely for readability of script:
# single-line comment
<#
multi-line
comment
#>

Windows PowerShell has some special comments:


• #Requires ensures a script has what it needs to run
#Requires -Version 4.0 -RunAsAdministrator
• Regions make code sections collapsible
#region
#endregion
• Comment-based help keywords can be placed in functions/scripts for cmdlet like help

The Windows PowerShell ISE includes features such as:


• IntelliSense, AutoSave, Brace Matching, Collapsible code, Rich copy, etc.
Microsoft Confidential 20
Help System
In the ISE, highlight or click on a cmdlet/about_ topic, then press F1 for a help window

PS v3.0+ doesn’t ship help content. It must be updated.

Modules often ship with help, but can also be updated

Updating help can be done with or without internet access:


Update-Help
Save-Help –DestinationPath \\Server\Share
Update-Help –SourcePath \\Server\Share

-SourcePath parameter can be pre-defined in a Group Policy Object (GPO)

Microsoft Confidential 21
Objects

Everything in Windows PowerShell is an object

Objects consist of properties & methods (members), defined in a type

An object is an instance of a type

The Get-Member cmdlet lists the type members of an object (properties and
methods)

Dot Notation is used to access an object’s members

Microsoft Confidential 22
Operators
Windows PowerShell provides operators for comparison and evaluation.

• Comparison (-eq, -ne, -contains,-like, -match, etc.) & case sensitive variants
• Logical (-and, -or, -not, -xor)

Microsoft Confidential 23
Operators continued

Number or Character ranges (1..5, a-z)

Numeric Multipliers (KB, MB, GB, TB, PB)

Arithmetic (+ , - , / ,* ,%)

Assignment (=, +=, -=, *=, /=, ++, --)

Microsoft Confidential 24
Operators continued

Bitwise
-bAnd, -bOr, -bNot, -bXor, -shl, -shr

Binary or Unary forms:


"Hello, World" –split ","
–split "Hello World"

Binary form only:


"Hello, World" –split ","
"Linux" –replace "Linux","Windows"

Format Operator (-f )


'{0:d4}' -f 4
Microsoft Confidential 25
Providers
A common interface to different data stores which is exposed as a file system
hierarchy

Drives allow providers to be accessed using classic naming C:, Cert:, Alias:

Get-PSProvider to list providers

Items can be manipulated using consistent cmdlets:


• *-Item, *-ItemProperty, *-Content, *-Path, *-Location, cmdlets

$<drive name>:<item name> is a quick way to access PSDrive items


• $env:COMPUTERNAME

Microsoft Confidential 26
Variables and Data Types
Variables reference objects

Two categories of variable:


• Built-in Variables
$Error, $HOME, $Host

• User defined Variables


$process = Get-Process

Cmdlets that manage variables


Get-Command -Noun variable

Microsoft Confidential 27
Variables and Data Types
"Double quotes" define an expandable string, ‘Single quotes’ define a literal string
$Number = 98052
"Expandable String $Number" Expandable String 98052
'Literal String $Number' Literal String $Number

Variable sub-expressions $(…) access an object’s property within strings

$b = Get-Service -Name BITS


"Service: $b.name" Service:
System.ServiceProcess.ServiceController.name
"Service: $ Service: BITS
($b.name)"

Microsoft Confidential 28
Variables and Data Types
Static members (methods & properties)
• Can be used without creating an instance of a type

[math] | Get-Member –Static


[math]::PI
[string]::Concat("abc","def")

Strongly typing a variable enforces its data type

[int]$var1 = 124
$var1 = "Fred"
Cannot convert value "Fred" to type "System.Int32".
Error: "Input string was not in a correct format."

Microsoft Confidential 29
Variables and Data Types

Type Operators:
• -is, -isnot : return True or False.
• -as : converts datatypes
"PSv4" -is [string]
"09/09/2014" -as [datetime]

The backtick, or escape character, ( ` ) is used for:


• Special characters
• Line continuation
• Literal characters in expandable strings

--% stops PowerShell from attempting to interpret input


Microsoft Confidential 30
Arrays
An array is a collection of objects (0, 1, or more)

Are created by:


• Assigning multiple values to a variable
• Using @()
• Cmdlets that return multiple values

Store objects starting at index 0: $array[0]

Return array size: $array.Count

Array concatenation: $array += 99

Microsoft Confidential 31
Arrays

Sorting
• sort pipeline output
$array | Sort-Object –Descending

• sort the array permanently


[array]::Sort($array)

Retrieving members (properties & methods)


Get-Member -InputObject $array #returns the array object’s members
$array | Get-Member #returns the members of elements within the array

Microsoft Confidential 32
Agenda

Module 1: Review of Part 1 Concepts


Module 2: Remoting
Module 3: Advanced Functions 1
Module 4: Advanced Functions 2
Module 5: Regular Expressions (Regex)
Module 6: Error Handling
Module 7: Debugging
Module 8: Introduction to Desired State Configuration (DSC)
Module 9: Introduction to Workflow

Microsoft Confidential 33
Module 2: Remoting

Module Overview

Microsoft Confidential 34
Module 2: Remoting

Section 1: Review of Remoting Basics Section 3: Security


• Lesson 1: What is Remoting? • Lesson 1: Constrained Session Configurations
• Lesson 2: Authentication Options
Section 2: Advanced Remoting Concepts • Lesson 3: SSL Listener/Endpoint
• Lesson 1: Implicit Remoting
• Lesson 4: Double-Hop Remoting
• Lesson 2: Serialized Objects
• Lesson 5: CredSSP
• Lesson 3: PSComputerName
• Lesson 4: Remoting on Public Networks
• Lesson 5: Disconnected Sessions
• Lesson 6: Remoting Variables
• Lesson 7: Modules & Remoting

Microsoft Confidential 35
Module 2: Remoting

Section 1: Review of Remoting Lesson 1: What is Remoting?


Basics

Microsoft Confidential 36
What is PowerShell Remoting?
Run commands on one or more remote computers
Utilize a temporary or a persistent connection, referred to as a session
A session connects to a runspace on the remote machine
A runspace is an instance of the PowerShell automation engine
Remote runspace capabilities can be constrained
Introduced in Windows PowerShell 2.0 and then enhanced in later versions

PS C:\>
Interactive (1:1)
PS C:\>

Run Command(s) (1:Many)


Temporary or Persistent Session(s) PS C:\>

Microsoft Confidential 37
Entry Point Transport Network
Resource-Specific
Cmdlets
Various Native OS Remoting
RPC
PowerShell WMI Cmdlets DCOM
Remote
Administration
Techniques CIM Cmdlets

CIM Sessions TCP/IP


CDXML Cmdlets Connection Settings
Only, Non-Stateful
WS-MAN
DSC Cmdlets

Workflows PSSessions
Stateful Connection
Remoting Cmdlets
Microsoft Confidential
Requirements

Local and Remote Computers


• PowerShell 2.0 or later (feature enhancements with newer versions)

PowerShell Remoting must be enabled on the target machine

Initiating user must be a member of the Local Administrators group on the remote
computer

Microsoft Confidential 39
Enabling Remoting using a Cmdlet

Use the Enable-PSRemoting PowerShell cmdlet

First, launch PowerShell with the "Run as administrator" option, then type:
PS C:\> Enable-PSRemoting

Microsoft Confidential 40
Enabling Remoting using a GPO
WinRM Service Automatic Startup
Allow remote server management (create listeners)

Optional Windows Firewall Inbound Rule

Microsoft Confidential 41
Windows Remoting Defaults

• Remoting is enabled on all 2012+ Server editions – Standard, Datacenter & Core
• Windows Remote Management (WinRM) Service running
• WS-Management (WSMan) protocol has an HTTP listener configured
• Inbound firewall rule for port 5985 is enabled (WsMan default listener port)

• Remoting is disabled on all client editions (WinXP – 8.1)


• Windows Remote Management (WinRM) Service disabled & stopped
• WS-Management (WSMan) protocol has no listener configured
• Inbound firewall rule for port 5985 is disabled

• Cross-version connection is possible (v2.0, v3.0, v4.0+)

Microsoft Confidential 42
Example: Interactive Session

PS C:\> Enter-PSSession -ComputerName 2012R2-DC


Remote
Computer

[2012R2-DC] PS C:\>

[2012R2-DC] PS C:\> Hostname


2012R2-DC Ending a session

[2012R2-DC] PS C:\> Exit-PSSession

Local Computer
PS C:\>

43
Example: Temporary Session

PS C:\> Invoke-Command -ComputerName 2012R2-DC –Credential contoso\


administrator -ScriptBlock {Get-Culture}

LCID Name DisplayName PSComputerName


---- ---- ----------- --------------
3081 en-AU English (Australia) 2012R2-DC

44
Example: Persistent Session

Step 1: Create a persistent session


PS C:\> $s = New-PSSession -ComputerName 2012R2-DC -Credential
Contoso\Administrator

Id Name ComputerName State ConfigurationName Availability


-- ---- ------------ ----- ----------------- ------------
1 Session1 2012R2-DC Opened Microsoft.PowerShell Available

Step 2: Use the session


PS C:\> Invoke-Command –Session $s -ScriptBlock {Get-Culture}

LCID Name DisplayName PSComputerName


---- ---- ----------- --------------
3081 en-AU English (Australia) 2012R2-DC

45
Module 2: Remoting

Section 2: Advanced Remoting Lesson 1: Implicit Remoting


Concepts

Microsoft Confidential 46
Implicit Remoting
"Feels" like a local session
command, but runs remotely

Local Functions "wrap" remote Use Import-PSSession or


invoke of command Import-Module –PSSession

Use of Invoke-Command is Implicit Several products like Exchange


implied, not explicit Remoting 2010+ use implicit remoting

Microsoft Confidential 47
Example: Import-PSSession

#Create Persistent Session


PS C:\> $Session = New-PSSession -ComputerName 2012R2-MS

#Import Remote Command and Automatically Create Local Function Wrapper


PS C:\> Import-PSSession -Session $session `
-CommandName Get-NetIPConfiguration -Prefix RemoteMS

ModuleType Version Name ExportedCommands

---------- ------- ---- ----------------

Script 1.0 tmp_way5tpwk.hxm Get-RemoteMSNetIPConfiguration

#Verify Imported Command


PS C:\> Get-Command get*IPConfig*

CommandType Name ModuleName

----------- ---- ----------


Function Get-NetIPConfiguration NetTCPIP

Function Get-RemoteMSNetIPConfiguration tmp_way5tpwk.hxm


Microsoft Confidential 48
Example: Import-Module -PSSession

#Create Persistent Session


PS C:\> $Session = New-PSSession -ComputerName 2012R2-MS

#Import Remote Module and Automatically Create Local Function Wrapper


PS C:\> Import-Module NetTCPIP -PSSession $Session -Prefix RemoteMS

#Verify Imported Module


PS C:\> Get-Module NetTCPIP
ModuleType Version Name ExportedCommands

---------- ------- ---- ----------------

Script 1.0 NetTCPIP {Find-RemoteMSNetRoute, Get-RemoteMSNetCompartment, Get-R...

Microsoft Confidential 49
Module 2: Remoting

Section 2: Advanced Remoting Lesson 2: Serialized Objects


Concepts

Microsoft Confidential 50
Object Serialization
• During remoting, objects are transmitted from a remote to a local session
• Serialization and de-serialization process occurs
• Some fidelity is lost. Methods are lost for non-basic types
• Basic Types typically de-serialize fully

Remote Type Style Object State


Enter-PSSession One-to-One • Output objects remain on remote system
(Interactive) • Formatting and Out cmdlets occur remotely
Invoke-Command One-to-One • Output objects transmitted to local session
One-to-Many • Formatting and Out cmdlets occur locally
Implicit Remoting One-to-One • Output objects transmitted to local session
• Formatting and Out cmdlets occur locally

Microsoft Confidential 51
Object
Serialization Invoke-Command

XML

This process is similar to using Export-CliXML and Import-CliXML


Example: Object De-Serialization

Note: Methods removed and de-serialized type name


PS C:\> Invoke-Command -ComputerName 2012R2-MS -ScriptBlock {Get-Service b*} |
Get-Member

TypeName: Deserialized.System.ServiceProcess.ServiceController

Name MemberType Definition

---- ---------- ----------

GetType Method type GetType()

ToString Method string ToString(), string ToString(stri...


Name NoteProperty System.String Name=BFE

PSComputerName NoteProperty System.String PSComputerName=2012R2-MS

...
CanPauseAndContinue Property System.Boolean {get;set;}

CanShutdown Property System.Boolean {get;set;}


Microsoft Confidential 53
CanStop Property System.Boolean {get;set;}
Module 2: Remoting

Section 2: Advanced Remoting Lesson 3: PSComputerName


Concepts

Microsoft Confidential 54
PSComputerName property
• During de-serialization, the PSComputerName property is added to all objects
• Identifies object source during One-to-Many remoting

PSComputerName Added to Objects


PS C:\> Invoke-Command -ComputerName 2012R2-MS -ScriptBlock {Get-Service b*}

Status Name DisplayName PSComputerName

------ ---- ----------- --------------

Running BFE Base Filtering Engine 2012R2-MS

Stopped BITS Background Intelligent Transfer Ser... 2012R2-MS

Running BrokerInfrastru... Background Tasks Infrastructure Ser... 2012R2-MS

Stopped Browser Computer Browser


Microsoft Confidential 2012R2-MS 55
Module 2: Remoting

Section 2: Advanced Remoting Lesson 4: Remoting on Public


Concepts Networks

Microsoft Confidential 56
Remoting on Public Networks
Remoting on public networks is a potential security risk
• PowerShell v2.0: Enable-PSRemoting fails if host is connected to a public network
• PowerShell v3.0+ on Client OS: use the –SkipNetworkProfileCheck parameter

To remove the public network location restriction on a Client OS:


PS C:\> Enable-PSRemoting –SkipNetworkProfileCheck

• PowerShell v3.0+ on Server OS: Enable-PSRemoting sets private and domain networks unrestricted,
but public networks are limited to the local subnet

To remove the local subnet restriction on Server OS:


PS C:\> Set-NetFirewallRule –Name "WINRM-HTTP-In-TCP-PUBLIC"
-RemoteAddress Any

Microsoft Confidential 57
Module 2: Remoting

Section 2: Advanced Remoting Lesson 5: Disconnected Sessions


Concepts

Microsoft Confidential 58
Disconnected Sessions

Remote PowerShell sessions can be re-connected, if interrupted

A timeout setting controls time-to-live of a disconnected session

This feature requires PowerShell v3.0+ on both sides

Microsoft Confidential 59
Disconnected Sessions Overview

Invoke-Command
-InDissconnectedSession

Get-PSSession
-ComputerName

Connect-PSSession
Receive-PSSession

Microsoft Confidential Microsoft Confidential 60


Managing Disconnected Sessions
Cmdlet Description
PS C:\> Invoke-Command –InDisconnectedSession Creates, then disconnects from a new session
PS C:\> Get-PSSession Lists local and remote sessions
PS C:\> Connect-PSSession Reconnects to a disconnected session
PS C:\> Receive-PSSession Reconnects and receives output
PS C:\> Disconnect-PSSession Disconnects a session

Invoke-Command –Computername RemotePC01 –Scriptblock {dir c:\} –InDisconnectedSession

$s = Get-PSSession –Computername RemotePC01


Connect-PSSession –Session $s
Receive-PSSession –Session $s #Receive will connect as well
Disconnect-PSSession –Session $s #Only when foreground not busy

NOTE: Another user can connect to PSSessions, but only if they can supply the credentials that were used to
create the initial session.
Microsoft Confidential 62
Session State
Id Name ComputerName State ConfigurationName Availability
-- ---- ------------ ----- ----------------- ------------
1 Session1 2012R2-MS Disconnected Microsoft.PowerShell None

Opened Runspace connected

State Local Session not


Relationship Between Local Disconnected
Session and Remote Runspace connected to Runspace

Connection to
Broken
Runspace lost
Microsoft Confidential 64
Session Availability
Id Name ComputerName State ConfigurationName Availability
-- ---- ------------ ----- ----------------- ------------
1 Session1 2012R2-MS Disconnected Microsoft.PowerShell None

Available Runspace is ready

Availability
Runspace not available
Ability for Remote Runspace None
to Accept Commands (not connected)

Busy Runspace is busy

Microsoft Confidential 65
Example: View Session State and Availability

PS C:\> New-PSSession -ComputerName 2012R2-MS

Id Name ComputerName State ConfigurationName Availability


-- ---- ------------ ----- ----------------- ------------
4 Session4 2012R2-MS Opened Microsoft.PowerShell Available

PS C:\> Disconnect-PSSession 4

Id Name ComputerName State ConfigurationName Availability


-- ---- ------------ ----- ----------------- ------------
4 Session4 2012R2-MS Disconnected Microsoft.PowerShell None

Microsoft Confidential 66
Example: Session State and Availability

This runspace is available for


re-connection

PS C:\> Get-PSSession -ComputerName 2012R2-MS


Id Name ComputerName State ConfigurationName Availability
-- ---- ------------ ----- ----------------- ------------
1 Session1 2012R2-MS Disconnected Microsoft.PowerShell None
2 Session2 2012R2-MS Disconnected Microsoft.PowerShell Busy
3 Session3 2012R2-MS Opened Microsoft.PowerShell Available

This runspace is performing


This is a connected remote work and has been
runspace disconnected

Microsoft Confidential 67
Robust Sessions

PowerShell 2.0
• Network issues may cause a remote PSSession to enter a "Broken" or "Closed" state

PowerShell 3.0+
• Remote Sessions remain in a "Connected" state for up to 4 minutes
• Progress bar indicates reconnection attempts
• Local session becomes "Broken" after 4 minutes
• Remote session becomes available for connection from anywhere, as the original user

When PowerShell is exited with an "Open" Session:


• If commands are running in the PSSession, it becomes "disconnected"
• If the PSSession is idle, it is terminated (similar to Remove-PSSession)

Microsoft Confidential Microsoft Confidential 68


Example: Connection Interruption

Progress Bar in ISE


and Console

PS C:\> Invoke-Command -ComputerName 2012R2-MS -ScriptBlock {


1..60 | Foreach {Write-Host "." -NoNewline ; Sleep -Seconds 1}}

.........WARNING: The network connection to 2012R2-MS has been interrupted.


Attempting to reconnect for up to 4 minutes...
WARNING: Attempting to reconnect to 2012R2-MS ...
WARNING: Attempting to reconnect to 2012R2-MS ...
WARNING: Attempting to reconnect to 2012R2-MS ...
WARNING: The network connection to 2012R2-MS has been restored.
...................................................

Microsoft Confidential 69
Disconnected Session Timeout
Disconnected sessions are maintained until removed or the Idle Timeout expires
• IdleTimeout property
• Default is 2 hours

-SessionOption parameter controls the timeout value for:


• Invoke-Command
• New-PSSession
• Disconnect-PSSession

New-PSSessionOption cmdlet creates an object to pass to –SessionOption parameter


• Change the timeout using Disconnect-PSSession –IdleTimeoutSec

Microsoft Confidential Microsoft Confidential 70


Module 2: Remoting

Section 2: Advanced Remoting Lesson 6: Remoting Variables


Concepts

Microsoft Confidential 71
$Using variable scope prefix
PowerShell 2.0
• Invoke-Command -Argumentlist parameter passes local variables to script blocks
• Script block required an embedded Param() statement
• Invoke-Command -ArgumentList arguments are bound by position

PowerShell 3.0+
• Implements a new variable scope prefix
• $Using:<local variable name>
• No Param() statement or -ArgumentList parameter required

$Using Variable Prefix


PS C:\> $eventLog = "Application"
PS C:\> Invoke-Command -ComputerName 2012MS -ScriptBlock {
Get-WinEvent -LogName $using:eventlog}

Microsoft Confidential 72
Module 2: Remoting

Section 2: Advanced Remoting Lesson 7: Modules and Remoting


Concepts

Microsoft Confidential 73
Remote Module Discovery and Import

• Get-Module can list modules on remote machines


• Import-Module can load modules from remote machines (Implicit Remoting)
• Optional noun prefix on imported commands
• PSSession or CIMSession (only for CIM Modules)

List remote modules over a PSSession


$ps = New-PSSession –ComputerName 2012DC
Get-Module –PSSession $ps -ListAvailable

Import remote modules over a PSSession


Import-Module –PSSession $ps –Name ActiveDirectory –Prefix REMOTE
Get-Module -Name ActiveDirectory
Get-REMOTEADUser user01

Microsoft Confidential 74
Example: Remote Module Import

#Create Persistent Session


PS C:\> $Session = New-PSSession -ComputerName 2012R2-MS

#List modules on remote system using PSSession


PS C:\> Get-Module -ListAvailable -PSSession $Session

ModuleType Version Name ExportedCommands


---------- ------- ---- ----------------

Manifest 2.0.0.0 AppLocker {Set-AppLockerPolicy, Test-App...


Manifest 2.0.0.0 Appx {Remove-AppxPackage, Add-AppxPacka...
Manifest 1.0 BestPractices {Get-BpaResult, Set-BpaResult, Invoke...
...
#Import Module (Implicit Remoting)
PS C:\> Import-Module -Name Storage -PSSession $Session -Prefix MS

#Run Imported Command (note prefix)


PS C:\> Get-MSDisk

Number Friendly Name OperationalStatus Total Size Partition Style

------ ------------- ----------------- ---------- ---------------


Microsoft Confidential 75
0 Virtual HD ATA Device Online 80 GB MBR
Module 2: Remoting

Section 3: Remoting Security Lesson 1: Creating Constrained


Session Configurations

Microsoft Confidential 76
Remoting Endpoints

Remoting clients target an "Endpoint" on the remoting server

The remoting endpoint is configurable

Use the *-PSSessionConfiguration cmdlets to manage endpoints

Endpoint capabilities can be limited


• Commands
• Permissions
• Language Security
• RunAs

Microsoft Confidential 77
Example: Viewing Remoting Endpoints

PS C:\> Get-PSSessionConfiguration

Name : microsoft.powershell
PSVersion
StartupScript
: 4.0
:
Default endpoint for remoting
RunAsUser :
Permission : BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed

Name : microsoft.powershell.workflow
PSVersion : 4.0
StartupScript :
RunAsUser : Used for remote workflows
Permission : BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed

Name : microsoft.powershell32
PSVersion : 4.0
StartupScript :
RunAsUser
Permission
:
32-bit remoting
: BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed

Name : microsoft.windows.servermanagerworkflows
PSVersion : 3.0
StartupScript :
RunAsUser :
Permission : NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed
Endpoint for Server Manager

Microsoft Confidential 78
Session Configuration Cmdlets
Session configuration management cmdlets:
Other Endpoint Cmdlets Purpose
Get/Set-PSSessionConfiguration View and edit registered endpoint(s)
Register/Unregister-PSSessionConfiguration Create new or remove endpoint(s)
Enable/Disable-PSSessionConfiguration Enable or disable registered endpoint(s)
New/Test-PSSessionConfigurationFile Create or test configuration file (for simplified setup)

Set-PSSessionConfiguration –RunAsCredential
• Endpoint can run in the context of another user
• Initial connection requires only a lower privileged, delegated account

Multiple remote sessions can run in the same wsmanprovhost.exe process


• Default is version 2.0 behaviour
Microsoft Confidential 79
Constrained Session Configuration

• New-PSSessionConfigurationFile cmdlet creates a new configuration file


• Cmdlet parameters control session behavior
• Configuration settings are stored in a .pssc file as a hashtable

Create a new session configuration file


PS C:\> New-PSSessionConfigurationFile `
-SessionType RestrictedRemoteServer `
-VisibleCmdlets "Get-Process","Get-EventLog" `
-LanguageMode ConstrainedLanguage `
-Path "$home\Documents\Session.pssc"

Microsoft Confidential 80
Endpoint Connection Permissions

Configure Endpoint Permission


PS C:\> Set-PSSessionConfiguration `
-Name myRestrictedConfig `
-ShowSecurityDescriptorUI

Microsoft Confidential 81
Overall Process for Constrained Endpoints
restricted.pssc
Create Session Configuration File
• New-PSSessionConfigurationFile -Path .\restricted.pssc -SessionType
RestrictedRemoteServer

Optional - Manipulate/View Configuration File

Associate Configuration File with New Remote Endpoint


• Register-PSSessionConfiguration -Path .\restricted.pssc -Name
myRestrictedConfig

Set Account Access Permissions / RunAsCredential


• Set-PSSessionConfiguration -Name myRestrictedConfig
-ShowSecurityDescriptorUI -RunAsCredential (Get-Credential)
Microsoft Confidential 82
Module 2: Remoting

Section 3: Remoting Security Lesson 2: Authentication Options

Microsoft Confidential 83
Authentication Mechanisms
Authentication Type Description Default Default
Endpoint (server) Client
Basic Username and Password sent (should use HTTPS) Disabled Enabled
(SSL required)
Digest Authentication exchange between client and server Not Supported Enabled
with digest session key used
Negotiate Windows integrated auth, Kerberos (preferred) or Enabled Enabled
NTLM
Kerberos Mutual authentication requiring a domain Enabled Enabled
Client Certificate- x.509 certificates public/private key authentication with Disabled Enabled
Based internal or internet PKI trust model
CredSSP Security Support Provider that allows credential Disabled Disabled
delegation
Configurable locally or via GPO

Microsoft Confidential 84
TrustedHosts

List of remote computers that are trusted

Computers in a workgroup, or different domain, should be added to allow


authentication

TrustedHosts are not authenticated

Client may send credential information to these computers

Microsoft Confidential 85
Example: Replace or Set TrustedHosts

# Replace or Set New Value


PS C:\> Set-Item -Path WSMan:\localhost\Client\TrustedHosts -Value WorkGroupPC

# Get current value


PS C:\> Get-Item -Path WSMan:\localhost\Client\TrustedHosts

WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Client

Type Name SourceOfValue Value


---- ---- ------------- -----
System.String TrustedHosts WorkGroupPC

Microsoft Confidential 86
Example: Append TrustedHosts

#Get current value


PS C:\> $trustedHosts = (Get-Item -Path WSMan:\localhost\Client\TrustedHosts).Value

#Append to current value


PS C:\> $trustedHosts += ",Server01.Domain01.Fabrikam.com"
PS C:\> Set-Item -Path WSMan:\localhost\Client\TrustedHosts –Value $trustedhosts

#Get new value


PS C:\> Get-Item -Path WSMan:\localhost\Client\TrustedHosts

WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Client

Type Name Value


---- ---- -----
System.String TrustedHosts WorkGroupMachine1,Server01.Domain01.Fabrikam.com

Microsoft Confidential 87
Example: Alternate Credentials (password typed interactively)

PS C:\> Invoke-Command -ComputerName 2012R2-MS -ScriptBlock {Hostname} `


-Credential contoso\administrator

2012R2-MS

PS C:\>

Microsoft Confidential 88
Example: Alternate Credentials - multiple uses (password typed interactively once)

PS C:\> $Creds = Get-Credential contoso\administrator

PS C:\> Invoke-Command -ComputerName 2012R2-MS -ScriptBlock {Hostname} `


-Credential $Creds
2012R2-MS

PS C:\> Enter-PSSession -ComputerName 2012R2-DC -Credential $Creds

[2012R2-DC]: PS C:\Users\Administrator\Documents> Hostname


2012R2-DC

[2012R2-DC]: PS C:\Users\Administrator\Documents> Exit-PSSession

Microsoft Confidential 89
Example: Alternate Credentials – Hardcoded Password (clear text)

# clear-text username and password


$Username = 'contoso\administrator'
$ClearPassword = 'PowerShell4'

# Convert clear password in SecureString


$SecurePassword = $ClearPassword | ConvertTo-SecureString -AsPlainText -Force

# Create credential object (same object that Get-Credential outputs)


$Cred = New-Object PSCredential -ArgumentList $Username,$SecurePassword

Invoke-Command -ComputerName 2012R2-MS -ScriptBlock {Hostname} -Credential $Cred

2012R2-MS

Warning: Anyone who gains access to this script gets the username and password
Microsoft Confidential 90
Example: Alternate Credentials – Hardcoded Password (Encrypted String)

#Run this line once manually on computer and user where script will run

PS C:\> $cred = Get-Credential contoso\administrator


PS C:\> $EncryptedString = $cred.Password | ConvertFrom-SecureString
PS C:\> $EncryptedString
01000000d08c9ddf0115d1118c7a00c04fc297eb0100000071f193d84290394f8...

#Place the encrypted string in your script


#It will only decrypt on machine/user that ran above lines
$EncryptedPassword = '01000000d08c9ddf0115d1118c7a00c04fc297eb0100000071...
$SecurePassword = $EncryptedPassword | ConvertTo-SecureString

$Username = 'contoso\administrator'
$Cred = New-Object PSCredential -ArgumentList $Username,$SecurePassword

Invoke-Command -ComputerName 2012R2-MS -ScriptBlock {Hostname} -Credential $Cred

2012R2-MS

Microsoft Confidential 91
Example: Alternate Authentication

PS C:\> Invoke-Command -Authentication Basic `


–Credential contoso\administrator -ComputerName 2012R2-MS `
-ScriptBlock {Hostname}

[2012R2-MS] Connecting to remote server 2012R2-MS failed with the following


error message : The WinRM client cannot process the request. Unencrypted
traffic is currently disabled in the client configuration. ...

PS C:\> Set-Item WSMan:\localhost\Client\AllowUnencrypted -Value $true

PS C:\> Invoke-Command -Authentication Basic `


-Credential contoso\administrator ` Basic auth fails over HTTP transport due to
-ComputerName 2012R2-MS ` client and server default settings. Password
-ScriptBlock {Hostname} would have been sent over wire in the clear.
If Basic needed, configure HTTPS
[2012R2-MS] Connecting to remote server 2012R2-MS failed with the following
error message : The WinRM client cannot process the request. The
authentication mechanism requested by the client is not supported by the
server or unencrypted traffic is disabled in the service configuration.
Verify the unencrypted traffic setting ...

Microsoft Confidential 92
Module 2: Remoting

Section 3: Remoting Security Lesson 3: SSL Listener/Endpoint

Microsoft Confidential 93
Example: First, Identify Certificate Thumbprint

Must have a certificate (typical SSL web server cert works)


• Installed in Local Computer/Personal (My)
• Key Usage must include: Server Authentication
• Must have PrivateKey
• Obtain through internal PKI or Public CA
#Identify possible certificates and get thumbprint value, this can be run remotely
$Filter = {$_.hasprivatekey -and $_.EnhancedKeyUsageList.FriendlyName -contains 'Server
Authentication'}

Get-ChildItem Cert:\LocalMachine\My | Where $Filter |


Format-List thumbprint,EnhancedKeyUsageList,DNSNameList,Issuer
Thumbprint : 3138F8B8B4A948ADAB752DE7E355408234D59800
EnhancedKeyUsageList : {Client Authentication (1.3.6.1.5.5.7.3.2), Server Authentication (1.3.6.1.5.5.7.3.1), Smart
Card Logon (1.3.6.1.4.1.311.20.2.2)}
DnsNameList : {2012R2-DC.contoso.com}
Issuer : CN=contoso-2012R2-DC-CA, DC=contoso, DC=com Eligible Certificate
Thumbprint : 060BD6561A0AA96B31696A24D81C91E9676B2BB3 Thumbprints
EnhancedKeyUsageList : {Client Authentication (1.3.6.1.5.5.7.3.2), Server Authentication (1.3.6.1.5.5.7.3.1), Smart
Card Logon (1.3.6.1.4.1.311.20.2.2), KDC Authentication (1.3.6.1.5.2.3.5)}
DnsNameList : {2012R2-DC.contoso.com, contoso.com, CONTOSO}
Issuer : CN=contoso-2012R2-DC-CA, DC=contoso, DC=com

Microsoft Confidential 94
Example: Second, Create Listener (Local or Remote)

#Example 1: Create new local HTTPS Listener using local certificate


$CertThumbprint = '3138F8B8B4A948ADAB752DE7E355408234D59800'
New-Item `
-ItemType Listener `
-Path WSMan:\LocalHost\Listener `
-Address * `
-Transport HTTPS `
-CertificateThumbPrint $CertThumbprint

#Example 2: Remotely connect to WSMAN and create new HTTPS Listener on target using target’s certificate
$CertThumbprint = '3138F8B8B4A948ADAB752DE7E355408234D59800'
Connect-WSMan -ComputerName 2012R2-DC
New-Item `
-ItemType Listener `
-Path WSMan:\2012r2-dc\Listener `
-Address * `
-Transport HTTPS `
-CertificateThumbPrint $CertThumbprint

WSManConfig: Microsoft.WSMan.Management\WSMan::2012r2-dc\Listener

Type Keys Name


---- ---- ----
Container {Transport=HTTPS, Address=*} Listener_1305953032

Microsoft Confidential 95
Example: Second, Create Inbound Firewall Rule (Local or Remote)

#Local – Copy HTTP Rule to create HTTPS Rule


Get-NetFirewallRule -Name WINRM-HTTP-In-TCP |
Copy-NetFirewallRule -NewName WINRM-HTTPS-In-TCP

Get-NetFirewallRule -Name WINRM-HTTPS-In-TCP |


Set-NetFirewallRule -LocalPort 5986 `
-NewDisplayName 'Inbound rule for Windows Remote Management via WS-Management. [TCP 5986]'

#Remote – Same copy technique as above


$CimSession = New-CimSession -ComputerName 2012R2-DC

Get-NetFirewallRule -Name WINRM-HTTP-In-TCP -CimSession $CimSession |


Copy-NetFirewallRule -NewName WINRM-HTTPS-In-TCP

Get-NetFirewallRule -Name WINRM-HTTPS-In-TCP -CimSession $CimSession |


Set-NetFirewallRule -LocalPort 5986 `
-NewDisplayName 'Inbound rule for Windows Remote Management via WS-Management. [TCP 5986]'

Microsoft Confidential 96
PS C:\> Invoke-Command -ComputerName 2012R2-DC.contoso.com `
Example:
Use SSL -ScriptBlock {Get-Culture} -UseSSL
Listener/
Endpoint LCID Name DisplayName PSComputerName
---- ---- ----------- --------------
3081 en-AU English (Australia) 2012R2-DC.contoso.com

97
Module 2: Remoting

Section 3: Remoting Security Lesson 4: Double Hop Remoting

Microsoft Confidential 98
The 2nd Hop Problem

1st Hop 2nd Hop

WIN8-WS 2012R2-MS Auth 2012R2-DC


Auth Succeeds
Fails

Enter-PSSession
PS C:\> -ComputerName 2012R2-MS

[2012R2-MS]: PS C:\Users\Administrator.CONTOSO\Documents> Test-Path -Path \\2012R2-DC\FileShare


Test-Path : Access is denied
+ CategoryInfo : PermissionDenied: (\\2012R2-DC\FileShare:String) [Tes...
+ FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,Microsoft.PowerShel...

False

Microsoft Confidential
Credential Delegation

By default:
• Your credentials are used to authenticate to the first machine
• Your security principal is used on the first hop machine
• Your credentials can not be passed from the first hop machine to the second hop
machine, thus the second hop authentication fails

Creating a custom endpoint using RunAs can achieve second hop without credential
delegation

Microsoft Confidential 100


Credential Delegation

For the second hop to succeed

• Credential delegation must occur from the intermediate computer

• CredSSP Authentication can be used

• Unconstrained (General) Kerberos Delegation can be used, but isn’t recommended

• Fresh credentials are required, but cannot use the logged-in user or integrated authentication

Microsoft Confidential 101


The Risk

You must trust the intermediate computer

If the intermediate computer is compromised:


• Your credentials could be harvested
• Your credentials could be delegated elsewhere without your knowledge

The same precautions you take before you type your password on your own machine,
must be used on computers that may delegate your credentials

Microsoft Confidential 102


Module 2: Remoting

Section 3: Remoting Security Lesson 5: CredSSP

Microsoft Confidential 103


CredSSP (Credential Security Service Provider)

Authentication protocol that allows delegation

Configure and Enable for client and server roles separately

When enabling on the client, designate specific targets (avoid using wildcard *)

Use the same naming format throughout (either: short name, FQDN or IP)

Consider the risks of allowing your credentials to be stored on another machine

Microsoft Confidential 104


Example: Enabling CredSSP

1st Hop 2nd Hop

WIN8-WS 2012R2-MS 2012R2-DC

Enable-WSManCredSSP -Role Server

Enable-WSManCredSSP -Role Client -DelegateComputer 2012R2-MS

Microsoft Confidential 105


Example: CredSSP

1st Hop 2nd Hop


Auth Succeeds Auth Succeeds
Win8-WS 2012R2-MS 2012R2-DC

Enable-WSManCredSSP -Role Client -DelegateComputer 2012R2-MS


Invoke-Command -ComputerName 2012R2-MS -ScriptBlock {Enable-WSManCredSSP -Role Server}

Invoke-Command `
-Authentication CredSSP `
-Credential contoso\administrator `
-ComputerName 2012R2-MS `
-ScriptBlock {Test-Path \\2012R2-DC\FileShare}

True

Microsoft Confidential 106


Module 2: Remoting

Lab

Microsoft Confidential 107


Agenda

Module 1: Review of Part 1 Concepts


Module 2: Remoting
Module 3: Advanced Functions 1
Module 4: Advanced Functions 2
Module 5: Regular Expressions (Regex)
Module 6: Error Handling
Module 7: Debugging
Module 8: Introduction to Desired State Configuration (DSC)
Module 9: Introduction to Workflow

Microsoft Confidential 108


Module 3: Advanced
Functions 1

Module Overview

Microsoft Confidential 109


Module 3: Advanced Functions 1
Section 1: Functions Review – PowerShell For The IT Pro – Part 1
• Lesson 1: Function Basics
• Lesson 2: Comment-Based Help

Section 2: Parameters
• Lesson 1: Static Parameters
• Lesson 2: Switch Parameters
• Lesson 3: Dynamic Parameters

Section 3: [CmdletBinding()]
• Lesson 1: Overview
• Lesson 2: Risk Mitigation
• Lesson 3: Arguments
Microsoft Confidential 110
Module 3: Advanced Functions 1

Section 1: Functions Review – Lesson 1: Function Basics


PowerShell for the IT Pro - Part 1

Microsoft Confidential 111


What is a Function?

Reusable code

Reduces size of code and increases reliability

Can accept parameter values and return output

Advanced functions act like cmdlets

Can include help content for use with Get-Help (like cmdlets)

Microsoft Confidential 112


Syntax

Param() statement is optional

Function [Scope:]<name>
{
Param ($parameter1,$parameterN)
<statement list>
<statement list>
}

Microsoft Confidential 113


A long command (or series of commands) can be turned into a
Example: function to simplify future use
Creating a
utility function PS C:\> Get-Service -Name spooler -RequiredServices
`
-ComputerName 2012R2DC

Use the function name to run the long command

PS C:\> Get-ServiceInfo

Microsoft Confidential 114


Example: Turn cmdlet parameter values into function parameters to make
Creating a code more dynamic
utility function
with
parameters

PS C:\> Get-ServiceInfo -svc spooler -computer


localhost

Microsoft Confidential 115


Module 3: Advanced Functions 1

Section 1: Functions Review – Lesson 2: Comment-Based


PowerShell for the IT Pro - Part 1 Function Help

Microsoft Confidential 116


Function Comment-based Help

Special help comment keywords can be used to write Get-Help topics for functions

Syntax Comment-Base Help Keywords


.SYNOPSIS
# .< help keyword> .DESCRIPTION
# <help content> .PARAMETER <ParameterName>
.EXAMPLE
-or - .INPUTS
.OUTPUTS
<# .NOTES
.< help keyword> .LINK
< help content> .COMPONENT
#> .ROLE
.FUNCTIONALITY

Microsoft Confidential 117


Example:
Function
Help

PS C:\> Get-Help Get-SysLogNN -full

NAME
Get-SysLogNN

SYNOPSIS
Function that returns the most recent system event log entries.

SYNTAX
Get-SysLogNN [[-log] <Object>] [[-numberofevents] <Object>]
[<CommonParameters>]
...

Microsoft Confidential 118


Module 3: Advanced Functions 1

Section 2: Parameters Lesson 1: Static Parameters

Microsoft Confidential 119


Parameter Overview

Like cmdlets, functions/scripts have parameters that can be named,


positional, switch, or dynamic

Can be defined in three ways:


• Param() keyword in body
• Following function name before body
• $Args automatic variable (positional only)

Microsoft Confidential 120


Static Parameters – No Param() Statement

Can appear in parentheses () prior to the function body

When defined outside of the function body the [CmdletBinging()] attribute


arguments are not available.

function <Name> ($p1,$p2,$pn)


{
<PowerShell code>
}

Microsoft Confidential 121


Static Parameters – Param() statement

Parameters may be defined within a Param() statement inside the function body.
Full set of advanced function parameter features are then available.

Parameters defined within a Param() statement


function <Name>
{param ($p1,$p2,$pn)}
Set default values
function <Name>
{param ($p1 ="V1",$p2 ="V2",$pn ="Value3")}
Strongly typed parameters
function <Name>
{param ([int]$p1 ="V1", [string]$p2 ="Value2")}

Microsoft Confidential 122


Unnamed, positional parameters – $Args
Automatic variable
Array of undeclared parameter values passed to a function, script, or
script block
Least-preferred technique

PS C:\> function Use-Args {$args[0],$args[1]}

PS C:\> Use-Args Hello World


Hello
World

Microsoft Confidential 123


Module 3: Advanced Functions 1

Section 2: Parameters Lesson 2: Switch Parameters

Microsoft Confidential 124


Switch Parameter
Parameters with no parameter value
To create a switch parameter in a function use the [Switch] type
False by default, True if present
Syntax
Param ([Switch]<ParameterName>)

Syntax
function SwitchExample {
Param([switch]$state)
if ($state) {"on"} else {"off"}
}

Microsoft Confidential 125


Switch Parameter
Example
function SwitchExample {
Param([switch]$state)
if ($state) {"on"} else {"off"}
}

PS C:\> SwitchExample
Off

PS C:\> SwitchExample -state


On

PS C:\> SwitchExample -state:$false


Off

PS C:\> SwitchExample -state:$true


on

Microsoft Confidential 126


Module 3: Advanced Functions 1

Section 2: Parameters Lesson 3: Dynamic Parameters

Microsoft Confidential 127


Dynamic Parameters
Parameters that are only available under certain conditions
Use an IF or SWITCH statement to control availability
Define parameters through objects instead of keywords
• System.Management.Automation.RuntimeDefinedParameter represents parameter
• System.Management.Automation.ParameterAttribute represents parameter attributes
(e.g. Mandatory, Position, ValueFromPipeline, Parameter Set)

Basic Syntax
function <name> {
Dynamicparam {<statement list>}
}
Microsoft Confidential 128
Example: Static
Dynamic Parameter
Parameter Determines
Slide 1/6 which other
Parameter(s)
will be
available

129
Example:
Dynamic Switch
Parameter Discovers
Slide 2/6 $param1 value
and creates
Dynamic
Parameters
accordingly

Switch here is the condition logic (like If ),


not the switch parameter

130
Example:
Dynamic
Parameter
Slide 3/6

Switch
If $param1 = val1 then Val1DP
parameter is available 131
Switch
If $param1 = val1 then Val1DP
parameter is available

Example:
Dynamic
Parameter
Slide 4/6

132
Example:
Dynamic
Parameter
Slide 5/6

Switch
If $param1 = val2 then Val2DP
parameter is available
133
Switch
If $param1 = val2 then Val2DP
parameter is available

Example:
Dynamic
Parameter
Slide 6/6

134
Module 3: Advanced Functions 1

Section 3: [CmdletBinding()] Lesson 1: Overview

Microsoft Confidential 135


[CmdletBinding()] Attribute

Gives a function parameter binding like a


compiled cmdlet

Automatically adds all common parameters

Param() Required
$Args cannot be used

Microsoft Confidential 136


[CmdletBinding()] Attribute – Basic Syntax

CmdletBinding syntax with no options used

function <Name>
{
[CmdletBinding()]
Parentheses required even if Param ()
specifying no arguments }

Microsoft Confidential 137


[CmdletBinding()] Attribute – Full Syntax

CmdletBinding syntax showing all options

function <Name>
{
[CmdletBinding(
SupportsShouldProcess=<Boolean>,
Optional arguments for the attribute ConfirmImpact=<String>,
DefaultParameterSetName=<String>,
are contained within the parentheses HelpURI=<URI>,
SupportsPaging=<Boolean>,
PositionalBinding=<Boolean>)]
Param ()
}

Microsoft Confidential 138


Module 3: Advanced Functions 1

Section 3: [CmdletBinding()] Lesson 2: Risk Mitigation

Microsoft Confidential 139


Enabling Risk Mitigation

Preferences and parameters determine behavior when:


• Changes are made
• Changes are simulated
• Changes are prompted for confirmation

Implemented by wrapping portions of code in If() statements to evaluate whether:


• To execute the scriptblock
• To display what would have occurred, without executing the scriptblock
• To prompt whether to execute the scriptblock

Microsoft Confidential 140


[CmdletBinding()] Attribute - Risk Mitigation

CmdletBinding syntax showing all options


Activates support for Risk Mitigation
when set to $True function <Name>
{
–Whatif and –Confirm common [CmdletBinding(
SupportsShouldProcess=<Boolean>,
parameter now present ConfirmImpact=<String>,
DefaultParameterSetName=<String>,
HelpURI=<URI>,
SupportsPaging=<Boolean>,
PositionalBinding=<Boolean>)]
Param ()
}

Microsoft Confidential 141


Supporting Risk Mitigation in Functions

Surround the code that makes changes to the system with an If() statement

In the If() statement condition, the ShouldProcess() method enables PowerShell to


determine whether the –WhatIf parameter has been used

Multiple If() statements are allowed

If ($pscmdlet.ShouldProcess("Target", "Operation"))
{
<Statement that makes changes>
}

Microsoft Confidential 142


Function Kill-Process
{
[CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Medium')]
Param([String]$Name)
Example:
ShouldProcess $TargetProcess = Get-Process -Name $Name
If ($pscmdlet.ShouldProcess($name, "Terminating Process"))
method {
$TargetProcess.Kill()
}
}

PS C:\> Kill-Process -Name notepad –WhatIf


What if: Performing the operation "Terminating Process" on target "notepad".

PS C:\> Kill-Process -Name notepad -Confirm


Confirm
Are you sure you want to perform this action?
Performing the operation "Terminating Process" on target "notepad".
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help
(default is "Y"):
Default Risk Mitigation Behavior

PowerShell uses a combination of all three mitigation mechanisms to determine


whether confirmation prompts appear:

$ConfirmPreference
• Automatic variable controls confirmation prompts
• Defaults to "High"

-Confirm parameter can also override confirmation prompts

ConfirmImpact keyword defines the impact level of the function

Microsoft Confidential 144


[CmdletBinding()] Attribute – ConfirmImpact

CmdletBinding syntax showing all options


• Sets general severity level of function <Name>
{
changes made by function [CmdletBinding(
SupportsShouldProcess=<Boolean>,
• Used in conjunction with ConfirmImpact="High","Medium","Low",
$ConfirmPreference automatic DefaultParameterSetName=<String>,
variable to control confirmation HelpURI=<URI>,
SupportsPaging=<Boolean>,
behaviour PositionalBinding=<Boolean>)]
Param ()
}

Microsoft Confidential 145


Confirmation Severity Levels

Default confirmations will be prompted when:


• ConfirmImpact value is greater than or equal to $ConfirmPreference value

ConfirmImpact and $ConfirmPreference Values


None No prompt(s)
Low Prompt for confirmation before running cmdlets or
functions with a low, medium, or high risk
Medium Prompt for confirmation before running cmdlets or
functions with a medium, or high risk
High Prompt for confirmation before running cmdlets or
$ConfirmPreference functions with a high risk
Default

Microsoft Confidential 146


Example: ConfirmImpact of "Medium" is lower than $ConfirmPreference default of "High"
ShouldProcess Result is No Default Confirmations
method

Function Kill-Process
{ [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact="Medium
")]
Param([String]$Name)
Process
{
$TargetProcess = Get-Process -Name $Name
If ($pscmdlet.ShouldProcess($name, "Terminating Process"))
{
$TargetProcess.Kill()
}
}
}
Example: Changing to "High" will display
ShouldProcess confirmations
method

Function Kill-Process
{
[CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='High')]
Param([String]$Name)

Process
{
$TargetProcess = Get-Process -Name $Name
If ($pscmdlet.ShouldProcess($name, "Terminating Process"))
{
$TargetProcess.Kill()
}
}
}
Module 3: Advanced Functions 1

Section 3: [CmdletBinding()] Lesson 3: Arguments

Microsoft Confidential 149


[CmdletBinding()] – DefaultParameterSetName

CmdletBinding syntax showing all options


function <Name>
{
[CmdletBinding(
SupportsShouldProcess=<Boolean>,
Specifies the parameter set to ConfirmImpact=<String>,
use when it cannot be DefaultParameterSetName=<String>,
HelpURI=<URI>,
determined from user input SupportsPaging=<Boolean>,
PositionalBinding=<Boolean>)]
Param ()
}

Microsoft Confidential 150


[CmdletBinding()] – HelpURI

CmdletBinding syntax showing all options


function <Name>
{
[CmdletBinding(
SupportsShouldProcess=<Boolean>,
• Specifies an online version of a ConfirmImpact=<String>,
DefaultParameterSetName=<String>,
help topic that describes the HelpURI=<URI>,
function SupportsPaging=<Boolean>,
PositionalBinding=<Boolean>)]
• Must begin with "http" or "https" Param ()
}

Microsoft Confidential 151


[CmdletBinding()] – SupportsPaging

CmdletBinding syntax showing all options


function <Name>
{
• Automatically adds First, Skip, and [CmdletBinding(
IncludeTotalCount parameters SupportsShouldProcess=<Boolean>,
ConfirmImpact=<String>,
DefaultParameterSetName=<String>,
• Allow users to select output from a HelpURI=<URI>,
large result set SupportsPaging=<Boolean>,
PositionalBinding=<Boolean>)]
• Designed for functions that return
Param ()
}
data from data stores, such as a SQL
database.

Microsoft Confidential 152


[CmdletBinding()] – PositionalBinding

• Determines whether function CmdletBinding syntax showing all options


parameters are positional by function <Name>
default {
[CmdletBinding(
• Default value is $True when not SupportsShouldProcess=<Boolean>,
ConfirmImpact=<String>,
present in CmdletBinding DefaultParameterSetName=<String>,
HelpURI=<URI>,
• When parameters are positional, SupportsPaging=<Boolean>,
the parameter name is optional PositionalBinding=<Boolean>)]
Param ()
• Position argument of the }
Parameter attribute takes
precedence over the
PositionalBinding argument

Microsoft Confidential 153


Module 3: Advanced
Functions 1

Lab

Microsoft Confidential 154


Agenda

Module 1: Review of Part 1 Concepts


Module 2: Remoting
Module 3: Advanced Functions 1
Module 4: Advanced Functions 2
Module 5: Regular Expressions (Regex)
Module 6: Error Handling
Module 7: Debugging
Module 8: Introduction to Desired State Configuration (DSC)
Module 9: Introduction to Workflow

Microsoft Confidential 155


Module 4: Advanced
Functions 2

Module Overview

Microsoft Confidential 156


Module 4: Functions - Attributes

Section 1: Advanced Parameters and Attributes


• Lesson 1: [Parameter()] Attribute
• Lesson 2: [Alias()] Attribute
• Lesson 3: [OutputType()] Attribute
• Lesson 4: Validation Attributes

Microsoft Confidential 157


Module 4: Advanced Functions 2

Section 1: Advanced Parameters Lesson 1: [Parameter()] Attribute


and Attributes

Microsoft Confidential 158


[Parameter()] Attribute

Optional

Used to declare attributes of function parameters

To be recognized as an ‘advanced function’, a function must have either, or both, of


the [CmdletBinding()] or the [Parameter] attributes

Parameter attribute has arguments that define the characteristics of the parameter

Microsoft Confidential 159


Parameter Attribute Syntax
Syntax – Single Argument
function <name>
{ Parentheses that enclose the argument
Param (
[parameter(Argument=value)] and its value must follow "Parameter"
$ParameterName keyword with no intervening space
)
}

Syntax – Multiple Arguments


function <name>
{
Param (
[parameter(Argument1=value1 ,
Argument2=value2)] Commas separate arguments
$ParameterName
)
}
Microsoft Confidential 160
ParameterSetName

ParameterSetName
Specifies parameter set to which a
Param (
[parameter(ParameterSetName="Machine")] parameter belongs
[String[]]$MachineName,
[parameter(ParameterSetName="User")] If no parameter set is specified,
[String[]]$UserName parameter belongs to all the parameter
) sets defined by the function

To be unique, each parameter set must


have at least one parameter that is not
a member of any other parameter set

Microsoft Confidential 161


Mandatory and Position

Mandatory
Param ([parameter(Mandatory=$true)][String[]]
$MachineName)

Position
Param ([parameter(Position=0)][String[]]$MachineName)

• By default, all function parameters are positional


• PowerShell assigns position numbers to parameters in the order in which the parameters are
declared in the function
• To disable, set PositionalBinding argument of CmdletBinding attribute to $False
• Position argument takes precedence over PositionalBinding argument for the parameters on
which it is declared

Microsoft Confidential 162


ValueFromPipeline
Use if parameter
accepts entire object
(not just a property)

ValueFromPipeline
Param ([parameter(ValueFromPipeline=$true)]
[String[]]$MachineName)

ValueFromPipelineByPropertyName
Param
([parameter(ValueFromPipelineByPropertyName=$true)]
[String[]]$MachineName)
Use if parameter
accepts property of an
object

Microsoft Confidential 163


HelpMessage and Remaining Arguments
HelpMessage
Param (
[parameter(Mandatory=$true,
HelpMessage="Enter computer names separated by commas.")]
[String[]]$ComputerName
)

Displays a message when a mandatory


parameter value is missing

ValueFromRemainingArguments
Param(
[parameter(ValueFromRemainingArguments=$true)] Parameter accepts all
[String[]]$ComputerName values that are not
) already assigned

Microsoft Confidential 164


Example: Without NoValueFromRemainingArguments $p2 = ‘two’
Value From function NoValueFromRemainingArguments {
Param($p1,$p2)
Remaining "`$p1 $p1"
"`$p2 $p2"}
Arguments
PS C:\> NoValueFromRemainingArguments one two three
$p1 one
$p2 two

With ValueFromRemainingArguments $p2 = ‘two three’


function ValueFromRemainingArguments {
Param($p1,[Parameter(ValueFromRemainingArguments=$true)]$p2)
"`$p1 $p1"
"`$p2 $p2"}
PS C:\> ValueFromRemainingArguments one two three
$p1 one
$p2 two three
Module 4: Advanced Functions 2

Section 1: Advanced Parameters Lesson 2: [Alias()] Attribute


and Attributes

Microsoft Confidential 166


[Alias()] Attribute

Establishes an alternate name for a parameter

An unlimited number of aliases can be assigned

Example: MachineName and CN are aliases for the ComputerName Parameter


Param ([parameter()][alias("CN","MachineName")]
[String[]]$ComputerName)

Microsoft Confidential 167


Module 4: Advanced Functions 2

Section 1: Advanced Parameters Lesson 3: [OutputType()] Attribute


and Attributes

Microsoft Confidential 168


[OutputType()] Attribute

Reports .NET type of object function returns


Can combine with optional ParameterSetName parameter for different output types
Use a null value when output is a not a .NET type

Multiple Output Types


[OutputType([<Type1>],[<Type2>],[<Type3>])]

One or more Parameter Sets


[OutputType([<Type1>], ParameterSetName="<Set1>","<Set2>")]
[OutputType([<Type2>], ParameterSetName="<Set3>")]

Microsoft Confidential 169


Example:
[OutputType()] Attribute

function Print-Hello {
[OutputType([double])]
Param ($Name)"Hello $Name"
}
PS C:\> (Get-Command Print-Hello).OutputType
Name Type
---- ----
System.Double System.Double

Note: The OutputType attribute value is only a documentation note. It is not derived from the
function code, or compared to the actual function output. As such, the value may be inaccurate.
Below command displays the actual .NET type returned by the command
PS C:\> (Print-Hello -Name Johan).GetType().FullName
System.String

170
Module 4: Advanced Functions 2

Section 1: Advanced Parameters Lesson 4: Validation Attributes


and Attributes

Microsoft Confidential 171


[ValidateSet()] Attribute
Specifies a set of valid values for a parameter or variable
PowerShell generates an error if a value does not exist in the set
Example: Create a validate set to simplify returning CPU performance counter values
function Get-CpuCounter {
Param (
[ValidateSet("% Processor Time","% Privileged Time","% User
Time")]
$perfcounter
)
Get-Counter -Counter "\Processor(_Total)\$perfcounter"
}

IntelliSense suggests
allowed values

Microsoft Confidential 172


Other Validation Attributes
AllowNull: $null is allowed
Param
([parameter(Mandatory=$true)][AllowNull()][String]$ComputerName)
AllowEmptyString: Empty string is allowed
Param
([parameter(Mandatory=$true)][AllowEmptyString()][String]$ComputerName)
AllowEmptyCollection: Empty collection is allowed
Param ([parameter(Mandatory=$true)][AllowEmptyCollection()][String[]]
$ComputerName)

Microsoft Confidential 173


Other Validation Attributes

ValidateNotNull: $null is not allowed


Param
([parameter(Mandatory=$true)][ValidateNotNull()]$ID)
ValidateNotNullOrEmpty: Neither $null nor empty string allowed
Param ([parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][String[]]
$UserName)

Microsoft Confidential 174


Other Validation Attributes

ValidateCount: Specifies minimum and maximum accepted number of parameter values


Param ([ValidateCount(1,5)][String[]]$ComputerName)
Validatelength: Specifies minimum and maximum accepted number of characters
Param ([ValidateLength(1,10)][String[]]$ComputerName)
ValidatePattern: Specifies a regular expression to compare to the parameter value
Param ([ValidatePattern("[0-9].[0-9].[0-9].[0-9]")][String[]]
$ComputerName)

Regular expressions are covered in a later module

Microsoft Confidential 175


Other Validation Attributes

ValidateRange: Specifies a numeric range for each parameter value


Param ([ValidateRange(0,10)][Int]$Attempts)

ValidateScript: Specifies a "script" that is used to validate a parameter value


PowerShell generates an error if the "script" returns "false" or if it throws an exception
Param ([ValidateScript({$_ -ge (get-date)})][DateTime]$EventDate)

Microsoft Confidential 176


Module 4: Advanced
Functions 2

Lab

Microsoft Confidential 177


Agenda

Module 1: Review of Part 1 Concepts


Module 2: Remoting
Module 3: Advanced Functions 1
Module 4: Advanced Functions 2
Module 5: Regular Expressions (Regex)
Module 6: Error Handling
Module 7: Debugging
Module 8: Introduction to Desired State Configuration (DSC)
Module 9: Introduction to Workflow

Microsoft Confidential 178


Module 5: Regular
Expressions (Regex)

Module Overview

Microsoft Confidential 179


Module 5: Regular Expressions (Regex)

Section 1: Introduction
• Lesson 1: What is Regex?
• Lesson 2: Characters, Character Classes and Quantifiers

Section 2: Regex Use Cases


• Lesson 1: Regex in PowerShell

Microsoft Confidential 180


Module 5: Regular Expressions
(Regex)

Section 1: Introduction Lesson 1: What is Regex?

Microsoft Confidential 181


What is a Regular Expression (RegEx)?
A sequence of characters that forms a search pattern

Enables parsing of large amounts of text to find specific character patterns, to validate,
extract, edit, replace, or delete text substrings

PowerShell supports the .NET Framework Regular Expression engine

PS C:\> "Phone number: +61 42 911 1972" -match "\+\d{2} \d{2} \d{3} \
d{4}"
True

Note: Escape character for regular expressions ( \ ) is different than for PowerShell ( ` )

Microsoft Confidential 182


PowerShell Regex Language Support

Operators Parameter Attribute


• -split • ValidatePattern
• -csplit (Discussed in Functions Module)
• -replace
• -creplace Cmdlets
• -join • Select-String
• -match
• -cmatch
• -notmatch
.NET
• System.Text.RegularExpressions namespace
• -cnotmatch

Statements
• Switch

Microsoft Confidential 183


System.Text.RegularExpressions namespace
Provides access to underlying .NET regular expression engine
[Regex] type accelerator contains methods for split, match, replace, etc.
[System.Text.RegularExpressions.RegexOptions] allows attributes like RightToLeft,
IgnoreCase, Multiline, etc.
[System.Configuration.RegexStringValidator] determines whether a string conforms to
a regex pattern

[System.Text.RegularExpressions.Regex]
#type accelerator [regex]
[System.Text.RegularExpressions.RegexOptions]
[System.Configuration.RegexStringValidator]

Microsoft Confidential 184


$Matches
Automatic variable
Hash table of matched string values
Works with operators and statements
Enables extraction of matched content in addition to boolean true
Stops after first match
Example: Searching for a simple match using literal "Dev"
PS C:\> "You say Yes, I say No, What does the Dev say?" -match "Dev"
True

PS C:\> $matches
Name Value
---- -----
0 Dev

Microsoft Confidential 185


$Matches

Overall regex match PS C:\> $Matches[0]

First capturing group PS C:\> $Matches[1]

Named group PS C:\> $Matches["group name"]

Microsoft Confidential 186


Module 5: Regular Expressions
(Regex)

Section 1: Introduction Lesson 2: Characters, Character


Classes and Quantifiers

Microsoft Confidential 187


Character Matches
Format Logic Example
value Exact characters anywhere in original value "book" -match "oo"
. Any single character, except newline "copy" -match "c..y"
[value] At least one character in brackets "big" -match "b[iou]g"
[range] At least one character within range "and" -match "[a-e]nd"
[^] Any character(s) except those in brackets "and" -match "[^brt]nd"
^ Beginning character(s) "book" -match "^bo"
$ End character(s) "book" -match "ok$"
\ Character that follows as an escaped character "Try$" -match "Try\$"

Microsoft Confidential 188


Character Class Matches
A character class defines a set of characters, any one of which can occur in an input string
for a match to succeed
Format Logic Example
"abcd defg" -match "\w+"
\w Any word character # matches abcd
"abcd defg" -match "\W+"
\W Any non-word character # matches the space
\s Any white-space character "abcd defg" -match "\s+"
\S Any non-white-space character "abcd defg" -match "\S+"
\d Any decimal digit 12345 -match "\d+"
\D Any non-decimal digit "abcd" -match "\D+"
Any character in named character class such as Ll, Nd, Z,
\p{name} IsGreek, and IsBoxDrawing "abcd defg" -match "\p{Ll}+"
Text not included in groups and block ranges specified in
\P{name} {name} 1234 -match "\P{Ll}+"

Microsoft Confidential 189


Quantifier Matches
Quantifiers specify how many instances of a character, group, or character class must be present
in the input for a match to be found

Format Logic Example


"abc" -match "\w*"
* Zero or more {0,} "baggy" -match "g*"
+ One or more {1,} "xyxyxy" -match "xy+"
"abc" -match "\w?"
? Zero or one {0,1} "http" -match "https?"
{n} Exactly n matches "abc" -match "\w{2}"
{n,} At least n matches "abc" -match "\w{2,}"
{n,m} At least n, but no more than m, matches "abc" -match "\w{2,3}"

Microsoft Confidential 190


Regex Groups and Alternation (OR)
Format Logic Example
Groups regular
expressions
Applies quantifier to PS C:\> "abcd defg" -match "(\w{4})"
()
group Name Value
---- -----
Restricts alternation 1 abcd
to group 0 abcd
PS C:\> "abcd defg" -match "(?<all>(?<word1>\w{4})(?
<nonword>\W)(?<word2>\w{4}))"
Name Value
Named groups ---- -----
(?<name>) Group names must word1 abcd
begin with a letter word2 defg
all abcd defg
nonword
0 abcd defg
Alternation
|
Logical OR PS C:\> "3001 2009 6754" –match "(3001)|(2009)"
Microsoft Confidential 191
Example: Groups

String -Match [Regex] $Matches


Name Value
"\w+\\\w+" ---- -----
0 contoso\administrator
Name Value
---- -----
"(\w+)\\(\w+)" 2 administrator
"contoso\administrator" 1 contoso
0 contoso\administrator
Name Value
---- -----
"(?<Domain>\w+)\\(?<UserName>\w+)" UserName administrator
Domain contoso
0 contoso\administrator

192
Example: Groups continued

String -Match [Regex] $Matches


Name Value
"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" ---- -----
0 192.168.1.254
Name Value
---- -----
4 254
"(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})" 3 1
2 168
"192.168.1.254" 1 192
0 192.168.1.254
Name Value
---- -----
"(?<FirstOctet>\d{1,3})\.(?<SecondOctet>\ FirstOctet 192
d{1,3})\.(?<ThirdOctet>\d{1,3})\.(? FourthOctet 254
<FourthOctet>\d{1,3})" SecondOctet 168
ThirdOctet 1
0 192.168.1.254

193
Mode Modifiers
Matching modes can be specified in the regex pattern
Specify regex options w/o using [System.Text.RegularExpressions.RegexOptions]
Useful with operators, where regex options cannot be specified
Can combine mode modifiers e.g. (?smi)
Use minus to turn mode off

Format Mode Description


(?i) IgnoreCase Case insensitive
(?m) Multi-line ^ and $ match next to line terminators
(?s) Single-line Dot matches any character including line terminator

Microsoft Confidential 194


Mode Modifier Examples
Mode Example
PS C:\> "test" -match "(?i)T"
Case insensitive True
PS C:\> "test" -match "(?-i)T"
Case sensitive False
PS C:\> $text = @"
Hello
a1
digital
Multi-line world, you binary a2
thing you
"@
PS C:\> ([regex]::Matches($text,"(?m)^.\d{1}")).value
a1
PS C:\> "hello`nworld" -match "(?s).+"
PS C:\> $Matches.Values
Single-line hello
World

Microsoft Confidential 195


Module 5: Regular Expressions
(Regex)

Section 2: Regex Use Cases Lesson 1: Regex in PowerShell

Microsoft Confidential 196


Example 1: Search for match with Select-String

PS C:\> Get-Content $env:windir\WindowsUpdate.log |


Select-String -Pattern "Found \d Updates" | Select-Object -First 1

2014-02-09 17:31:10:691 360 72b8 Agent * Found 0 updates and 53


categories in search; evaluated appl. rules of 128 out of 187
deployed entities

\d Any decimal digit

197
Example 2: Search for match with switch –regex and extract data with $matches

function Get-WiFiSignalStrength {
$wlan = (netsh wlan show interfaces)
Switch -Regex ($wlan) {
"\d{2}%" {Write-Host $($matches.Values) -ForegroundColor Green}
}
}
\d Any decimal digit
{2} Exactly 2 matches
% Literal % sign
PS C:\> Get-WiFiSignalStrength
80%

198
Example 3: Replacing substrings with –replace or -creplace

PS C:\> "Mr. Henry Hunt, Mrs. Sara Samuels, Miss. Nicole Norris" `
-replace "Mr\. |Mrs\. |Ms\.",""

Henry Hunt, Sara Samuels, Miss. Nicole Norris


\. Escapes dot to use it as a literal dot
(instead of regex ‘any single character’)
Space Literal space

| Alternation operator
Mr. OR Mrs. OR Ms.

199
Example 4: Split text with –split or -csplit

Syntax: Split Regex Options


<String> -Split <Delimiter>[,<Max-substrings>[,"<Options>"]]

Options Syntax: RegexMatch:


• SimpleMatch [,IgnoreCase] • RegexMatch: Use regular expression. Default
• [RegexMatch] [,IgnoreCase] [,CultureInvariant] • IgnoreCase: Case-insensitive (even with –cSplit)
[,IgnorePatternWhitespace] [,ExplicitCapture] • CultureInvariant: Ignores cultural differences
[,Singleline | ,Multiline] • IgnorePatternWhitespace: Ignores un-escaped
whitespace and comments (#)
SimpleMatch: • Multiline: Multiline mode recognizes start and
• SimpleMatch: Use simple string comparison end of lines and strings
(regex characters are considered as normal text) • Singleline: Recognizes only start and end of
• IgnoreCase: Case-insensitive (even with –cSplit) strings; default
• ExplicitCapture: Ignores non-named match
groups; only explicit capture groups are returned

200
Example 5: Split text with –split or -csplit

PS C:\> $a = @"
1The first line.
2The second line.
3The third of three lines.
"@
PS C:\> $a -split "^\d", 0, "multiline"

The first line.

The second line.

The third of three lines.


^ Beginning with character(s)
\d Any decimal digit

201
Example 6: Split text with regex TYPE

PS C:\> [Regex]::Split("www.microsoft.com","\.")

www
microsoft
Com
\. Matches a literal dot
[Regex] Built-in TYPE accelerator for [System.Text.RegularExpressions.Regex]

202
Example 7: Regex and regex option TYPES

PS C:\> $text = @("www.microsoft.com", "www.Microsoft.com")


Case sensitive pattern match
PS C:\> [regex]::matches($text,"[a-z]icrosoft.com")
Case insensitive pattern match
PS C:\> [regex]::matches($text, "[a-z]icrosoft.com",
[System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
matches() Returns multiple matches. Tip: match() returns single match
\. Matches a literal dot
[a-z] Matches any lowercase character between a and z
[Regex] Built-in TYPE accelerator for [System.Text.RegularExpressions.Regex]

203
Module 5: Regular
Expressions (Regex)

Lab

Microsoft Confidential 204


Agenda

Module 1: Review of Part 1 Concepts


Module 2: Remoting
Module 3: Advanced Functions 1
Module 4: Advanced Functions 2
Module 5: Regular Expressions (Regex)
Module 6: Error Handling
Module 7: Debugging
Module 8: Introduction to Desired State Configuration (DSC)
Module 9: Introduction to Workflow

Microsoft Confidential 205


Module 6: Error Handling

Module Overview

Microsoft Confidential 206


Module 6: Error Handling
Section 1: Intro to Errors • Lesson 4: $Error Array
• Lesson 1: What is an Error • Lesson 5: Creating Non-Terminating
• Lesson 2: Dealing with Errors Errors

Section 2: Streams Section 4: Terminating errors


• Lesson 1: PowerShell’s Five Streams • Lesson 1: Overview
• Lesson 2: Redirection Operators • Lesson 2: Creating Terminating Errors
• Lesson 3: Try Catch Finally
Section 3: Non-terminating errors • Lesson 4: Trap
• Lesson 1: Overview • Lesson 5: Error Handling and Scope
• Lesson 2: Error Action
• Lesson 3: Testing for Errors

Microsoft Confidential 207


Module 6: Error Handling

Section 1: Introduction to Errors Lesson 1: What is an Error

Microsoft Confidential 208


What is an Error
PowerShell representation of an object-based exception

Design Time Errors


• Syntax errors are caught by the PowerShell parser and/or PowerShell
ISE

Runtime Errors
• When something goes wrong during code execution
• Only detectable when a specific state is reached or statement is
executed

Microsoft Confidential 209


Types of Errors

• Stops a statement from running


Terminating • If PowerShell does not handle the terminating error, it
stops running the function or script

• Less severe, often just a single operation out of many


Non-Terminating • Primary processing doesn’t need to stop
• Error may be displayed in host application

Cmdlet/Function/Script/Object author decides


which type of errors to trigger
Microsoft Confidential 210
Module 6: Error Handling

Section 1: Introduction to Errors Lesson 2: Dealing with Errors

Microsoft Confidential 211


What to do when an Error Occurs?

• Red error messages are displayed


Nothing • Results could be unpredictable

• Identify where the error has occurred


Debug Code • Resolve syntax or logic problems

Handle the Errors • Typically hide the red error messages


• Write logic to handle errors appropriately
with Code • Actions can be: ignore, process, log, raise or halt further execution

Microsoft Confidential 212


Error Handling: Terminating vs. Non-Terminating
Terminating Errors
• Requires Try, Catch, Finally or a Trap statement
• Enters a child scope

Non-Terminating Errors
• Test for error and run handling code
• Can be converted into terminating error
• “Stop” with –ErrorAction or $ErrorActionPreference
• Use the "throw" keyword

Microsoft Confidential 213


Module 6: Error Handling

Section 2: Streams Lesson 1: PowerShell’s Five


Streams

Microsoft Confidential 214


PowerShell Streams

Streams separate different categories of output

Without separation, error and output objects would be mixed, requiring later filtering

Some streams are hidden (Verbose, Debug)

Redirection operators allow control over a stream’s destination

Microsoft Confidential 215


The Streams (v4)
1 – Output
• Most common
• Flows down pipeline
• Captured by Assignment "="

2 – Error
• Execution Problems
• Shown by default in red

3 – Warning
• Less severe execution problems
• Shown by default in yellow

4 – Verbose
• More detailed execution information
• Hidden by default

5 – Debug
• Related to debugging code
• Hidden by default

Microsoft Confidential 216


Example:
•Example: Trace parameter binding
Streams

PS C:\> "Output Stream"


Output Stream
PS C:\> Write-Output "Output Stream"
Output Stream

PS C:\> Write-Error "Error Stream"


Write-Error "Error Stream" : Error Stream
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

PS C:\> Write-Warning "Warning Stream"


WARNING: Warning Stream

PS C:\> Write-Verbose "Verbose Stream" -Verbose


VERBOSE: Verbose Stream
PS C:\> Write-Debug "Debug Stream" -Debug
DEBUG: Debug Stream

Microsoft Confidential 217


Controlling Stream Behavior
Stream Defaults
Preference Variables PS C:\> $ErrorActionPreference
Continue
• Variables that control how PowerShell reacts to
stream messages PS C:\> $WarningPreference
Continue

PS C:\> $VerbosePreference
Cmdlet common parameters SilentlyContinue
• -Verbose, -Debug, -ErrorAction, -WarningAction
PS C:\> $DebugPreference
SilentlyContinue
No preference variable for Output Stream
• Controlled by assignments, redirection, and pipeline Preference levels covered with Error Action

Microsoft Confidential 218


Module 6: Error Handling

Section 2: Streams Lesson 2: Redirection Operators

Microsoft Confidential 219


Redirection Operators
Save streams of information to a file
Operator Description Example
> Sends output to specified file PS C:\> Get-Process > Process.txt
Appends output to contents of specified
>> file PS C:\> dir *.ps1 >> Scripts.txt
2> Sends errors to specified file PS C:\> Get-Process none 2> Errors.txt
2>> Appends errors to contents of specified file PS C:\> Get-Process none 2>> Errors.txt
Sends errors (2) and success output (1) to
2>&1 success output stream PS C:\> Get-Process none, Powershell 2>&1
3> Sends warnings to specified file PS C:\> Write-Warning "Test!" 3> Warnings.txt
Appends warnings to contents of specified
3>> file PS C:\> Write-Warning "Test!" 3>> Warnings.txt
PS C:\> function Test-Warning {
Get-Process PowerShell;
Sends warnings (3) and success output (1) Write-Warning "Test!"}
3>&1 to success output stream Test-Warning 3>&1

Microsoft Confidential 220


Redirection Operators

Operator Description Example


4> Sends verbose output to specified file PS C:\> Import-Module * -Verbose 4> Verbose.txt
Appends verbose output to contents of
4>>
specified file PS C:\> Import-Module * -Verbose 4>> Verbose.txt
Sends verbose output (4) and success
4>&1
output (1) to success output stream PS C:\> Import-Module * -Verbose 4>&1
5> Sends debug messages to specified file PS C:\> Write-Debug "Starting" 5> Debug.txt
Appends debug messages to contents of PS C:\> Write-Debug "Saving" 5>> Debug.txt
5>>
specified file
PS C:\> function Test-Debug {
Sends debug messages (5) and success Get-Process PowerShell
5>&1 Write-Debug "PS"}
output (1) to success output stream
Test-Debug 5>&1

Microsoft Confidential 221


Redirection Operators

Operator Description Example


PS C:\> function Test-Output {
Get-Process PowerShell, none
Write-Warning "Test!"
*> Sends all output types to specified file Write-Verbose "Test Verbose"
Write-Debug "Test Debug"}
PS C:\> Test-Output *> Test-Output.txt
Appends all output types to contents of
*>>
specified file PS C:\> Test-Output *>> Test-Output.txt
Sends all output types (*) to success
*>&1
output stream PS C:\> Test-Output *>&1

Microsoft Confidential 222


Module 6: Error Handling

Section 3: Non-Terminating Errors Lesson 1: Overview

Microsoft Confidential 223


Non-Terminating Errors

Errors do not stop processing


• Optionally handle error in code
• Continue with rest of code
• Does not trigger Trap, Try..Catch..Finally

Can be converted into Terminating errors


• -ErrorAction Stop or $ErrorActionPreference = ‘Stop’
• Can then utilize Trap, Try..Catch..Finally

Microsoft Confidential 224


Non-terminating error handling flow

Suppress Error Messages • $ErrorActionPreference = SilentlyContinue

Error and/or Success • Non-Terminating


Occurs

Check if we had error • $? Or $Error

• Log File, Custom


Run Error Handler Code Message, etc.

Continue with rest of


normal code
Microsoft Confidential 225
Module 6: Error Handling

Section 3: Non-Terminating Errors Lesson 2: Error Action

Microsoft Confidential 226


Actions to Suppress Error Messages

$ErrorActionPreference
• Automatic variable for remaining script/function/session

-ErrorAction common parameter


• On all cmdlets and advanced functions/scripts

Microsoft Confidential 227


Error Action Values
Determines PowerShell response
to non-terminating errors
Continue (Default) • Displays error message and continues executing

• Error message is not displayed and execution


SilentlyContinue continues w/o interruption

• Raises terminating error and displays an error


Stop message and stops command execution
Optional Numerical Values
• Automatically suspends a workflow job
SilentlyContinue 0 Suspend • Allows for investigation, can be resumed
Stop 1
• Displays error message and prompts user to
Continue 2 Inquire continue
Inquire 3
• Can only be used with -ErrorAction common
Ignore 4 Ignore parameter (not with $ErrorActionPreference)
Suspend 5
Microsoft Confidential 228
$ErrorActionPreference

Variable value affects all subsequent commands in same variable scope

Errors are displayed by default:

PS C:\> $ErrorActionPreference
Continue

Visible Errors Suppressed:

PS C:\> $ErrorActionPreference = "SilentlyContinue"


# or
PS C:\> $ErrorActionPreference = 0

Microsoft Confidential 229


ErrorAction Common Parameter

Affects only command where used


Available on all cmdlets and advanced functions
Parameter Alias: -EA
PS C:\> Get-Process -Name NotValidName
Get-Process : Cannot find a process with the name "NotValidName". Verify the process
name and call the cmdlet again.
At line:1 char:1
+ Get-Process -Name NotValidName
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (NotValidName:String) [Get-Process],
ProcessCommandException

PS C:\> Get-Process -Name NotValidName -ErrorAction SilentlyContinue


PS C:\>
PS C:\> Get-Process -Name NotValidName –EA 0 #Using param alias and numerical value
PS C:\>

Microsoft Confidential 230


Module 6: Error Handling

Section 3: Non-Terminating Errors Lesson 3: Testing for Errors

Microsoft Confidential 231


$? – Last operation execution status

Automatic Variable
• Contains execution status of last operation
• Applies to both terminating and non-terminating errors
• Even applies to external command exit codes

True = Complete Success


False = Failure (Partial or Complete)

Typically used in an If() statement, to test and then run error handling code

Microsoft Confidential 232


Example:
•Example: $? Trace parameter binding
PS C:\> $WindowsFolder = Get-Item C:\Windows
PS C:\> $?
True

PS C:\> $WindowsFolder = Get-Item C:\NotValidFolderName -ErrorAction SilentlyContinue


PS C:\> $?
False

PS C:\> Get-Process System,NotValidName


Get-Process : Cannot find a process with the name "NotValidName". Verify the process
name and
call the cmdlet again.
At line:1 char:1 ...

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName

------- ------ ----- ----- ----- ------ -- -----------

735 0 7692 652 12 1,469.14 4 System

PS C:\> $?
False

Microsoft Confidential 233


Example:
•Example: Trace
$? with parameter
External Commands binding

PS C:\> ping.exe 2012R2-DC -n 1

Pinging 2012R2-DC.contoso.com [10.0.1.200] with 32 bytes of data:


Reply from 10.0.1.200: bytes=32 time<1ms TTL=128 ...

PS C:\> $?
True

PS C:\> ping.exe NotValidName

Ping request could not find host NotValidName. Please check the name and try again.

PS C:\> $?
False

Microsoft Confidential 234


Module 6: Error Handling

Section 3: Non-Terminating Errors Lesson 4: $Error Array

Microsoft Confidential 235


$Error – An array of error objects

Automatic variable – Array holds errors that have occurred in the current session

Control maximum array size:

PS C:\> $MaximumErrorCount
256

The most recent error is the first object in the array:


PS C:\> $Error[0]

Prevent an error from being added to the $Error array, by using "-ErrorAction Ignore"

Microsoft Confidential 236


$Error – View all properties

By default $Error only displays a summary of the error

View all properties using one of the following examples:


PS C:\> $Error[0] | Format-List * -Force
PS C:\> $Error[0] | fl * -Force
PS C:\> $Error[0] | Select-Object *
PS C:\> $Error[0] | Select *

Drill into the object model for more error details


PS C:\> $Error[0].CategoryInfo
PS C:\> $Error[0].InvocationInfo
PS C:\> $Error[0].ScriptStackTrace

Microsoft Confidential 237


-ErrorVariable Common Parameter
Capture errors from a specific action into a dedicated variable

Create the variable and store any errors in it:


Get-Process -Id 6 -ErrorVariable MyErrors

Append error messages to the variable:


Get-Process -Id 6 -ErrorVariable +MyErrors

Work with the variable just like $Error:


$MyErrors

$Error holds all errors, including those sent to -ErrorVariable.

Microsoft Confidential 238


Module 6: Error Handling

Section 3: Non-Terminating Errors Lesson 5: Creating Non-


Terminating Errors

Microsoft Confidential 239


Write-Error
Creates non-terminating errors
Can be handled in-code via $?
Automatically stored in $Error
Useful for re-usable functions to report errors to caller

PS C:\> Write-Error "My Custom Error"


Write-Error "My Custom Error" : My Custom Error
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

PS C:\> $Error[0]
Write-Error "My Custom Error" : My Custom Error
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

Microsoft Confidential 240


Module 6: Error Handling

Section 4: Terminating Errors Lesson 1: Overview

Microsoft Confidential 241


Terminating Errors

Severe errors where processing of the current scope can’t continue

Error cannot be handled in the same code block, like non-terminating


errors

Use Trap or Try{} Catch{} Finally{} to handle

Non-Terminating Errors can be re-thrown as terminating errors using


"-ErrorAction stop"

Microsoft Confidential 242


Overview of Trap/Try..Catch..Finally
Trap
Set a Trap
Run CODE
Terminating error triggers
trap code

Try/Catch/Finally
Encapsulate CODE into Try Block
Terminating error fires catch block
Finally block always run
even during Ctrl-C

Microsoft Confidential
Module 6: Error Handling

Section 4: Terminating Errors Lesson 2: Creating Terminating


Errors

Microsoft Confidential 244


Throw

User-created terminating error

Throws a message string or any object type

Can be used to enforce mandatory parameters


• PowerShell 3.0+, use the [Parameter(Mandatory)] attribute

Useful in re-usable code to cause halt and report errors to caller for severe errors

PS C:\> If ( -not (Test-Path $UserFile)) { Throw "ERROR: File not found" }

Microsoft Confidential 245


Example:
•Example: Trace parameter binding
Basic Throw

If (1 -eq 1)
{
"Line before the terminating error"
Throw "This is my custom terminating error"
"Line after the throw" Line doesn’t run because
} of termination
PS C:\> C:\Simple-Throw-Sample.ps1
Line before the terminating error
This is my custom terminating error
At C:\Users\danpark\OneDrive @ Microsoft\Scripting\Simple-Throw-Sample.ps1:4
char:5
+ Throw "This is my custom terminating error"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (This is my custom terminating
error:String) [], RuntimeException
+ FullyQualifiedErrorId : This is my custom terminating error

PS C:\>

Microsoft Confidential 246


Example:
•Example: TraceParameter
Mandatory parameter
using binding
Throw

Function SampleThrowBasedMandatoryParam
{
Param ($ComputerName = $(Throw "You must specify a value"))
Get-CimInstance Win32_BIOS -ComputerName $ComputerName
}
PS C:\> SampleThrowBasedMandatoryParam
You must specify a value
At C:\Sample-Mand-Param-Throw.ps1:3 char:30
+ Param ($ComputerName = $(Throw "You must specify a value"))
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (You must specify a value:String)
[], RuntimeException
+ FullyQualifiedErrorId : You must specify a value

PS C:\> SampleThrowBasedMandatoryParam -ComputerName 2012R2-MS

SMBIOSBIOSVersion : 090006
Manufacturer : American Megatrends Inc.
Name : BIOS Date: 05/23/12 17:15:53 Ver: 09.00.06
SerialNumber : 7279-1135-6341-8380-3829-5634-16
Version : VRTUAL - 5001223
PSComputerName : 2012R2-MS

Microsoft Confidential 247


Module 6: Error Handling

Section 4: Terminating Errors Lesson 3: Try, Catch and Finally


Blocks

Microsoft Confidential 248


Try, Catch, Finally Syntax
Try
{
<Code that could cause terminating errors>
}

Catch [Exception Type1], [Exception Type2], [Exception Type3]


{
<Error handling>
}
• One or more catch blocks
Catch
• Exception type optional
{
Note: most specific to least specific
<Handle uncaught errors>
• Finally block optional
}
• Must have at least one Catch or Finally block
Finally
{
<Clean up code>
} Microsoft Confidential 249
Try, Catch, Finally Flow

The Try block defines a section of a script


to monitor for errors

When an error occurs within the Try block,


the error is first saved to $Error

PowerShell then searches for a Catch


block to handle the error

If no matching Catch block is found or


defined, then parent scopes are searched

After the Catch block, the Finally block


executes

If the error cannot be handled, the error is


written to the error stream

Microsoft Confidential 250


Finally Block
Will run even if Ctrl-C is used during the Try block execution

Useful for:
• Releasing resources
• Closing network connections
• Closing database connections
• Logging
• Etc.

Microsoft Confidential 251


Example: Try/Catch/Finally

Try
{
$wc = New-Object System.Net.WebClient
$wc.DownloadFile("http://www.contoso.com/MyDoc.doc")
}
Catch [System.Net.WebException],[System.IO.IOException]
{
"Cannot get MyDoc.doc from http://www.contoso.com"
}
Catch
{
"An error occurred that could not be resolved."
$_.Exception.Message
}
Finally
{
If ($wc)
{
$_ contains caught error
$wc.Dispose()
}
}

Microsoft Confidential 252


Module 6: Error Handling

Section 4: Terminating Errors Lesson 4: Trap Statement

Microsoft Confidential 253


Trap { }

Specifies a list of statements to run when a terminating error occurs

Handles terminating errors and allow execution to continue

Can catch all, generic (namespace), or specific exception types

Multiple Trap statements can be specified in a script

Is "global", applies to all code in the same scope, before or after

Microsoft Confidential 254


Example:
Trap [System.DivideByZeroException] { #This is specific trap
"Can not divide by ZERO!!!--> " + $_.exception.message
Continue
Trap }
Trap {#This is a generic catch all trap
"A serious error occurred--> " + $_.exception.message
Continue
}

Write-Host -ForegroundColor Yellow "`nAttempting to Divide by Zero"


1 / $null

Write-Host -ForegroundColor Yellow "`nAttempting to find a fake file"


Get-Item c:\fakefile.txt -ErrorAction Stop

Write-Host -ForegroundColor Yellow "`nAttempting an invalid command"


1..10 | ForEach-Object {Bogus-Command}
Attempting to Divide by Zero
Can not divide by ZERO!!!--> Attempted to divide by zero.

Attempting to find a fake file


A serious error occurred--> Cannot find path 'C:\fakefile.txt' because it does not
exist.

Attempting an invalid command


A serious error occurred--> The term 'Bogus-Command' is not recognized as the name
of a cmdlet, function, script file, or operable program. Check the spelling of the
name, or if a path was included, verify that the path is correct and try
again.

Microsoft Confidential 255


Module 6: Error Handling

Section 4: Terminating Errors Lesson 5: Error Handling and


Scope

Microsoft Confidential 256


Scopes and Try, Catch, Finally

Exceptions can be re-thrown to the parent scope


• i.e. from a function to the calling scope (exception ‘bubbling’)
• Unhandled exceptions in any scope will be processed by the Windows PowerShell Host

In the code below


• The "function3" catch block is executed, which throws a new exception
• The new exception is caught by the parent catch block
• This affects flow control, as the "function3 was completed" text is NOT executed
$ErrorActionPreference = SilentlyContinue

Function function3 {
Try { NonsenseString }
Catch {"Error trapped inside function" ; Throw}
"Function3 was completed"
}

Try{ Function3 }
Catch { "Internal Function error re-thrown: $($_.ScriptStackTrace)" }
"Script Completed"
Microsoft Confidential 257
Module 6: Error Handling

Lab

Microsoft Confidential 258


Agenda

Module 1: Review of Part 1 Concepts


Module 2: Remoting
Module 3: Advanced Functions 1
Module 4: Advanced Functions 2
Module 5: Regular Expressions (Regex)
Module 6: Error Handling
Module 7: Debugging
Module 8: Introduction to Desired State Configuration (DSC)
Module 9: Introduction to Workflow

Microsoft Confidential 259


Module 7: Debugging

Module Overview

Microsoft Confidential 260


Module 7: Debugging

Section 1: Introduction
• Lesson 1: Overview
• Lesson 2: Customized Debugging Information

Section 2: Debugging your Code


• Lesson 1: Break Points
• Lesson 2: ISE Debugging
• Lesson 3: Command-Line Debugging
• Lesson 4: Debugging Cmdlets

Microsoft Confidential 261


Module 7: Debugging

Section 1: Introduction Lesson 1: Overview

Microsoft Confidential 262


Debugging Overview

The process of examining code while running to identify and correct errors

Works with PowerShell scripts, functions, commands, workflows, or expressions

Windows PowerShell includes cmdlets to manage breakpoints and view the call stack

Windows PowerShell ISE includes graphical debugging capabilities

Microsoft Confidential 263


Debugging Features

Runtime code examination Remote debugging (only via console)


Identify errors $DebugPreference
Debug with Console or ISE -Debug Common Parameter
v4.0 debugger targets: Debugging cmdlets:
• Scripts • Breakpoint
• Functions • Call stack
• Workflows • Debug
• Commands • StrictMode
• Expressions • Trace

Microsoft Confidential 264


Module 7: Debugging

Section 1: Introduction Lesson 2: Customized Debugging


Information

Microsoft Confidential 265


Custom Debug Messages
[CmdletBinding()] enables debug common parameter
Write-Debug adds custom messages
-Debug displays messages and prompts to continue
Function Get-LogNN {
[CmdletBinding()]
Param ($log, $count)
Write-Debug "$(Get-Date -DisplayHint Time):Retrieving $count from $log"
Get-EventLog -LogName $log -Newest $count}

displays Write-Debug Cmdlet output

Microsoft Confidential 266


Debug Common Parameter

Custom Debug
Message

PS C:\Scripts> Get-LogNN -log system -count 2 -Debug


DEBUG: 02/25/2014 13:35:58:Retrieving 2 from system

Confirm
Continue with this operation?
[Y] Yes [A] Yes to All [H] Halt Command [S] Suspend [?] Help (default is "Y"):

Microsoft Confidential 267


$DebugPreference
Automatic Variable Valid Values

Debug information is not SilentlyContinue • Debug message is not displayed and


displayed by default execution continues w/o interruption
(Default)
PS C:\> $DebugPreference • Displays debug message and stops
SilentlyContinue Stop execution
• Writes error to console

To display debug • Displays debug message and prompts


information: Inquire user to continue

1. Change $DebugPreference, • Displays debug message and continues


or Continue with execution
2. Use -Debug common
parameter
Microsoft Confidential 268
Module 7: Debugging

Section 2: Debugging your Code Lesson 1: Breakpoints

Microsoft Confidential 269


Breakpoints

A place in the script to pause execution


Triggers the debugger environment
While paused, command prompt is prefixed with "[DBG]:"

Microsoft Confidential 270


Breakpoints

While paused, you can interact with the debug environment to:
• Examine variables
• Query runtime state
• Test conditions

Breakpoints can be set at:


• Variables (Read / Write / ReadWrite)
• Commands (Cmdlet or function)
• Line and Column Numbers
Microsoft Confidential 271
Breakpoint Cmdlets

Get-PSBreakpoint Gets breakpoints in current session


Set-PSBreakpoint Sets breakpoints on lines, variables, or commands
Disable-PSBreakpoint Turns off breakpoints in current session
Enable-PSBreakpoint Re-enables breakpoints in current session
Remove-PSBreakpoint Deletes breakpoints from current session

The Windows PowerShell ISE includes menu


items that map to some of these cmdlets.

Microsoft Confidential 272


Breakpoints – Automatic Variables

PS C:\> $NestedPromptLevel Find prompt nesting level


PS C:\> $PSDebugContext Defined in local scope
Use presence to determine whether in
debugger or not e.g.:
PS C:\> if ($PSDebugContext)
{"Debugging"} else {"Not
Debugging"}

Microsoft Confidential 273


Module 7: Debugging

Section 2: Debugging your Code Lesson 2: ISE Debugging

Microsoft Confidential 274


ISE Breakpoints
Script must
be saved
before a
breakpoint
can be set

Enabled
breakpoints
highlighted in
red

Microsoft Confidential 275


ISE Breakpoints

To set a breakpoint: List/Remove/Enable/Disable breakpoints:


• Debug menu • Debug menu
• Right-click line Toggle breakpoint • Ctrl+Shift+L/Ctrl+Shift+F9
• Press F9

Microsoft Confidential 276


ISE Debugger Commands

Once a breakpoint is reached, the line is highlighted in yellow


• Check current status of execution
• Proceed to the next line, or continue to next breakpoint
• Can step into, over, and out of nested functions or script calls

Debug Menu Shortcut


Step Into F11
Step Over F10
Step Out SHIFT+F11
Continue F5
Stop Debugger SHIFT+F5
Microsoft Confidential 277
ISE Breakpoints – Variables

Hover over
Breakpoint
variable to see
Does not work for:
• $_ its value
• $input
• $PSBoundParameters
• $Args
Microsoft Confidential 278
Module 7: Debugging

Section 2: Debugging your Code Lesson 3: Command-Line


Debugging

Microsoft Confidential 279


Command-Line Debugging
Full debugging experience in the PowerShell console

Allows debugging of scripts at runtime in production situations without ISE

For example, if setting a breakpoint on the variable $name


• Debugger begins when $name is accessed in any script, command, function or
expression in the current session
PS C:\> Set-PSBreakpoint -Script .\ScriptHelpExample.ps1 -Variable log -Mode Read

ID Script Line Command Variable Action


-- ------ ---- ------- -------- ------
7 ScriptHelpExample.ps1 log

PS C:\> .\ScriptHelpExample.ps1 -log system -numberofevents 2


Hit Variable breakpoint on 'C:\ScriptHelpExample.ps1:$log' (Read access)
[DBG]: PS C:\>>
Microsoft Confidential 280
Debugger Commands

[DBG]: PS C:\Scripts>> ?

s, stepInto Single step (step into functions, scripts, etc.)


v, stepOver Step to next statement (step over functions, scripts, etc.)
o, stepOut Step out of the current function, script, etc.
c, continue Continue operation
q, quit Stop operation and exit the debugger
k, Get-PSCallStack Display call stack
l, list List source code for the current script.
Use "list" to start from the current line, "list <m>"
to start from line <m>, and "list <m> <n>" to list <n>
lines starting from line <m>

<enter> Repeat last command if it was stepInto, stepOver or list

?, h displays this help message.

Microsoft Confidential 281


Debugger Commands

[DBG]: PS C:\Scripts>> ?

s, stepInto Single step (step into functions, scripts, etc.)


v, stepOver Step to next statement (step over functions, scripts, etc.)
o, stepOut Step out of the current function, script, etc.
c, continue Continue operation
q, quit Stop operation and exit the debugger
k, Get-PSCallStack Display call stack
l, list List source code for the current script.
Use "list" to start from the current line, "list <m>"
to start from line <m>, and "list <m> <n>" to list <n>
lines starting from line <m>

<enter> Repeat last command if it was stepInto, stepOver or list

?, h displays this help message.

Microsoft Confidential 282


Debugger Commands

[DBG]: PS C:\Scripts>> ?

s, stepInto Single step (step into functions, scripts, etc.)


v, stepOver Step to next statement (step over functions, scripts, etc.)
o, stepOut Step out of the current function, script, etc.
c, continue Continue operation
q, quit Stop operation and exit the debugger
k, Get-PSCallStack Display call stack
l, list List source code for the current script.
Use "list" to start from the current line, "list <m>"
to start from line <m>, and "list <m> <n>" to list <n>
lines starting from line <m>

<enter> Repeat last command if it was stepInto, stepOver or list

?, h displays this help message.

Microsoft Confidential 283


Debugger Commands

[DBG]: PS C:\Scripts>> ?

s, stepInto Single step (step into functions, scripts, etc.)


v, stepOver Step to next statement (step over functions, scripts, etc.)
o, stepOut Step out of the current function, script, etc.
c, continue Continue operation
q, quit Stop operation and exit the debugger
k, Get-PSCallStack Display call stack
l, list List source code for the current script.
Use "list" to start from the current line, "list <m>"
to start from line <m>, and "list <m> <n>" to list <n>
lines starting from line <m>

<enter> Repeat last command if it was stepInto, stepOver or list

?, h displays this help message.

Microsoft Confidential 284


Debugger Commands

[DBG]: PS C:\Scripts>> ?

s, stepInto Single step (step into functions, scripts, etc.)


v, stepOver Step to next statement (step over functions, scripts, etc.)
o, stepOut Step out of the current function, script, etc.
c, continue Continue operation
q, quit Stop operation and exit the debugger
k, Get-PSCallStack Display call stack
l, list List source code for the current script.
Use "list" to start from the current line, "list <m>"
to start from line <m>, and "list <m> <n>" to list <n>
lines starting from line <m>

<enter> Repeat last command if it was stepInto, stepOver or list

?, h displays this help message.

Microsoft Confidential 285


Debugger Commands

[DBG]: PS C:\Scripts>> ?

s, stepInto Single step (step into functions, scripts, etc.)


v, stepOver Step to next statement (step over functions, scripts, etc.)
o, stepOut Step out of the current function, script, etc.
c, continue Continue operation
q, quit Stop operation and exit the debugger
k, Get-PSCallStack Display call stack
l, list List source code for the current script.
Use "list" to start from the current line, "list <m>"
to start from line <m>, and "list <m> <n>" to list <n>
lines starting from line <m>

<enter> Repeat last command if it was stepInto, stepOver or list

?, h displays this help message.

Microsoft Confidential 286


Debugger Commands

[DBG]: PS C:\Scripts>> ?

s, stepInto Single step (step into functions, scripts, etc.)


v, stepOver Step to next statement (step over functions, scripts, etc.)
o, stepOut Step out of the current function, script, etc.
c, continue Continue operation
q, quit Stop operation and exit the debugger
k, Get-PSCallStack Display call stack
l, list List source code for the current script.
Use "list" to start from the current line, "list <m>"
to start from line <m>, and "list <m> <n>" to list <n>
lines starting from line <m>

<enter> Repeat last command if it was stepInto, stepOver or list

?, h displays this help message.

Microsoft Confidential 287


Debugger Commands

[DBG]: PS C:\Scripts>> ?

s, stepInto Single step (step into functions, scripts, etc.)


v, stepOver Step to next statement (step over functions, scripts, etc.)
o, stepOut Step out of the current function, script, etc.
c, continue Continue operation
q, quit Stop operation and exit the debugger
k, Get-PSCallStack Display call stack
l, list List source code for the current script.
Use "list" to start from the current line, "list <m>"
to start from line <m>, and "list <m> <n>" to list <n>
lines starting from line <m>

<enter> Repeat last command if it was stepInto, stepOver or list

?, h displays this help message.

Microsoft Confidential 288


Debugger Commands

[DBG]: PS C:\Scripts>> ?

s, stepInto Single step (step into functions, scripts, etc.)


v, stepOver Step to next statement (step over functions, scripts, etc.)
o, stepOut Step out of the current function, script, etc.
c, continue Continue operation
q, quit Stop operation and exit the debugger
k, Get-PSCallStack Display call stack
l, list List source code for the current script.
Use "list" to start from the current line, "list <m>"
to start from line <m>, and "list <m> <n>" to list <n>
lines starting from line <m>

<enter> Repeat last command if it was stepInto, stepOver or list

?, h displays this help message.

Microsoft Confidential 289


Debugging Workflows
Console or ISE
PS C:\> Set-PSBreakpoint -Script .\WF-TestSequence.ps1 -Line
3

ID Script Line Command Variable Action


-- ------ ---- ------- -------- ------
1 WF-TestSequence.ps1 3

PS C:\> . .\WF-TestSequence.ps1

PS C:\Scripts> test-seq
Hit Line breakpoint on 'C:\WF-TestSequence.ps1:3'

At C:\WF-TestSequence.ps1:3 char:9
+ sequence {
+ ~~~~~~~~~~
[WFDBG:localhost]: PS C:\>>

Microsoft Confidential 290


Debugging Workflows – Limitations

Can view workflow variables, but cannot set from debugger

When stopped in debugger Tab completion is not available

Works only with synchronous running of workflows from a script, cannot


debug workflows that run as a job

No nested debugging (e.g. workflow calling workflow, or workflow calling


script)

Microsoft Confidential 291


Debugging Functions
function Test-DebugFunction {
begin { Begin, Process,
Write-Host "Begin" and End blocks
}
process {
Write-Host "Process"
} Break at each
end {
Write-Host "End"
section
}
}
PS C:\> Set-PSBreakpoint -Command Test-DebugFunction
PS C:\> Test-DebugFunction
Hit Command breakpoint on 'Test-DebugFunction'
Stopped at: begin {
[DBG]: PS C:\>>

Microsoft Confidential 292


Debugging Remote Scripts

Enter-PSSession

Debug with breakpoints

If script hits breakpoint, client starts debugger

If disconnected session is at breakpoint, Enter-PSSession starts


debugger when reconnecting

Microsoft Confidential 293


Example: Debugging Remote Script

PS C:\> Enter-Pssession -ComputerName 2012R2-DC

[2012R2-DC]: PS C:\> Set-PSBreakpoint -Script .\ScriptEx.ps1 -Line 1

ID Script Line Command Variable Action


-- ------ ---- ------- -------- ------
0 ScriptEx.ps1 1

[2012R2-DC]: PS C:\> .\ScriptEx.ps1

[2012R2-DC]: PS C:\> .\ScriptEx.ps1


Entering debug mode. Use h or ? for help.
Hit Line breakpoint on 'C:\ScriptEx.ps1:1'

At C:\ScriptEx.ps1:14 char:5
+ Get-EventLog -LogName $log -Newest $numberofevents
[2012R2-DC]: [DBG]: PS C:\>>

294
Debugging and Scope

Breaking into debugger does not change scope

Breakpoint in script = script scope

Script scope = child of scope in which debugger was run

Use Scope parameter of Get-Alias and Get-Variable to find variables and aliases
defined in script scope, e.g.:

PS C:\> Get-Variable -Scope 0 • Returns variables in local (script) scope


• Useful to find all variables defined in
script and since debugging started

Microsoft Confidential 295


Module 7: Debugging

Section 2: Debugging your Code Lesson 4: Debugging Cmdlets

Microsoft Confidential 296


Debugging Cmdlets – Set-PSDebug
Turns script debugging features on and off
• Sets trace level
• Toggles strict mode
• Affects global scope
Set-PSDebug -Off Turns off all script debugging
Set-PSDebug -Step Steps before each line, user is prompted to:
stop, continue, or enter new interpreter level to inspect state
of script
Set-PSDebug -Strict Throws exception if a variable is referenced before a value is
assigned to it
Set-PSDebug -Trace <int32> Specifies trace level:
0 = turns off tracing
1 = each line
2 = variable assignments, function calls, and script calls
Microsoft Confidential 297
Example: Trace with PSDebug

Set-PSDebug -Trace 1
function Get-LogNN {
[CmdletBinding()]
Param ($log, $count)
Write-Debug "$(Get-Date -DisplayHint Time):Retrieving $count from $log"
Get-EventLog -LogName $log -Newest $count}
Get-LogNN -log system -count 2
PS C:\> .\fDebugEx.ps1
DEBUG: 7+ >>>> Get-LogNN -log system -count 2
DEBUG: 2+ function Get-LogNN >>>> {
DEBUG: 5+ >>>> Write-Debug "$(Get-Date -DisplayHint Time):Retrieving $count from
$log"
DEBUG: 5+ Write-Debug "$( >>>> Get-Date -DisplayHint Time):Retrieving $count from
$log"
DEBUG: 6+ >>>> Get-EventLog -LogName $log -Newest $count}

Index Time EntryType Source InstanceID Message


----- ---- --------- ------ ---------- -------
47851 Feb 25 13:48 Information Micros... 1501 The Gro...
DEBUG: 6+ Get-EventLog -LogName $log -Newest $count >>>> }

298
Debugging Cmdlets – Set-StrictMode

Set-StrictMode -Version • Affects only current scope and its child scopes
<1 or 2 or Latest>
• Specifies conditions that cause an error in strict mode
• Version determines level of enforced coding rules

• Errors when code violates best-practice, i.e.


o Reference uninitialized variable  Version 1, 2, Latest
o Reference non-existent property  Version 2, Latest
o Incorrectly called function
e.g. put arguments in parentheses or, separate arguments using
commas  Version 2, Latest
o Variable w/o a name e.g. ${}  Version 2, Latest

Note: ‘Latest’ is strictest version


(Useful when new versions are added to PowerShell)
Microsoft Confidential 299
Debugging Cmdlets – Set-StrictMode

Set-StrictMode –Off • Turns strict mode off


• Also turns off "Set-PSDebug -Strict"
• Uninitialized variables are assumed to have a value of 0 or $null
• References to non-existent properties return $null
• Unnamed variables are not permitted

Microsoft Confidential 300


Debugging Cmdlets – Get-PSCallStack

Data structure with current execution stack

Designed for use with Debugger (Option k in Breakpoint)

Use in a script or function outside debugger

Microsoft Confidential 301


Debugging Cmdlets – Get-PSCallStack

function Get-LogNN {
Param ($log, $count)
Get-EventLog -LogName $log -Newest $count
Get-PSCallStack
}

PS C:\> Get-LogNN -log system -count 2


ScriptName :
ScriptLineNumber : 4
InvocationInfo : System.Management.Automation.InvocationInfo
Position : Get-PSCallStack
FunctionName : Get-LogNN
Command : Get-LogNN
Location : <No file>
Arguments : {log=system, count=2}

Microsoft Confidential 302


Debugging Cmdlets – Trace-Command
Detailed messages about each internal processing step
Traces steps within expressions or commands
Only applies to specified expression or command
Parameter Description
-PSHost • Output options
-Debugger • Debugger can be any user-mode or kernel-mode debugger or Visual Studio
-FilePath
-Option • Type of events to trace
• E.g. None, Constructor, All, Warning, Error
-Name • Determines PowerShell components to be traced
• Too many to list, and different for each machine, list with:
Get-TraceSource | Sort-Object Name
• E.g. parameterbinding, typeconversion, cmdlet
Microsoft Confidential 303
Example: Trace parameter binding
PS C:\> Trace-Command -PSHost -Expression {Start-Process Notepad} `
-Option all -Name parameterbinding
DEBUG:1+>>>> Trace-Command -PSHost -Expression {Start-Process Notepad} -Option all -
Name parameterbinding
DEBUG:1+Trace-Command -PSHost -Expression >>>> {Start-Process Notepad} -Option all -
Name parameterbinding
DEBUG:ParameterBinding Information: 0 : BIND NAMED cmd line args [Start-Process]
DEBUG:ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Start-Process]
DEBUG:ParameterBinding Information: 0 : BIND arg [Notepad] to parameter [FilePath]
DEBUG:ParameterBinding Information: 0 : Executing VALIDATION metadata:
[System.Management.Automation.ValidateNotNullOrEmptyAttribute]
DEBUG:ParameterBinding Information: 0 : BIND arg [Notepad] to param [FilePath]
SUCCESSFUL
DEBUG:ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Start-
Process]
DEBUG:ParameterBinding Information: 0 : CALLING BeginProcessing
DEBUG:ParameterBinding Information: 0 : CALLING EndProcessing
DEBUG:1+Trace-Command -PSHost -Expression {Start-Process Notepad >>>> } -Option all -
Name parameterbinding
Module 7: Debugging

Lab

Microsoft Confidential 305


Agenda

Module 1: Review of Part 1 Concepts


Module 2: Remoting
Module 3: Advanced Functions 1
Module 4: Advanced Functions 2
Module 5: Regular Expressions (Regex)
Module 6: Error Handling
Module 7: Debugging
Module 8: Introduction to Desired State Configuration (DSC)
Module 9: Introduction to Workflow

Microsoft Confidential 306


Module 8: Introduction to
Desired State Configuration
(DSC)

Module Overview

Microsoft Confidential 307


Module 8: Intro to Desired State Configuration (DSC)
Section 1: Introduction
• Lesson 1: Overview
• Lesson 2: The Configuration
• Lesson 3: Resources
• Lesson 4: MOF Files
• Lesson 5: Local Configuration Manager (LCM)
• Lesson 6: Applying Configurations – Push
• Lesson 7: Applying Configurations – Pull

Section 2: Real-World Example


• Lesson 1: Web Site Installation and Configuration (Push)

Microsoft Confidential 308


Module 8: Introduction to
Desired State Configuration
(DSC)

Section 1: Introduction Lesson 1: Overview

Microsoft Confidential 309


What is Desired State Configuration (DSC)?

New management platform in Windows PowerShell

Enables deployment and management of a remote machine’s software and host OS

PowerShell language extensions, cmdlets, and resources to declaratively specify state

Enforce the desired state and prevent configuration drift

No procedural scripting required

Microsoft Confidential 310


Imperative vs. Declarative Language

Imperative
Add-WindowsFeature Windows-Server-Backup

Declarative
Configuration BaseBuild {
WindowsFeature Backup {
Ensure = "Present"
Name = "Windows-Server-Backup"
}
}

Microsoft Confidential
When to use DSC?
Automate configuration of a set of computers (target nodes)

Report Repair
Environment
Desired Desired Registry Scripts
Variables
State State

Users and Processes and Files and Roles and Deploy


Groups Services Directories Features Software

Option to create custom resources to configure the state of any application or system setting

Microsoft Confidential 313


What about Group Policy?

DSC GPO
• No domain needed • Only works in domain scenario
• Works with no network at all • Connectivity generally needed
• MOF based (open platform) • Born from registry control
• Resources drive scalability • Fairly easy to setup and deploy
• Not as simple to deploy • Works everywhere
• Authentication flexibility • Well-known and established
• Requires PS v4.0
• Requires remoting is enabled
• New unknown factor

Microsoft Confidential
DSC Components
Configuration

Optional Pull
Resources
Server

DSC
Local
Configuration MOF Files
Manager

Microsoft Confidential
DSC Distribution Modes (Push vs. Pull)
Authoring Staging Nodes

Config Pushed

Server1

Config Pulled
Server1.mof Configs Deployed

Server1.mof IIS Server1

Config Pulled
Server1.mof Configs Deployed

Server1.mof
File Share Server1
Microsoft Confidential 317
Module 8: Introduction to
Desired State Configuration
(DSC)

Section 1: Introduction Lesson 2: The Configuration

Microsoft Confidential 318


Configuration Script

Defines the desired configuration and separates the configuration logic ("What") from
the node data ("Where")

• Simplifies configuration data reuse


• Definitions consist of nested hash tables
• Configuration block (outer wrapper for a complete state)
• Node blocks (inner wrapper for node(s))
• Resource blocks
• Configuration data

Microsoft Confidential 319


The Configuration

Declarative end state

Simpler than a script

More like an old .ini

Microsoft Confidential
Configuration Block Configuration CreatePullServer
The outside bounds {
param
(
[string[]]$ComputerName = 'localhost'
)

Import-DSCResource -ModuleName xPSDesiredStateConfiguratio

Node Block Node $ComputerName


Machine Centric {
WindowsFeature DSCServiceFeature Resource Block
{ The workers
Ensure = "Present"
Name = "DSC-Service"
}

xDscWebService PSDSCPullServer
{
Ensure = "Present"
EndpointName = "PSDSCPullServer"
Microsoft Confidential
Port = 8080
Configuration CreatePullServer
{
param
Optional Param Block
(
[string[]]$ComputerName = 'localhost'
)

Import-DSCResource -ModuleName xPSDesiredStateConfiguratio

Node $ComputerName
{
WindowsFeature DSCServiceFeature
Valid Resource Name Cosmetic Name
{
Ensure = "Present"
Name = "DSC-Service"
}

xDscWebService PSDSCPullServer
{
Ensure = "Present"
Resource Properties EndpointName = "PSDSCPullServer"
Port Microsoft Confidential = 8080
Ensure = "Present"
EndpointName = "PSDSCComplianceServer"
Port = 9080
PhysicalPath = "$env:SystemDrive\inetpub\wwwroot\PSDSCC
CertificateThumbPrint = "AllowUnencryptedTraffic"
State = "Started"
IsComplianceServer = $true
DependsOn = ("[WindowsFeature]DSCServiceFeature","[x
}
}
}

CreatePullServer -ComputerName WebServer01.contoso.com -OutputPath c:\dsc\

Execute Configuration Target Node Name Location of MOFs


MOF file(s) created MOF file(s) created In folder named for Config

Microsoft Confidential
Module 8: Introduction to
Desired State Configuration
(DSC)

Section 1: Introduction Lesson 3: Resources

Microsoft Confidential 324


DSC Resources

Resources implement the configuration

Contain the PowerShell code to get to the desired state

Configurations generally combine resource settings and dependencies

Contained within modules

Microsoft Confidential
Where to get resources

Windows PowerShell v4.0 ships with 12 built-in resources

Download additional resources from Microsoft as Resource Kits hosted on the TechNet
Script Center

Create custom resources

Microsoft Confidential
Built-in DSC Resources
Provider Description
Archive Unpacks archive (.zip) files at specific paths
Environment Manages system environment variables
File Manages files and directories
Group Manages local groups
Log Logs configuration messages
Package Installs and manages Windows Installer and setup.exe packages
Process Configures Windows processes
Registry Manages registry keys and values
Role Adds or removes Windows features and roles
Script Runs PowerShell script blocks
Service Manages services
User Manages local user accounts
Microsoft Confidential 327
Additional Resources

Microsoft has released multiple "waves" via resources kits


Download from TechNet Script Center
Many community resources available
Once released, use PowerShellGet to find/install resources
https://github.com/powershell is the home for the ResKit since Wave 10.

Microsoft Confidential
Create Custom Resources

Use xDSCResourceDesigner Module (much easier)

Create an empty parent module

Create resource sub-modules (1 per resource)

Standard functions required for each


• Get-TargetResource
• Set-TargetResource
• Test-TargetResource

Microsoft Confidential
*-TargetResource Functions

Functions contain PowerShell code necessary to implement the state

Code will differ based on target technology

Specific output requirements of each function

• Get-TargetResource function returns the current state.


• Set-TargetResource function sets the system state.
• Test-TargetResource function compares the current state to the desired state.

Microsoft Confidential
File Structure Overview

$env: psmodulepath (folder)


|- <ModuleName> (folder)
|- <ModuleName>.psd1 (file)
|- DSCResources (folder)
|- <ResourceName1> (folder)
|- <ResourceName1>.psm1 (file, required)
|- <ResourceName1>.schema.mof (file, required)
|- <ResourceName2>(folder)
|- <ResourceName2>.psm1 (file, required)
|- <ResourceName2>.schema.mof (file, required)

Microsoft Confidential
Module 8: Introduction to
Desired State Configuration
(DSC)

Section 1: Introduction Lesson 4: MOF Files

Microsoft Confidential 332


1. Author Configuration

Configuration SimpleConfig 3. MOF Files Automatically Created


{
$Nodes = '2012R2-MS','2012R2-DC','WIN8-WS'
Node $Nodes
Directory: C:\dsc\SimpleConfig
{
File CreateFolder Mode Length Name
----- ------ ----
{ -a--- 1266 2012R2-
DestinationPath = 'c:\temp\' MS.mof
Ensure = 'Present' -a--- 1266 2012R2-
DC.mof
Type = 'Directory' -a--- 1262 WIN8-WS.mof
}
}
}

2. Execute Configuration

SimpleConfig -OutputPath c:\dsc\SimpleConfig

Microsoft Confidential
Managed Object Format

DSC Middle-Man

Per Node
In Pull Mode, node names
are abstracted with a GUID

Cross Platform

Microsoft Confidential
Module 8: Introduction to
Desired State Configuration
(DSC)

Section 1: Introduction Lesson 5: Local Configuration


Manager (LCM)

Microsoft Confidential 335


Local Configuration Manager (LCM)

Local Configuration Manager is the engine that applies the configuration

Two ways to apply a configuration to nodes


• Manual Push
• Automatic Pull

One configuration per node (v4)

Microsoft Confidential 336


LCM Options
LCM is configured through a DSC configuration (normally pushed once)
LocalConfigurationManager
{
Configuration to pull ConfigurationID = "646e48cb-3082-4a12-9fd9-f71b9a562d4e"
ConfigurationModeFrequencyMins = 90
ApplyAndAutoCorrect ConfigurationMode = "ApplyAndAutocorrect"
ApplyAndMonitor
ApplyOnly
RefreshFrequencyMins = 45
DownloadManagerName = "WebDownloadManager"
Push vs. Pull RefreshMode = "Pull"
DownloadManagerCustomData =
Pull Server Location (@{ServerUrl="https://$PullServer/psdscpullserver.svc"})
CertificateID = "71AA68562316FE3F73536F1096B85D66289ED60E"
Credential = $cred
RebootNodeIfNeeded = $true
AllowModuleOverwrite = $false
}

337
Microsoft Confidential
Module 8: Introduction to
Desired State Configuration
(DSC)

Section 1: Introduction Lesson 6: Applying


Configurations - Push

Microsoft Confidential 338


Push a Configuration
Create
Configuration

Run Configuration
to Create MOF
File(s)

Push
Configuration to
Target(s)

Microsoft Confidential
Single MOF

PS> Start-DSCConfiguration –Path c:\MOFs\

Configuration Pushed

Server1.mof
Server1

Microsoft Confidential
Many MOFs

PS> Start-DSCConfiguration –Path c:\MOFs\

Configuration Pushed

Server1.mof
Server1

Configuration Pushed
Server2.mof
Server2

Configuration Pushed
Server3.mof
Server3
Microsoft Confidential
Module 8: Introduction to
Desired State Configuration
(DSC)

Section 1: Introduction Lesson 7: Apply Configurations -


Pull

Microsoft Confidential 342


Pull Servers

Possible Server Modes


• HTTPS Web Server
• HTTP Web Server File Share
• SMB File Share

Local configuration manager


on target node pulls the
configuration

Microsoft Confidential
Overview - Setting up for Pull
Authoring
Run Config ,
and Staging Create Pull
Create Config which creates
Server
MOF File(s)

Checksum MOFs Place MOFs and


Rename MOFs
and Resource Modules on Pull
with GUIDs
Modules Server

Per Node
Targets Pull
Configure LCM
Config and
on targets
Apply

Microsoft Confidential
Resources and Clients

Push Configuration
• Resource manually deployed

Pull Configuration
• Pull server stores needed modules
• Pull client downloads modules based on configuration

Microsoft Confidential
Module 8: Introduction to
Desired State Configuration
(DSC)

Section 2: Real-World Example Lesson 1: Web Site Installation


and Configuration (Push)

Microsoft Confidential 346


Example 1:
Push Mode – Web Site Installation and Configuration

Preparation:
Define Goals

Step 1:
Create Custom Resources (if required)

Step 2:
Define Configuration

Step 3:
Create consumable MOF File

Step 4:
Push Configuration to target node(s)

Microsoft Confidential 347


Preparation: Define Setting Value
Goals (List Settings Ensure IIS is installed Yes
and Desired Values) Define Web Server Name Web-Server
Define DestinationPath c:\inetpub\wwwroot
(Desired location to ensure state for
a file or directory)

Ensure subdirectories exist Yes


Define SourcePath Specify with parameter (to make
(Path to copy from) code more dynamic)

Microsoft Confidential 348


Step 1: Create Not required for this example – Built-in resources will be used
Custom Resources
(if required)

Microsoft Confidential 349


Configuration MyWebConfig
{
param ($MachineName, $WebsiteFilePath)
Node $MachineName
{ Node Block
Step 2: Define WindowsFeature IIS
Windows Feature Resource Block
Configuration {
Ensure = "Present"
Name = "Web-Server"
}
File WebDirectory
{
Ensure = "Present"
Type = "Directory" File Resource Block
Recurse = $true
SourcePath = $WebsiteFilePath
DestinationPath = "C:\inetpub\wwwroot"
DependsOn = "[WindowsFeature]IIS"
}
}
}

Microsoft Confidential 350


Step 3: Create • Run Configuration in previous step
Consumable MOF • Create a Consumable MOF File
File PS C:\> MyWebConfig `
-MachineName om12ms `
-WebsiteFilePath "c:\scripts\inetpub\
wwwroot"

Directory: C:\MyWebConfig
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 10/02/2014 3:45 PM 1878 om12ms.mof

‘MyWebConfig’ directory and ‘om12ms.mof’ file is created

Microsoft Confidential 351


Step 4: Push Configuration

Apply MOF File using Push Mode


PS C:\> Start-DscConfiguration –Path .\MyWebConfig –Wait –Verbose

VERBOSE: Perform operation 'Invoke CimMethod' with following


parameters, ''methodName' =
SendConfigurationApply,'className' =
MSFT_DSCLocalConfigurationManager,'namespaceName' =
root/Microsoft/Windows/DesiredStateConfiguration'.
VERBOSE: An LCM method call arrived from computer OM12 with user sid
S-1-5-21-3390618620-1605188856-1237132424-500.
...
VERBOSE: Operation 'Invoke CimMethod' complete.
VERBOSE: Time taken for configuration job to complete is 181.518 sec…

Note: The configuration is applied immediately to the target node


Microsoft Confidential 352
Detecting Configuration Drift

Compare current and actual configuration


PS C:\> $Session = New-CimSession –ComputerName "om12ms"
PS C:\> Test-DscConfiguration –CimSession $session
Returns "True" if the configuration matches and "False" if it does not match

Microsoft Confidential 353


Module 8: Introduction to
Desired State Configuration
(DSC)

Lab

Microsoft Confidential 354


Agenda

Module 1: Review of Part 1 Concepts


Module 2: Remoting
Module 3: Advanced Functions 1
Module 4: Advanced Functions 2
Module 5: Regular Expressions (Regex)
Module 6: Error Handling
Module 7: Debugging
Module 8: Introduction to Desired State Configuration (DSC)
Module 9: Introduction to Workflow

Microsoft Confidential 355


Module 9: Introduction to
Workflow

Module Overview

Microsoft Confidential 356


Module 9: Introduction to Workflow

Section 1: Introduction
• Lesson 1: Overview
• Lesson 2: Authoring
• Lesson 3: Activities and Keywords
• Lesson 4: Workflow Execution
• Lesson 5: Checkpoints and Failure Recovery

Microsoft Confidential 357


Module 9: Introduction to
Workflow

Section 1: Introduction Lesson 1: Overview

Microsoft Confidential 358


What is a PowerShell Workflow?

Function-like command consisting of an ordered sequence of


related activities

Can survive a Looks like


Can run in Can be paused
reboot or PowerShell
parallel and resumed
failure Script

Microsoft Confidential 359


Based on Windows Workflow Foundation (WF)

An extensive product that spans many Microsoft products including Visual Studio and
the .NET Framework

A mechanism that facilitates running complex activities sequentially or in parallel, with


the ability to recover from interruptions

Consist of an ordered sequence of related tasks, known as activities

Activities are authored in Visual Studio in native Windows Workflow Foundation (WF)
Extensible Application Markup Language (XAML) format
PowerShell Workflows reap all the benefits, but are authored in PowerShell script.

Microsoft Confidential Microsoft Confidential 360


Summary of PowerShell Workflow Benefits
Interruptible
• Disconnection and re-connection
• Automated failure recovery (state and data persistence)
• Connection and activity retries

Parallelizable
• Easier to implement than background jobs or runspace pooling

Scalable
• Leverage the power of the Windows Workflow Foundation (WF)

Authored using PowerShell Syntax


• PowerShell converts syntax to WF XAML format
• WF native language supports scalable and remote, multi-device management

Microsoft Confidential Microsoft Confidential 361


Workflow Prerequisites

PowerShell v3.0+ installed on local workflow host (in-process)

PowerShell v3.0+ installed on remote workflow host (out-of-process)

Enable PowerShell Remoting for remote workflow execution


Also required if running workflow locally in a workflow session

Import PSWorkflow module to access workflow help topics

Microsoft Confidential Microsoft Confidential 362


Workflows Consist Of:

Client computer, Local or Remote Managed nodes -


which triggers the Session to Run the target computers
workflow Workflow affected by the
workflow activities

Microsoft Confidential 363


Workflow Execution Models
Out-of-Process

Role Minimum Requirements


PowerShell 2.0
Workflow Client
.NET Framework 2.0
PowerShell 3.0
Workflow Server
.NET Framework 4.0

Managed Node
In-Process

Roles on same machine

Microsoft Confidential Microsoft Confidential 364


In-Process Workflow Architecture
Workflow Engine runs locally within the PowerShell host
Workflow stops when its host process is terminated

Client Managed Node


Activity Host Process

Workflow
Activity PowerShell
Host Remoting
Host

Managed Node

PowerShell
PowerShell
Workflow
Workflow Executive CIMOM/WMI
Cmdlets

PowerShell.exe

Microsoft Confidential Microsoft Confidential 365


Out-of-Process Workflow Architecture
Workflow engine executes in a local or remote workflow session
• Client connects to Microsoft.PowerShell.Workflow session configuration on workflow host
• Client can disconnect without disrupting workflow

Client Workflow Managed Node


Host Activity Host Process

PowerShell
Activity Remoting
Host
PSJobProxy/
JobAPI/
PSRemoting

Managed Node

CIMOM/
WinRM WinRM PSWF Executive WMI
Client Service (wsmanprovhost.exe)

Microsoft Confidential Microsoft Confidential 366


Functions vs. Workflows

Function Workflow
Serial execution Parallel execution
Run to completion and return Can be paused, stopped and restarted
State is lost during an unexpected outage State is maintained, if requested, and is
recoverable after an unexpected outage
Run in the PowerShell Host engine context Run in the Windows Workflow engine context
Logging and recovery have to be implemented Logging and recovery are included
by the author
Commands, functions and cmdlets run in the Each activity executes in its own environment
same environment
Must be executed remotely using PowerShell Remote execution available using the
Remoting –PSComputerName workflow common parameter

Microsoft Confidential Microsoft Confidential 367


Module 9: Introduction to
Workflow

Section 1: Introduction Lesson 2: Authoring

Microsoft Confidential 368


Authoring a Workflow

Workflow Activities
Keyword Core Cmdlet / Workflow Script

Foreach Activity
Command Common
Inlinescript Parallel Sequence Common
Keyword Parameters –Parallel Parameters

Microsoft Confidential
Workflow Syntax
Uses the same syntax as a Windows PowerShell function
Supports common function parameters & CmdletBinding
Allows workflow common parameters to be specified

Workflow Syntax
workflow Test-Workflow
{
[CmdletBinding()]
Param([Parameter()]$Param1)

[<Activity>]
[<Activity>]
...
}

Microsoft Confidential Microsoft Confidential 370


Workflow Common Parameters

Available on all workflows and activities

Parameters must be named and not used positionally

Used to configure connection environment

PSParameterCollection PSComputerName PSCredential


PSConnectionRetryIntervalSec PSRunningTimeoutSec PSElapsedTimeoutSec
PSAuthentication PSAuthenticationLevel PSApplicationName
PSUseSSL PSConfigurationName PSConnectionURI
PSSessionOption PSCertificateThumbprint PSPrivateMetadata
JobName PSPersist PSAllowRedirection
PSConnectionRetryCount PSPort AsJob
Microsoft Confidential Microsoft Confidential 371
Example:
Workflow
common
parameters Workflow
common
parameters

Important Parameters
• PSPersist - Force workflow to checkpoint workflow state and data after each activity
• PSComputerName - A list of computers to run workflow against
Process to Design a Workflow

Can the task be performed using simpler methods, such as Functions, Remoting or Jobs?
List Tasks to perform
Organize Tasks into Activities
Each activity should use a PowerShell cmdlet or custom function

Add a Checkpoint after each step

Identify Sequential Tasks


Identify Parallel Tasks
Identify child commands that must be executed sequentially

Microsoft Confidential 373


Module 9: Introduction to
Workflow

Section 2: Workflow Features Lesson 3: Activities and Keywords

Microsoft Confidential 374


Workflow Activities

Basic unit of workflow


• A workflow is composed of one or more activities
• Activities run independently of one another
• Allows for sequential and parallel execution
• Workflows can be nested

Two groups of activities


• Core cmdlet activities
• Workflow script activities

Microsoft Confidential Microsoft Confidential 375


Example:
Define a workflow with only one activity
Single
Activity workflow SingleActivity-WF {
Workflow #Activity 1
Start-Process -FilePath $env:SystemRoot\notepad.exe
}
Run workflow
PS C:\> SingleActivity-WF

Check the type of command


PS C:\> Get-Command SingleActivity-WF

CommandType Name ModuleName


----------- ---- ----------
Workflow SingleActivity-WF

376
Example: Multiple Activity Workflow

Define a workflow containing two activities


workflow MultiActivity-WF {
#Activity 1
Start-Process -FilePath $env:SystemRoot\notepad.exe
#Activity 2
Get-Process -Name notepad
}
Run workflow – Each activity runs independently of the other!
PS C:\> MultiActivity-WF

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName PSComputerName


------- ------ ----- ----- ----- ------ -- ----------- --------------
78 8 1220 5840 102 0.03 19892 notepad Localhost

377
Core Cmdlet Activities
Core cmdlets have been packaged as workflow activities
• Some cmdlets have been excluded

All activities are executed within their own workflow session


• If an activity matching the cmdlet name is not found, the command is run using the InlineScript Activity

• Microsoft.PowerShell.Core (PSSnapin)
• Microsoft.PowerShell.Host
Core Modules • Microsoft.PowerShell.Diagnostics
Containing Cmdlet • Microsoft.PowerShell.Management
• Microsoft.PowerShell.Security
Activities • Microsoft.PowerShell.Utility
• Microsoft.Wsman.Management

Microsoft Confidential Microsoft Confidential 378


Activity Common Parameters

• Override workflow common parameters


• Available on InlineScript activity and cmdlets implemented as activities

AppendOutput PSDebug Debug PSComputerName


PSDisableSerialization DisplayName PSError PSWarning
ErrorAction PSPersist Input PSConfigurationName
PSPort MergeErrorToOutput PSProgress Result
PSActionRetryCount PSProgressMessage PSActionRetryIntervalSec PSConnectionRetryCount
PSRemotingBehavior PSActionRunningTimeoutSec PSRequiredModules UseDefaultInput
PSApplicationName PSSessionOption PSAuthentication PSConnectionRetry-IntervalSec
PSUseSSL PSCertificateThumbprint PSVerbose Verbose
PSConnectionURI WarningAction PSCredential
Microsoft Confidential 379
Example:
Core cmdlet
as activity and
activity
common
parameters

Activity
Common
Parameters


Example: Core cmdlet not packaged as a workflow activity

PS C:\> workflow simplewf {Write-Host "Starting workflow..." `


-ForegroundColor Green}

At line:1 char:20
+ workflow simplewf {Write-Host "Starting workflow..." -
ForegroundColor Green}
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Cannot call the 'Write-Host' command. Other commands from this
module have been packaged as workflow activities, but this
command was specifically excluded. This is likely because the
command requires an interactive Windows PowerShell session, or
has behavior not suited for workflows. To run this command
anyway, place it within an inline-script (InlineScript
{ Write-Host }) where it will be invoked in isolation.
+ CategoryInfo : ParserError: (:) [],
ParseException
+ FullyQualifiedErrorId : CommandActivityExcluded

381
Workflow Activities and Keywords

InlineScript • Executes ‘standard’ cmdlets in separate PowerShell runspace

Sequence • Control order of execution of multiple activities

Parallel • Run multiple activities in parallel

ForEach –Parallel • Iterate through a collection and execute each item in parallel

Checkpoint-Workflow • Create on disk representation of workflow state

Suspend-Workflow • Suspend workflows – resumed using standard *-Job cmdlets

Get-PSWorkflowData • Return workflow common parameters

Set-PSWorkflowData • Used to modify workflow common parameters

Microsoft Confidential 382


InlineScript Keyword
Executes a script block within a workflow as a regular script
Only valid when declared within a workflow
Useful for calling .NET methods (not possible in a native workflow activity)
Runs in its own process
Unless InlineScript value removed from session configuration OutOfProcessActivity property
Workflow features & variables are not inherited
$Using scope variable is supported

Syntax
InlineScript
{
<Scriptblock>
} <ActivityCommonParameters>

Microsoft Confidential Microsoft Confidential 383


Example: Call .NET method in a workflow using InlineScript

Define a workflow that calls a .NET method – without using an InlineScript block

workflow DotNetMethod {
(Get-Service -Name BITS).Stop()
}

PS C:\> workflow DotNetMethod {


(Get-Service -Name BITS).Stop()}
At line:2 char:1
+ (Get-Service -Name BITS).Stop()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Method invocation is not supported in a Windows PowerShell
Workflow. To use .NET scripting, place your commands in an
inline script: InlineScript {<commands> }.
+ CategoryInfo : ParserError: (:) [],
ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MethodInvocationNotSupported
Example: Call .NET method in a workflow using InlineScript

Define a workflow that calls a .NET method – within an InlineScript block


workflow DotNetMethod {
InlineScript {
(Get-Service -Name BITS).Stop()
}
}
Run workflow
PS C:\> DotNetMethod
Parallel Activity
It is possible to run activities in Parallel
Performance benefit
Only valid when declared within a workflow
Command execution runs in arbitrary order

Parallel activity
Parallel
{
[<Activity>]
[<Activity>]
...
}

Microsoft Confidential 386


Sequence Activity

Forces commands to run in order within a Parallel script block


Only valid when declared within a workflow

Sequence activity
Sequence
{
[<Activity1>]
[<Activity2>]
...
}

Microsoft Confidential 387


Example 1: Parallel and Sequential Execution

workflow test-seq {
parallel {
sequence {
Start-Process cmd.exe
Get-Process -Name cmd
} Script blocks
sequence { execute in parallel,
Start-Process notepad.exe individual activities
Get-Process -Name notepad
} execute in order
}
}

PS C:\> test-seq
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName PSComputer
Name
------- ------ ----- ----- ----- ------ -- ---------- ----------
27 3 1464 2292 12 0.00 9780 cmd localhost
95 8 1320 6608 104 0.03 16324 notepad localhost
Example 2: Multiple Activities with Parallel and Sequential Tasks

workflow Test-Workflow
{
Get-Service –Name Dhcp # workflow activity
Get-WindowsFeature –Name RSAT # Automatic InlineScript activity
Parallel
{
Sequence
{
Stop-Service -Name Dhcp
Start-Service -Name Dhcp
}
Sequence
{
Stop-Service -Name Bits
Start-Service -Name BITS
}
}
}

389
ForEach –Parallel Activity
Collection items can also be processed in Parallel

Only valid when declared within a workflow

Commands in the Script Block are run Sequentially

ThrottleLimit parameter (v4.0) allows throttling the number concurrent of connections


-Parallel Parameter
ForEach -Parallel ($<item> in $<collection>)
{
[<Activity1>]
[<Activity2>]
...
}

Microsoft Confidential 390


Module 9: Introduction to
Workflow

Section 1: Introduction Lesson 4: Workflow Execution

Microsoft Confidential 391


Controlling a Workflow

Controlling Execution Workflow Cmdlets

New-
New-
Check PSWorkflow Invoke-
Execute Suspend Resume PSWorkflow
Point Execution AsWorkflow
Session
Option

Microsoft Confidential
Execute a Workflow (In-Process)

Workflows are called by name like a function


In-Process execution is launched in current PowerShell session

Workflow Test-Workflow {Get-Process -Name System}


Test-Workflow
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
PSComputerName
------- ------ ----- ----- ----- ------ -- -----------
--------------
1333 0 136 4772 16 4 System localhost

Microsoft Confidential 393


Workflow Cmdlets

Run any command or expression as a simple workflow


Invoke-AsWorkflow

Create workflow session on Workflow Server Role (same or different machine)


Cmdlet is basically a New-PSSession against the ‘Microsoft.PowerShell.Workflow’ endpoint
New-PSWorkflowSession
Once the session is established, the workflow is invoked in the session like an in-process
workflow

Customize workflow session endpoint


Creates a new PSWorkflowExecutionOption object
New-PSWorkflowExecutionOption

Microsoft Confidential 394


Execute a Workflow (Out-of-Process)

Out-of-Process execution is launched in a dedicated PowerShell Session


• Same computer
• Different computer

When launching out-of-process on another machine


• Workflow must exist on that machine
• Typically deploy module containing the workflow
• For simple workflows, define then execute

Microsoft Confidential 395


Example : Executing Out-of-Process Workflow

$Workflow = {Workflow Test-Workflow {Get-Process -Name System}}

#Establish a remote workflow session


$Wfs = New-PSWorkflowSession -ComputerName 2012R2-MS

#Define the workflow in the session (local or remote)


Invoke-Command -Session $Wfs -ScriptBlock $Workflow

#Execute the workflow in the session (local or remote)


Invoke-Command -Session $Wfs -ScriptBlock {Test-Workflow -PSPersist $true}

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName PSComputerName


------- ------ ----- ----- ----- ------ -- ----------- --------------
639 0 112 276 3 70.88 4 System 2012R2-MS

396
Example : Initiating Workflow from PSv2.0+ on PSv3.0+ Workflow host

$ServerList = Get-ADComputer -Filter * |


Select-Object -ExpandProperty Name

$wfs = New-PSSession –ComputerName 2012R2-MS –ConfigurationName Microsoft.PowerShell.workflow

# invoke command in the workflow session on remote hosts


Invoke-Command –Session $wfs –Scriptblock {
myWorkflow –PSComputername $using:ServerList
}

397
Module 9: Introduction to
Workflow

Section 1: Introduction Lesson 5: Checkpoints and Failure


Recovery

Microsoft Confidential 398


Checkpointing Workflows

A checkpoint is a snapshot of the workflow execution state


• Variables, Data, Output

Used to save state after expensive operations


Avoids re-executing previous code in the event of crash
Saved to the machine hosting the workflow session, not on the targets nodes
Default Location
• c:\Users\<username>\AppData\Local\Microsoft\Windows\PowerShell\WF\PS\default\<user SID>

Microsoft Confidential 399


Checkpoint-Workflow
Keyword only valid inside workflows
Creates a checkpoint at that moment
Cannot be placed within an InlineScript block
No parameters (common or otherwise)
Workflow Get-FileData
{
$LargeResults = Get-CimInstance -ClassName CIM_DataFile

#Save workflow after large WMI Query


Checkpoint-Workflow
Foreach -parallel ($Item in $LargeResults)
{
[PSCustomObject]@{FileName=$Item.Name ; FilePath=$Item.Path}
}
}

Microsoft Confidential 400


Workflow Common Parameter –PSPersist
PSPersist workflow common parameter:
• $True: Automatically creates checkpoint after every single activity
• $False: Checkpoints only when explicitly specified in workflow (Checkpoint-Workflow)
Invoke-Command -Session $Wfs -ScriptBlock {Test-Workflow}
WARNING: [localhost]:This workflow job cannot be suspended because there are no
checkpoints (also called persistence points) in the workflow. To make the workflow job
suspendable, add checkpoints to the workflow.

For more information about how to add checkpoints, see the help topics for Windows
PowerShell Workflow.
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName PSComputerName
------- ------ ----- ----- ----- ------ -- ----------- --------------
639 0 112 276 3 70.88 4 System 2012R2-MS

Invoke-Command -Session $Wfs -ScriptBlock {Test-Workflow -PSPersist $True}


Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName PSComputerName
------- ------ ----- ----- ----- ------ -- ----------- --------------
639 0 112 276 3 70.88 4 System 2012R2-MS
Microsoft Confidential 401
Activity Common Parameter –PSPersist

Creates a checkpoint after that activity completes


Not valid on expressions or commands in an InlineScript block
$True: Adds checkpoint after activity completes

Example
Workflow Test-Workflow
{
Get-Process -Name wsmprovhost -PSPersist $True
}

Microsoft Confidential 402


Controlling Workflow Execution – $PSPersistPreference Variable

Toggles automatic checkpointing

If $True, checkpoint will be created after each activity (same as –PSPersist $True)

Example
Workflow Test-Workflow {
$WinRm = Get-Service Winrm
$PSPersistPreference = $true
$Assets = InlineScript {\\Server\Share\Get-Data.ps1}
...
$PSPersistPreference = $false
Parallel
{...}

Microsoft Confidential 403


Recovering from Failures

Must utilize checkpoint(s)

If Workflow host crashes, workflow becomes a suspended workflow job

Resume-Job will manually resume the workflow from the last checkpoint

Can create a scheduled job (on startup) to automatically resume suspended workflows

• Restart-Computer –Wait - on remote nodes will automatically resume on node

• On workflow host, workflow will gracefully checkpoint, and must be resumed

Microsoft Confidential 404


Controlling Workflow Execution – Suspend-Workflow
Suspends workflow from within
Checkpoint created before suspension
Resume same as recovering from failure

Example
workflow Test-Suspend {
$a = Get-Date
Suspend-Workflow
(Get-Date) - $a
}

Note: A workflow cannot be resumed from within the workflow itself

Microsoft Confidential 405


Controlling Workflow Execution – Checkpoints

Checkpoint on a set of activities in a pipeline is not taken until pipeline completes

Checkpoints on activities in a Parallel script block are not taken until Parallel script
block has run on all target computers

Checkpoints on activities in a Sequence script block, are taken after each activity
completes on the target computers

Microsoft Confidential 406


Module 9: Introduction to
Workflow

Lab

Microsoft Confidential 408


PowerShell best practices

Microsoft Confidential 409


Windows PowerShell best practices
Scripts
• Write your code for someone else to read
• Comment your code where warranted
• Add help documentation to your script or function, with examples
• Use native PowerShell, rather than equivalent external commands
• One function implements one task (Verb-Noun)
• Expand all aliases
• Let the ISE expand the Cmdlet (using <TAB>) for spelling and correct case
• Use code-signing for production scripts
• Invoke-Expression can be used for code-injection, so use carefully
• Declare all variables in scope before use
• Use the Module concept to group related functions into a single suite

Pipeline
• Filter to the left, format to the right
• Accept input from the pipeline and send output to the pipeline
Windows PowerShell best practices - continued
Functions
• Use named parameters (avoid positional parameters)
• Include [CmdletBinding()] to enable common parameters. Requires a Param() statement
• Use Write-Verbose, Write-Error and Write-Debug cmdlets to leverage Cmdlet binding
• Use [OutputType()] in your functions (enables IntelliSense)
• If a parameter refers to a file path, name the parameter PATH or use an alias of PATH
• Name your parameters using the existing cmdlet naming conventions.
• Assign default values to function parameters
• Specify validation attributes for function parameters
• Use Out-* and Write-* cmdlets properly. Write-Host only emits to the host application
• Make use of switch parameters to enact different behaviours
• Implement –WhatIf for dangerous choices

Errors
• Ensure you have error handling in place
• Use try{} catch{} finally{} blocks rather than $errorActionPreference
• Avoid single empty catch-blocks
Clickicon
Click icon to add
to add picture
picture Click icon to add p

PowerShell v4.0 for the IT


Professional
Part 2

Thank You
Microsoft Confidential 413
Appendix: PowerShell and
the Web

Module Overview

Microsoft Confidential 414


Appendix: PowerShell and the Web

Section 1: Web Access


• Lesson 1 – PowerShell Web Access

Section 2: Web Services


• Lesson 1 – PowerShell Web Services

Section 3: Web Cmdlets


• Lesson 1 – Web Cmdlets

Microsoft Confidential 415


Appendix: PowerShell and the
Web

Section 1: Web Access Lesson 1: PowerShell Web Access


(PSWA)

Microsoft Confidential 416


Overview

PowerShell console in a Web Browser


Built for tablets and mobile devices as well as PCs

Perimeter Internal
Network Network

Internet

PowerShell
Web Access
Gateway
Server

Microsoft Confidential Microsoft Confidential 417


Browser Experience

Microsoft Confidential Microsoft Confidential 418


Features and Requirements

Features
• Cross-platform access (tablets, smartphones, browsers)
• No extra cost or license
• Includes role configuration cmdlets
• Any browser with HTTPS, cookies and JavaScript enabled
• Save button in console allows disconnect/reconnect to an existing session without losing data

Requirements
• Windows Server 2012 (or later)
• IIS 8.0 Web Role

Microsoft Confidential Microsoft Confidential 419


Install & Configuration
Three step setup

1. Install PSWA Windows feature


PS C:\> Install-WindowsFeature WindowsPowerShellWebAccess

2. Install PSWA web application


PS C:\> Install-PswaWebApplication –UseTestCertificate

3. Add PSWA authorization rules to control and secure access


PS C:\> Add-PswaAuthorizationRule -ConfigurationName * `
–UserName * -ComputerName *
PS C:\> Add-PswaAuthorizationRule -ConfigurationName * `
–UserGroupName * –ComputerGroupName *

This example code is only appropriate for use in a test lab scenario. An unsecured, self-signed certificate is in use. The
PSWA authorization rule is set up without restrictions on users, computer destination, or session constraints. For a
production implementation far more security would be required.

Microsoft Confidential Microsoft Confidential 420


Security Summary

Internet

Enterprise Firewall
PowerShell Web Access Gateway
IIS Authentication Client Certificate
PSWA Form Authentication
PSWA Authorization Rules
Firewall PowerShell Web Access Deployed on Internet

Internal PowerShell Endpoint


Local permissions & rights PowerShell Web Access Gateway
PSSessionConfiguration IIS Authentication Client Certificate
(SDDL, Visible Cmdlets, RunAs) PSWA Form Authentication Domain Authentication
WinRM (Listener, Service) PSWA Authorization Rules
Firewall Firewall PowerShell Web Access Deployed Internally

Microsoft Confidential Microsoft Confidential 421


Appendix: PowerShell and the
Web

Section 2: Web Services Lesson 1: PowerShell Web


Services

Microsoft Confidential 422


PSWS Overview
Formerly called Management OData IIS Extension
Framework for exposing PowerShell cmdlets and scripts through an OData-based web
service running in an IIS Web Server
IIS processes OData requests and converts them into a PowerShell invocation
Provides remote access to run cmdlets from both Windows-based and non-Windows-based
client computers or devices
Users can build on top of this infrastructure to create RESTful web endpoints that expose
sets of Management Data (e.g. a set of PowerShell cmdlets to manage Windows Services and Processes)
Creating a Management OData Web Service
http://msdn.microsoft.com/library/windows/desktop/hh880865.aspx

Microsoft Confidential 423


Appendix: PowerShell and the
Web

Section 3: Web Cmdlets Lesson 1: Web Cmdlets

Microsoft Confidential 424


Invoke-WebRequest

Needs PowerShell v3 (or later)

Used to access Web content

Returns HTTPWebResponseObject

Microsoft Confidential 425


Explore a Web Request Object - Type

Create Web Request Object


PS C:\> $PSBlog = Invoke-WebRequest –Uri
http://blogs.msdn.com/b/powershell
Return Object Type
PS C:\> $PSBlog.GetType().FullName

Microsoft.PowerShell.Commands.HtmlWebResponseObject

Microsoft Confidential 426


Explore a Web Request Object - Methods

List Methods

PS C:\> $PSBlog | Get-Member -MemberType Method | Select-Object Name

Name
----
Equals
GetHashCode
GetType
ToString

Microsoft Confidential 427


Explore a Web Request Object - Properties

List Properties
PS C:\> $PSBlog | Get-Member -MemberType Properties | Format-Wide -Column 2

AllElements BaseResponse
Content Forms
Headers Images
InputFields Links
ParsedHtml RawContent
RawContentLength RawContentStream
Scripts StatusCode
StatusDescription

Microsoft Confidential 428


Example: Invoke-WebRequest

Web Request Object


PS C:\> $PSBlog = Invoke-WebRequest `
–Uri http://blogs.msdn.com/b/powershell
Return links to tagged content
PS C:\> $PSBlog.links.href | ? {$_ -match "tags"}

http://blogs.technet.com/b/josebda/archive/tags/hyper_2d00_v/
http://blogs.technet.com/b/wincat/archive/tags/virtualization/
http://blogs.technet.com/b/askcore/archive/tags/hyper_2d00_v/
http://blogs.technet.com/b/askcore/archive/tags/failover+cluster/
http://blogs.msdn.com/b/powershell/archive/tags/Advanced+Functions/
...

429
Invoke-RestMethod

Requires PowerShell v3.0 (or later)


Used to invoke Representational State Transfer (REST) methods
Sends HTTP(S) request to a RESTful web service
Returns richly structured data
PowerShell formats response based on data type, e.g.:
• RSS or ATOM feed  PowerShell returns XML
• JSON or XML  PowerShell deserializes content into objects

Microsoft Confidential 430


Example: Return titles and publish date from System Center Team blog

PS C:\> Invoke-RestMethod -Uri http://blogs.technet.com/b/systemcenter/atom.aspx |


Format-Table -Property Title,Published -Wrap

title published
----- ---------
Now Available: System Center 2012 Service Pack 1 Update 2014-01-29 17:34:26
Service Management Automation and SharePoint - #MVP 2014-01-14 16:50:42
2014 and the year of the #LyncUp 2014-01-14 01:58:00
System Center Universe: US & Simulcast 2014-01-09 07:00:00
#MVA Course – ITIL for IT Pros 2013-12-10 15:21:11
Update Rollup 5 for System Center Advisor is available 2013-11-25 19:28:45
...

431
Example: Return titles and publish date from PowerShell Team blog

PS C:\> Invoke-RestMethod -Uri http://blogs.msdn.com/b/powershell/rss.aspx |


Format-Table -Property Title,PubDate -Wrap

title pubDate
----- -------
ConvertFrom-String: Example-based text parsing Fri, 31 Oct 2014 19:36:35 GMT
Powershell DSC ResKit Wave 8: Now with 100+ Resources! Tue, 28 Oct 2014 20:41:00 GMT
Manage the PowerShell DSC Extension in the Azure Preview Portal Tue, 28 Oct 2014 17:52:00 GMT
PowerShell DSC Does Exchange! Tue, 21 Oct 2014 21:57:00 GMT
Heads Up: Hey, Scripting Guy! Blog Series Mon, 20 Oct 2014 18:33:00 GMT
Simple HTTP api for Executing PowerShell Scripts Mon, 29 Sep 2014 23:37:00 GMT

432
Appendix: Jobs

Module Overview

Microsoft Confidential 434


Appendix: Jobs

Section 1: Background jobs


• Local
• Remote

Section 2: Job scheduling


• PSScheduledJob module
• Cmdlets

Section 3: Jobs and Workflows


• Lesson 1: Running Workflows as Background Jobs

Microsoft Confidential 435


Appendix: Jobs

Section 1: Background Jobs Lesson 1: Local Background Jobs

Microsoft Confidential 436


What are Background Jobs?

PowerShell work running in the background


Multiple jobs can be started
Jobs created by Start-Job cmdlet or –AsJob parameter (some cmdlets)

Sample List of Core Cmdlets that Support –AsJob Parameter


Get-WmiObject Invoke-Command
Invoke-WmiMethod Remove-WmiObject
Restart-Computer Set-WmiInstance
Stop-Computer Test-Connection

Microsoft Confidential 437


Job Throttling and Queuing

Cmdlets with –AsJob Parameter

–ThrottleLimit parameter handled automatically

Start-Job starts a single job only

When Start-Job leveraged, throttling and queuing completely manual

Microsoft Confidential 438


Starting and Viewing Existing Background Jobs

Start-Job:

Start-Job -ScriptBlock {dir –path c:\windows –rec}


Start-Job -Filepath c:\scripts\sample.ps1
ICM -computername s1 -scriptblock {get-eventlog system} -asjob

Get-Job:

Id Name State HasMoreData Location Command


-- ---- ----- ----------- -------- -------
1 Job1 Running True localhost dir c:\

Microsoft Confidential Microsoft Confidential 439


Retrieving Job Output

Receive-Job gets job results (or partial results if the job is incomplete)

PS C:\> Start-Job -ScriptBlock {gps vpc*}

Id Name State HasMoreData Location Command


-- ---- ----- ----------- -------- -------
11 Job11 Running True localhost gps vpc*

PS G:\> Receive-Job -id 11 | fl cpu

CPU : 849.6282463

Receive-Job –keep prevents deleting of the job results

Microsoft Confidential Microsoft Confidential 440


Job Managment

Wait-Job
• Suppresses the PowerShell prompt until the job is complete

Stop-Job
Get-Job –name n*| Stop-Job
Stop-Job *

Remove-Job
• The Job must be stopped before it can be removed

Microsoft Confidential Microsoft Confidential 441


Appendix: Jobs

Section 1: Background Jobs Lesson 2: Remote Background


Jobs

Microsoft Confidential 442


Invoke-Command with -AsJob

Invoke-Command supports –AsJob for remote background jobs

One local job created

Child jobs created for each remote machine used with Invoke-Command

Use –ThrottleLimit param for queueing and throttling

Use same job management cmdlets as local jobs once jobs exist
• Receive-Job, Remove-Job, Wait-Job, Stop-Job, etc.

Microsoft Confidential 443


Appendix: Jobs

Section 2: Job Scheduling Lesson 1: The PSScheduleJob


Module

Microsoft Confidential 444


Overview

• Scheduled jobs are a combination of PowerShell jobs and the Windows Task
Scheduler
• Jobs run asynchronously in the background
• Jobs include a rich job triggering mechanism
• Scheduled jobs can be run as a different user account
• The PSScheduledJob module includes 16 cmdlets
• Jobs can be managed using the *-Job cmdlets

Microsoft Confidential 445


Scheduled Job Overview
Job Triggers File persistence
Start Jobs on a schedule Jobs, job triggers and job options
are stored as XML
A job trigger reference is stored in
a job object property Job instance output stored as XML
Each job supports multiple triggers Jobs are created & stored per user

Scheduled Jobs
Job Options Job Module
Define conditions for starting and PSScheduledJob module
running the job Only available in PowerShell 3.0
A Job Option reference is stored in Module must be loaded to manage
a job object property job instances using *-Job cmdlets

Microsoft Confidential 446


Scheduled Job Object Relationships

ScheduledJobDefinition
Options [ScheduledJobOptions]
JobTriggers <List>[ScheduledJobTrigger]

ScheduledJobTrigger
ScheduledJobOptions JobDefinition [ScheduledJobDefinition]
JobDefinition [ScheduledJobDefinition]

Microsoft Confidential 447


Appendix: Jobs

Section 2: Job Scheduling Lesson 2: Job Scheduling Cmdlets

Microsoft Confidential 448


Scheduled Job Cmdlets

• Register-ScheduledJob • Get-ScheduledJob
• Unregister-ScheduledJob • Set-ScheduledJob
ScheduledJobDefinition
• Enable-ScheduledJob
• Disable-ScheduledJob

• New-ScheduledJobOption
ScheduledJobOption • Get-ScheduledJobOption
• Set-ScheduledJobOption

• Add-JobTrigger • Get-JobTrigger
• Remove-JobTrigger • Set-JobTrigger
ScheduledJobTrigger • Enable-JobTrigger
• Disable-JobTrigger
• New-JobTrigger
Microsoft Confidential 449
Create a Scheduled Job
PS C:\> Register-ScheduledJob -Name PSJob1 -ScriptBlock {dir
Example: c:\}
Creating Create Job Trigger Objects
New PS C:\> $trigger1 = New-JobTrigger -At (Get-
Scheduled Date).AddMinutes(10) –Once
Jobs & PS C:\> $trigger2 = New-JobTrigger -At 3pm -Weekly -
Triggers DaysOfWeek Monday
Associate a Job Trigger Object with a new or existing Scheduled Job
PS C:\> Register-ScheduledJob -Name PSJob2 –FilePath
$home\script.ps1 -Credential (Get-Credential) -Trigger
$trigger2
PS C:\> Add-JobTrigger -Name PSJob1 -Trigger $trigger1

450
PowerShell Scheduled Jobs in Task Scheduler

PowerShell Scheduled Jobs can be viewed in the Task Scheduler GUI


• Only jobs in path Microsoft\Windows\PowerShell\ScheduledJobs
can be created and managed using
PowerShell Scheduled Jobs

• Use ‘ScheduledTasks’ module


to manage all other scheduled tasks
(Only available in Windows 8 and
Server 2012)

Microsoft Confidential 451


Managing Existing Scheduled Jobs

List (current user only)


PS C:\> Get-ScheduledJob -Name PSJob1
Modify
PS C:\> Get-ScheduledJob -Name PSJob1 |
Set-ScheduledJob -ScriptBlock {Get-Process} -RunAs32
Disable/Enable
PS C:\> Disable-ScheduledJob -Name PSJob3
PS C:\> Enable-ScheduledJob -Name PSJob3
Delete
PS C:\> Unregister-ScheduledJob -Name PSJob3

Microsoft Confidential 452


Managing Job Triggers
List All Job Triggers on a Job
PS C:\> Get-JobTrigger -Name SJob2

Modify Single Job Trigger by ID (numbers match trigger creation order)


PS C:\> Get-JobTrigger -TriggerId 1 -Name SJob2 |
Set-JobTrigger -AtStartup -RandomDelay (New-TimeSpan -Minutes 5)
Disable All Triggers on a Job
PS C:\> Get-JobTrigger -Name SJob2 | Disable-JobTrigger

Enable One Trigger on a Job


PS C:\> Get-ScheduledJob -Name SJob2 | Get-JobTrigger -TriggerId 1 |
Enable-JobTrigger
Delete All Job Triggers on a Job
PS C:\> Get-ScheduledJob -Name SJob2 | Remove-JobTrigger

Microsoft Confidential 453


Configuring Job Options
Set advanced options for running a job
Create Job Option Object
PS C:\> $option = New-ScheduledJobOption -RunElevated `
-IdleTimeout 00:05:00 -MultipleInstancePolicy Queue
Create Scheduled Job with Option Object
PS C:\> Register-ScheduledJob -Name SJob1 -ScriptBlock {dir c:\}` -
ScheduledJobOption $option
Displaying Job Options
PS C:\> Get-ScheduledJobOption -Name SJob1
Modifying Job Options
PS C:\> Get-ScheduledJob -Name SJob1 |
Get-ScheduledJobOption |
Set-ScheduledJobOption –RequireNetwork –HideInTaskScheduler

Microsoft Confidential 454


Managing Job Instances
PSScheduledJob module MUST be loaded
Manage Job Instances with *-Job cmdlets
Listing Scheduled Job Instances
PS C:\> Get-ScheduledJob #Load module
PS C:\> Get-Job SJob5 | Format-Table -Property ID, Name, PSBeginTime

Id Name PSBeginTime
-- ---- -----------
4 TestJob5 29/10/2012 11:41:26 PM
5 TestJob5 29/10/2012 11:42:25 PM

Job output is saved to disk in an XML file –Keep is required to access results multiple times
Receiving Job Output
PS C:\> Receive-job -Id 6 –Keep

Microsoft Confidential 455


Job Definition & Job Output Storage
$home\AppData\Local\Microsoft\Windows\PowerShell\ScheduledJob\

<Jobname>\

ScheduledJobDefinition.xml Output\

<Job Instance Date stamp>\

Results.xml Status.xml

Microsoft Confidential 456


Appendix: Jobs

Section 3: Jobs and Workflows Lesson 1: Running Workflows as


Background Jobs

Microsoft Confidential 457


Running Workflows as Background Jobs
• Use the –AsJob workflow common parameter
• Manage workflows using the *-Job cmdlets

Run local workflow on remote machines as a job


$myWfJob = myWorkflow –PSComputername $hostlist –AsJob

Get-Job
Receive-Job –Job $myWfJob

Microsoft Confidential 458


Module 8: Introduction to
Desired State Configuration
(DSC)

Section 1: Introduction Lesson 3: Custom Resources

Microsoft Confidential 460


Building Custom DSC Resources

It is possible to create additional DSC resources


A basic understanding of the following is necessary:
• Writing PowerShell functions and creating basic PowerShell providers
• Using DSC providers in configuration scripts

• To Build a Custom Resource:


1. Create Folder Structure (Required)
2. Create MOF Schema File (Required)
3. Create Script Module File (Required)
4. Create Module Manifest File (Optional)
5. Confirm Custom Resource Installation (Optional)

Microsoft Confidential 461


Building Custom DSC Resources – Step 1 (Required)

Create File And Folder Structure

$env: psmodulepath (folder)


|- <ModuleName> (folder)
|- DSCResources (folder) Manifest: Hash table containing more info and
instructions for loading module
|- <ResourceName1> (folder)
|- <ResourceName>.psd1 (file, optional)
|- <ResourceName>.psm1 (file, required) Script Module: Implements
|- <ResourceName>.schema.mof (file, required) resource logic

Schema: Defines resource


properties

Microsoft Confidential 462


Building Custom DSC Resources – Step 2 (Required)

• Create MOF Schema File using ISE or Notepad


• MOF Schema File Defines Resource Properties
• DSC is specified by assigning values to these properties in a Configuration Script
Block

Microsoft Confidential 463


Building Custom DSC Resources – Step 2 (Required)

Example MOF Schema File


[ClassVersion("1.0.0.0"), FriendlyName("xVMSwitch")]
class MSFT_xVMSwitch : OMI_BaseResource
{
[Key, Description("VM Switch Name")] String Name;

[Key, Description("Switch Type"), ValueMap{"External","Internal","Private"},


Values{"External","Internal","Private"}] String Type;

[Write, Description("External Switch NIC name")] String NetAdapterName;


[Write, Description("Allow access to physical NIC")] Boolean AllowManagementOS;

[Write, Description("Switch present or absent"), ValueMap{"Present","Absent"},


Values{"Present","Absent"}] String Ensure;
};

Microsoft Confidential 464


Building Custom DSC Resources – Step 3 (Required)

• Create Script Module File


• Implements Resource Logic
• Must include three functions
• All three functions must take parameter set as defined in MOF schema

1 Get-TargetResource • Use key resource property values to check status of resource


instance
• Function must return hash table listing all resource properties as
keys and actual values
2 Set-TargetResource • Install, Configure and/or Update Resource Instance
3 Test- • Check status of Resource Instance
TargetResource
• If status does not match values specified in parameter set, return
$false. Otherwise, return $true
Microsoft Confidential 465
Building Custom DSC Resources – Step 3 (Required)

Example Script Module File:

Microsoft Confidential 466


Building Custom DSC Resources – Step 3 (Required)
Example Script Module File:

Microsoft Confidential 467


Building Custom DSC Resources – Step 3 (Required)
Example Script Module File:

Microsoft Confidential 468


Building Custom DSC Resources – Step 3 (Required)
Example Script Module File:

Microsoft Confidential 469


Building Custom DSC Resources – Step 4 (Optional)
• Create Module Manifest File with New-ModuleManifest
• Hash table containing more information and instructions for loading Module

Sample Manifest File:


@{
# Version number of this module.
ModuleVersion = '2.0'

# ID used to uniquely identify this module


GUID = 'f5a5f169-7026-4053-932a-19a7c37b1ca5'

# Author of this module


Author = 'Microsoft Corporation'

# Company or vendor of this module


CompanyName = 'Microsoft Corporation'

# Description of the functionality provided by this module


Description = 'Module with DSC Resources for Hyper-V area'
...
}
Microsoft Confidential 470
Building Custom DSC Resources – Step 5 (Optional)

Confirm Custom Resource Installation


PS C:\> Get-DscResource -Name xVMSwitch
ImplementedAs Name Module Properties
------------- ---- ------ ----------
PowerShell xVMSwitch xHyper-V {Name, Type, AllowManagementOS...}

Microsoft Confidential 471


Module 8: Introduction to
Desired State Configuration
(DSC)

Section 2: Examples Example 2: Pull Mode - Web Site


Installation and Configuration

Microsoft Confidential 472


Example 2: Pull Mode – Web Site Installation and Configuration

Preparation:
Set Up Pull Server (if not already available)
Define Goals

Step 1:
Create Custom Resources (if required)

Step 2:
Create unique identifier (GUID)
Define Configuration

Step 3:
Create Consumable MOF File

Step 4:
Generate MOF File Checksum
Deploy configuration files to Pull Server

Step 5:
Configure Target Nodes
Microsoft Confidential 473
Preparation: Set up oData based Web Service DSC Pull Server

1. Download DSC Resource Kit by the Microsoft PowerShell Team from


http://gallery.technet.microsoft.com/xPSDesiredStateConfiguratio-417dc71d
2. Unzip xPSDesiredStateConfiguration_1.1.zip to $env:ProgramFiles\WindowsPowerShell\Modules on the
allocated Pull Server

Note
• All resources in the DSC Resource Kit are provided AS IS, and are not supported through any Microsoft standard
support program or service
• DSC Resource Kit requires Windows 8.1 or Windows Server 2012 R2 with update KB2883200

Microsoft Confidential 474


Preparation: Set up oData based Web Service DSC Pull Server

3. Confirm xDSCWebService is a listed DSC Resource

PS C:\> Get-DscResource -Name xDSCWebService

ImplementedAs Name Module Properties


------------- ---- ------ ----------
PowerShell xDSCWebService xPSDesiredStateConfiguration ...

Microsoft Confidential 475


Preparation: Set up oData based Web Service DSC Pull Server

4. Copy MSFT_xDSCWebService folder from unzipped files to $env:SystemRoot\System32\


WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\DSCResources

Microsoft Confidential 476


Preparation: Set up oData based Web Service DSC Pull Server
5. Import PSWSIISEndpoint Module
PS C:\> Import-Module "C:\Program Files\WindowsPowerShell\Modules\
xPSDesiredStateConfiguration\PSWSIISEndpoint.psm1"
6. Create a Configuration for new Pull Server

Microsoft Confidential 477


Preparation: Set up oData based Web Service DSC Pull Server

6. Create a Configuration for new Pull Server (continued)

Microsoft Confidential 478


Preparation: Set up oData based Web Service DSC Pull Server

6. Create a Configuration for new Pull Server (continued)

Microsoft Confidential 479


Preparation: Set up oData based Web Service DSC Pull Server

6. Create a Configuration for new Pull Server (continued)

Microsoft Confidential 480


Preparation: Set up oData based Web Service DSC Pull Server

7. Run DSC Configuration using F5 in the ISE to define it, then execute configuration to create a MOF file.
Note:
Use ‘nodename’ parameter, or run command locally on assigned Pull Server.
Command below defines a non SSL configuration. For SSL use a certificate in computer store of Pull
Server and specify its thumbprint.
PS C:\Scripts> Sample_xDscWebService `
–certificateThumbPrint "AllowUnencryptedTraffic" –OutputPath .
8. Apply the Configuration

PS C:\Scripts> Start-DSCConfiguration –Path .\Sample_DSCWebService `


–Wait –Verbose –Force

Microsoft Confidential 481


Preparation: Set up oData based Web Service DSC Pull Server

9. Enable directory browsing in IIS Manager

Microsoft Confidential 482


Preparation: Set up oData based Web Service DSC Pull Server

10. Test Pull Server endpoint


http://localhost:8080/PSDSCPullServer/PSDSCPullServer.svc/

Microsoft Confidential 483


Preparation: Define Goals (List Settings and Desired Values)

Setting Value
Ensure that IIS is installed Yes
Define Web Server Name Web-Server
Define DestinationPath c:\inetpub\wwwroot
(Desired location to ensure state for a file or
directory)

Ensure subdirectories exist Yes


Define SourcePath Specify with parameter (to make code more
(Path to copy File or Folder Resource) dynamic)

Microsoft Confidential 484


Step 1: Create Not required – Built-in resources will be used
Custom Resources
(if required)

Microsoft Confidential 485


Configuration MyWebConfigPull
{
param ($MachineName, $WebsiteFilePath)
Node 66f08f93-155e-415f-ae11-702bff8ec6c8
{ Node Block
Step 2: WindowsFeature IIS
Windows Feature Resource Block
Define DSC {
Ensure = "Present"
Configuration Name = "Web-Server"
with unique } [guid]::newguid() Or
File WebDirectory (Get_ADComputer -Identity
identifier (GUID) { <computername>).ObjectGuid
Ensure = "Present"
Type = "Directory" File Resource Block
Recurse = $true
SourcePath = $WebsiteFilePath
DestinationPath = "C:\inetpub\wwwroot"
DependsOn = "[WindowsFeature]IIS"
}
}
}

Microsoft Confidential 486


Step 3: Create Consumable MOF File

• Run Configuration in previous step


• Create a Consumable MOF File
PS C:\> PS C:\> MyWebConfigPull -MachineName om12ms `
-WebsiteFilePath "c:\scripts\inetpub\wwwroot"

Directory: C:\MyWebConfigPull

Mode LastWriteTime Length Name


---- ------------- ------ ----
-a--- 10/02/2014 3:45 PM 1878 66f08f93-155e-415f-ae11-702bff8ec6c8.mof

A directory and a MOF File is created using configuration id

Microsoft Confidential 487


Step 4:
Generate MOF file checksum
Deploy configuration files to Pull Server

MOF checksum allows LCM to validate configuration


PS C:\> New-DSCCheckSum `
-ConfigurationPath .\MyWebConfigPull `
-OutPath .\MyWebConfigPull -Verbose -Force
Copy all files from c:\MyWebConfigPull to Pull Server
"$env:SystemDrive\Program Files\WindowsPowershell\DscService\Configuration"

Microsoft Confidential 488


Step 5: Configure target nodes to periodically check pull server for configuration changes

Default LCM = Push Mode (wait for configurations to be pushed)

Create file to configure target node LCM to contact Pull Server


instance of MSFT_KeyValuePair as $keyvaluepair1 {
key = "ServerUrl";
value =
"http://2012r2:8080/PSDSCPullServer/PSDSCPullServer.svc";
};

instance of MSFT_KeyValuePair as $keyvaluepair2 {


key = "AllowUnsecureConnection";
value = "true";
};

#... (continues on next slide)

Microsoft Confidential 489


Step 5: Configure target nodes to periodically check pull server for configuration changes

#...
instance of MSFT_DSCMetaConfiguration {
ConfigurationID = "66f08f93-155e-415f-ae11-702bff8ec6c8";
RefreshMode = "PULL";
DownloadManagerName = "WebDownloadManager";
RebootNodeIfNeeded = True; GUID from step 2
RefreshFrequencyMins = 15;
ConfigurationModeFrequencyMins = 15;
ConfigurationMode = "ApplyAndAutoCorrect";
DownloadManagerCustomData = {$keyvaluepair1,$keyvaluepair2};
};

instance of OMI_ConfigurationDocument {
Version = "1.0.0";
Author = "Johan";
};

Microsoft Confidential 490


LCM Configuration File Properties
Property Description
AllowModuleOverwrite Whether new modules downloaded from a pull server overwrite old ones. True/False
CertificateID GUID of certificate
ConfigurationID GUID used to get configuration from server when in PULL mode
ConfigurationMode Specifies how LCM should apply configuration. Valid values:
• ApplyOnly: Configuration applied once
• ApplyAndMonitor: Configuration applied, LCM monitors for changes. Configuration drift reported
in logs
• ApplyAndAutoCorrect: Configuration applied, LCM monitors for changes. LCM reapplies
configuration if there is drift
ConfigurationModeFrequencyMins How often LCM ensures configuration is in desired state
Credential Credentials to access remote resources
DownloadManagerCustomData Specifies additional data to send to download manager
DownloadManagerName Which download manager to use: WebDownloadManager and DscFileDownloadManager
RebootNodeIfNeeded Whether target node is automatically restarted when configuration requires it. True/False
RefreshFrequencyMins How often LCM attempts to obtain configuration from pull server
RefreshMode Refresh mode:
• PUSH – Configuration is sent to node via Start-DscConfiguration (from same or remote node)
• PULL – Node periodically checks for configuration updates on pull server
Pull server is specified with DownloadManagerName and DownloadManagerCustomData
Microsoft Confidential 491
Step 5: Configure target nodes to periodically check pull server for configuration changes

Apply LCM configuration to target node

PS C:\> Set-DscLocalConfigurationManager -ComputerName om12ms `


-Path .\MyWebConfigPull -Verbose
Confirm LCM Configuration

Microsoft Confidential 492


Confirm target node successfully pulls configuration from Pull Server

Open Target Node Event Log: Applications and Services > Microsoft > Windows > Desired State Configuration
> Operational

Microsoft Confidential 493


Module 8: Introduction to
Desired State Configuration
(DSC)

Section 3: Demo Demo: DSC Push

Microsoft Confidential 494


Module 8: Introduction to
Desired State Configuration
(DSC)

Section 3: Quick Reference

Microsoft Confidential 495

You might also like