Effective Windows PowerShell

34
Effective Windows PowerShell Keith Hill Windows PowerShell MVP [email protected] http://rkeithhill.wordpress.com twitter: @r_keith_hill

description

Effective Windows PowerShell. Keith Hill Windows PowerShell MVP [email protected] 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 - PowerPoint PPT Presentation

Transcript of Effective Windows PowerShell

Microsoft //BUILD/ 2012 Brown Bag

Effective Windows PowerShellKeith HillWindows PowerShell [email protected]://rkeithhill.wordpress.comtwitter: @r_keith_hillGoalsProvide you with tools & knowledge to make you effective using PowerShellTeach someone to fish and they can feed themselvesWell focus on broad understanding & using commandsAlong the wayProvide a mental model of how PowerShell worksDiscuss where transfer of learning helps (and hinders)Point out some gotchasShow where to get help from the community

PowerShell Mental ModelPowerShell is an automation engine for WindowsPowerShell.exe / PowerShell_ISE.exe are just host appsEngine can be hosted in other applicationsPowerShell is a shell and a scripting languageCommandsProvidersType systemProgramming constructsPowerShell ArchitectureHost process: PowerShell.exe, PowerShell_ISE.exe, etcProcess Env Block includes environment variablesRunspace(s) Pipeline executes script Variables Functions Aliases Module import tablePowerShell Engine (SMA.dll) Parses and executes scriptBuilt-in commandsImplementation of PSHost* interfaces used by engine for UI I/OSimple C# PowerShell Host AppusingSystem; usingSystem.Collections.ObjectModel; usingSystem.Management.Automation;

namespacePowerShellHosting{ classProgram{ staticvoidMain(){ using(varps=PowerShell.Create()){ while(true){ Console.WriteLine("Enteranexpression:"); stringinput=Console.ReadLine(); if(String.IsNullOrWhiteSpace(input))break; ps.AddScript(input); Collectionresults=ps.Invoke(); foreach(varresultinresults){ Console.WriteLine(result); } } } } } } Mental Model CommandsPowerShell provides monadic commands that can be composed in pipeline to accomplish complex tasksProduction-oriented: verify destructive ops before executingPowerShell commands output objects NOT textPowerShell commands run in-process (not exes)PowerShell provides:A common param parsing engine set of common parametersAn extensible formatting & output engineCommands are named - for consistencyCommands can be verbose for readabilityGet-Process | Where-Object {$_.PagedMemorySize gt 100MB} | Foreach-Object {$_.Name}Or pithy for your wrists (and ego)gps | ? PM gt 100MB | % NameMental Model ProvidersWindows has various data stores:File system, registry, certificate store, environment varsA Provider is an abstraction over a data storeInstances of providers look like file system drivesC:\, D:\, HKLM:\, Cert:\Standard set of commands to manipulateSet-Location (cd), Get-ChildItem, Get/Set-Item, Move-Item, Rename-Item, Copy-Item, Remove-ItemPowerShell exposes some of its own data stores via providers: alias, variable, functionMental Model Type SystemETS extended type systemAugments objects with new properties & methods necessary to provide better admin experience.NET types were not designed with admins in mindFileInfo gets BaseName, VersionInfoProcess gets Company, Cpu, FileVersion, ProductVersionOther object representations are adapted into PowerShellWMI, COM, ADSI, ADOPromiscuously typed languageTries hard to turn what you have into what you needType System DemoTypeSystemDemo.ps1Mental Model Scripting LanguageProvides very useful, C# like programming constructs:if/elseif/else, for, foreach, while, do while, switchProvides many useful operators:-eq/ne/gt/lt/ge/le (why not ==, !=, >, =, ipconfig /allPS C:\> netsh dumpPS C:\> vaultcmd /listcreds:"Web Credentials" /all

Up/down arrows and F7 still work recalls historyPowerShell tab completes path just as CMD doesPowerShell tab completion is way more extensivePowerShell follows UNIX rule you have to use .\foo.exe to run from current directory

#2 Four Commands of DiscoveryHow 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 DemoGetCommandDemo.ps1GetHelpDemo.ps1GetMemberDemo.ps1GetPSDriveDemo.ps1

#3 How the Pipeline WorksPiping in other shells pipes text (sometimes binary):$ ps axu | grep python | cut -d' ' -f2PowerShell pipes pass .NET objectsEach line executed at the console executes in a pipelinePipe operator "|" is not what makes it a pipelineEntire scripts are executed in a pipelineObjects pass from one stage of pipeline to another:PS C:\> Get-Process python | Foreach-Object {$_.Id}The automatic variable $_ represents the current pipeline objectEnd of the (Pipe)lineYou can specify output formatter and destination:PS C:\> Get-Process | Format-Table | Out-HostOr let PowerShell choose for you:PS C:\> Get-ProcessIn this case PowerShell implicitly pipes to Out-Default which selects a default formatter and uses Out-HostDefault formatter selected based on first objectIf subsequent objects dont match format they are displayed using Format-List

