🔙 Quay lại trang tải sách pdf ebook PowerShell Notes for Professionals Ebooks Nhóm Zalo Notes for Professionals PowerShell® PowerShell Notes for Professionals 100+ pages of professional hints and tricks GoalKicker.com Free Programming Books Disclaimer This is an unocial free book created for educational purposes and is not aliated with ocial PowerShell® group(s) or company(s). All trademarks and registered trademarks are the property of their respective owners Contents About ................................................................................................................................................................................... 1 Chapter 1: Getting started with PowerShell .................................................................................................... 2 Section 1.1: Allow scripts stored on your machine to run un-signed ........................................................................ 2 Section 1.2: Aliases & Similar Functions ....................................................................................................................... 2 Section 1.3: The Pipeline - Using Output from a PowerShell cmdlet ........................................................................ 3 Section 1.4: Calling .Net Library Methods .................................................................................................................... 4 Section 1.5: Installation or Setup .................................................................................................................................. 5 Section 1.6: Commenting ............................................................................................................................................... 5 Section 1.7: Creating Objects ........................................................................................................................................ 6 Chapter 2: Variables in PowerShell ..................................................................................................................... 7 Section 2.1: Simple variable .......................................................................................................................................... 7 Section 2.2: Arrays ........................................................................................................................................................ 7 Section 2.3: List Assignment of Multiple Variables ..................................................................................................... 7 Section 2.4: Scope ......................................................................................................................................................... 8 Section 2.5: Removing a variable ................................................................................................................................ 8 Chapter 3: Operators .................................................................................................................................................. 9 Section 3.1: Comparison Operators ............................................................................................................................. 9 Section 3.2: Arithmetic Operators ................................................................................................................................ 9 Section 3.3: Assignment Operators ........................................................................................................................... 10 Section 3.4: Redirection Operators ............................................................................................................................ 10 Section 3.5: Mixing operand types, the type of the left operand dictates the behavior ...................................... 11 Section 3.6: Logical Operators ................................................................................................................................... 11 Section 3.7: String Manipulation Operators .............................................................................................................. 11 Chapter 4: Special Operators .............................................................................................................................. 13 Section 4.1: Array Expression Operator ..................................................................................................................... 13 Section 4.2: Call Operation ......................................................................................................................................... 13 Section 4.3: Dot sourcing operator ............................................................................................................................ 13 Chapter 5: Basic Set Operations ......................................................................................................................... 14 Section 5.1: Filtering: Where-Object / where / ? ...................................................................................................... 14 Section 5.2: Ordering: Sort-Object / sort .................................................................................................................. 14 Section 5.3: Grouping: Group-Object / group .......................................................................................................... 15 Section 5.4: Projecting: Select-Object / select .......................................................................................................... 16 Chapter 6: Conditional logic .................................................................................................................................. 17 Section 6.1: if, else and else if ..................................................................................................................................... 17 Section 6.2: Negation .................................................................................................................................................. 17 Section 6.3: If conditional shorthand ......................................................................................................................... 18 Chapter 7: Loops ......................................................................................................................................................... 19 Section 7.1: Foreach ..................................................................................................................................................... 19 Section 7.2: For ............................................................................................................................................................ 19 Section 7.3: ForEach() Method ................................................................................................................................... 19 Section 7.4: ForEach-Object ....................................................................................................................................... 20 Section 7.5: Continue ................................................................................................................................................... 21 Section 7.6: Break ........................................................................................................................................................ 21 Section 7.7: While ......................................................................................................................................................... 22 Section 7.8: Do ............................................................................................................................................................. 22 Chapter 8: Switch statement ................................................................................................................................ 24 Section 8.1: Simple Switch ........................................................................................................................................... 24 Section 8.2: Switch Statement with CaseSensitive Parameter ............................................................................... 24 Section 8.3: Switch Statement with Wildcard Parameter ........................................................................................ 24 Section 8.4: Switch Statement with File Parameter ................................................................................................. 25 Section 8.5: Simple Switch with Default Condition ................................................................................................... 25 Section 8.6: Switch Statement with Regex Parameter ............................................................................................ 26 Section 8.7: Simple Switch With Break ...................................................................................................................... 26 Section 8.8: Switch Statement with Exact Parameter .............................................................................................. 27 Section 8.9: Switch Statement with Expressions ...................................................................................................... 27 Chapter 9: Strings ....................................................................................................................................................... 28 Section 9.1: Multiline string .......................................................................................................................................... 28 Section 9.2: Here-string .............................................................................................................................................. 28 Section 9.3: Concatenating strings ............................................................................................................................ 28 Section 9.4: Special characters .................................................................................................................................. 29 Section 9.5: Creating a basic string ........................................................................................................................... 29 Section 9.6: Format string .......................................................................................................................................... 30 Chapter 10: HashTables ........................................................................................................................................... 31 Section 10.1: Access a hash table value by key ........................................................................................................ 31 Section 10.2: Creating a Hash Table .......................................................................................................................... 31 Section 10.3: Add a key value pair to an existing hash table .................................................................................. 31 Section 10.4: Remove a key value pair from an existing hash table ..................................................................... 32 Section 10.5: Enumerating through keys and Key-Value Pairs .............................................................................. 32 Section 10.6: Looping over a hash table ................................................................................................................... 32 Chapter 11: Working with Objects ....................................................................................................................... 34 Section 11.1: Examining an object ............................................................................................................................... 34 Section 11.2: Updating Objects ................................................................................................................................... 35 Section 11.3: Creating a new object ............................................................................................................................ 35 Section 11.4: Creating Instances of Generic Classes ................................................................................................ 37 Chapter 12: PowerShell Functions ...................................................................................................................... 39 Section 12.1: Basic Parameters ................................................................................................................................... 39 Section 12.2: Advanced Function ............................................................................................................................... 39 Section 12.3: Mandatory Parameters ........................................................................................................................ 41 Section 12.4: Parameter Validation ............................................................................................................................ 41 Section 12.5: Simple Function with No Parameters .................................................................................................. 43 Chapter 13: PowerShell Classes ........................................................................................................................... 44 Section 13.1: Listing available constructors for a class ............................................................................................ 44 Section 13.2: Methods and properties ....................................................................................................................... 45 Section 13.3: Constructor overloading ....................................................................................................................... 45 Section 13.4: Get All Members of an Instance ........................................................................................................... 46 Section 13.5: Basic Class Template ............................................................................................................................ 46 Section 13.6: Inheritance from Parent Class to Child Class ..................................................................................... 47 Chapter 14: PowerShell Modules ........................................................................................................................ 48 Section 14.1: Create a Module Manifest ..................................................................................................................... 48 Section 14.2: Simple Module Example ....................................................................................................................... 48 Section 14.3: Exporting a Variable from a Module ................................................................................................... 49 Section 14.4: Structuring PowerShell Modules .......................................................................................................... 49 Section 14.5: Location of Modules .............................................................................................................................. 49 Section 14.6: Module Member Visibility ..................................................................................................................... 49 Chapter 15: PowerShell profiles .......................................................................................................................... 50 Section 15.1: Create an basic profile .......................................................................................................................... 50 Chapter 16: Calculated Properties ..................................................................................................................... 51 Section 16.1: Display file size in KB - Calculated Properties ..................................................................................... 51 Chapter 17: Using existing static classes ........................................................................................................ 52 Section 17.1: Adding types ........................................................................................................................................... 52 Section 17.2: Using the .Net Math Class ..................................................................................................................... 52 Section 17.3: Creating new GUID instantly ................................................................................................................ 52 Chapter 18: Built-in variables ................................................................................................................................ 54 Section 18.1: $PSScriptRoot ......................................................................................................................................... 54 Section 18.2: $Args ...................................................................................................................................................... 54 Section 18.3: $PSItem ................................................................................................................................................... 54 Section 18.4: $? ............................................................................................................................................................. 54 Section 18.5: $error ...................................................................................................................................................... 54 Chapter 19: Automatic Variables ........................................................................................................................ 56 Section 19.1: $OFS ........................................................................................................................................................ 56 Section 19.2: $? ............................................................................................................................................................. 56 Section 19.3: $null ......................................................................................................................................................... 56 Section 19.4: $error ...................................................................................................................................................... 57 Section 19.5: $pid ......................................................................................................................................................... 57 Section 19.6: Boolean values ...................................................................................................................................... 57 Section 19.7: $_ / $PSItem .......................................................................................................................................... 58 Section 19.8: $PSVersionTable ................................................................................................................................... 58 Chapter 20: Environment Variables .................................................................................................................. 59 Section 20.1: Windows environment variables are visible as a PS drive called Env: ............................................ 59 Section 20.2: Instant call of Environment Variables with $env: .............................................................................. 59 Chapter 21: Splatting ................................................................................................................................................ 60 Section 21.1: Piping and Splatting ............................................................................................................................... 60 Section 21.2: Passing a Switch parameter using Splatting ...................................................................................... 60 Section 21.3: Splatting From Top Level Function to a Series of Inner Function .................................................... 61 Section 21.4: Splatting parameters ............................................................................................................................ 61 Chapter 22: PowerShell "Streams"; Debug, Verbose, Warning, Error, Output and Information .................................................................................................................................................................... 63 Section 22.1: Write-Output .......................................................................................................................................... 63 Section 22.2: Write Preferences ................................................................................................................................. 63 Chapter 23: Sending Email ..................................................................................................................................... 65 Section 23.1: Send-MailMessage with predefined parameters ............................................................................... 65 Section 23.2: Simple Send-MailMessage ................................................................................................................... 66 Section 23.3: SMTPClient - Mail with .txt file in body message ............................................................................... 66 Chapter 24: PowerShell Remoting .................................................................................................................... 67 Section 24.1: Connecting to a Remote Server via PowerShell ................................................................................ 67 Section 24.2: Run commands on a Remote Computer ........................................................................................... 67 Section 24.3: Enabling PowerShell Remoting ........................................................................................................... 69 Section 24.4: A best practise for automatically cleaning-up PSSessions .............................................................. 70 Chapter 25: Working with the PowerShell pipeline ................................................................................... 71 Section 25.1: Writing Functions with Advanced Lifecycle ........................................................................................ 71 Section 25.2: Basic Pipeline Support in Functions .................................................................................................... 71 Section 25.3: Working concept of pipeline ............................................................................................................... 72 Chapter 26: PowerShell Background Jobs .................................................................................................... 73 Section 26.1: Basic job creation .................................................................................................................................. 73 Section 26.2: Basic job management ........................................................................................................................ 73 Chapter 27: Return behavior in PowerShell .................................................................................................. 75 Section 27.1: Early exit ................................................................................................................................................. 75 Section 27.2: Gotcha! Return in the pipeline ............................................................................................................. 75 Section 27.3: Return with a value ............................................................................................................................... 75 Section 27.4: How to work with functions returns .................................................................................................... 75 Section 27.5: Gotcha! Ignoring unwanted output ..................................................................................................... 77 Chapter 28: CSV parsing ......................................................................................................................................... 78 Section 28.1: Basic usage of Import-Csv ................................................................................................................... 78 Section 28.2: Import from CSV and cast properties to correct type ..................................................................... 78 Chapter 29: Working with XML Files .................................................................................................................. 80 Section 29.1: Accessing an XML File ........................................................................................................................... 80 Section 29.2: Creating an XML Document using XmlWriter() ................................................................................. 81 Section 29.3: Adding snippets of XML to current XMLDocument ........................................................................... 82 Chapter 30: Communicating with RESTful APIs ........................................................................................... 88 Section 30.1: Post Message to hipChat ...................................................................................................................... 88 Section 30.2: Using REST with PowerShell Objects to GET and POST many items .............................................. 88 Section 30.3: Use Slack.com Incoming Webhooks .................................................................................................. 88 Section 30.4: Using REST with PowerShell Objects to Get and Put individual data ............................................. 89 Section 30.5: Using REST with PowerShell to Delete items ..................................................................................... 89 Chapter 31: PowerShell SQL queries ................................................................................................................. 90 Section 31.1: SQLExample ............................................................................................................................................ 90 Section 31.2: SQLQuery ............................................................................................................................................... 90 Chapter 32: Regular Expressions ........................................................................................................................ 91 Section 32.1: Single match .......................................................................................................................................... 91 Section 32.2: Replace .................................................................................................................................................. 93 Section 32.3: Replace text with dynamic value using a MatchEvalutor ................................................................ 93 Section 32.4: Escape special characters ................................................................................................................... 94 Section 32.5: Multiple matches ................................................................................................................................... 94 Chapter 33: Aliases ..................................................................................................................................................... 97 Section 33.1: Get-Alias ................................................................................................................................................. 97 Section 33.2: Set-Alias ................................................................................................................................................. 97 Chapter 34: Using the progress bar ................................................................................................................. 98 Section 34.1: Simple use of progress bar .................................................................................................................. 98 Section 34.2: Usage of inner progress bar ............................................................................................................... 98 Chapter 35: PowerShell.exe Command-Line ............................................................................................... 100 Section 35.1: Executing a command ........................................................................................................................ 100 Section 35.2: Executing a script file ......................................................................................................................... 101 Chapter 36: Cmdlet Naming ................................................................................................................................ 102 Section 36.1: Verbs ..................................................................................................................................................... 102 Section 36.2: Nouns ................................................................................................................................................... 102 Chapter 37: Running Executables .................................................................................................................... 103 Section 37.1: GUI Applications .................................................................................................................................. 103 Section 37.2: Console Streams ................................................................................................................................. 103 Section 37.3: Exit Codes ............................................................................................................................................ 103 Chapter 38: Enforcing script prerequisites ................................................................................................. 104 Section 38.1: Enforce minimum version of PowerShell host .................................................................................. 104 Section 38.2: Enforce running the script as administrator .................................................................................... 104 Chapter 39: Using the Help System ................................................................................................................. 105 Section 39.1: Updating the Help System ................................................................................................................. 105 Section 39.2: Using Get-Help .................................................................................................................................... 105 Section 39.3: Viewing online version of a help topic .............................................................................................. 105 Section 39.4: Viewing Examples ............................................................................................................................... 105 Section 39.5: Viewing the Full Help Page ................................................................................................................ 106 Section 39.6: Viewing help for a specific parameter ............................................................................................. 106 Chapter 40: Modules, Scripts and Functions ............................................................................................. 107 Section 40.1: Function ............................................................................................................................................... 107 Section 40.2: Script .................................................................................................................................................... 107 Section 40.3: Module ................................................................................................................................................. 108 Section 40.4: Advanced Functions .......................................................................................................................... 109 Chapter 41: Naming Conventions ..................................................................................................................... 112 Section 41.1: Functions ............................................................................................................................................... 112 Chapter 42: Common parameters .................................................................................................................. 113 Section 42.1: ErrorAction parameter ....................................................................................................................... 113 Chapter 43: Parameter sets ............................................................................................................................... 115 Section 43.1: Parameter set to enforce the use of a parameter when a other is selected ............................... 115 Section 43.2: Parameter set to limit the combination of parameters ................................................................. 115 Chapter 44: PowerShell Dynamic Parameters ......................................................................................... 116 Section 44.1: "Simple" dynamic parameter ............................................................................................................ 116 Chapter 45: GUI in PowerShell ........................................................................................................................... 118 Section 45.1: WPF GUI for Get-Service cmdlet ....................................................................................................... 118 Chapter 46: URL Encode/Decode .................................................................................................................... 120 Section 46.1: Encode Query String with `[System.Web.HttpUtility]::UrlEncode()` ............................................... 120 Section 46.2: Quick Start: Encoding ......................................................................................................................... 120 Section 46.3: Quick Start: Decoding ........................................................................................................................ 120 Section 46.4: Encode Query String with `[uri]::EscapeDataString()` .................................................................... 121 Section 46.5: Decode URL with `[uri]::UnescapeDataString()` .............................................................................. 121 Section 46.6: Decode URL with `[System.Web.HttpUtility]::UrlDecode()` ............................................................ 123 Chapter 47: Error handling ................................................................................................................................. 126 Section 47.1: Error Types .......................................................................................................................................... 126 Chapter 48: Package management ............................................................................................................... 128 Section 48.1: Create the default PowerShell Module Repository .......................................................................... 128 Section 48.2: Find a module by name .................................................................................................................... 128 Section 48.3: Install a Module by name .................................................................................................................. 128 Section 48.4: Uninstall a module my name and version ....................................................................................... 128 Section 48.5: Update a module by name ............................................................................................................... 128 Section 48.6: Find a PowerShell module using a pattern ...................................................................................... 128 Chapter 49: TCP Communication with PowerShell .................................................................................. 129 Section 49.1: TCP listener .......................................................................................................................................... 129 Section 49.2: TCP Sender ......................................................................................................................................... 129 Chapter 50: PowerShell Workflows ................................................................................................................. 131 Section 50.1: Workflow with Input Parameters ....................................................................................................... 131 Section 50.2: Simple Workflow Example ................................................................................................................ 131 Section 50.3: Run Workflow as a Background Job ............................................................................................... 131 Section 50.4: Add a Parallel Block to a Workflow ................................................................................................. 131 Chapter 51: Embedding Managed Code (C# | VB) .................................................................................... 133 Section 51.1: C# Example ........................................................................................................................................... 133 Section 51.2: VB.NET Example .................................................................................................................................. 133 Chapter 52: How to download latest artifact from Artifactory using PowerShell script (v2.0 or below)? ......................................................................................................................................................... 135 Section 52.1: PowerShell Script for downloading the latest artifact .................................................................... 135 Chapter 53: Comment-based help ................................................................................................................... 136 Section 53.1: Function comment-based help .......................................................................................................... 136 Section 53.2: Script comment-based help .............................................................................................................. 138 Chapter 54: Archive Module ............................................................................................................................... 141 Section 54.1: Compress-Archive with wildcard ....................................................................................................... 141 Section 54.2: Update existing ZIP with Compress-Archive ................................................................................... 141 Section 54.3: Extract a Zip with Expand-Archive .................................................................................................... 141 Chapter 55: Infrastructure Automation ........................................................................................................ 142 Section 55.1: Simple script for black-box integration test of console applications ............................................ 142 Chapter 56: PSScriptAnalyzer - PowerShell Script Analyzer .............................................................. 143 Section 56.1: Analyzing scripts with the built-in preset rulesets ........................................................................... 143 Section 56.2: Analyzing scripts against every built-in rule ................................................................................... 143 Section 56.3: List all built-in rules ............................................................................................................................. 143 Chapter 57: Desired State Configuration .................................................................................................... 145 Section 57.1: Simple example - Enabling WindowsFeature ................................................................................... 145 Section 57.2: Starting DSC (mof) on remote machine .......................................................................................... 145 Section 57.3: Importing psd1 (data file) into local variable ................................................................................... 145 Section 57.4: List available DSC Resources ............................................................................................................ 145 Section 57.5: Importing resources for use in DSC .................................................................................................. 146 Chapter 58: Using ShouldProcess .................................................................................................................... 147 Section 58.1: Full Usage Example ............................................................................................................................ 147 Section 58.2: Adding -WhatIf and -Confirm support to your cmdlet .................................................................. 148 Section 58.3: Using ShouldProcess() with one argument ..................................................................................... 148 Chapter 59: Scheduled tasks module ............................................................................................................ 149 Section 59.1: Run PowerShell Script in Scheduled Task ......................................................................................... 149 Chapter 60: ISE module ......................................................................................................................................... 150 Section 60.1: Test Scripts .......................................................................................................................................... 150 Chapter 61: Creating DSC Class-Based Resources .................................................................................. 151 Section 61.1: Create a DSC Resource Skeleton Class ............................................................................................. 151 Section 61.2: DSC Resource Skeleton with Key Property ...................................................................................... 151 Section 61.3: DSC Resource with Mandatory Property .......................................................................................... 151 Section 61.4: DSC Resource with Required Methods ............................................................................................. 152 Chapter 62: WMI and CIM ...................................................................................................................................... 153 Section 62.1: Querying objects ................................................................................................................................. 153 Section 62.2: Classes and namespaces .................................................................................................................. 155 Chapter 63: ActiveDirectory module .............................................................................................................. 158 Section 63.1: Users ..................................................................................................................................................... 158 Section 63.2: Module ................................................................................................................................................. 158 Section 63.3: Groups .................................................................................................................................................. 158 Section 63.4: Computers ........................................................................................................................................... 159 Section 63.5: Objects ................................................................................................................................................. 159 Chapter 64: SharePoint Module ........................................................................................................................ 160 Section 64.1: Loading SharePoint Snap-In .............................................................................................................. 160 Section 64.2: Iterating over all lists of a site collection ......................................................................................... 160 Section 64.3: Get all installed features on a site collection ................................................................................... 160 Chapter 65: Introduction to Psake .................................................................................................................. 161 Section 65.1: Basic outline ......................................................................................................................................... 161 Section 65.2: FormatTaskName example .............................................................................................................. 161 Section 65.3: Run Task conditionally ....................................................................................................................... 161 Section 65.4: ContinueOnError ................................................................................................................................. 162 Chapter 66: Introduction to Pester .................................................................................................................. 163 Section 66.1: Getting Started with Pester ................................................................................................................ 163 Chapter 67: Handling Secrets and Credentials ......................................................................................... 164 Section 67.1: Accessing the Plaintext Password ..................................................................................................... 164 Section 67.2: Prompting for Credentials ................................................................................................................. 164 Section 67.3: Working with Stored Credentials ...................................................................................................... 164 Section 67.4: Storing the credentials in Encrypted form and Passing it as parameter when Required ............................................................................................................................................................................. 165 Chapter 68: Security and Cryptography ...................................................................................................... 166 Section 68.1: Calculating a string's hash codes via .Net Cryptography ............................................................... 166 Chapter 69: Signing Scripts ................................................................................................................................. 167 Section 69.1: Signing a script .................................................................................................................................... 167 Section 69.2: Bypassing execution policy for a single script ................................................................................ 167 Section 69.3: Changing the execution policy using Set-ExecutionPolicy ............................................................. 168 Section 69.4: Get the current execution policy ....................................................................................................... 168 Section 69.5: Getting the signature from a signed script ...................................................................................... 168 Section 69.6: Creating a self-signed code signing certificate for testing ............................................................ 168 Chapter 70: Anonymize IP (v4 and v6) in text file with PowerShell ................................................ 170 Section 70.1: Anonymize IP address in text file ....................................................................................................... 170 Chapter 71: Amazon Web Services (AWS) Rekognition ......................................................................... 171 Section 71.1: Detect Image Labels with AWS Rekognition ..................................................................................... 171 Section 71.2: Compare Facial Similarity with AWS Rekognition ........................................................................... 171 Chapter 72: Amazon Web Services (AWS) Simple Storage Service (S3) ...................................... 173 Section 72.1: Create a new S3 Bucket ...................................................................................................................... 173 Section 72.2: Upload a Local File Into an S3 Bucket ............................................................................................. 173 Section 72.3: Delete a S3 Bucket ............................................................................................................................. 173 Credits ............................................................................................................................................................................ 174 You may also like ...................................................................................................................................................... 176 About Please feel free to share this PDF with anyone for free, latest version of this book can be downloaded from: https://goalkicker.com/PowerShellBook This PowerShell® Notes for Professionals book is compiled from Stack Overflow Documentation, the content is written by the beautiful people at Stack Overflow. Text content is released under Creative Commons BY-SA, see credits at the end of this book whom contributed to the various chapters. Images may be copyright of their respective owners unless otherwise specified This is an unofficial free book created for educational purposes and is not affiliated with official PowerShell® group(s) or company(s) nor Stack Overflow. All trademarks and registered trademarks are the property of their respective company owners The information presented in this book is not guaranteed to be correct nor accurate, use at your own risk Please send feedback and corrections to [email protected] GoalKicker.com – PowerShell® Notes for Professionals 1 Chapter 1: Getting started with PowerShell Version Included with Windows Notes Release Date 1.0 XP / Server 2008 2006-11-01 2.0 7 / Server 2008 R2 2009-11-01 3.0 8 / Server 2012 2012-08-01 4.0 8.1 / Server 2012 R2 2013-11-01 5.0 10 / Server 2016 Tech Preview 2015-12-16 5.1 10 Anniversary edition / Server 2016 2017-01-27 Section 1.1: Allow scripts stored on your machine to run un signed For security reasons, PowerShell is set up by default to only allow signed scripts to execute. Executing the following command will allow you to run unsigned scripts (you must run PowerShell as Administrator to do this). Set-ExecutionPolicy RemoteSigned Another way to run PowerShell scripts is to use Bypass as ExecutionPolicy: powershell.exe -ExecutionPolicy Bypass -File "c:\MyScript.ps1" Or from within your existing PowerShell console or ISE session by running: Set-ExecutionPolicy Bypass Process A temporary workaround for execution policy can also be achieved by running the PowerShell executable and passing any valid policy as -ExecutionPolicy parameter. The policy is in effect only during process' lifetime, so no administrative access to the registry is needed. C:\>powershell -ExecutionPolicy RemoteSigned There are multiple other policies available, and sites online often encourage you to use Set-ExecutionPolicy Unrestricted. This policy stays in place until changed, and lowers the system security stance. This is not advisable. Use of RemoteSigned is recommended because it allows locally stored and written code, and requires remotely acquired code be signed with a certificate from a trusted root. Also, beware that the Execution Policy may be enforced by Group Policy, so that even if the policy is changed to Unrestricted system-wide, Group Policy may revert that setting at its next enforcement interval (typically 15 minutes). You can see the execution policy set at the various scopes using Get-ExecutionPolicy -List TechNet Documentation: Set-ExecutionPolicy about_Execution_Policies Section 1.2: Aliases & Similar Functions In PowerShell, there are many ways to achieve the same result. This can be illustrated nicely with the simple & familiar Hello World example: Using Write-Host: GoalKicker.com – PowerShell® Notes for Professionals 2 Write-Host "Hello World" Using Write-Output: Write-Output 'Hello world' It's worth noting that although Write-Output & Write-Host both write to the screen there is a subtle difference. Write-Host writes only to stdout (i.e. the console screen), whereas Write-Output writes to both stdout AND to the output [success] stream allowing for redirection. Redirection (and streams in general) allow for the output of one command to be directed as input to another including assignment to a variable. > $message = Write-Output "Hello World" > $message "Hello World" These similar functions are not aliases, but can produce the same results if one wants to avoid "polluting" the success stream. Write-Output is aliased to Echo or Write Echo 'Hello world' Write 'Hello world' Or, by simply typing 'Hello world'! 'Hello world' All of which will result with the expected console output Hello world Another example of aliases in PowerShell is the common mapping of both older command prompt commands and BASH commands to PowerShell cmdlets. All of the following produce a directory listing of the current directory. C:\Windows> dir C:\Windows> ls C:\Windows> Get-ChildItem Finally, you can create your own alias with the Set-Alias cmdlet! As an example let's alisas Test-NetConnection, which is essentially the PowerShell equivalent to the command prompt's ping command, to "ping". Set-Alias -Name ping -Value Test-NetConnection Now you can use ping instead of Test-NetConnection! Be aware that if the alias is already in use, you'll overwrite the association. The Alias will be alive, till the session is active. Once you close the session and try to run the alias which you have created in your last session, it will not work. To overcome this issue, you can import all your aliases from an excel into your session once, before starting your work. Section 1.3: The Pipeline - Using Output from a PowerShell GoalKicker.com – PowerShell® Notes for Professionals 3 cmdlet One of the first questions people have when they begin to use PowerShell for scripting is how to manipulate the output from a cmdlet to perform another action. The pipeline symbol | is used at the end of a cmdlet to take the data it exports and feed it to the next cmdlet. A simple example is using Select-Object to only show the Name property of a file shown from Get-ChildItem: Get-ChildItem | Select-Object Name #This may be shortened to: gci | Select Name More advanced usage of the pipeline allows us to pipe the output of a cmdlet into a foreach loop: Get-ChildItem | ForEach-Object { Copy-Item -Path $_.FullName -destination C:\NewDirectory\ } #This may be shortened to: gci | % { Copy $_.FullName C:\NewDirectory\ } Note that the example above uses the $_ automatic variable. $_ is the short alias of $PSItem which is an automatic variable which contains the current item in the pipeline. Section 1.4: Calling .Net Library Methods Static .Net library methods can be called from PowerShell by encapsulating the full class name in third bracket and then calling the method using :: #calling Path.GetFileName() C:\> [System.IO.Path]::GetFileName('C:\Windows\explorer.exe') explorer.exe Static methods can be called from the class itself, but calling non-static methods requires an instance of the .Net class (an object). For example, the AddHours method cannot be called from the System.DateTime class itself. It requires an instance of the class: C:\> [System.DateTime]::AddHours(15) Method invocation failed because [System.DateTime] does not contain a method named 'AddHours'. At line:1 char:1 + [System.DateTime]::AddHours(15) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : MethodNotFound In this case, we first create an object, for example: C:\> $Object = [System.DateTime]::Now Then, we can use methods of that object, even methods which cannot be called directly from the System.DateTime class, like the AddHours method: C:\> $Object.AddHours(15) GoalKicker.com – PowerShell® Notes for Professionals 4 Monday 12 September 2016 01:51:19 Section 1.5: Installation or Setup Windows PowerShell is included with the Windows Management Framework. Installation and Setup are not required on modern versions of Windows. Updates to PowerShell can be accomplished by installing a newer version of the Windows Management Framework. Other Platforms PowerShell 6 can be installed on other platforms. The installation packages are available here. For example, PowerShell 6, for Ubuntu 16.04, is published to package repositories for easy installation (and updates). To install run the following: # Import the public repository GPG keys curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - # Register the Microsoft Ubuntu repository curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list | sudo tee /etc/apt/sources.list.d/microsoft.list # Update apt-get sudo apt-get update # Install PowerShell sudo apt-get install -y powershell # Start PowerShell powershell After registering the Microsoft repository once as superuser, from then on, you just need to use sudo apt-get upgrade powershell to update it. Then just run powershell Section 1.6: Commenting To comment on power scripts by prepending the line using the # (hash) symbol # This is a comment in PowerShell Get-ChildItem You can also have multi-line comments using <# and #> at the beginning and end of the comment respectively. <# This is a multi-line comment #> Get-ChildItem GoalKicker.com – PowerShell® Notes for Professionals 5 Section 1.7: Creating Objects The New-Object cmdlet is used to create an object. # Create a DateTime object and stores the object in variable "$var" $var = New-Object System.DateTime # calling constructor with parameters $sr = New-Object System.IO.StreamReader -ArgumentList "file path" In many instances, a new object will be created in order to export data or pass it to another commandlet. This can be done like so: $newObject = New-Object -TypeName PSObject -Property @{ ComputerName = "SERVER1" Role = "Interface" Environment = "Production" } There are many ways of creating an object. The following method is probably the shortest and fastest way to create a PSCustomObject: $newObject = [PSCustomObject]@{ ComputerName = 'SERVER1' Role = 'Interface' Environment = 'Production' } In case you already have an object, but you only need one or two extra properties, you can simply add that property by using Select-Object: Get-ChildItem | Select-Object FullName, Name, @{Name='DateTime'; Expression={Get-Date}}, @{Name='PropertyName'; Expression={'CustomValue'}} All objects can be stored in variables or passed into the pipeline. You could also add these objects to a collection and then show the results at the end. Collections of objects work well with Export-CSV (and Import-CSV). Each line of the CSV is an object, each column a property. Format commands convert objects into text stream for display. Avoid using Format-* commands until the final step of any data processing, to maintain the usability of the objects. GoalKicker.com – PowerShell® Notes for Professionals 6 Chapter 2: Variables in PowerShell Variables are used for storing values. Let the value be of any type , we need to store it somewhere so that we can use it throughout the console/script. Variable names in PowerShell begin with a $, as in $Variable1, and values are assigned using =, like $Variable1 = "Value 1".PowerShell supports a huge number of variable types; such as text strings, integers, decimals, arrays, and even advanced types like version numbers or IP addresses. Section 2.1: Simple variable All variables in PowerShell begin with a US dollar sign ($). The simplest example of this is: $foo = "bar" This statement allocates a variable called foo with a string value of "bar". Section 2.2: Arrays Array declaration in Powershell is almost the same as instantiating any other variable, i.e. you use a $name = syntax. The items in the array are declared by separating them by commas(,): $myArrayOfInts = 1,2,3,4 $myArrayOfStrings = "1","2","3","4" Adding to an array Adding to an array is as simple as using the + operator: $myArrayOfInts = $myArrayOfInts + 5 # now contains 1,2,3,4 & 5! Combining arrays together Again this is as simple as using the + operator $myArrayOfInts = 1,2,3,4 $myOtherArrayOfInts = 5,6,7 $myArrayOfInts = $myArrayOfInts + $myOtherArrayOfInts # now 1,2,3,4,5,6,7 Section 2.3: List Assignment of Multiple Variables Powershell allows multiple assignment of variables and treats almost everything like an array or list. This means that instead of doing something like this: $input = "foo.bar.baz" $parts = $input.Split(".") $foo = $parts[0] $bar = $parts[1] $baz = $parts[2] You can simply do this: $foo, $bar, $baz = $input.Split(".") GoalKicker.com – PowerShell® Notes for Professionals 7 Since Powershell treats assignments in this manner like lists, if there are more values in the list than items in your list of variables to assign them to, the last variable becomes an array of the remaining values. This means you can also do things like this: $foo, $leftover = $input.Split(".") #Sets $foo = "foo", $leftover = ["bar","baz"] $bar = $leftover[0] # $bar = "bar" $baz = $leftover[1] # $baz = "baz" Section 2.4: Scope The default scope for a variable is the enclosing container. If outside a script, or other container then the scope is Global. To specify a scope, it is prefixed to the variable name $scope:varname like so: $foo = "Global Scope" function myFunc { $foo = "Function (local) scope" Write-Host $global:foo Write-Host $local:foo Write-Host $foo } myFunc Write-Host $local:foo Write-Host $foo Output: Global Scope Function (local) scope Function (local) scope Global Scope Global Scope Section 2.5: Removing a variable To remove a variable from memory, one can use the Remove-Item cmdlet. Note: The variable name does NOT include the $. Remove-Item Variable:\foo Variable has a provider to allow most *-item cmdlets to work much like file systems. Another method to remove variable is to use Remove-Variable cmdlet and its alias rv $var = "Some Variable" #Define variable 'var' containing the string 'Some Variable' $var #For test and show string 'Some Variable' on the console Remove-Variable -Name var $var #also can use alias 'rv' rv var GoalKicker.com – PowerShell® Notes for Professionals 8 Chapter 3: Operators An operator is a character that represents an action. It tells the compiler/interpreter to perform specific mathematical, relational or logical operation and produce final result. PowerShell interprets in a specific way and categorizes accordingly like arithmetic operators perform operations primarily on numbers, but they also affect strings and other data types. Along with the basic operators, PowerShell has a number of operators that save time and coding effort (eg: -like, -match, -replace, etc). Section 3.1: Comparison Operators PowerShell comparison operators are comprised of a leading dash (-) followed by a name (eq for equal, gt for greater than, etc...). Names can be preceded by special characters to modify the behavior of the operator: i # Case-Insensitive Explicit (-ieq) c # Case-Sensitive Explicit (-ceq) Case-Insensitive is the default if not specified, ("a" -eq "A") same as ("a" -ieq "A"). Simple comparison operators: 2 -eq 2 # Equal to (==) 2 -ne 4 # Not equal to (!=) 5 -gt 2 # Greater-than (>) 5 -ge 5 # Greater-than or equal to (>=) 5 -lt 10 # Less-than (<) 5 -le 5 # Less-than or equal to (<=) String comparison operators: "MyString" -like "*String" # Match using the wildcard character (*) "MyString" -notlike "Other*" # Does not match using the wildcard character (*) "MyString" -match '^String$' # Matches a string using regular expressions "MyString" -notmatch '^Other$' # Does not match a string using regular expressions Collection comparison operators: "abc", "def" -contains "def" # Returns true when the value (right) is present # in the array (left) "abc", "def" -notcontains "123" # Returns true when the value (right) is not present # in the array (left) "def" -in "abc", "def" # Returns true when the value (left) is present # in the array (right) "123" -notin "abc", "def" # Returns true when the value (left) is not present # in the array (right) Section 3.2: Arithmetic Operators 1 + 2 # Addition 1 - 2 # Subtraction -1 # Set negative value 1 * 2 # Multiplication 1 / 2 # Division 1 % 2 # Modulus GoalKicker.com – PowerShell® Notes for Professionals 9 100 -shl 2 # Bitwise Shift-left 100 -shr 1 # Bitwise Shift-right Section 3.3: Assignment Operators Simple arithmetic: $var = 1 # Assignment. Sets the value of a variable to the specified value $var += 2 # Addition. Increases the value of a variable by the specified value $var -= 1 # Subtraction. Decreases the value of a variable by the specified value $var *= 2 # Multiplication. Multiplies the value of a variable by the specified value $var /= 2 # Division. Divides the value of a variable by the specified value $var %= 2 # Modulus. Divides the value of a variable by the specified value and then # assigns the remainder (modulus) to the variable Increment and decrement: $var++ # Increases the value of a variable, assignable property, or array element by 1 $var-- # Decreases the value of a variable, assignable property, or array element by 1 Section 3.4: Redirection Operators Success output stream: cmdlet > file # Send success output to file, overwriting existing content cmdlet >> file # Send success output to file, appending to existing content cmdlet 1>&2 # Send success and error output to error stream Error output stream: cmdlet 2> file # Send error output to file, overwriting existing content cmdlet 2>> file # Send error output to file, appending to existing content cmdlet 2>&1 # Send success and error output to success output stream Warning output stream: (PowerShell 3.0+) cmdlet 3> file # Send warning output to file, overwriting existing content cmdlet 3>> file # Send warning output to file, appending to existing content cmdlet 3>&1 # Send success and warning output to success output stream Verbose output stream: (PowerShell 3.0+) cmdlet 4> file # Send verbose output to file, overwriting existing content cmdlet 4>> file # Send verbose output to file, appending to existing content cmdlet 4>&1 # Send success and verbose output to success output stream Debug output stream: (PowerShell 3.0+) cmdlet 5> file # Send debug output to file, overwriting existing content cmdlet 5>> file # Send debug output to file, appending to existing content cmdlet 5>&1 # Send success and debug output to success output stream Information output stream: (PowerShell 5.0+) cmdlet 6> file # Send information output to file, overwriting existing content cmdlet 6>> file # Send information output to file, appending to existing content GoalKicker.com – PowerShell® Notes for Professionals 10 cmdlet 6>&1 # Send success and information output to success output stream All output streams: cmdlet *> file # Send all output streams to file, overwriting existing content cmdlet *>> file # Send all output streams to file, appending to existing content cmdlet *>&1 # Send all output streams to success output stream Differences to the pipe operator (|) Redirection operators only redirect streams to files or streams to streams. The pipe operator pumps an object down the pipeline to a cmdlet or the output. How the pipeline works differs in general from how redirection works and can be read on Working with the PowerShell pipeline Section 3.5: Mixing operand types, the type of the left operand dictates the behavior For Addition "4" + 2 # Gives "42" 4 + "2" # Gives 6 1,2,3 + "Hello" # Gives 1,2,3,"Hello" "Hello" + 1,2,3 # Gives "Hello1 2 3" For Multiplication "3" * 2 # Gives "33" 2 * "3" # Gives 6 1,2,3 * 2 # Gives 1,2,3,1,2,3 2 * 1,2,3 # Gives an error op_Multiply is missing The impact may have hidden consequences on comparison operators: $a = Read-Host "Enter a number" Enter a number : 33 $a -gt 5 False Section 3.6: Logical Operators -and # Logical and -or # Logical or -xor # Logical exclusive or -not # Logical not ! # Logical not Section 3.7: String Manipulation Operators Replace operator: The -replace operator replaces a pattern in an input value using a regular expression. This operator uses two arguments (separated by a comma): a regular expression pattern and its replacement value (which is optional and an empty string by default). "The rain in Seattle" -replace 'rain','hail' #Returns: The hail in Seattle GoalKicker.com – PowerShell® Notes for Professionals 11 "[email protected]" -replace '^[\w]+@(.+)', '$1' #Returns: contoso.com Split and Join operators: The -split operator splits a string into an array of sub-strings. "A B C" -split " " #Returns an array string collection object containing A,B and C. The -join operator joins an array of strings into a single string. "E","F","G" -join ":" #Returns a single string: E:F:G GoalKicker.com – PowerShell® Notes for Professionals 12 Chapter 4: Special Operators Section 4.1: Array Expression Operator Returns the expression as an array. @(Get-ChildItem $env:windir\System32\ntdll.dll) Will return an array with one item @(Get-ChildItem $env:windir\System32) Will return an array with all the items in the folder (which is not a change of behavior from the inner expression. Section 4.2: Call Operation $command = 'Get-ChildItem' & $Command Will execute Get-ChildItem Section 4.3: Dot sourcing operator . .\myScript.ps1 runs .\myScript.ps1 in the current scope making any functions, and variable available in the current scope. GoalKicker.com – PowerShell® Notes for Professionals 13 Chapter 5: Basic Set Operations A set is a collection of items which can be anything. Whatever operator we need to work on these sets are in short the set operators and the operation is also known as set operation. Basic set operation includes Union, Intersection as well as addition, subtraction, etc. Section 5.1: Filtering: Where-Object / where / ? Filter an enumeration by using a conditional expression Synonyms: Where-Object where ? Example: $names = @( "Aaron", "Albert", "Alphonse","Bernie", "Charlie", "Danny", "Ernie", "Frank") $names | Where-Object { $_ -like "A*" } $names | where { $_ -like "A*" } $names | ? { $_ -like "A*" } Returns: Aaron Albert Alphonse Section 5.2: Ordering: Sort-Object / sort Sort an enumeration in either ascending or descending order Synonyms: Sort-Object sort Assuming: $names = @( "Aaron", "Aaron", "Bernie", "Charlie", "Danny" ) Ascending sort is the default: $names | Sort-Object $names | sort Aaron Aaron Bernie GoalKicker.com – PowerShell® Notes for Professionals 14 Charlie Danny To request descending order: $names | Sort-Object -Descending $names | sort -Descending Danny Charlie Bernie Aaron Aaron You can sort using an expression. $names | Sort-Object { $_.length } Aaron Aaron Danny Bernie Charlie Section 5.3: Grouping: Group-Object / group You can group an enumeration based on an expression. Synonyms: Group-Object group Examples: $names = @( "Aaron", "Albert", "Alphonse","Bernie", "Charlie", "Danny", "Ernie", "Frank") $names | Group-Object -Property Length $names | group -Property Length Response: Count Name Group 4 5 {Aaron, Danny, Ernie, Frank} 2 6 {Albert, Bernie} 1 8 {Alphonse} 1 7 {Charlie} GoalKicker.com – PowerShell® Notes for Professionals 15 Section 5.4: Projecting: Select-Object / select Projecting an enumeration allows you to extract specific members of each object, to extract all the details, or to compute values for each object Synonyms: Select-Object SELECT Selecting a subset of the properties: $dir = dir "C:\MyFolder" $dir | Select-Object Name, FullName, Attributes $dir | select Name, FullName, Attributes Name FullName Attributes Images C:\MyFolder\Images Directory data.txt C:\MyFolder\data.txt Archive source.c C:\MyFolder\source.c Archive Selecting the first element, and show all its properties: $d | select -first 1 * PSPath PSParentPath PSChildName PSDrive PSProvider PSIsContainer BaseName Mode Name Parent Exists Root FullName Extension CreationTime CreationTimeUtc LastAccessTime LastAccessTimeUtc LastWriteTime LastWriteTimeUtc Attributes GoalKicker.com – PowerShell® Notes for Professionals 16 Chapter 6: Conditional logic Section 6.1: if, else and else if Powershell supports standard conditional logic operators, much like many programming languages. These allow certain functions or commands to be run under particular circumstances. With an if the commands inside the brackets ({}) are only executed if the conditions inside the if(()) are met $test = "test" if ($test -eq "test"){ Write-Host "if condition met" } You can also do an else. Here the else commands are executed if the if conditions are not met: $test = "test" if ($test -eq "test2"){ Write-Host "if condition met" } else{ Write-Host "if condition not met" } or an elseif. An else if runs the commands if the if conditions are not met and the elseif conditions are met: $test = "test" if ($test -eq "test2"){ Write-Host "if condition met" } elseif ($test -eq "test"){ Write-Host "ifelse condition met" } Note the above use -eq(equality) CmdLet and not = or == as many other languages do for equality. Section 6.2: Negation You may want to negate a boolean value, i.e. enter an if statement when a condition is false rather than true. This can be done by using the -Not CmdLet $test = "test" if (-Not $test -eq "test2"){ Write-Host "if condition not met" } You can also use !: $test = "test" if (!($test -eq "test2")){ Write-Host "if condition not met" } there is also the -ne (not equal) operator: GoalKicker.com – PowerShell® Notes for Professionals 17 $test = "test" if ($test -ne "test2"){ Write-Host "variable test is not equal to 'test2'" } Section 6.3: If conditional shorthand If you want to use the shorthand you can make use of conditional logic with the following shorthand. Only the string 'false' will evaluate to true (2.0). #Done in Powershell 2.0 $boolean = $false; $string = "false"; $emptyString = ""; If($boolean){ # this does not run because $boolean is false Write-Host "Shorthand If conditions can be nice, just make sure they are always boolean." } If($string){ # This does run because the string is non-zero length Write-Host "If the variable is not strictly null or Boolean false, it will evaluate to true as it is an object or string with length greater than 0." } If($emptyString){ # This does not run because the string is zero-length Write-Host "Checking empty strings can be useful as well." } If($null){ # This does not run because the condition is null Write-Host "Checking Nulls will not print this statement." } GoalKicker.com – PowerShell® Notes for Professionals 18 Chapter 7: Loops A loop is a sequence of instruction(s) that is continually repeated until a certain condition is reached. Being able to have your program repeatedly execute a block of code is one of the most basic but useful tasks in programming. A loop lets you write a very simple statement to produce a significantly greater result simply by repetition. If the condition has been reached, the next instruction "falls through" to the next sequential instruction or branches outside the loop. Section 7.1: Foreach ForEach has two different meanings in PowerShell. One is a keyword and the other is an alias for the ForEach Object cmdlet. The former is described here. This example demonstrates printing all items in an array to the console host: $Names = @('Amy', 'Bob', 'Celine', 'David') ForEach ($Name in $Names) { Write-Host "Hi, my name is $Name!" } This example demonstrates capturing the output of a ForEach loop: $Numbers = ForEach ($Number in 1..20) { $Number # Alternatively, Write-Output $Number } Like the last example, this example, instead, demonstrates creating an array prior to storing the loop: $Numbers = @() ForEach ($Number in 1..20) { $Numbers += $Number } Section 7.2: For for($i = 0; $i -le 5; $i++){ "$i" } A typical use of the for loop is to operate on a subset of the values in an array. In most cases, if you want to iterate all values in an array, consider using a foreach statement. Section 7.3: ForEach() Method Version > 4.0 Instead of the ForEach-Object cmdlet, the here is also the possibility to use a ForEach method directly on object arrays like so (1..10).ForEach({$_ * $_}) GoalKicker.com – PowerShell® Notes for Professionals 19 or - if desired - the parentheses around the script block can be omitted (1..10).ForEach{$_ * $_} Both will result in the output below 1 4 9 16 25 36 49 64 81 100 Section 7.4: ForEach-Object The ForEach-Object cmdlet works similarly to the foreach statement, but takes its input from the pipeline. Basic usage $object | ForEach-Object { code_block } Example: $names = @("Any","Bob","Celine","David") $names | ForEach-Object { "Hi, my name is $_!" } Foreach-Object has two default aliases, foreach and % (shorthand syntax). Most common is % because foreach can be confused with the foreach statement. Examples: $names | % { "Hi, my name is $_!" } $names | foreach { "Hi, my name is $_!" } Advanced usage Foreach-Object stands out from the alternative foreach solutions because it's a cmdlet which means it's designed to use the pipeline. Because of this, it has support for three scriptblocks just like a cmdlet or advanced function: Begin: Executed once before looping through the items that arrive from the pipeline. Usually used to create functions for use in the loop, creating variables, opening connections (database, web +) etc. Process: Executed once per item arrived from the pipeline. "Normal" foreach codeblock. This is the default used in the examples above when the parameter isn't specified. End: Executed once after processing all items. Usually used to close connections, generate a report etc. GoalKicker.com – PowerShell® Notes for Professionals 20 Example: "Any","Bob","Celine","David" | ForEach-Object -Begin { $results = @() } -Process { #Create and store message $results += "Hi, my name is $_!" } -End { #Count messages and output Write-Host "Total messages: $($results.Count)" $results } Section 7.5: Continue The Continue operator works in For, ForEach, While and Do loops. It skips the current iteration of the loop, jumping to the top of the innermost loop. $i =0 while ($i -lt 20) { $i++ if ($i -eq 7) { continue } Write-Host $I } The above will output 1 to 20 to the console but miss out the number 7. Note: When using a pipeline loop you should use return instead of Continue. Section 7.6: Break The break operator will exit a program loop immediately. It can be used in For, ForEach, While and Do loops or in a Switch Statement. $i = 0 while ($i -lt 15) { $i++ if ($i -eq 7) {break} Write-Host $i } The above will count to 15 but stop as soon as 7 is reached. Note: When using a pipeline loop, break will behave as continue. To simulate break in the pipeline loop you need to incorporate some additional logic, cmdlet, etc. It is easier to stick with non-pipeline loops if you need to use break. Break Labels Break can also call a label that was placed in front of the instantiation of a loop: $i = 0 :mainLoop While ($i -lt 15) { Write-Host $i -ForegroundColor 'Cyan' $j = 0 While ($j -lt 15) { Write-Host $j -ForegroundColor 'Magenta' GoalKicker.com – PowerShell® Notes for Professionals 21 $k = $i*$j Write-Host $k -ForegroundColor 'Green' if ($k -gt 100) { break mainLoop } $j++ } $i++ } Note: This code will increment $i to 8 and $j to 13 which will cause $k to equal 104. Since $k exceed 100, the code will then break out of both loops. Section 7.7: While A while loop will evaluate a condition and if true will perform an action. As long as the condition evaluates to true the action will continue to be performed. while(condition){ code_block } The following example creates a loop that will count down from 10 to 0 $i = 10 while($i -ge 0){ $i $i-- } Unlike the Do-While loop the condition is evaluated prior to the action's first execution. The action will not be performed if the initial condition evaluates to false. Note: When evaluating the condition, PowerShell will treat the existence of a return object as true. This can be used in several ways but below is an example to monitor for a process. This example will spawn a notepad process and then sleep the current shell as long as that process is running. When you manually close the notepad instance the while condition will fail and the loop will break. Start-Process notepad.exe while(Get-Process notepad -ErrorAction SilentlyContinue){ Start-Sleep -Milliseconds 500 } Section 7.8: Do Do-loops are useful when you always want to run a codeblock at least once. A Do-loop will evaluate the condition after executing the codeblock, unlike a while-loop which does it before executing the codeblock. You can use do-loops in two ways: Loop while the condition is true: Do { code_block } while (condition) GoalKicker.com – PowerShell® Notes for Professionals 22 Loop until the condition is true, in other words, loop while the condition is false: Do { code_block } until (condition) Real Examples: $i = 0 Do { $i++ "Number $i" } while ($i -ne 3) Do { $i++ "Number $i" } until ($i -eq 3) Do-While and Do-Until are antonymous loops. If the code inside the same, the condition will be reversed. The example above illustrates this behaviour. GoalKicker.com – PowerShell® Notes for Professionals 23 Chapter 8: Switch statement A switch statement allows a variable to be tested for equality against a list of values. Each value is called a case, and the variable being switched on is checked for each switch case. It enables you to write a script that can choose from a series of options, but without requiring you to write a long series of if statements. Section 8.1: Simple Switch Switch statements compare a single test value to multiple conditions, and performs any associated actions for successful comparisons. It can result in multiple matches/actions. Given the following switch... switch($myValue) { 'First Condition' { 'First Action' } 'Second Condition' { 'Second Action' } } 'First Action' will be output if $myValue is set as 'First Condition'. 'Section Action' will be output if $myValue is set as 'Second Condition'. Nothing will be output if $myValue does not match either conditions. Section 8.2: Switch Statement with CaseSensitive Parameter The -CaseSensitive parameter enforces switch statements to perform exact, case-sensitive matching against conditions. Example: switch -CaseSensitive ('Condition') { 'condition' {'First Action'} 'Condition' {'Second Action'} 'conditioN' {'Third Action'} } Output: Second Action The second action is the only action executed because it is the only condition that exactly matches the string 'Condition' when accounting for case-sensitivity. Section 8.3: Switch Statement with Wildcard Parameter The -Wildcard parameter allows switch statements to perform wildcard matching against conditions. Example: switch -Wildcard ('Condition') { GoalKicker.com – PowerShell® Notes for Professionals 24 'Condition' {'Normal match'} 'Condit*' {'Zero or more wildcard chars.'} 'C[aoc]ndit[f-l]on' {'Range and set of chars.'} 'C?ndition' {'Single char. wildcard'} 'Test*' {'No match'} } Output: Normal match Zero or more wildcard chars. Range and set of chars. Single char. wildcard Section 8.4: Switch Statement with File Parameter The -file parameter allows the switch statement to receive input from a file. Each line of the file is evaluated by the switch statement. Example file input.txt: condition test Example switch statement: switch -file input.txt { 'condition' {'First Action'} 'test' {'Second Action'} 'fail' {'Third Action'} } Output: First Action Second Action Section 8.5: Simple Switch with Default Condition The Default keyword is used to execute an action when no other conditions match the input value. Example: switch('Condition') { 'Skip Condition' { 'First Action' } 'Skip This Condition Too' { 'Second Action' } Default { GoalKicker.com – PowerShell® Notes for Professionals 25 'Default Action' } } Output: Default Action Section 8.6: Switch Statement with Regex Parameter The -Regex parameter allows switch statements to perform regular expression matching against conditions. Example: switch -Regex ('Condition') { 'Con\D+ion' {'One or more non-digits'} 'Conditio*$' {'Zero or more "o"'} 'C.ndition' {'Any single char.'} '^C\w+ition$' {'Anchors and one or more word chars.'} 'Test' {'No match'} } Output: One or more non-digits Any single char. Anchors and one or more word chars. Section 8.7: Simple Switch With Break The break keyword can be used in switch statements to exit the statement before evaluating all conditions. Example: switch('Condition') { 'Condition' { 'First Action' } 'Condition' { 'Second Action' break } 'Condition' { 'Third Action' } } Output: First Action Second Action GoalKicker.com – PowerShell® Notes for Professionals 26 Because of the break keyword in the second action, the third condition is not evaluated. Section 8.8: Switch Statement with Exact Parameter The -Exact parameter enforces switch statements to perform exact, case-insensitive matching against string conditions. Example: switch -Exact ('Condition') { 'condition' {'First Action'} 'Condition' {'Second Action'} 'conditioN' {'Third Action'} '^*ondition$' {'Fourth Action'} 'Conditio*' {'Fifth Action'} } Output: First Action Second Action Third Action The first through third actions are executed because their associated conditions matched the input. The regex and wildcard strings in the fourth and fifth conditions fail matching. Note that the fourth condition would also match the input string if regular expression matching was being performed, but was ignored in this case because it is not. Section 8.9: Switch Statement with Expressions Conditions can also be expressions: $myInput = 0 switch($myInput) { # because the result of the expression, 4, # does not equal our input this block should not be run. (2+2) { 'True. 2 +2 = 4' } # because the result of the expression, 0, # does equal our input this block should be run. (2-2) { 'True. 2-2 = 0' } # because our input is greater than -1 and is less than 1 # the expression evaluates to true and the block should be run. { $_ -gt -1 -and $_ -lt 1 } { 'True. Value is 0' } } #Output True. 2-2 = 0 True. Value is 0 GoalKicker.com – PowerShell® Notes for Professionals 27 Chapter 9: Strings Section 9.1: Multiline string There are multiple ways to create a multiline string in PowerShell: You can use the special characters for carriage return and/or newline manually or use the NewLine environment variable to insert the systems "newline" value) "Hello`r`nWorld" "Hello{0}World" -f [environment]::NewLine Create a linebreak while defining a string (before closing quote) "Hello World" Using a here-string. This is the most common technique. @" Hello World "@ Section 9.2: Here-string Here-strings are very useful when creating multiline strings. One of the biggest benefits compared to other multiline strings are that you can use quotes without having to escape them using a backtick. Here-string Here-strings begin with @" and a linebreak and end with "@ on its own line ("@must be first characters on the line, not even whitespace/tab). @" Simple Multiline string with "quotes" "@ Literal here-string You could also create a literal here-string by using single quotes, when you don't want any expressions to be expanded just like a normal literal string. @' The following line won't be expanded $(Get-Date) because this is a literal here-string '@ Section 9.3: Concatenating strings Using variables in a string GoalKicker.com – PowerShell® Notes for Professionals 28 You can concatenate strings using variables inside a double-quoted string. This does not work with properties. $string1 = "Power" $string2 = "Shell" "Greetings from $string1$string2" Using the + operator You can also join strings using the + operator. $string1 = "Greetings from" $string2 = "PowerShell" $string1 + " " + $string2 This also works with properties of objects. "The title of this console is '" + $host.Name + "'" Using subexpressions The output/result of a subexpressions $() can be used in a string. This is useful when accessing properties of an object or performing a complex expression. Subexpressions can contain multiple statements separated by semicolon ; "Tomorrow is $((Get-Date).AddDays(1).DayOfWeek)" Section 9.4: Special characters When used inside a double-quoted string, the escape character (backtick `) represents a special character. `0 #Null `a #Alert/Beep `b #Backspace `f #Form feed (used for printer output) `n #New line `r #Carriage return `t #Horizontal tab `v #Vertical tab (used for printer output) Example: > "This`tuses`ttab`r`nThis is on a second line" This uses tab This is on a second line You can also escape special characters with special meanings: `# #Comment-operator `$ #Variable operator `` #Escape character `' #Single quote `" #Double quote Section 9.5: Creating a basic string String GoalKicker.com – PowerShell® Notes for Professionals 29 Strings are created by wrapping the text with double quotes. Double-quoted strings can evaluate variables and special characters. $myString = "Some basic text" $mySecondString = "String with a $variable" To use a double quote inside a string it needs to be escaped using the escape character, backtick (`). Single quotes can be used inside a double-quoted string. $myString = "A `"double quoted`" string which also has 'single quotes'." Literal string Literal strings are strings that doesn't evaluate variables and special characters. It's created using single quotes. $myLiteralString = 'Simple text including special characters (`n) and a $variable-reference' To use single quotes inside a literal string, use double single quotes or a literal here-string. Double quotes can be used safely inside a literal string $myLiteralString = 'Simple string with ''single quotes'' and "double quotes".' Section 9.6: Format string $hash = @{ city = 'Berlin' } $result = 'You should really visit {0}' -f $hash.city Write-Host $result #prints "You should really visit Berlin" Format strings can be used with the -f operator or the static [String]::Format(string format, args) .NET method. GoalKicker.com – PowerShell® Notes for Professionals 30 Chapter 10: HashTables A Hash Table is a structure which maps keys to values. See Hash Table for details. Section 10.1: Access a hash table value by key An example of defining a hash table and accessing a value by the key $hashTable = @{ Key1 = 'Value1' Key2 = 'Value2' } $hashTable.Key1 #output Value1 An example of accessing a key with invalid characters for a property name: $hashTable = @{ 'Key 1' = 'Value3' Key2 = 'Value4' } $hashTable.'Key 1' #Output Value3 Section 10.2: Creating a Hash Table Example of creating an empty HashTable: $hashTable = @{} Example of creating a HashTable with data: $hashTable = @{ Name1 = 'Value' Name2 = 'Value' Name3 = 'Value3' } Section 10.3: Add a key value pair to an existing hash table An example, to add a "Key2" key with a value of "Value2" to the hash table, using the addition operator: $hashTable = @{ Key1 = 'Value1' } $hashTable += @{Key2 = 'Value2'} $hashTable #Output Name Value ---- ----- Key1 Value1 GoalKicker.com – PowerShell® Notes for Professionals 31 Key2 Value2 An example, to add a "Key2" key with a value of "Value2" to the hash table using the Add method: $hashTable = @{ Key1 = 'Value1' } $hashTable.Add("Key2", "Value2") $hashTable #Output Name Value ---- ----- Key1 Value1 Key2 Value2 Section 10.4: Remove a key value pair from an existing hash table An example, to remove a "Key2" key with a value of "Value2" from the hash table, using the remove operator: $hashTable = @{ Key1 = 'Value1' Key2 = 'Value2' } $hashTable.Remove("Key2", "Value2") $hashTable #Output Name Value ---- ----- Key1 Value1 Section 10.5: Enumerating through keys and Key-Value Pairs Enumerating through Keys foreach ($key in $var1.Keys) { $value = $var1[$key] # or $value = $var1.$key } Enumerating through Key-Value Pairs foreach ($keyvaluepair in $var1.GetEnumerator()) { $key1 = $_.Key1 $val1 = $_.Val1 } Section 10.6: Looping over a hash table $hashTable = @{ Key1 = 'Value1' Key2 = 'Value2' GoalKicker.com – PowerShell® Notes for Professionals 32 } foreach($key in $hashTable.Keys) { $value = $hashTable.$key Write-Output "$key : $value" } #Output Key1 : Value1 Key2 : Value2 GoalKicker.com – PowerShell® Notes for Professionals 33 Chapter 11: Working with Objects Section 11.1: Examining an object Now that you have an object, it might be good to figure out what it is. You can use the Get-Member cmdlet to see what an object is and what it contains: Get-Item c:\windows | Get-Member This yields: TypeName: System.IO.DirectoryInfo Followed by a list of properties and methods the object has. Another way to get the type of an object is to use the GetType method, like so: C:\> $Object = Get-Item C:\Windows C:\> $Object.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True DirectoryInfo System.IO.FileSystemInfo To view a list of properties the object has, along with their values, you can use the Format-List cmdlet with its Property parameter set to: * (meaning all). Here is an example, with the resulting output: C:\> Get-Item C:\Windows | Format-List -Property * PSPath : Microsoft.PowerShell.Core\FileSystem::C:\Windows PSParentPath : Microsoft.PowerShell.Core\FileSystem::C:\ PSChildName : Windows PSDrive : C PSProvider : Microsoft.PowerShell.Core\FileSystem PSIsContainer : True Mode : d----- BaseName : Windows Target : {} LinkType : Name : Windows Parent : Exists : True Root : C:\ FullName : C:\Windows Extension : CreationTime : 30/10/2015 06:28:30 CreationTimeUtc : 30/10/2015 06:28:30 LastAccessTime : 16/08/2016 17:32:04 LastAccessTimeUtc : 16/08/2016 16:32:04 LastWriteTime : 16/08/2016 17:32:04 LastWriteTimeUtc : 16/08/2016 16:32:04 Attributes : Directory GoalKicker.com – PowerShell® Notes for Professionals 34 Section 11.2: Updating Objects Adding properties If you'd like to add properties to an existing object, you can use the Add-Member cmdlet. With PSObjects, values are kept in a type of "Note Properties" $object = New-Object -TypeName PSObject -Property @{ Name = $env:username ID = 12 Address = $null } Add-Member -InputObject $object -Name "SomeNewProp" -Value "A value" -MemberType NoteProperty # Returns PS> $Object Name ID Address SomeNewProp ---- -- ------- ----------- nem 12 A value You can also add properties with Select-Object Cmdlet (so called calculated properties): $newObject = $Object | Select-Object *, @{label='SomeOtherProp'; expression={'Another value'}} # Returns PS> $newObject Name ID Address SomeNewProp SomeOtherProp ---- -- ------- ----------- ------------- nem 12 A value Another value The command above can be shortened to this: $newObject = $Object | Select *,@{l='SomeOtherProp';e={'Another value'}} Removing properties You can use the Select-Object Cmdlet to remove properties from an object: $object = $newObject | Select-Object * -ExcludeProperty ID, Address # Returns PS> $object Name SomeNewProp SomeOtherProp ---- ----------- ------------- nem A value Another value Section 11.3: Creating a new object PowerShell, unlike some other scripting languages, sends objects through the pipeline. What this means is that when you send data from one command to another, it's essential to be able to create, modify, and collect objects. Creating an object is simple. Most objects you create will be custom objects in PowerShell, and the type to use for that is PSObject. PowerShell will also allow you to create any object you could create in .NET. Here's an example of creating a new objects with a few properties: Option 1: New-Object GoalKicker.com – PowerShell® Notes for Professionals 35 $newObject = New-Object -TypeName PSObject -Property @{ Name = $env:username ID = 12 Address = $null } # Returns PS> $newObject Name ID Address ---- -- ------- nem 12 You can store the object in a variable by prefacing the command with $newObject = You may also need to store collections of objects. This can be done by creating an empty collection variable, and adding objects to the collection, like so: $newCollection = @() $newCollection += New-Object -TypeName PSObject -Property @{ Name = $env:username ID = 12 Address = $null } You may then wish to iterate through this collection object by object. To do that, locate the Loop section in the documentation. Option 2: Select-Object A less common way of creating objects that you'll still find on the internet is the following: $newObject = 'unuseddummy' | Select-Object -Property Name, ID, Address $newObject.Name = $env:username $newObject.ID = 12 # Returns PS> $newObject Name ID Address ---- -- ------- nem 12 Option 3: pscustomobject type accelerator (PSv3+ required) The ordered type accelerator forces PowerShell to keep our properties in the order that we defined them. You don't need the ordered type accelerator to use [PSCustomObject]: $newObject = [PSCustomObject][Ordered]@{ Name = $env:Username ID = 12 Address = $null } # Returns PS> $newObject Name ID Address ---- -- ------- nem 12 GoalKicker.com – PowerShell® Notes for Professionals 36 Section 11.4: Creating Instances of Generic Classes Note: examples written for PowerShell 5.1 You can create instances of Generic Classes #Nullable System.DateTime [Nullable[datetime]]$nullableDate = Get-Date -Year 2012 $nullableDate $nullableDate.GetType().FullName $nullableDate = $null $nullableDate #Normal System.DateTime [datetime]$aDate = Get-Date -Year 2013 $aDate $aDate.GetType().FullName $aDate = $null #Throws exception when PowerShell attempts to convert null to Gives the output: Saturday, 4 August 2012 08:53:02 System.DateTime Sunday, 4 August 2013 08:53:02 System.DateTime Cannot convert null to type "System.DateTime". At line:14 char:1 + $aDate = $null + ~~~~~~~~~~~~~~ + CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException + FullyQualifiedErrorId : RuntimeException Generic Collections are also possible [System.Collections.Generic.SortedDictionary[int, String]]$dict = [System.Collections.Generic.SortedDictionary[int, String]]::new() $dict.GetType().FullName $dict.Add(1, 'a') $dict.Add(2, 'b') $dict.Add(3, 'c') $dict.Add('4', 'd') #powershell auto converts '4' to 4 $dict.Add('5.1', 'c') #powershell auto converts '5.1' to 5 $dict $dict.Add('z', 'z') #powershell can't convert 'z' to System.Int32 so it throws an error Gives the output: System.Collections.Generic.SortedDictionary`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] Key Value --- ----- 1 a 2 b GoalKicker.com – PowerShell® Notes for Professionals 37 3 c 4 d 5 c Cannot convert argument "key", with value: "z", for "Add" to type "System.Int32": "Cannot convert value "z" to type "System.Int32". Error: "Input string was not in a correct format."" At line:15 char:1 + $dict.Add('z', 'z') #powershell can't convert 'z' to System.Int32 so ... + ~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodException + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument GoalKicker.com – PowerShell® Notes for Professionals 38 Chapter 12: PowerShell Functions A function is basically a named block of code. When you call the function name, the script block within that function runs. It is a list of PowerShell statements that has a name that you assign. When you run a function, you type the function name. It is a method of saving time when tackling repetitive tasks. PowerShell formats in three parts: the keyword 'Function', followed by a Name, finally, the payload containing the script block, which is enclosed by curly/parenthesis style bracket. Section 12.1: Basic Parameters A function can be defined with parameters using the param block: function Write-Greeting { param( [Parameter(Mandatory,Position=0)] [String]$name, [Parameter(Mandatory,Position=1)] [Int]$age ) "Hello $name, you are $age years old." } Or using the simple function syntax: function Write-Greeting ($name, $age) { "Hello $name, you are $age years old." } Note: Casting parameters is not required in either type of parameter definition. Simple function syntax (SFS) has very limited capabilities in comparison to the param block. Though you can define parameters to be exposed within the function, you cannot specify Parameter Attributes, utilize Parameter Validation, include [CmdletBinding()], with SFS (and this is a non-exhaustive list). Functions can be invoked with ordered or named parameters. The order of the parameters on the invocation is matched to the order of the declaration in the function header (by default), or can be specified using the Position Parameter Attribute (as shown in the advanced function example, above). $greeting = Write-Greeting "Jim" 82 Alternatively, this function can be invoked with named parameters $greeting = Write-Greeting -name "Bob" -age 82 Section 12.2: Advanced Function This is a copy of the advanced function snippet from the Powershell ISE. Basically this is a template for many of the things you can use with advanced functions in Powershell. Key points to note: get-help integration - the beginning of the function contains a comment block that is set up to be read by the get-help cmdlet. The function block may be located at the end, if desired. cmdletbinding - function will behave like a cmdlet GoalKicker.com – PowerShell® Notes for Professionals 39 parameters parameter sets <# .Synopsis Short description .DESCRIPTION Long description .EXAMPLE Example of how to use this cmdlet .EXAMPLE Another example of how to use this cmdlet .INPUTS Inputs to this cmdlet (if any) .OUTPUTS Output from this cmdlet (if any) .NOTES General notes .COMPONENT The component this cmdlet belongs to .ROLE The role this cmdlet belongs to .FUNCTIONALITY The functionality that best describes this cmdlet #> function Verb-Noun { [CmdletBinding(DefaultParameterSetName='Parameter Set 1', SupportsShouldProcess=$true, PositionalBinding=$false, HelpUri = 'http://www.microsoft.com/', ConfirmImpact='Medium')] [Alias()] [OutputType([String])] Param ( # Param1 help description [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ValueFromRemainingArguments=$false, Position=0, ParameterSetName='Parameter Set 1')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [ValidateCount(0,5)] [ValidateSet("sun", "moon", "earth")] [Alias("p1")] $Param1, # Param2 help description [Parameter(ParameterSetName='Parameter Set 1')] [AllowNull()] [AllowEmptyCollection()] [AllowEmptyString()] [ValidateScript({$true})] [ValidateRange(0,5)] [int] $Param2, # Param3 help description [Parameter(ParameterSetName='Another Parameter Set')] GoalKicker.com – PowerShell® Notes for Professionals 40 [ValidatePattern("[a-z]*")] [ValidateLength(0,15)] [String] $Param3 ) Begin { } Process { if ($pscmdlet.ShouldProcess("Target", "Operation")) { } } End { } } Section 12.3: Mandatory Parameters Parameters to a function can be marked as mandatory function Get-Greeting{ param ( [Parameter(Mandatory=$true)]$name ) "Hello World $name" } If the function is invoked without a value, the command line will prompt for the value: $greeting = Get-Greeting cmdlet Get-Greeting at command pipeline position 1 Supply values for the following parameters: name: Section 12.4: Parameter Validation There are a variety of ways to validate parameter entry, in PowerShell. Instead of writing code within functions or scripts to validate parameter values, these ParameterAttributes will throw if invalid values are passed. ValidateSet Sometimes we need to restrict the possible values that a parameter can accept. Say we want to allow only red, green and blue for the $Color parameter in a script or function. We can use the ValidateSet parameter attribute to restrict this. It has the additional benefit of allowing tab completion when setting this argument (in some environments). param( [ValidateSet('red','green','blue',IgnoreCase)] [string]$Color GoalKicker.com – PowerShell® Notes for Professionals 41 ) You can also specify IgnoreCase to disable case sensitivity. ValidateRange This method of parameter validation takes a min and max Int32 value, and requires the parameter to be within that range. param( [ValidateRange(0,120)] [Int]$Age ) ValidatePattern This method of parameter validation accepts parameters that match the regex pattern specified. param( [ValidatePattern("\w{4-6}\d{2}")] [string]$UserName ) ValidateLength This method of parameter validation tests the length of the passed string. param( [ValidateLength(0,15)] [String]$PhoneNumber ) ValidateCount This method of parameter validation tests the amount of arguments passed in, for example, an array of strings. param( [ValidateCount(1,5)] [String[]]$ComputerName ) ValidateScript Finally, the ValidateScript method is extraordinarily flexible, taking a scriptblock and evaluating it using $_ to represent the passed argument. It then passes the argument if the result is $true (including any output as valid). This can be used to test that a file exists: param( [ValidateScript({Test-Path $_})] [IO.FileInfo]$Path ) To check that a user exists in AD: GoalKicker.com – PowerShell® Notes for Professionals 42 param( [ValidateScript({Get-ADUser $_})] [String]$UserName ) And pretty much anything else you can write (as it's not restricted to oneliners): param( [ValidateScript({ $AnHourAgo = (Get-Date).AddHours(-1) if ($_ -lt $AnHourAgo.AddMinutes(5) -and $_ -gt $AnHourAgo.AddMinutes(-5)) { $true } else { throw "That's not within five minutes. Try again." } })] [String]$TimeAboutAnHourAgo ) Section 12.5: Simple Function with No Parameters This is an example of a function which returns a string. In the example, the function is called in a statement assigning a value to a variable. The value in this case is the return value of the function. function Get-Greeting{ "Hello World" } # Invoking the function $greeting = Get-Greeting # demonstrate output $greeting Get-Greeting function declares the following code to be a function. Get-Greeting is the name of the function. Any time that function needs to be used in the script, the function can be called by means of invoking it by name. { ... } is the script block that is executed by the function. If the above code is executed in the ISE, the results would be something like: Hello World Hello World GoalKicker.com – PowerShell® Notes for Professionals 43 Chapter 13: PowerShell Classes A class is an extensible program-code-template for creating objects, providing initial values for state (member variables) and implementations of behavior (member functions or methods).A class is a blueprint for an object. It is used as a model to define the structure of objects. An object contains data that we access through properties and that we can work on using methods. PowerShell 5.0 added the ability to create your own classes. Section 13.1: Listing available constructors for a class Version ≥ 5.0 In PowerShell 5.0+ you can list available constructors by calling the static new-method without parentheses. PS> [DateTime]::new OverloadDefinitions ------------------- datetime new(long ticks) datetime new(long ticks, System.DateTimeKind kind) datetime new(int year, int month, int day) datetime new(int year, int month, int day, System.Globalization.Calendar calendar) datetime new(int year, int month, int day, int hour, int minute, int second) datetime new(int year, int month, int day, int hour, int minute, int second, System.DateTimeKind kind) datetime new(int year, int month, int day, int hour, int minute, int second, System.Globalization.Calendar calendar) datetime new(int year, int month, int day, int hour, int minute, int second, int millisecond) datetime new(int year, int month, int day, int hour, int minute, int second, int millisecond, System.DateTimeKind kind) datetime new(int year, int month, int day, int hour, int minute, int second, int millisecond, System.Globalization.Calendar calendar) datetime new(int year, int month, int day, int hour, int minute, int second, int millisecond, System.Globalization.Calendar calendar, System.DateTimeKind kind) This is the same technique that you can use to list overload definitions for any method > 'abc'.CompareTo OverloadDefinitions ------------------- int CompareTo(System.Object value) int CompareTo(string strB) int IComparable.CompareTo(System.Object obj) int IComparable[string].CompareTo(string other) For earlier versions you can create your own function to list available constructors: function Get-Constructor { [CmdletBinding()] param( [Parameter(ValueFromPipeline=$true)] [type]$type ) Process { $type.GetConstructors() | Format-Table -Wrap @{ n="$($type.Name) Constructors" GoalKicker.com – PowerShell® Notes for Professionals 44 e={ ($_.GetParameters() | % { $_.ToString() }) -Join ", " } } } } Usage: Get-Constructor System.DateTime #Or [datetime] | Get-Constructor DateTime Constructors --------------------- Int64 ticks Int64 ticks, System.DateTimeKind kind Int32 year, Int32 month, Int32 day Int32 year, Int32 month, Int32 day, System.Globalization.Calendar calendar Int32 year, Int32 month, Int32 day, Int32 hour, Int32 minute, Int32 second Int32 year, Int32 month, Int32 day, Int32 hour, Int32 minute, Int32 second, System.DateTimeKind kind Int32 year, Int32 month, Int32 day, Int32 hour, Int32 minute, Int32 second, System.Globalization.Calendar calendar Int32 year, Int32 month, Int32 day, Int32 hour, Int32 minute, Int32 second, Int32 millisecond Int32 year, Int32 month, Int32 day, Int32 hour, Int32 minute, Int32 second, Int32 millisecond, System.DateTimeKind kind Int32 year, Int32 month, Int32 day, Int32 hour, Int32 minute, Int32 second, Int32 millisecond, System.Globalization.Cal endar calendar Int32 year, Int32 month, Int32 day, Int32 hour, Int32 minute, Int32 second, Int32 millisecond, System.Globalization.Cal endar calendar, System.DateTimeKind kind Section 13.2: Methods and properties class Person { [string] $FirstName [string] $LastName [string] Greeting() { return "Greetings, {0} {1}!" -f $this.FirstName, $this.LastName } } $x = [Person]::new() $x.FirstName = "Jane" $x.LastName = "Doe" $greeting = $x.Greeting() # "Greetings, Jane Doe!" Section 13.3: Constructor overloading class Person { [string] $Name [int] $Age Person([string] $Name) { $this.Name = $Name } Person([string] $Name, [int]$Age) { $this.Name = $Name $this.Age = $Age GoalKicker.com – PowerShell® Notes for Professionals 45 } } Section 13.4: Get All Members of an Instance PS > Get-Member -InputObject $anObjectInstance This will return all members of the type instance. Here is a part of a sample output for String instance TypeName: System.String Name MemberType Definition ---- ---------- ---------- Clone Method System.Object Clone(), System.Object ICloneable.Clone() CompareTo Method int CompareTo(System.Object value), int CompareTo(string strB), i... Contains Method bool Contains(string value) CopyTo Method void CopyTo(int sourceIndex, char[] destination, int destinationI... EndsWith Method bool EndsWith(string value), bool EndsWith(string value, System.S... Equals Method bool Equals(System.Object obj), bool Equals(string value), bool E... GetEnumerator Method System.CharEnumerator GetEnumerator(), System.Collections.Generic... GetHashCode Method int GetHashCode() GetType Method type GetType() ... Section 13.5: Basic Class Template # Define a class class TypeName { # Property with validate set [ValidateSet("val1", "Val2")] [string] $P1 # Static property static [hashtable] $P2 # Hidden property does not show as result of Get-Member hidden [int] $P3 # Constructor TypeName ([string] $s) { $this.P1 = $s } # Static method static [void] MemberMethod1([hashtable] $h) { [TypeName]::P2 = $h } # Instance method [int] MemberMethod2([int] $i) { GoalKicker.com – PowerShell® Notes for Professionals 46 $this.P3 = $i return $this.P3 } } Section 13.6: Inheritance from Parent Class to Child Class class ParentClass { [string] $Message = "It's under the Parent Class" [string] GetMessage() { return ("Message: {0}" -f $this.Message) } } # Bar extends Foo and inherits its members class ChildClass : ParentClass { } $Inherit = [ChildClass]::new() SO, $Inherit.Message will give you the "It's under the Parent Class" GoalKicker.com – PowerShell® Notes for Professionals 47 Chapter 14: PowerShell Modules Starting with PowerShell version 2.0, developers can create PowerShell modules. PowerShell modules encapsulate a set of common functionality. For example, there are vendor-specific PowerShell modules that manage various cloud services. There are also generic PowerShell modules that interact with social media services, and perform common programming tasks, such as Base64 encoding, working with Named Pipes, and more. Modules can expose command aliases, functions, variables, classes, and more. Section 14.1: Create a Module Manifest @{ RootModule = 'MyCoolModule.psm1' ModuleVersion = '1.0' CompatiblePSEditions = @('Core') GUID = '6b42c995-67da-4139-be79-597a328056cc' Author = 'Bob Schmob' CompanyName = 'My Company' Copyright = '(c) 2017 Administrator. All rights reserved.' Description = 'It does cool stuff.' FunctionsToExport = @() CmdletsToExport = @() VariablesToExport = @() AliasesToExport = @() DscResourcesToExport = @() } Every good PowerShell module has a module manifest. The module manifest simply contains metadata about a PowerShell module, and doesn't define the actual contents of the module. The manifest file is a PowerShell script file, with a .psd1 file extension, that contains a HashTable. The HashTable in the manifest must contain specific keys, in order for PowerShell to correctly interpret it as a PowerShell module file. The example above provides a list of the core HashTable keys that make up a module manifest, but there are many others. The New-ModuleManifest command helps you create a new module manifest skeleton. Section 14.2: Simple Module Example function Add { [CmdletBinding()] param ( [int] $x , [int] $y ) return $x + $y } Export-ModuleMember -Function Add This is a simple example of what a PowerShell script module file might look like. This file would be called MyCoolModule.psm1, and is referenced from the module manifest (.psd1) file. You'll notice that the Export ModuleMember command enables us to specify which functions in the module we want to "export," or expose, to the user of the module. Some functions will be internal-only, and shouldn't be exposed, so those would be omitted from the call to Export-ModuleMember. GoalKicker.com – PowerShell® Notes for Professionals 48 Section 14.3: Exporting a Variable from a Module $FirstName = 'Bob' Export-ModuleMember -Variable FirstName To export a variable from a module, you use the Export-ModuleMember command, with the -Variable parameter. Remember, however, that if the variable is also not explicitly exported in the module manifest (.psd1) file, then the variable will not be visible to the module consumer. Think of the module manifest like a "gatekeeper." If a function or variable isn't allowed in the module manifest, it won't be visible to the module consumer. Note: Exporting a variable is similar to making a field in a class public. It is not advisable. It would be better to expose a function to get the field and a function to set the field. Section 14.4: Structuring PowerShell Modules Rather than defining all of your functions in a single .psm1 PowerShell script module file, you might want to break apart your function into individual files. You can then dot-source these files from your script module file, which in essence, treats them as if they were part of the .psm1 file itself. Consider this module directory structure: \MyCoolModule \Functions Function1.ps1 Function2.ps1 Function3.ps1 MyCoolModule.psd1 MyCoolModule.psm1 Inside your MyCoolModule.psm1 file, you could insert the following code: Get-ChildItem -Path $PSScriptRoot\Functions | ForEach-Object -Process { . $PSItem.FullName } This would dot-source the individual function files into the .psm1 module file. Section 14.5: Location of Modules PowerShell looks for modules in the directories listed in the $Env:PSModulepath. A module called foo, in a folder called foo will be found with Import-Module foo In that folder, PowerShell will look for a module manifest (foo.psd1), a module file (foo.psm1), a DLL (foo.dll). Section 14.6: Module Member Visibility By default, only functions defined in a module are visible outside of the module. In other words, if you define variables and aliases in a module, they won't be available except in the module's code. To override this behavior, you can use the Export-ModuleMember cmdlet. It has parameters called -Function, - Variable, and -Alias which allow you to specify exactly which members are exported. It is important to note that if you use Export-ModuleMember, only the items you specify will be visible. GoalKicker.com – PowerShell® Notes for Professionals 49 Chapter 15: PowerShell profiles Section 15.1: Create an basic profile A PowerShell profile is used to load user defined variables and functions automatically. PowerShell profiles are not automatically created for users. To create a PowerShell profile C:>New-Item -ItemType File $profile. If you are in ISE you can use the built in editor C:>psEdit $profile An easy way to get started with your personal profile for the current host is to save some text to path stored in the $profile-variable "#Current host, current user" > $profile Further modification to the profile can be done using PowerShell ISE, notepad, Visual Studio Code or any other editor. The $profile-variable returns the current user profile for the current host by default, but you can access the path to the machine-policy (all users) and/or the profile for all hosts (console, ISE, 3rd party) by using its properties. PS> $PROFILE | Format-List -Force AllUsersAllHosts : C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1 AllUsersCurrentHost : C:\Windows\System32\WindowsPowerShell\v1.0\Microsoft.PowerShell_profile.ps1 CurrentUserAllHosts : C:\Users\user\Documents\WindowsPowerShell\profile.ps1 CurrentUserCurrentHost : C:\Users\user\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 Length : 75 PS> $PROFILE.AllUsersAllHosts C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1 GoalKicker.com – PowerShell® Notes for Professionals 50 Chapter 16: Calculated Properties Calculated Properties in PowerShell are custom derived (Calculated) properties. It lets the user to format a certain property in a way he want it to be. The calculation(expression) can be a quite possibly anything. Section 16.1: Display file size in KB - Calculated Properties Let's consider the below snippet, Get-ChildItem -Path C:\MyFolder | Select-Object Name, CreationTime, Length It simply output the folder content with the selected properties. Something like, What if I want to display the file size in KB ? This is where calcualted properties comes handy. Get-ChildItem C:\MyFolder | Select-Object Name, @{Name="Size_In_KB";Expression={$_.Length / 1Kb}} Which produces, The Expression is what holds the calculation for calculated property. And yes, it can be anything! GoalKicker.com – PowerShell® Notes for Professionals 51 Chapter 17: Using existing static classes These classes are reference libraries of methods and properties that do not change state, in one word, immutable. You don't need to create them, you simply use them. Classes and methods such as these are called static classes because they are not created, destroyed, or changed. You can refer to a static class by surrounding the class name with square brackets. Section 17.1: Adding types By Assembly Name, add library Add-Type -AssemblyName "System.Math" or by file path: Add-Type -Path "D:\Libs\CustomMath.dll" To Use added type: [CustomMath.NameSpace]::Method(param1, $variableParam, [int]castMeAsIntParam) Section 17.2: Using the .Net Math Class You can use the .Net Math class to do calculations ([System.Math]) If you want to know which methods are available you can use: [System.Math] | Get-Member -Static -MemberType Methods Here are some examples how to use the Math class: PS C:\> [System.Math]::Floor(9.42) 9 PS C:\> [System.Math]::Ceiling(9.42) 10 PS C:\> [System.Math]::Pow(4,3) 64 PS C:\> [System.Math]::Sqrt(49) 7 Section 17.3: Creating new GUID instantly Use existing .NET classes instantly with PowerShell by using [class]::Method(args): PS C:\> [guid]::NewGuid() Guid ---- 8874a185-64be-43ed-a64c-d2fe4b6e31bc Similarly, in PowerShell 5+ you may use the New-Guid cmdlet: PS C:\> New-Guid GoalKicker.com – PowerShell® Notes for Professionals 52 Guid ---- 8874a185-64be-43ed-a64c-d2fe4b6e31bc To get the GUID as a [String] only, referenced the .Guid property: [guid]::NewGuid().Guid GoalKicker.com – PowerShell® Notes for Professionals 53 Chapter 18: Built-in variables PowerShell offers a variety of useful "automatic" (built-in) variables. Certain automatic variables are only populated in special circumstances, while others are available globally. Section 18.1: $PSScriptRoot Get-ChildItem -Path $PSScriptRoot This example retrieves the list of child items (directories and files) from the folder where the script file resides. The $PSScriptRoot automatic variable is $null if used from outside a PowerShell code file. If used inside a PowerShell script, it automatically defined the fully-qualified filesystem path to the directory that contains the script file. In Windows PowerShell 2.0, this variable is valid only in script modules (.psm1). Beginning in Windows PowerShell 3.0, it is valid in all scripts. Section 18.2: $Args $Args Contains an array of the undeclared parameters and/or parameter values that are passed to a function, script, or script block. When you create a function, you can declare the parameters by using the param keyword or by adding a comma-separated list of parameters in parentheses after the function name. In an event action, the $Args variable contains objects that represent the event arguments of the event that is being processed. This variable is populated only within the Action block of an event registration command. The value of this variable can also be found in the SourceArgs property of the PSEventArgs object (System.Management.Automation.PSEventArgs) that Get-Event returns. Section 18.3: $PSItem Get-Process | ForEach-Object -Process { $PSItem.Name } Same as $_. Contains the current object in the pipeline object. You can use this variable in commands that perform an action on every object or on selected objects in a pipeline. Section 18.4: $? Get-Process -Name doesnotexist Write-Host -Object "Was the last operation successful? $?" Contains the execution status of the last operation. It contains TRUE if the last operation succeeded and FALSE if it failed. Section 18.5: $error Get-Process -Name doesnotexist GoalKicker.com – PowerShell® Notes for Professionals 54 Write-Host -Object ('The last error that occurred was: {0}' -f $error[0].Exception.Message) Contains an array of error objects that represent the most recent errors. The most recent error is the first error object in the array ($Error[0]). To prevent an error from being added to the $Error array, use the ErrorAction common parameter with a value of Ignore. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). GoalKicker.com – PowerShell® Notes for Professionals 55 Chapter 19: Automatic Variables Automatic Variables are created and maintained by Windows PowerShell. One has the ability to call a variable just about any name in the book; The only exceptions to this are the variables that are already being managed by PowerShell. These variables, without a doubt, will be the most repetitious objects you use in PowerShell next to functions (like $? - indicates Success/ Failure status of the last operation) Section 19.1: $OFS Variable called Output Field Separator contains string value that is used when converting an array to a string. By default $OFS = " " (a space), but it can be changed: PS C:\> $array = 1,2,3 PS C:\> "$array" # default OFS will be used 1 2 3 PS C:\> $OFS = ",." # we change OFS to comma and dot PS C:\> "$array" 1,.2,.3 Section 19.2: $? Contains status of the last operation. When there is no error, it is set to True: PS C:\> Write-Host "Hello" Hello PS C:\> $? True If there is some error, it is set to False: PS C:\> wrt-host wrt-host : The term 'wrt-host' 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. At line:1 char:1 + wrt-host + ~~~~~~~~ + CategoryInfo : ObjectNotFound: (wrt-host:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException PS C:\> $? False Section 19.3: $null $null is used to represent absent or undefined value. $null can be used as an empty placeholder for empty value in arrays: PS C:\> $array = 1, "string", $null PS C:\> $array.Count 3 When we use the same array as the source for ForEach-Object, it will process all three items (including $null): GoalKicker.com – PowerShell® Notes for Professionals 56 PS C:\> $array | ForEach-Object {"Hello"} Hello Hello Hello Be careful! This means that ForEach-Object WILL process even $null all by itself: PS C:\> $null | ForEach-Object {"Hello"} # THIS WILL DO ONE ITERATION !!! Hello Which is very unexpected result if you compare it to classic foreach loop: PS C:\> foreach($i in $null) {"Hello"} # THIS WILL DO NO ITERATION PS C:\> Section 19.4: $error Array of most recent error objects. The first one in the array is the most recent one: PS C:\> throw "Error" # resulting output will be in red font Error At line:1 char:1 + throw "Error" + ~~~~~~~~~~~~~ + CategoryInfo : OperationStopped: (Error:String) [], RuntimeException + FullyQualifiedErrorId : Error PS C:\> $error[0] # resulting output will be normal string (not red ) Error At line:1 char:1 + throw "Error" + ~~~~~~~~~~~~~ + CategoryInfo : OperationStopped: (Error:String) [], RuntimeException + FullyQualifiedErrorId : Error Usage hints: When using the $error variable in a format cmdlet (e.g. format-list), be aware to use the -Force switch. Otherwise the format cmdlet is going to output the $errorcontents in above shown manner. Error entries can be removed via e.g. $Error.Remove($Error[0]). Section 19.5: $pid Contains process ID of the current hosting process. PS C:\> $pid 26080 Section 19.6: Boolean values $true and $false are two variables that represent logical TRUE and FALSE. Note that you have to specify the dollar sign as the first character (which is different from C#). $boolExpr = "abc".Length -eq 3 # length of "abc" is 3, hence $boolExpr will be True if($boolExpr -eq $true){ "Length is 3" GoalKicker.com – PowerShell® Notes for Professionals 57 } # result will be "Length is 3" $boolExpr -ne $true #result will be False Notice that when you use boolean true/false in your code you write $true or $false, but when Powershell returns a boolean, it looks like True or False Section 19.7: $_ / $PSItem Contains the object/item currently being processed by the pipeline. PS C:\> 1..5 | % { Write-Host "The current item is $_" } The current item is 1 The current item is 2 The current item is 3 The current item is 4 The current item is 5 $PSItem and $_ are identical and can be used interchangeably, but $_ is by far the most commonly used. Section 19.8: $PSVersionTable Contains a read-only hash table (Constant, AllScope) that displays details about the version of PowerShell that is running in the current session. $PSVersionTable #this call results in this: Name Value ---- ----- PSVersion 5.0.10586.117 PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...} BuildVersion 10.0.10586.117 CLRVersion 4.0.30319.42000 WSManStackVersion 3.0 PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1 The fastest way to get a version of PowerShell running: $PSVersionTable.PSVersion # result : Major Minor Build Revision ----- ----- ----- -------- 5 0 10586 117 GoalKicker.com – PowerShell® Notes for Professionals 58 Chapter 20: Environment Variables Section 20.1: Windows environment variables are visible as a PS drive called Env: You can see list with all environment variables with: Get-Childitem env: Section 20.2: Instant call of Environment Variables with $env: $env:COMPUTERNAME GoalKicker.com – PowerShell® Notes for Professionals 59 Chapter 21: Splatting Splatting is a method of passing multiple parameters to a command as a single unit. This is done by storing the parameters and their values as key-value pairs in a hashtable and splatting it to a cmdlet using the splatting operator @. Splatting can make a command more readable and allows you to reuse parameters in multiple command calls. Section 21.1: Piping and Splatting Declaring the splat is useful for reusing sets of parameters multiple times or with slight variations: $splat = @{ Class = "Win32_SystemEnclosure" Property = "Manufacturer" ErrorAction = "Stop" } Get-WmiObject -ComputerName $env:COMPUTERNAME @splat Get-WmiObject -ComputerName "Computer2" @splat Get-WmiObject -ComputerName "Computer3" @splat However, if the splat is not indented for reuse, you may not wish to declare it. It can be piped instead: @{ ComputerName = $env:COMPUTERNAME Class = "Win32_SystemEnclosure" Property = "Manufacturer" ErrorAction = "Stop" } | % { Get-WmiObject @_ } Section 21.2: Passing a Switch parameter using Splatting To use Splatting to call Get-Process with the -FileVersionInfo switch similar to this: Get-Process -FileVersionInfo This is the call using splatting: $MyParameters = @{ FileVersionInfo = $true } Get-Process @MyParameters Note: This is useful because you can create a default set of parameters and make the call many times like this $MyParameters = @{ FileVersionInfo = $true } Get-Process @MyParameters -Name WmiPrvSE Get-Process @MyParameters -Name explorer GoalKicker.com – PowerShell® Notes for Professionals 60 Section 21.3: Splatting From Top Level Function to a Series of Inner Function Without splatting it is very cumbersome to try and pass values down through the call stack. But if you combine splatting with the power of the @PSBoundParameters then you can pass the top level parameter collection down through the layers. Function Outer-Method { Param ( [string] $First, [string] $Second ) Write-Host ($First) -NoNewline Inner-Method @PSBoundParameters } Function Inner-Method { Param ( [string] $Second ) Write-Host (" {0}!" -f $Second) } $parameters = @{ First = "Hello" Second = "World" } Outer-Method @parameters Section 21.4: Splatting parameters Splatting is done by replacing the dollar-sign $ with the splatting operator @ when using a variable containing a HashTable of parameters and values in a command call. $MyParameters = @{ Name = "iexplore" FileVersionInfo = $true } Get-Process @MyParameters Without splatting: Get-Process -Name "iexplore" -FileVersionInfo GoalKicker.com – PowerShell® Notes for Professionals 61 You can combine normal parameters with splatted parameters to easily add common parameters to your calls. $MyParameters = @{ ComputerName = "StackOverflow-PC" } Get-Process -Name "iexplore" @MyParameters Invoke-Command -ScriptBlock { "Something to execute remotely" } @MyParameters GoalKicker.com – PowerShell® Notes for Professionals 62 Chapter 22: PowerShell "Streams"; Debug, Verbose, Warning, Error, Output and Information Section 22.1: Write-Output Write-Output generates output. This output can go to the next command after the pipeline or to the console so it's simply displayed. The Cmdlet sends objects down the primary pipeline, also known as the "output stream" or the "success pipeline." To send error objects down the error pipeline, use Write-Error. # 1.) Output to the next Cmdlet in the pipeline Write-Output 'My text' | Out-File -FilePath "$env:TEMP\Test.txt" Write-Output 'Bob' | ForEach-Object { "My name is $_" } # 2.) Output to the console since Write-Output is the last command in the pipeline Write-Output 'Hello world' # 3.) 'Write-Output' CmdLet missing, but the output is still considered to be 'Write-Output' 'Hello world' 1. The Write-Output cmdlet sends the specified object down the pipeline to the next command. 2. If the command is the last command in the pipeline, the object is displayed in the console. 3. The PowerShell interpreter treats this as an implicit Write-Output. Because Write-Output's default behavior is to display the objects at the end of a pipeline, it is generally not necessary to use the Cmdlet. For example, Get-Process | Write-Output is equivalent to Get-Process. Section 22.2: Write Preferences Messages can be written with; Write-Verbose "Detailed Message" Write-Information "Information Message" Write-Debug "Debug Message" Write-Progress "Progress Message" Write-Warning "Warning Message" Each of these has a preference variable; $VerbosePreference = "SilentlyContinue" $InformationPreference = "SilentlyContinue" $DebugPreference = "SilentlyContinue" $ProgressPreference = "Continue" $WarningPreference = "Continue" The preference variable controls how the message and subsequent execution of the script are handled; $InformationPreference = "SilentlyContinue" Write-Information "This message will not be shown and execution continues" GoalKicker.com – PowerShell® Notes for Professionals 63 $InformationPreference = "Continue" Write-Information "This message is shown and execution continues" $InformationPreference = "Inquire" Write-Information "This message is shown and execution will optionally continue" $InformationPreference = "Stop" Write-Information "This message is shown and execution terminates" The color of the messages can be controlled for Write-Error by setting; $host.PrivateData.ErrorBackgroundColor = "Black" $host.PrivateData.ErrorForegroundColor = "Red" Similar settings are available for Write-Verbose, Write-Debug and Write-Warning. GoalKicker.com – PowerShell® Notes for Professionals 64 Chapter 23: Sending Email Parameter Details Attachments Path and file names of files to be attached to the message. Paths and filenames can be piped to Send-MailMessage. Email addresses that receive a copy of an email message but does not appear as a Bcc recipient in the message. Enter names (optional) and the email address (required), such as Name [email protected] or [email protected]. Body Content of the email message. BodyAsHtml It indicates that the content is in HTML format. Email addresses that receive a copy of an email message. Enter names (optional) and Cc Credential DeliveryNotificationOption the email address (required), such as Name [email protected] or [email protected]. Specifies a user account that has permission to send message from specified email address. The default is the current user. Enter name such as User or Domain\User, or enter a PSCredential object. Specifies the delivery notification options for the email message. Multiple values can be specified. Delivery notifications are sent in message to address specified in To parameter. Acceptable values: None, OnSuccess, OnFailure, Delay, Never. Encoding Encoding for the body and subject. Acceptable values: ASCII, UTF8, UTF7, UTF32, Unicode, BigEndianUnicode, Default, OEM. From Email addresses from which the mail is sent. Enter names (optional) and the email address (require), such as Name [email protected] or [email protected]. Port Alternate port on the SMTP server. The default value is 25. Available from Windows PowerShell 3.0. Priority Priority of the email message. Acceptable values: Normal, High, Low. SmtpServer Name of the SMTP server that sends the email message. Default value is the value of the $PSEmailServer variable. Subject Subject of the email message. To Email addresses to which the mail is sent. Enter names (optional) and the email address (required), such as Name [email protected] or [email protected] UseSsl Uses the Secure Sockets Layer (SSL) protocol to establish a connection to the remote computer to send mail A useful technique for Exchange Server administrators is to be able to send email messages via SMTP from PowerShell. Depending on the version of PowerShell installed on your computer or server, there are multiple ways to send emails via PowerShell. There is a native cmdlet option that is simple and easy to use. It uses the cmdlet Send-MailMessage. Section 23.1: Send-MailMessage with predefined parameters $parameters = @{ From = '[email protected]' To = '[email protected]' Subject = 'Email Subject' Attachments = @('C:\files\samplefile1.txt','C:\files\samplefile2.txt') BCC = '[email protected]' Body = 'Email body' BodyAsHTML = $False CC = '[email protected]' Credential = Get-Credential DeliveryNotificationOption = 'onSuccess' Encoding = 'UTF8' Port = '25' GoalKicker.com – PowerShell® Notes for Professionals 65 Priority = 'High' SmtpServer = 'smtp.com' UseSSL = $True } # Notice: Splatting requires @ instead of $ in front of variable name Send-MailMessage @parameters Section 23.2: Simple Send-MailMessage Send-MailMessage -From [email protected] -Subject "Email Subject" -To [email protected] -SmtpServer smtp.com Section 23.3: SMTPClient - Mail with .txt file in body message # Define the txt which will be in the email body $Txt_File = "c:\file.txt" function Send_mail { #Define Email settings $EmailFrom = "[email protected]" $EmailTo = "[email protected]" $Txt_Body = Get-Content $Txt_File -RAW $Body = $Body_Custom + $Txt_Body $Subject = "Email Subject" $SMTPServer = "smtpserver.domain.com" $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 25) $SMTPClient.EnableSsl = $false $SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body) } $Body_Custom = "This is what contain file.txt : " Send_mail GoalKicker.com – PowerShell® Notes for Professionals 66 Chapter 24: PowerShell Remoting Section 24.1: Connecting to a Remote Server via PowerShell Using credentials from your local computer: Enter-PSSession 192.168.1.1 Prompting for credentials on the remote computer Enter-PSSession 192.168.1.1 -Credential $(Get-Credential) Section 24.2: Run commands on a Remote Computer Once Powershell remoting is enabled (Enable-PSRemoting) You can run commands on the remote computer like this: Invoke-Command -ComputerName "RemoteComputerName" -ScriptBlock { Write-Host "Remote Computer Name: $ENV:ComputerName" } The above method creates a temporary session and closes it right after the command or scriptblock ends. To leave the session open and run other command in it later, you need to create a remote session first: $Session = New-PSSession -ComputerName "RemoteComputerName" Then you can use this session each time you invoke commands on the remote computer: Invoke-Command -Session $Session -ScriptBlock { Write-Host "Remote Computer Name: $ENV:ComputerName" } Invoke-Command -Session $Session -ScriptBlock { Get-Date } If you need to use different Credentials, you can add them with the -Credential Parameter: $Cred = Get-Credential Invoke-Command -Session $Session -Credential $Cred -ScriptBlock {...} Remoting serialization warning Note: It is important to know that remoting serializes PowerShell objects on the remote system and deserializes them on your end of the remoting session, i.e. they are converted to XML during transport and lose all of their methods. $output = Invoke-Command -Session $Session -ScriptBlock { Get-WmiObject -Class win32_printer } GoalKicker.com – PowerShell® Notes for Professionals 67 $output | Get-Member -MemberType Method TypeName: Deserialized.System.Management.ManagementObject#root\cimv2\Win32_Printer Name MemberType Definition ---- ---------- ---------- GetType Method type GetType() ToString Method string ToString(), string ToString(string format, System.IFormatProvi... Whereas you have the methods on the regular PS object: Get-WmiObject -Class win32_printer | Get-Member -MemberType Method TypeName: System.Management.ManagementObject#root\cimv2\Win32_Printer Name MemberType Definition ---- ---------- ---------- CancelAllJobs Method System.Management.ManagementBaseObject CancelAllJobs() GetSecurityDescriptor Method System.Management.ManagementBaseObject GetSecurityDescriptor() Pause Method System.Management.ManagementBaseObject Pause() PrintTestPage Method System.Management.ManagementBaseObject PrintTestPage() RenamePrinter Method System.Management.ManagementBaseObject RenamePrinter(System.String NewPrinterName) Reset Method System.Management.ManagementBaseObject Reset() Resume Method System.Management.ManagementBaseObject Resume() SetDefaultPrinter Method System.Management.ManagementBaseObject SetDefaultPrinter() SetPowerState Method System.Management.ManagementBaseObject SetPowerState(System.UInt16 PowerState, System.String Time) SetSecurityDescriptor Method System.Management.ManagementBaseObject SetSecurityDescriptor(System.Management.ManagementObject#Win32_SecurityDescriptor Descriptor) Argument Usage To use arguments as parameters for the remote scripting block, one might either use the ArgumentList parameter of Invoke-Command, or use the $Using: syntax. Using ArgumentList with unnamed parameters (i.e. in the order they are passed to the scriptblock): $servicesToShow = "service1" $fileName = "C:\temp\servicestatus.csv" Invoke-Command -Session $session -ArgumentList $servicesToShow,$fileName -ScriptBlock { Write-Host "Calling script block remotely with $($Args.Count)" Get-Service -Name $args[0] Remove-Item -Path $args[1] -ErrorAction SilentlyContinue -Force } Using ArgumentList with named parameters: $servicesToShow = "service1" $fileName = "C:\temp\servicestatus.csv" Invoke-Command -Session $session -ArgumentList $servicesToShow,$fileName -ScriptBlock { Param($serviceToShowInRemoteSession,$fileToDelete) GoalKicker.com – PowerShell® Notes for Professionals 68 Write-Host "Calling script block remotely with $($Args.Count)" Get-Service -Name $serviceToShowInRemoteSession Remove-Item -Path $fileToDelete -ErrorAction SilentlyContinue -Force } Using $Using: syntax: $servicesToShow = "service1" $fileName = "C:\temp\servicestatus.csv" Invoke-Command -Session $session -ScriptBlock { Get-Service $Using:servicesToShow Remove-Item -Path $fileName -ErrorAction SilentlyContinue -Force } Section 24.3: Enabling PowerShell Remoting PowerShell remoting must first be enabled on the server to which you wish to remotely connect. Enable-PSRemoting -Force This command does the following: Runs the Set-WSManQuickConfig cmdlet, which performs the following tasks: Starts the WinRM service. Sets the startup type on the WinRM service to Automatic. Creates a listener to accept requests on any IP address, if one does not already exist. Enables a firewall exception for WS-Management communications. Registers the Microsoft.PowerShell and Microsoft.PowerShell.Workflow session configurations, if it they are not already registered. Registers the Microsoft.PowerShell32 session configuration on 64-bit computers, if it is not already registered. Enables all session configurations. Changes the security descriptor of all session configurations to allow remote access. Restarts the WinRM service to make the preceding changes effective. Only for non-domain environments For servers in an AD Domain the PS remoting authentication is done through Kerberos ('Default'), or NTLM ('Negotiate'). If you want to allow remoting to a non-domain server you have two options. Either set up WSMan communication over HTTPS (which requires certificate generation) or enable basic authentication which sends your credentials across the wire base64-encoded (that's basically the same as plain-text so be careful with this). In either case you'll have to add the remote systems to your WSMan trusted hosts list. Enabling Basic Authentication Set-Item WSMan:\localhost\Service\AllowUnencrypted $true Then on the computer you wish to connect from, you must tell it to trust the computer you're connecting to. Set-Item WSMan:\localhost\Client\TrustedHosts '192.168.1.1,192.168.1.2' Set-Item WSMan:\localhost\Client\TrustedHosts *.contoso.com Set-Item WSMan:\localhost\Client\TrustedHosts * GoalKicker.com – PowerShell® Notes for Professionals 69 Important: You must tell your client to trust the computer addressed in the way you want to connect (e.g. if you connect via IP, it must trust the IP not the hostname) Section 24.4: A best practise for automatically cleaning-up PSSessions When a remote session is created via the New-PSsession cmdlet, the PSSession persists until the current PowerShell session ends. Meaning that, by default, the PSSession and all associated resources will continue to be used until the current PowerShell session ends. Multiple active PSSessions can become a strain on resources, particularly for long running or interlinked scripts that create hundreds of PSSessions in a single PowerShell session. It is best practise to explicitly remove each PSSession after it is finished being used. [1] The following code template utilises try-catch-finally in order to achieve the above, combining error handling with a secure way to ensure all created PSSessions are removed when they are finished being used: try { $session = New-PSsession -Computername "RemoteMachineName" Invoke-Command -Session $session -ScriptBlock {write-host "This is running on $ENV:ComputerName"} } catch { Write-Output "ERROR: $_" } finally { if ($session) { Remove-PSSession $session } } References: [1] https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/new-pssession GoalKicker.com – PowerShell® Notes for Professionals 70 Chapter 25: Working with the PowerShell pipeline PowerShell introduces an object pipelining model, which allows you to send whole objects down through the pipeline to consuming commandlets or (at least) the output. In contrast to classical string-based pipelining, information in piped objects don't have to be on specific positions. Commandlets can declare to interact with Objects from the pipeline as input, while return values are sent to the pipeline automatically. Section 25.1: Writing Functions with Advanced Lifecycle This example shows how a function can accept pipelined input, and iterate efficiently. Note, that the begin and end structures of the function are optional when pipelining, but that process is required when using ValueFromPipeline or ValueFromPipelineByPropertyName. function Write-FromPipeline{ [CmdletBinding()] param( [Parameter(ValueFromPipeline)] $myInput ) begin { Write-Verbose -Message "Beginning Write-FromPipeline" } process { Write-Output -InputObject $myInput } end { Write-Verbose -Message "Ending Write-FromPipeline" } } $foo = 'hello','world',1,2,3 $foo | Write-FromPipeline -Verbose Output: VERBOSE: Beginning Write-FromPipeline hello world 1 2 3 VERBOSE: Ending Write-FromPipeline Section 25.2: Basic Pipeline Support in Functions This is an example of a function with the simplest possible support for pipelining. Any function with pipeline support must have at least one parameter with the ParameterAttribute ValueFromPipeline or ValueFromPipelineByPropertyName set, as shown below. function Write-FromPipeline { param( GoalKicker.com – PowerShell® Notes for Professionals 71 [Parameter(ValueFromPipeline)] # This sets the ParameterAttribute [String]$Input ) Write-Host $Input } $foo = 'Hello World!' $foo | Write-FromPipeline Output: Hello World! Note: In PowerShell 3.0 and above, Default Values for ParameterAttributes is supported. In earlier versions, you must specify ValueFromPipeline=$true. Section 25.3: Working concept of pipeline In a pipeline series each function runs parallel to the others, like parallel threads. The first processed object is transmitted to the next pipeline and the next processing is immediately executed in another thread. This explains the high speed gain compared to the standard ForEach @( bigFile_1, bigFile_2, ..., bigFile_n) | Copy-File | Encrypt-File | Get-Md5 1. step - copy the first file (in Copy-file Thread) 2. step - copy second file (in Copy-file Thread) and simultaneously Encrypt the first (in Encrypt-File) 3. step - copy third file (in Copy-file Thread) and simultaneously encrypt second file (in Encrypt-File) and simultaneously get-Md5 of the first (in Get-Md5) GoalKicker.com – PowerShell® Notes for Professionals 72