PowerShell v4.
0 for the IT
Professional
Part 2
Meet your trainer
<Trainer Name>
<Position, Location>
<email@[Link]>
<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
[Link] [Link] [Link]
Domain Name [Link]
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
[Link]
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 { $[Link] –gt 1MB }
Alternatively, create a custom pipeline variable using –PipelineVariable
Get-Process -PipelineVariable CurrentProcess |
Where-Object {$[Link] -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 [Link]
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: $[Link]" Service:
[Link]
"Service: $ Service: BITS
($[Link])"
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: $[Link]
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 [Link] 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: [Link]
Name MemberType Definition
---- ---------- ----------
GetType Method type GetType()
ToString Method string ToString(), string ToString(stri...
Name NoteProperty [Link] Name=BFE
PSComputerName NoteProperty [Link] PSComputerName=2012R2-MS
...
CanPauseAndContinue Property [Link] {get;set;}
CanShutdown Property [Link] {get;set;}
Microsoft Confidential 53
CanStop Property [Link] {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 [Link] 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 [Link] 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 [Link] Available
PS C:\> Disconnect-PSSession 4
Id Name ComputerName State ConfigurationName Availability
-- ---- ------------ ----- ----------------- ------------
4 Session4 2012R2-MS Disconnected [Link] 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 [Link] None
2 Session2 2012R2-MS Disconnected [Link] Busy
3 Session3 2012R2-MS Opened [Link] 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 [Link] AppLocker {Set-AppLockerPolicy, Test-App...
Manifest [Link] 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 : [Link]
PSVersion
StartupScript
: 4.0
:
Default endpoint for remoting
RunAsUser :
Permission : BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed
Name : [Link]
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 : [Link]
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 [Link] 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\[Link]"
Microsoft Confidential 80
Endpoint Connection Permissions
Configure Endpoint Permission
PS C:\> Set-PSSessionConfiguration `
-Name myRestrictedConfig `
-ShowSecurityDescriptorUI
Microsoft Confidential 81
Overall Process for Constrained Endpoints
[Link]
Create Session Configuration File
• New-PSSessionConfigurationFile -Path .\[Link] -SessionType
RestrictedRemoteServer
Optional - Manipulate/View Configuration File
Associate Configuration File with New Remote Endpoint
• Register-PSSessionConfiguration -Path .\[Link] -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: [Link]\WSMan::localhost\Client
Type Name SourceOfValue Value
---- ---- ------------- -----
[Link] 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 += ",[Link]"
PS C:\> Set-Item -Path WSMan:\localhost\Client\TrustedHosts –Value $trustedhosts
#Get new value
PS C:\> Get-Item -Path WSMan:\localhost\Client\TrustedHosts
WSManConfig: [Link]\WSMan::localhost\Client
Type Name Value
---- ---- -----
[Link] TrustedHosts WorkGroupMachine1,[Link]
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 = $[Link] | 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 $_.[Link] -contains 'Server
Authentication'}
Get-ChildItem Cert:\LocalMachine\My | Where $Filter |
Format-List thumbprint,EnhancedKeyUsageList,DNSNameList,Issuer
Thumbprint : 3138F8B8B4A948ADAB752DE7E355408234D59800
EnhancedKeyUsageList : {Client Authentication ([Link].[Link].2), Server Authentication ([Link].[Link].1), Smart
Card Logon ([Link].[Link].2.2)}
DnsNameList : {[Link]}
Issuer : CN=contoso-2012R2-DC-CA, DC=contoso, DC=com Eligible Certificate
Thumbprint : 060BD6561A0AA96B31696A24D81C91E9676B2BB3 Thumbprints
EnhancedKeyUsageList : {Client Authentication ([Link].[Link].2), Server Authentication ([Link].[Link].1), Smart
Card Logon ([Link].[Link].2.2), KDC Authentication ([Link].[Link])}
DnsNameList : {[Link], [Link], 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: [Link]\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 [Link] `
Example:
Use SSL -ScriptBlock {Get-Culture} -UseSSL
Listener/
Endpoint LCID Name DisplayName PSComputerName
---- ---- ----------- --------------
3081 en-AU English (Australia) [Link]
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\[Link]\Documents> Test-Path -Path \\2012R2-DC\FileShare
Test-Path : Access is denied
+ CategoryInfo : PermissionDenied: (\\2012R2-DC\FileShare:String) [Tes...
+ FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,[Link]...
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
• [Link] represents parameter
• [Link] 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 ($[Link]("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 ($[Link]($name, "Terminating Process"))
method {
$[Link]()
}
}
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 ($[Link]($name, "Terminating Process"))
{
$[Link]()
}
}
}
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 ($[Link]($name, "Terminating Process"))
{
$[Link]()
}
}
}
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
---- ----
[Link] [Link]
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
[Link]
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
• [Link] namespace
• -cnotmatch
Statements
• Switch
Microsoft Confidential 183
[Link] namespace
Provides access to underlying .NET regular expression engine
[Regex] type accelerator contains methods for split, match, replace, etc.
[[Link]] allows attributes like RightToLeft,
IgnoreCase, Multiline, etc.
[[Link]] determines whether a string conforms to
a regex pattern
[[Link]]
#type accelerator [regex]
[[Link]]
[[Link]]
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 [Link]
Name Value
---- -----
4 254
"(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})" 3 1
2 168
"[Link]" 1 192
0 [Link]
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 [Link]
193
Mode Modifiers
Matching modes can be specified in the regex pattern
Specify regex options w/o using [[Link]]
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:\> $[Link]
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\[Link] |
Select-String -Pattern "Found \d Updates" | Select-Object -First 1
2014-02-09 [Link] 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 $($[Link]) -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("[Link]","\.")
www
microsoft
Com
\. Matches a literal dot
[Regex] Built-in TYPE accelerator for [[Link]]
202
Example 7: Regex and regex option TYPES
PS C:\> $text = @("[Link]", "[Link]")
Case sensitive pattern match
PS C:\> [regex]::matches($text,"[a-z][Link]")
Case insensitive pattern match
PS C:\> [regex]::matches($text, "[a-z][Link]",
[[Link]]::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 [[Link]]
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 : [Link]
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 > [Link]
Appends output to contents of specified
>> file PS C:\> dir *.ps1 >> [Link]
2> Sends errors to specified file PS C:\> Get-Process none 2> [Link]
2>> Appends errors to contents of specified file PS C:\> Get-Process none 2>> [Link]
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> [Link]
Appends warnings to contents of specified
3>> file PS C:\> Write-Warning "Test!" 3>> [Link]
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> [Link]
Appends verbose output to contents of
4>>
specified file PS C:\> Import-Module * -Verbose 4>> [Link]
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> [Link]
Appends debug messages to contents of PS C:\> Write-Debug "Saving" 5>> [Link]
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 *> [Link]
Appends all output types to contents of
*>>
specified file PS C:\> Test-Output *>> [Link]
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:\> [Link] 2012R2-DC -n 1
Pinging [Link] [[Link]] with 32 bytes of data:
Reply from [Link]: bytes=32 time<1ms TTL=128 ...
PS C:\> $?
True
PS C:\> [Link] 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 : [Link]
PS C:\> $Error[0]
Write-Error "My Custom Error" : My Custom Error
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : [Link]
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 [Link] 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 [Link]
$[Link]("[Link]
}
Catch [[Link]],[[Link]]
{
"Cannot get [Link] from [Link]
}
Catch
{
"An error occurred that could not be resolved."
$_.[Link]
}
Finally
{
If ($wc)
{
$_ contains caught error
$[Link]()
}
}
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 [[Link]] { #This is specific trap
"Can not divide by ZERO!!!--> " + $_.[Link]
Continue
Trap }
Trap {#This is a generic catch all trap
"A serious error occurred--> " + $_.[Link]
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:\[Link] -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:\[Link]' 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 [Link]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 : [Link]
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:
[[Link]]
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
[Link] Configs Deployed
[Link] IIS Server1
Config Pulled
[Link] Configs Deployed
[Link]
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 [Link] -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 [Link] 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
[Link] 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>.[Link] (file, required)
|- <ResourceName2>(folder)
|- <ResourceName2>.psm1 (file, required)
|- <ResourceName2>.[Link] (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\' [Link]
Ensure = 'Present' -a--- 1266 2012R2-
[Link]
Type = 'Directory' -a--- 1262 [Link]
}
}
}
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="[Link]
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
[Link]
Server1
Microsoft Confidential
Many MOFs
PS> Start-DSCConfiguration –Path c:\MOFs\
Configuration Pushed
[Link]
Server1
Configuration Pushed
[Link]
Server2
Configuration Pushed
[Link]
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 [Link]
‘MyWebConfig’ directory and ‘[Link]’ 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
[Link]
Microsoft Confidential Microsoft Confidential 365
Out-of-Process Workflow Architecture
Workflow engine executes in a local or remote workflow session
• Client connects to [Link] 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 ([Link])
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\[Link]
}
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\[Link]
#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
• [Link] (PSSnapin)
• [Link]
Core Modules • [Link]
Containing Cmdlet • [Link]
• [Link]
Activities • [Link]
• [Link]
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 [Link]
Get-Process -Name cmd
} Script blocks
sequence { execute in parallel,
Start-Process [Link] 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 ‘[Link]’ 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 [Link]
# 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=$[Link] ; FilePath=$[Link]}
}
}
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
[Link]
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
[Link]
Return Object Type
PS C:\> $[Link]().FullName
[Link]
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 [Link]
Return links to tagged content
PS C:\> $[Link] | ? {$_ -match "tags"}
[Link]
[Link]
[Link]
[Link]
[Link]
...
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 [Link] |
Format-Table -Property Title,Published -Wrap
title published
----- ---------
Now Available: System Center 2012 Service Pack 1 Update 2014-01-29 [Link]
Service Management Automation and SharePoint - #MVP 2014-01-14 [Link]
2014 and the year of the #LyncUp 2014-01-14 [Link]
System Center Universe: US & Simulcast 2014-01-09 [Link]
#MVA Course – ITIL for IT Pros 2013-12-10 [Link]
Update Rollup 5 for System Center Advisor is available 2013-11-25 [Link]
...
431
Example: Return titles and publish date from PowerShell Team blog
PS C:\> Invoke-RestMethod -Uri [Link] |
Format-Table -Property Title,PubDate -Wrap
title pubDate
----- -------
ConvertFrom-String: Example-based text parsing Fri, 31 Oct 2014 [Link] GMT
Powershell DSC ResKit Wave 8: Now with 100+ Resources! Tue, 28 Oct 2014 [Link] GMT
Manage the PowerShell DSC Extension in the Azure Preview Portal Tue, 28 Oct 2014 [Link] GMT
PowerShell DSC Does Exchange! Tue, 21 Oct 2014 [Link] GMT
Heads Up: Hey, Scripting Guy! Blog Series Mon, 20 Oct 2014 [Link] GMT
Simple HTTP api for Executing PowerShell Scripts Mon, 29 Sep 2014 [Link] 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 [Link] -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 [Link] PM
5 TestJob5 29/10/2012 [Link] 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>\
[Link] Output\
<Job Instance Date stamp>\
[Link] [Link]
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>.[Link] (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("[Link]"), 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
[Link]
2. Unzip xPSDesiredStateConfiguration_1.[Link] 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
[Link]
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 [Link]
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 =
"[Link]
};
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