II. Precautions: Non-Medical
- Not for Medical Care
- The author uses several software packages and programming languages to develop FPnotebook content
- For convenience, a dozen pages in FPNotebook are dedicated to quick notes on content creation
III. Background
- Commands are shown in Pascal Case for readability, but they are typically used in lower case
- In most cases, Powershell is case insensitive
- Running script files (.ps1) from within powershell command line
- Comments
- # precedes each plain text comment
- Clear screen
- Clear-Host (cls)
- Get-History
- Displays a list of all Powershell commands issued during the current session
- Transcript
- Start-Transcript
- Starts copying all powershell window output to file (filename output to window)
- Stop-Transcript
- Stops copying powershell window output to file (filename output to window)
- Start-Transcript
- Debugging
- Breakpoints (F9) can be set within Powershell ISE
- May step into (F11) or over (F10) functions
- Within the command line, variable values may be queried (or modified) while at line break
- Alias
- Get-Alias
- New-Alias -name clr -value clear-host
- Set an alias (shortcut abbreviation to a function)
- Powershell IDEs
- Powershell and PowerShell ISE
- Visual Studio with POSH Tools Extension
- Cmd
- Most old command-line utilities will run without a problem from within Powershell
- However, there may be exceptions and typing "cmd" at the powershell prompt, will change to a command window
- Type "exit" to return to the Powershell prompt
IV. Techniques: Piped Expressions
- Pipes (|)
- Get-Help About_Pipelines
- Get-process | where-object {$_.cpu -gt 1} | sort-object -property cpu -descending
- Finds all processes
- Then pipes all processes to a filter (cpu>1)
- Then pipes filtered processes to a descending sort based on the "cpu" member property
- ForEach-Object
- ForEach-Object {$_.propertyName}
- Used in a piped expression to act on each item as directed in the bracketed clause
- The $_. prefix followed by the property name, refers to the object within the iteration
- ForEach-Object {$_.propertyName}
- Where-Object
- $_
- Represents the current item in the iteration
- Where-Object ($_.ProcessName -eq 'chrome')
- Filters process to only the one named 'chrome'
- $_
- Write-Output
- See output below
V. Techniques: Output
- Write-Output
- Writes objects that may be piped to another function (and if no pipe, then to the console)
- More
- Use after a pipe (e.g. get-service | more) to display the info in pages (space-bar moves to the next page)
- Out-File
- Out-File filename.txt
- Format-List (or fl)
- Outputs each table column on its own row (get-service | format-list)
- Format-Wide -Column 2
- Outputs piped data in 2 columns
VI. Techniques: Flow control
- Operators
- See specific comparison operators for strings, arrays and hash tables below
- Get-Help About_Operators
- Arithmetic: +, -, *, /, %
- Unary: ++X, X++, --X, X--
- Assignment: =, +=, -=, *=, /=, %=
- Comparison: -eq, -ne, -gt, -lt, -le, -ge
- Logical: -and, -or, -xor, -not, !
- Type: -is, -isnot, -as
- If
- If (1 -eq 1) {'one equals one'} elseif ($var -lt 5) {'below 5'} else {'the sky is falling'}
- Switch
- switch ($var) { 1 {"one"; break} 2 {"two"; break} 3 {"three"} default {"default"} }
- switch (1,2,3) {...} matches any or all of the item collection 1,2,3
- switch -wildcard ("hello") { "he*" {"matches wildcard"} }
- Use break unless you want to match more than one case/option
- String matches are case insensitive (exception: switch -casesensitive)
- For
- For ($i = 0; $i -le 10; $i++) { $i }
- $i=0; for (; $i -lt $arr.Length; i++) { $arr[$i] }
- ForEach
- Foreach ($i in 1..3) { $i }
- Foreach ($file in Get-ChildItem) { $file.Name }
- While
- $i=0; While ($i -lt 10) {$i++; $i}
- Do While
- $i=0; Do {$i++; $i} While ($i -lt 10)
- Break and Continue
- Break exits the current loop (but if embedded in an outer loop, it will continue to iterate the outer loop)
- Loops can be named and break statement can specify a specifc loop to break out of
- :outerloop foreach(...){ break outerloop}
- Continue exits the current loop iteration, and then continues with the next item in the loop
- Like "break", continue can also specific a loop name to return to
- Break exits the current loop (but if embedded in an outer loop, it will continue to iterate the outer loop)
- Script Blocks
- Script blocks may be stored and executed
- $method = {Clear-Host; "Run Me"}
- & $method will execute the code (without the ampersand, only the text will be output, but not run)
- Try Catch Finally
- Error handling
- try {} catch { break} finally {}
VII. Techniques: Data types
- Variables
- Get-Variable (or GV)
- Displays all variables including system built-in variables
- Variables are preceded by $ and may be defined implicitly (typical use)
- $ten = 10
- $ten.GetType() returns int32
- $ten | Get-Member returns all methods on the int32 object
- Methods may also be called on literal values not defined with a variable
- "no variable".ToUpper() returns "NO VARIABLE"
- (10).GetType() returns int32
- Strongly typed variables may also be defined (used when calling COM objects)
- [System.Int32]$ten = 10
- Built-in Variables
- Includes $false, $true, $null
- $pth is the current location (equivalent to Get-Location)
- $home is the path for the user's directory
- $pid is the current process id
- Get-Variable (or GV)
- Strings
- Comparison operators (-like, -match) listed above
- "..." -like
- "Pizza Parlor" -like "?izza *"
- ? matches a single wildcard character
- * matches multiple characters
- "..." -match
- Regular expression matching: "55126-8967" -match "[0-9]{5}-[0-9]{4}"
- "..." -like
- Surround string definitions
- Double quotes(")
- Single quotes(')
- Here-Strings or multi-line strings: @" "@
- Also works with single quotes (must be double quotes)
- The closing quote ("@) must not be indented (must be flush with start of line)
- Need to be inside the ISE for this to work (not the immediate window)
- String Interpolation
- Variables may be enclosed in strings
- "There are $ten items in the list" will replace the $ten with its value
- Expressions may be used in strings
- "There are $((Get-ChildItem).Count) items in this folder: $(Get-Location)"
- "BMI is $(($wtKg)/($htM*$htM))"
- String formatting
- "There are {0} {1} in the {2}." -f $ten,"bugs","soup"
- "{0,8}" -f "hello" will right justify "hello"
- Used when specific formatting of variable value is needed (e.g. currency format, dates)
- Currency: "{0:C2} is in dollars" -f 12.25
- Hemidecimal: "{0:X0}" -f 250 will display the hex conversion of 250
- DateTime: "{0:MM/dd/yyyy hh:mm:ss}" -f $(Get-Date) will output current date as formatted
- Percent: P1 for one decimal, P2 for 2 decimal places
- Variables may be enclosed in strings
- May escape characters with backtick
- CrLf: `r`n
- Tab: `t
- Backtick will treat undefined characters as text (e.g. `$, displays a "$", not a variable)
- Comparison operators (-like, -match) listed above
- Arrays (zero based)
- Array operators
- $arr -contains 2 if the array contains the number 2; -NotContains may also be used
- Array manipulation
- $arr1 = 1,2,3,4,5
- $arr2 = 1..5
- $arr = $arr1, $arr2
- Creates a 2 dimensional array with 5 columns (1-5) in each of 2 rows
- $arr[0][1] accesses the item in the first column in the second row
- $arr = @(1,2,3,4,5)
- Formal notation (but usually short form is used as above)
- $arr = @() creates an empty array
- $arr[2] ="this replaces the third item"
- $arr += "appending new item to array"
- $arr -join ";"
- Concatenates each string in the array with a semi-colon
- $arr[2..4]
- $arr.Count
- Array operators
- Hash tables (dictionaries)
- Hash table operators
- $hash.Contains("hello") if there is a key "hello"; -NotContains may also be used
- $hash.ContainsValue("hello contents")
- $hash.Keys
- $hash.Values
- Hash table editing
- $hash = @{a=1; b=2}
- $hash['a'] = 5
- $hash.$a if we set the $a="a"
- $hash.Remove("a")
- Hash table operators
- JsonString (output to file)
- '{"name":"myname"}' | Out-File "myfile.json" -Encoding utf8
- Enum (introduced in Powershell version 5)
- Enum MyEnum { one two three}
- $enum = [MyEnum]::two
VIII. Techniques: Functions
- Function verb-noun ($parameter1, $parameter2...) { return "done"}
- Use approved verbs for naming (type get-verb to see verbs used in powershell)
- Return statement is optional
- Default is to return void)
- Return "done" may be written as only "done" and this will be returned
- Call functions as follows
- verb-noun "a" "b"
- verb-noun ("a","b")
- verb-noun -parameter1 "a" -parameter2 "b"
- Parameters may be passed by reference (instead of value)
- function verb-noun ( $param1)...
- verb-noun ( "hello")
- Pipeline enable function
- Three blocks are used within pipeline enabled functions
- Begin
- Runs once before process is started (init code). Optional and may be ommitted
- Process
- Called for one iteration for each item piped to the function
- Can return an item for each iteration which allows for other function to pipe from this one
- End
- Runs once before function exits (cleanup code). Optional and may be ommitted
- Begin
- function verb-noun
- begin {}
- process { if ($_ -lt 10) return $_ }
- end {}
- Three blocks are used within pipeline enabled functions
- Advanced function (allows for more control over parameter definitions)
- Allows for setting default param values, assigning parameter datatypes, and other settings
- Starts with cmdletBinding attribute tag, followed by each parameter definition above each declaration
- function verb-noun {
- [cmdletBinding()]
- param ( [Parameter(Mandatory=$false, HelpMessage="Type something here")]
- [int] $param =54
- Creating Help for custom functions
- Place help in comment block within the function using powershell official tags
- Place just below the function opening bracket
- Official tags
- .SYNOPSIS, .DESCRIPTION, .PARAMETER, .EXAMPLE, .INPUTS, .OUTPUTS, .NOTES, .LINK
- Example
- <# .SYNOPSIS I just made this up #>
- Place help in comment block within the function using powershell official tags
- Help
- Get-Help About_Functions
IX. Techniques: Classes (Powershell Version 5, much simplified)
- See the older version of Object/Class creation below (much clunkier)
- Create Class
- Class MyClass { [string] $MyProp = 'default value' [string] MyFunction() { return $this.MyProp }}
- Standard class definition defines a property (MyProp) with optional default value and function (MyFunction)
- If function has no return value, define as [void]
- Class can have a constructor (as well as overloads) each named the same as the class
- MyClass(){...}
- MyClass([string] param1){...}
- Methods and Properties may be static
- static MyFunction([string] param2) { return param2 }
- static $MyProp = 'default value'
- Class MyClass { [string] $MyProp = 'default value' [string] MyFunction() { return $this.MyProp }}
- Instantiate Class
- $object = [MyClass]::new()
- $object = [MyClass]::new('param 1 value here')
- $object.MyProp = 'new value'
- $object.MyFunction()
X. Techniques: Modules
- Module Overall Structure
- Modules are typically placed within their own directory (with the module name)
- Files include Module file (.psm1), manifest file (.psd1), and function files (.ps1)
- Manifest file defines which module to process (ModuleToProcess='filename.psm1')
- Module file, in turn, defines which functions to include (either inline or in separate files)
- Module file (psm1)
- Instead of .ps1, modules have extension .psm1
- Module name is the file name (without the path or extension)
- Module files contain multiple functions or include a link to external ps1 file
- Starts with period "." followed by the path and filename: . path/file.ps1
- Module manifest (psd1)
- Manifest is metadata placed within a file with extension "psd1" and within a module directory
- Enclosed in @{ ModuleToProcess = 'filename.psm1' GUID='e8f8...' Author... CompanyName... Description...}
- Use New-GUID to generate a new GUID
- System Defined Related Variables
- $PSScriptRoot
- File path of currently executing code
- $env:PSModulePath
- Shows the default locations (win env) Powershell will look for modules
- $PSScriptRoot
- Module Commands
- Get-Module
- Import-module
- Import-Module path\module_name.psm1 imports the module into the current code
- Import-module -force myModule
- Forces a reload of imported module
- Remove-module myModule
- Unloads a module from memory (pass the module name)
- Scope
- Variables defined inside the module are typically private
- Globals can be defined in the module: $Global : myGlobal
- Best practice, however, is to avoid globals and return values from functions
- Script Variables, $Script : myScriptVar, may be returned from functions
- Functions inside of a module are all public by default
- Best to explicitly make functions public (and others default as private)
- Once a module defines any function as public, all other functions will become private as default
- Export-ModuleMember MyFunction-Public
- Exports a function as a public function
- All non-exported functions will be private
- Best to explicitly make functions public (and others default as private)
- Variables defined inside the module are typically private
- Help
- Get-Help about_modules -online
XI. Techniques: Help
- Update-Help
- May also call Update-Help -Force
- Downloads all help information for powershell (repeat command when installing or updating Powershell)
- Get-Help
- Get-Help *process*
- Lists all "process" related topics (with * as wildcard) for which help is available
- Get-Help Start-Process
- Shows basic information about the Start-Process command
- Get-Help Start-Process -full
- Shows all help information including examples for Start-Process
- Get-Help Start-Process -Examples
- Shows examples for the topic
- Get-Help About_*
- Gets all of the "About" topics in powershell
- Get-Help Get-Process -online
- Opens online help in browser
- Get-Help *process*
- Get-Command
- Get-Command
- Gets all commands in powershell
- Get-Command -Name *DNS*
- Gets all commands with DNS in the name
- Get-Command -noun process
- Shows all commands that relate to process
- Get-Command -verb get
- Shows all get commands
- Get-Command
- Get-Member
- Get-Process | Get-Member
- Displays all member property and method names of the Get-Process command
- Get-Process | Get-Member
- Select-Object
- Get-Process -name powershell | Select-Object *
- Displays all member properties AND their values
- Get-Process -name powershell | Select-Object *
- What-If
- To make a dry run before actually performing an action, follow a command with -What-if
XII. Management: Powershell Setup
- Reset console colors and settings
- Delete registry key "console" for current user
- Precaution: As with all registry edits, backup before hand (regedit > export, and/or set windows Restore point)
- Computer -> HKEY_CURRENT_USER > console
- Delete registry key "console" for current user
- Information
- $PSVersionTable displays a table of powershell related information
- $host displays the current powershell developer environment (e.g. Powershell ISE with version)
- Profile Scripts File
- Each version of powershell (console or ISE) has a profile script file that is called on start-up
- Placing function in the profile script file will allow use of those scripts by default
- $profile holds the path of the profile script file for the current powershell implementation (e.g. ISE)
- $profile = "~\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1"
- For each version of powershell there are 4 powershell scripts (current host, all hosts, current user, all users)
- $profile | select *
- Profile script file may not exist (create it to add your own scripts)
- if ($(Test-Path $profile) -eq false) {...}
- New-Item -ItemType file -path $profile -force
- psEdit $profile
- Loads the profile file path (stored in $profile) into the Powershell ISE
- Invoke-Item $profile
- Help
- Get-Help About_Profiles
XIII. Management: Execution Policy
- Get-Help about_execution_policies
- Get-ExecutionPolicy
- Restricted - Will not allow Running scripts, only single line commands (change as below)
- AllSigned - All Scripts (remote and local) must have code signing to run
- RemoteSigned - Local scripts may run without signing, but remote scripts must be signed
- Unrestricted - all scripts can be run regardless of origin
- Set-ExecutionPolicy remoteSigned
- Allows current user created scripts to run on the current machine
- Scripts created on other machines will need to be signed with a digital signature
- May also use attribute -Scope with scope settings below
- Scope settings
- MachinePolicy or UserPolicy
- Set within group policy
- CurrentUser or LocalMachine
- Valid for this user or for all users on local machine
- Process
- Setting only for current process
- MachinePolicy or UserPolicy
- Code Signing of a powershell script
- Create a self-sign certificate OR create a certificate via active directory OR purchase a certificate
- Self-Signed certificate (do not use in production)
- Create the certificate using powershell
- New-SelfSignedCertificate -DnsName mySite.myCompany.com -CertStoreLocation cert:\LocalMachine\My
- $Password = ConvertTo-SecureString -String “myPassword” -Force –AsPlainText
- Export-PfxCertificate -Cert cert:\LocalMachine\My\123... -FilePath C:\cert.pfx -Password $Password
- http://woshub.com/how-to-create-self-signed-certificate-with-powershell/
- Alternative: Self-sign certificate process using older process with MakeCert
- Confirm certificate exists
- Get-ChildItem cert:\CurrentUser\My -CodeSigningCert
- Use CertIm.msc also displays certificates (will be in personal folder)
- Apply signed certificate to the script
- $certificates = Get-ChildItem cert:\CurrentUser\My -CodeSigningCert
- Set-AuthenticodeSignature myFile.ps1 @($certificates)
- Create the certificate using powershell
- Help and Utilities
- CertIm.msc
- Windows utility that displays all certificates
- Get-Command -Module PKI
- Displays all commands related to code signing
- CertIm.msc
XIV. Management: Powershell Remote
- Set-up
- Enable-PSRemoting -Force
- Enable remoting on machine to receive connection
- Set-Item wsman:\localhost\client\trustedhosts IPAddressHost
- Perform Restart-Service WinRM after executing set trusted host command
- Where IPAddressHost is of the machines you wish to trust
- Alternatively, IPAddressHost may be replaced with * wildcard to trust all hosts (dangerous)
- Needed on home networks (but not if machines are on the same domain)
- Perform on both host and client machines
- Test-WsMan myRemoteComputerName
- Returns information regarding the remote if normal (otherwise, fails)
- Remote Server Administration Tools (RSAT)
- Install on client machine that will issue powershell commands
- Network connections must be private for Powershell Remoting to work
- Get-NetConnectionProfile
- Displays network connections
- Set-NetConnectionProfile -InterfaceAlias "myEthernetPublic" -NetworkCategory Private
- Sets the named network connection ("myEthernetPublic") to private
- May be changed back to public with attribute -NetworkCategory Public
- Get-NetConnectionProfile
- Enable-PSRemoting -Force
- Remote connection options
- Enter-PsSession
- Starts interactive session in Powershell with remote computer
- Invoke-Command
- Runs commands (or scripts) on local or remote computers
- Invoke-command -ComputerName myOtherComputer -ScriptBlock {Get-Process}
- Enter-PsSession
XV. Techniques: Folder Management (Windows Explorer in Powershell)
- Get-Command -Module Storage | Select-Object -Property Name
- Displays all commands related to storage
- Get-PsDrive (GDr)
- Returns all the Powershell Drives
- Includes physical drives (e.g. C:\), alias, registry (HKCU, HKLM), certificates (Cert), and processes (Env)
- Note that changing to a root directory, requires a ':' (e.g. cd env:\)
- Get-Location (GL)
- Returns current directory location
- Current location is stored automatically as $pwd (without trailing \)
- Get-Childitem (Dir)
- Returns all files or items in the current directory
- Dir filename /S will search all subdirectories for the file
- Get-ChildItem myRootDir -filter "*myPattern??" -Recurse
- Find a file matching pattern (with wildcards) starting with myRootDir and checking subfolders
- Directories can be searched with attribute -Directory
- Set-Location (ChDir, CD)
- Changes to new specified directory
- Push-Location (PushD)
- Pushes a location onto a stack (as well as changing to that location)
- Multiple locations/directories can be pushed onto the stack
- Pop-Location (PopD)
- Returns to the prior location before the last push
- Allows for return to initial directory prior to Running a script
- Get-Item (GU)
- Lists the particular item in its directory
- Get-Item ./test.txt
- New-Item (NI)
- Create a new item (e.g. file, folder or alias)
- New-Item ./test.txt -type file -value "Text within the file"
- New-Item ./test.udp -type file -value ""
- New-Item alias:/clr -value "clear-host" (or New-Alias -name clr -value clear-host)
- New-Item -ItemType directory -Force "myDirName"
- Remove-Item "path/filename" or "path/wildcard"
- Delete a file or file(s) from a directory
- Copy-Item "path/myFile" "myFileDest" -force
- Copy a file or file(s) to a destination folder
- Directories
- Current directory: "."
- Windows User root or home directory (e.g. c:\Users\Username): "~/"
- Invoke-Item (ii)
- Opens an item with it's default program (e.g. "ii ./test.txt" will open in notepad)
- To open Windows Explorer in the current directory, type: "ii ."
- Test-Path myPath
- Returns true if file or directory exist
- PsEdit myFilePath
- Loads the file at myFilePath into the Powershell ISE editor
- Help
- Get-Help *Location
- Get-Help About_Providers
- Related DOS Commands
- Dir
- Displays contents from current directory (equivalent to get-childitem)
- CHDir (CD)
- Change directory (e.g. cd "~/")
- MkDir (MD)
- Make directory
- RmDir (RD)
- Remove directory (if adding the "/s" switch, remove directory is forced even if subfolders)
- Copy, XCopy, RoboCopy, and RichCopy
- Copy files and folders
- Erase (DEL)
- Delete files (e.g. del 'i:\bogus\*.md /f')
- Force switch ("/f") forces the delete
- Format H: /q /v: VOL
- Format drive specified
- Where /q = quick format and /v: VOL = volume label
- DiskPart
- Manage disks, partitions and volumes
- ChkDsk
- Show disk status and also corrects errors
- Dir
XVI. Techniques: Task Management
XVII. Techniques: Server Configuration
- Rename-Computer
- Rename-Computer -NewName MyName
- Servers are often named DC1 (e.g. domain controller), Server1
- Set-Timezone
- Tzutil.exe /s "Central Standard Time"
XVIII. Techniques: Network Configuration
- Related DOS commands
- GpuUpdate /f
- Refreshes group policy (local and active directory) with or without force switch (/f)
- GpResult
- Displays who is logged onto system and what group policies are being applied
- Evaluates RSoP (Resultant Set of Policy)
- GpuUpdate /f
-
Computer Network connections
- Wireless info
- netsh wlan show drivers
- Wireless info
XIX. Techniques: General Server
- Restart-Computer
- Restarts the system
- Stop-Computer
- Shuts down computer
- New-GUID
- Generates a GUID
- Related DOS commands
- Shutdown -f -r -t 60
- Where -f = forces, -r = restart and -t = timer
- BootRec
- Troubleshoot and repairs/recover boot record
- SFC /scannow
- Scans protected system files and confirms/validates these files
- Shutdown -f -r -t 60
XX. Techniques: Visual Studio Package Manager
- Update package by reinstall
- Update-Package -reinstall
XXI. Techniques: Legacy - Objects/Classes (older method, before Powershell version 5)
- See the newer Class method used in Powershell 5 as above
- Create object - hash table method (typically preferred)
- $properties = [ordered] @{prop1 = 'one', prop2 = 2}
- $object = New-Object -TypeName PSObject -Property $properties
- $object.prop1 refers to property on the object
- Create object - adding properties later
- $object = New-Object -TypeName PSObject
- Then add property in one of two ways
- Add-Member -InputObject $object -memberType NoteProperty -Name Prop1 - Value "one"
- $object | Add-member -memberType NoteProperty -Name Prop1 - Value "one"
- Property aliases
- $object | Add-member -memberType AliasProperty -Name MyPropAlias - Value "prop1" -PassThru
- Both MyPropAlias and prop1 will refer to the same property on $object
- $object | Add-member -memberType AliasProperty -Name MyPropAlias - Value "prop1" -PassThru
- Adding functions to objects
- $myScriptBlock = { param($myParam) $result = $this.prop1 + this.prop2 + $myParam; return $result }
- $object | Add-member -memberType ScriptMethod -Name MyCoolScript - Value $myScriptBlock -PassThru
- $object.MyCoolScript("myParamValue") calls the function
- Getters and Setters
- Precaution - the original properties are public and can be directly changed, bypassing getter/setter
- $object | Add-member -memberType NoteProperty -Name Prop1 - Value "one"
- $getter = {return $this.Prop1}
- $setter = {param ($prop1); $this.MyProp = $prop1}
- $object | add-member -memberType ScriptProperty -Name MyProp -Value $getter -SeconValue $setter
- Default properties
- Default properties may be set
XXII. Resources
- Powershell.org
- Hey, Powershell Scripting Guy
- Powershell Prompt Here (Scott Hanselman)
XXIII. References
- Bender (2016) Windows Server Admin Fundamentals Using Powershell, Pluralsight
- Cain (2016) Powershell Scripting for Developers, Pluralsight
- Christopher (2012) Everyday Powershell for Developers, Pluralsight
- Young (2016) Powershell for Beginners, Channel 9