PowerShell Pipeline in ActionGet-Process | Where {$_.PM gt 60MB} | Sort ProcessNameSystem.Diagnostics.ProcessSystem.Diagnostics.ProcessSystem.Diagnostics.Process WhereProcess.PagedMemorySize > 60*1024*1024NoYesSystem.Diagnostics.ProcessSystem.Diagnostics.ProcessSystem.Diagnostics.ProcessSystem.Diagnostics.ProcessSystem.Diagnostics.ProcessSort on Process.ProcessNameGet-ProcessSystem.Diagnostics.Processout-defaultHandles NPM ------- --- ---105 11189 99Console.Write

Pipeline Object Types Can ChangeYou may know what type the initial command outputs but the next command may output a different typeThis works:PS C:\> Get-ChildItem *.ps1 | Where {$_.LastWriteTime -gt (Get-Date).AddMonths(-1)}But this doesnt: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 DemoPipelineDemo.ps1#4 Formatting & OutputFormatting rendering object to formatted textDetermine what parts of the object are to be displayedDetermine what display format to use:Table, list, wide and customUser can explicitly choose: Format-Table/List/Wide/CustomOutput sending formatted text to desired locationOut-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 TextFormatting directionsFormat (ps1xml) files provide directions on what properties to display and what format to useReflection over public propertiesPublic properties are displayNumber of properties determines the formatter used 5 displays data in a listObject.ToString() last ditch if no public properties

Formatting DemoFormattingDemo.ps1Format & Type Data FilesFormat data file instructs PowerShell how to display a particular object type in various formatsType data file instructs PowerShell what properties to display and specifies new properties: AliasProperty, NoteProperty, ScriptPropertyExamineFormat data file: $pshome\DotNetTypes.format.ps1xmlType data file: $pshome\types.ps1xml

#5 Understanding Parsing ModesPowerShell parses for both command execution & expression evaluationString isnt the only literal type parsed:int, double, decimal, bool, array, hashtableCommand execution: must feel natural e.g.:PS C:\> Select-String xyzzy c:\foo.txtPS C:\> notepad.exe c:\foo.txtExpression 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 stringsThe Two Parsing ModesArgument (command) parsing modeStrings dont need to quotedNumbers are parsed as stringsCertain characters kick parsing into expression mode:$ @ ' " and (Expression parsing modeStrings must be quotedNumbers not in quotes are treated a numerical valuesCertain 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 expressionWithin expression, start new parsing context with ( or $(Parsing Mode DeterminationBy initial characters of line and after: (, $( , { and =

Parsing modePatternsArgument/Command[_aA-zZ] # command name& # call operator.\s+ # dot source operator[./\]+ # start of a path.[^0-9./\ ] # .n7.exe ok, .7 & .7kb are nums[0-9]+[_aA-zZ] # except for d, kb, mb, gb, tbExpression[0-9]*\.?[0-9]+(d|kb|mb|gb|tb|pb)?'"$ # variable reference or subexpression start@ # hashtable and splatting(PowerShell Parsing GotchaInterop with executables taking complex arguments can be very problematic in PowerShellQuotes get lostPowerShell interprets certain chars: $ @ ( { ; `Stop parser symbol kicks into dumb parsing mode:icacls --% X:\VMS /grant Dom\HVAdmin:(CI)(OI)FCan use env variables:$env:table = 'AdventureWorks.Person.Contact'sqlcmd -S .\SQLEXPRESS -v lname="Gates" --% -Q "SELECT FirstName,LastName FROM %table% WHERE LastName = '$(lname)'"

Parsing Modes DemoParsingModedDemo.ps1#6 Error HandlingTwo flavorsNon-terminatingTerminatingNon-terminating errors dont alter control flowCan be converted to terminating errors with:ErrorAction common parameter$ErrorActionPreference variableTerminating errors alter control flowUse try/catch to handle terminating errorsOr let the script error out on a terminating errorError 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 commandTrue indicates command succeeded without any errorsFalse indicates complete or partial failureTrue for exes returning 0 and False any other exit code$LastExitCode int containing last exes exit codeError Handling DemoErrorHandlingDemo.ps1Popular Modules / Tools / ReposPowerShell Community Extensionshttp://pscx.codeplex.com & PSGet GalleryPSReadlinehttps://github.com/lzybkr/PSReadLine & PSGet GalleryPowerShell Tools for Visual Studiohttp://visualstudiogallery.msdn.microsoft.com/c9eb3ba8-0c59-4944-9a62-6eee37294597ISESteriods 2.0http://www.powertheshell.com/isesteroids2/PoshCode.orghttp://poshcode.orgHelp ResourcesStackOverflowhttp://stackoverflow.com/tags/powershellPowerShell.orghttp://powershell.org/wp/forums/ MS TechNet ScriptCenter forumshttp://social.technet.microsoft.com/Forums/scriptcenter/en-US/homeEffective Windows PowerShell (free) eBookhttps://onedrive.live.com/view.aspx?cid=5A8D2641E0963A97&resid=5A8D2641E0963A97%216929&app=WordPdf

Make PowerShell BetterReport a bugSubmit a suggestion (enhancement request)Vote on already submitted bugs & suggestionshttps://connect.microsoft.com/PowerShell/Feedback Questions?