350 likes | 580 Views
Effective Windows PowerShell. Keith Hill Windows PowerShell MVP keith.hill@outlook.com http://rkeithhill.wordpress.com twitter: @ r_keith_hill. Goals. Provide you with tools & knowledge to make you effective using PowerShell Teach someone to fish and they can feed themselves
E N D
Effective Windows PowerShell Keith Hill Windows PowerShell MVP keith.hill@outlook.com http://rkeithhill.wordpress.com twitter: @r_keith_hill
Goals • Provide you with tools & knowledge to make you effective using PowerShell • Teach someone to fish and they can feed themselves • We’ll focus on broad understanding & using commands • Along the way • Provide a mental model of how PowerShell works • Discuss where transfer of learning helps (and hinders) • Point out some gotchas • Show where to get help from the community
PowerShell Mental Model • PowerShell is an automation engine for Windows • PowerShell.exe / PowerShell_ISE.exe are just host apps • Engine can be hosted in other applications • PowerShell is a shell and a scripting language • Commands • Providers • Type system • Programming constructs
PowerShell Architecture Host process: PowerShell.exe, PowerShell_ISE.exe, etc Process Env Block – includes environment variables Implementation of PSHost* interfaces – used by engine for UI I/O PowerShell Engine (SMA.dll) – Parses and executes script Built-in commands Runspace(s) Pipeline executes script Variables Functions Aliases Module import table
Simple C# PowerShell Host App using System; usingSystem.Collections.ObjectModel; usingSystem.Management.Automation; namespacePowerShellHosting { classProgram { staticvoid Main() { using (varps = PowerShell.Create()) { while (true) { Console.WriteLine("Enter an expression:"); string input = Console.ReadLine(); if (String.IsNullOrWhiteSpace(input)) break; ps.AddScript(input); Collection<PSObject> results = ps.Invoke(); foreach (var result in results) { Console.WriteLine(result); } } } } } }
Mental Model – Commands • PowerShell provides “monadic” commands that can be composed in pipeline to accomplish complex tasks • Production-oriented: verify destructive ops before executing • PowerShell commands output objects NOT text • PowerShell commands run “in-process” (not exes) • PowerShell provides: • A common param parsing engine – set of common parameters • An extensible formatting & output engine • Commands are named <verb>-<noun> for consistency • Commands can be verbose for readabilityGet-Process | Where-Object {$_.PagedMemorySize –gt 100MB} | Foreach-Object {$_.Name} • Or pithy for your wrists (and ego)gps| ? PM –gt100MB | % Name
Mental Model – Providers • Windows has various data stores: • File system, registry, certificate store, environment vars • A Provider is an abstraction over a data store • Instances of providers look like file system drives • C:\, D:\, HKLM:\, Cert:\ • Standard set of commands to manipulate • Set-Location (cd), Get-ChildItem, Get/Set-Item, Move-Item, Rename-Item, Copy-Item, Remove-Item • PowerShell exposes some of its own “data stores” via providers: alias, variable, function
Mental Model – Type System • ETS – extended type system • Augments objects with new properties & methods necessary to provide better admin experience • .NET types were not designed with admins in mind • FileInfo gets BaseName, VersionInfo • Process gets Company, Cpu, FileVersion, ProductVersion • Other object representations are adapted into PowerShell • WMI, COM, ADSI, ADO • Promiscuously typed language • Tries hard to turn what you have into what you need
Type System Demo • TypeSystemDemo.ps1
Mental Model – Scripting Language • Provides very useful, C# like programming constructs: • if/elseif/else, for, foreach, while, do while, switch • Provides many useful operators: • -eq/ne/gt/lt/ge/le (why not ==, !=, >, <, >=, <= ?) • -match, -notmatch, -contains, -notcontains, -replace, -split, -join, -and, -or, -not • Users can create their own commands – functions • Users can create their own types – [pscustomobject] • Users can easily create scripts by copying commands they execute in the console into a .ps1 file
#1 PowerShell Runs Exes • Start simple, use PowerShell instead of CMD to run your favorite utilities:PS C:\> ipconfig /allPS C:\> netsh dumpPS C:\> vaultcmd /listcreds:"Web Credentials" /all • Up/down arrows and F7 still work – recalls history • PowerShell tab completes path just as CMD does • PowerShell tab completion is way more extensive • PowerShell follows UNIX rule – you have to use .\foo.exe to run from current directory
#2 Four Commands of Discovery • How do you get past the “blank screen of death”? • #1 Get-Command: discover available commands • #2 Get-Help: learn how to use commands • #3 Get-Member: discover what objects can do • #4 Get-PSDrive:discover available data stores
Four Commands Demo • GetCommandDemo.ps1 • GetHelpDemo.ps1 • GetMemberDemo.ps1 • GetPSDriveDemo.ps1
#3 How the Pipeline Works • Piping in other shells pipes text (sometimes binary):$ psaxu | grep python | cut -d' ' -f2 • PowerShell pipes pass .NET objects • Each line executed at the console executes in a pipeline • Pipe operator "|" is not what makes it a pipeline • Entire scripts are executed in a pipeline • Objects pass from one stage of pipeline to another:PS C:\> Get-Process python | Foreach-Object {$_.Id} • The automatic variable $_ represents the current pipeline object
End of the (Pipe)line • You can specify output formatter and destination:PS C:\> Get-Process | Format-Table | Out-Host • Or let PowerShell choose for you:PS C:\> Get-Process • In this case PowerShell implicitly pipes to Out-Default which selects a default formatter and uses Out-Host • Default formatter selected based on first object • If subsequent objects don’t match format they are displayed using Format-List
Get-Process System.Diagnostics.Process System.Diagnostics.Process System.Diagnostics.Process Sort on Process.ProcessName System.Diagnostics.Process System.Diagnostics.Process System.Diagnostics.Process System.Diagnostics.Process out-default PowerShell Pipeline in Action System.Diagnostics.Process Get-Process | Where {$_.PM –gt 60MB} | Sort ProcessName WhereProcess.PagedMemorySize > 60*1024*1024 System.Diagnostics.Process No Yes Handles NPM …------- --- ---105 11189 99 Console.Write
Pipeline Object Types Can Change • You may know what type the initial command outputs but the next command may output a different type • This works:PS C:\> Get-ChildItem *.ps1 | Where {$_.LastWriteTime -gt (Get-Date).AddMonths(-1)} • But this doesn’t:PS C:\> Get-ChildItem *.ps1 | Select-String psdrive | Where {$_.LastWriteTime -gt (Get-Date).AddMonths(-1)} • Use Get-Member at various pipeline stages to examine the output object type
Pipeline Demo • PipelineDemo.ps1
#4 Formatting & Output • Formatting – rendering object to formatted text • Determine what parts of the object are to be displayed • Determine what display format to use: • Table, list, wide and custom • User can explicitly choose: Format-Table/List/Wide/Custom • Output – sending formatted text to desired location • Out-File, Out-String, Out-Printer, Out-Host (default) • Output sent to Host goes through HOST UI interface:PSHostUserInterface.WriteLine(String)
How Objects Get Rendered as Text • Formatting directions • Format (ps1xml) files provide directions on what properties to display and what format to use • Reflection over public properties • Public properties are display • Number of properties determines the formatter used • <= 4 displays data in a table • > 5 displays data in a list • Object.ToString() – last ditch if no public properties
Formatting Demo • FormattingDemo.ps1
Format & Type Data Files • Format data file instructs PowerShell how to display a particular object type in various formats • Type data file instructs PowerShell what properties to display and specifies new properties: AliasProperty, NoteProperty, ScriptProperty • Examine • Format data file: $pshome\DotNetTypes.format.ps1xml • Type data file: $pshome\types.ps1xml
#5 Understanding Parsing Modes • PowerShell parses for both command execution & expression evaluation • String isn’t the only literal type parsed: • int, double, decimal, bool, array, hashtable • Command execution: must feel natural e.g.:PS C:\> Select-String xyzzy c:\foo.txtPS C:\> notepad.exe c:\foo.txt • Expression evaluation: scripting must feel natural e.g.:PS C:\> $sum = 6*7PS C:\> if ($sum –eq 42) {"What's the question"}PS C:\> 'Select-String xyzzy c:\foo.txt' >> foo.logPS C:\> [Math]::Max($sum, 100)PS C:\> [int]::Parse('2A8D', 'HexNumber') # quote strings
The Two Parsing Modes • Argument (command) parsing mode • Strings don’t need to quoted • Numbers are parsed as strings • Certain characters kick parsing into expression mode: • $ @ ' " and ( • Expression parsing mode • Strings must be quoted • Numbers not in quotes are treated a numerical values • Certain characters kick into argument parsing mode • \/ - path characters e.g. $pwd\foo.txt – no quoting necessary • = -the value on the right can be either a command or expression • Within expression, start new parsing context with ( or $(
Parsing Mode Determination • By initial characters of line and after: (, $( , { and =
PowerShell Parsing Gotcha • Interop with executables taking complex arguments can be very problematic in PowerShell • Quotes get lost • PowerShell interprets certain chars: $ @ ( { ; ` • Stop parser symbol kicks into dumb parsing mode:icacls--% X:\VMS /grant Dom\HVAdmin:(CI)(OI)F • Can use env variables:$env:table= 'AdventureWorks.Person.Contact'sqlcmd -S .\SQLEXPRESS -v lname="Gates" --% -Q "SELECT FirstName,LastNameFROM %table% WHERE LastName = '$(lname)'"
Parsing Modes Demo • ParsingModedDemo.ps1
#6 Error Handling • Two flavors • Non-terminating • Terminating • Non-terminating errors don’t alter control flow • Can be converted to terminating errors with: • ErrorAction common parameter • $ErrorActionPreference variable • Terminating errors alter control flow • Use try/catch to handle terminating errors • Or let the script error outon a terminating error
Error Related Variables • $Error - PowerShell stores all errors in this collection • $Error[0] always contains the most recent error • $MaximumErrorCount– max size of $Error collection • $? – boolean execution status of last command • True indicates command succeeded without any errors • False indicates complete or partial failure • True for exes returning 0 and False any other exit code • $LastExitCode– int containing last exe’s exit code
Error Handling Demo • ErrorHandlingDemo.ps1
Popular Modules / Tools / Repos • PowerShell Community Extensionshttp://pscx.codeplex.com & PSGet Gallery • PSReadlinehttps://github.com/lzybkr/PSReadLine & PSGet Gallery • PowerShell Tools for Visual Studiohttp://visualstudiogallery.msdn.microsoft.com/c9eb3ba8-0c59-4944-9a62-6eee37294597 • ISESteriods 2.0http://www.powertheshell.com/isesteroids2/ • PoshCode.org • http://poshcode.org
Help Resources • StackOverflowhttp://stackoverflow.com/tags/powershell • PowerShell.orghttp://powershell.org/wp/forums/ • MS TechNet ScriptCenter forumshttp://social.technet.microsoft.com/Forums/scriptcenter/en-US/home • Effective Windows PowerShell (free) eBookhttps://onedrive.live.com/view.aspx?cid=5A8D2641E0963A97&resid=5A8D2641E0963A97%216929&app=WordPdf
Make PowerShell Better • Report a bug • Submit a suggestion (enhancement request) • Vote on already submitted bugs & suggestionshttps://connect.microsoft.com/PowerShell/Feedback