använda PSScriptAnalyzer för att kontrollera PowerShell version kompatibilitet

0 Comments

PSScriptAnalyzer version 1.18 släpptes nyligen, och fartyg med kraftfulla nya regler som kan kontrollera PowerShell skript för inkompatibiliteter med andra PowerShell versioner och miljöer.

i det här blogginlägget, den första i en serie, ser vi hur du använder dessa nya regler för att kontrollera ett skript för problem som körs på PowerShell 3, 5.1 och 6.

Vänta, vad är PSScriptAnalyzer?,

PSScriptAnalzyer är en modul som tillhandahåller statisk analys (eller linting) och en del dynamisk analys (baserat på tillståndet i din miljö) för PowerShell. Det kan hitta problem och fixa dåliga vanor i PowerShell-skript när du skapar dem, som liknar hur C# – kompilatorn ger dig varningar och hittar fel i C# – kod innan den körs.,

om du använder vscode PowerShell-tillägget kanske du har sett de ”gröna squiggliesna” och problemrapporterna som PSScriptAnalyzer genererar för skript som du Författare:

Du kan installera PSScriptAnalyzer för att använda på egna skript med:

Install-Module PSScriptAnalyzer -Scope CurrentUser

psscriptanalyzer fungerar genom att köra en serie regler på dina skript, som var och en självständigt bedömer vissa problem., Till exempel kontrollerar AvoidUsingCmdletAliases att Alias inte används i skript, och MisleadingBackticks kontrollerar att backticks i slutet av rader inte följs av blanktecken.

Mer information finns i bloggserien psscriptanalyzer deep dive.

införa reglerna för kompatibilitetskontroll

den nya kompatibilitetskontrollfunktionen tillhandahålls av tre nya regler:

  • PSUseCompatibleSyntax, som kontrollerar om en syntax som används i ett skript kommer att fungera i andra PowerShell-versioner.,
  • PSUseCompatibleCommands, som kontrollerar om kommandon som används i ett skript är tillgängliga i andra PowerShell-miljöer.
  • PSUseCompatibleTypes, som kontrollerar om.NET-typer och statiska metoder/egenskaper är tillgängliga i andra PowerShell-miljöer.

kontrollregeln för syntax kräver helt enkelt en lista över PowerShell-versioner som du vill rikta in dig på, och kommer att berätta om en syntax som används i skriptet inte fungerar i någon av dessa versioner.,

reglerna för kontroll av kommando och typ är mer sofistikerade och bygger på profiler (kataloger över kommandon och typer tillgängliga) från vanliga PowerShell-plattformar. De kräver konfiguration för att använda dessa profiler, som vi kommer att gå över nedan.

För det här inlägget tittar vi på att konfigurera och använda PSUseCompatibleSyntax och PSUseCompatibleCommands för att kontrollera att ett skript fungerar med olika versioner av PowerShell. Vi tittar på PSUseCompatibleTypes i ett senare inlägg, även om det är konfigurerat mycket på samma sätt som PSUseCompatibleCommands.,

arbetsexempel: ett litet PowerShell-skript

Föreställ dig att vi har ett litet (och konstruerat) arkivskript sparat till .\archiveScript.ps1:

det här skriptet skrevs i PowerShell 6.2, och vi har testat att det fungerar där. Men vi vill också köra det på andra maskiner, varav några Kör PowerShell 5.1 och några Kör PowerShell 3.0.

helst kommer vi att testa det på de andra plattformarna, men det skulle vara trevligt om vi kunde försöka stryka ut så många buggar som möjligt i förväg.,

kontrollera syntax med PSUseCompatibleSyntax

den första och enklaste regeln att tillämpa är PSUseCompatibleSyntax. Vi kommer att skapa några inställningar för PSScriptAnalyzer för att aktivera regeln och kör sedan analys på vårt skript för att få tillbaka någon diagnostik om kompatibilitet.

det är enkelt att köra PSScriptAnalyzer., Den kommer som en PowerShell-modul, så när den är installerad på din modulsökväg anropar du bara den på din fil med Invoke-ScriptAnalyzer, så här:

Invoke-ScriptAnalyzer -Path ".\archiveScript.ps1`

en mycket enkel anrop som den här kommer att köra PSScriptAnalyzer med sina standardregler och konfigurationer på skriptet du pekar den på.

eftersom de kräver mer målinriktad konfiguration aktiveras inte kompatibilitetsreglerna som standard. I stället måste vi ange vissa inställningar för att köra syntaxkontrollregeln., I synnerhet kräver PSUseCompatibleSyntax en lista över PowerShell-versionerna du riktar in dig på med ditt skript.

kör detta kommer att presentera oss med följande utgång:

detta säger oss att]::new() syntax vi använde kommer inte att fungera i PowerShell 3. Bättre än så, i det här fallet har regeln faktiskt föreslagit en fix:

$diagnostics = Invoke-ScriptAnalyzer -Path .\archiveScript.ps1 -Settings $settings$diagnostics.SuggestedCorrections

den föreslagna korrigeringen är att använda New-Object istället., Det sätt som detta föreslås kan tyckas lite ohjälpligt här med all positionsinformation, men vi får se senare varför det här är användbart.

det här ordboksexemplet är naturligtvis lite artificiellt (eftersom en hashtable skulle komma mer naturligt), men att ha en nyckel kastad i verken i PowerShell 3 eller 4 på grund av en ::new() är inte ovanligt. Den psusecompatiblesyntax regeln kommer också att varna dig om klasser, arbetsflöden ochusing uttalanden beroende på versioner av PowerShell du författar för.,

Vi kommer inte att göra den föreslagna ändringen ännu, eftersom det finns mer att visa dig först.

kontrollera kommandoanvändningen med PSUseCompatibleCommands

vi vill nu kontrollera kommandona. Eftersom kommandokompatibilitet är lite mer komplicerad än syntax (eftersom tillgången på kommandon beror på mer än vilken version av PowerShell som körs) måste vi rikta profiler istället.

profiler är kataloger av information som tas från lagermaskiner som kör vanliga PowerShell-miljöer., De som skickas i PSScriptAnalyzer kan inte alltid matcha din arbetsmiljö perfekt, men de kommer ganska nära (det finns också ett sätt att skapa din egen profil, detaljerad i ett senare blogginlägg). I vårt fall försöker vi rikta PowerShell 3.0, PowerShell 5.1 och PowerShell 6.2 på Windows. Vi har de två första profilerna, men i det sista fallet måste vi rikta 6.1 istället. Dessa mål är mycket nära, så varningar kommer fortfarande att vara relevanta för att använda PowerShell 6.2. Senare när en 6.2-profil görs tillgänglig kan vi byta till det.,

Vi måste titta under psusecompatiblecommands dokumentation för en lista över profiler som är tillgängliga som standard. För våra önskade mål väljer vi:

de långa namnen till höger är kanoniska profilkoder, som vi använder i inställningarna:

det kan finnas en fördröjning första gången du utför detta eftersom reglerna måste ladda katalogerna i en cache. Varje katalog över en PowerShell-plattform innehåller detaljer om alla moduler och .,NET assemblies tillgängliga för PowerShell på den plattformen, som kan vara så många som 1700-kommandon med 15,000-parametrar och 100-aggregat med 10,000-typer. Men när den är laddad kommer ytterligare kompatibilitetsanalys att vara snabb. Vi får utdata så här:

RuleName Severity ScriptName Line Message-------- -------- ---------- ---- -------PSUseCompatibleCommands Warning archiveScr 2 The parameter "FullyQualifiedName" is not available for ipt.ps1 command "Import-Module" by default in PowerShell version "3.0" on platform "Microsoft Windows Server 2012 Datacenter"PSUseCompatibleCommands Warning archiveScr 12 The command "Get-FileHash" is not available by default in ipt.ps1 PowerShell version "3.0" on platform "Microsoft Windows Server 2012 Datacenter"PSUseCompatibleCommands Warning archiveScr 18 The parameter "LeafBase" is not available for command ipt.ps1 "Split-Path" by default in PowerShell version "5.1.17763.316" on platform "Microsoft Windows Server 2019 Datacenter"PSUseCompatibleCommands Warning archiveScr 18 The parameter "LeafBase" is not available for command ipt.ps1 "Split-Path" by default in PowerShell version "3.0" on platform "Microsoft Windows Server 2012 Datacenter"PSUseCompatibleCommands Warning archiveScr 19 The command "Compress-Archive" is not available by ipt.ps1 default in PowerShell version "3.0" on platform "Microsoft Windows Server 2012 Datacenter"PSUseCompatibleCommands Warning archiveScr 23 The parameter "NoNewline" is not available for command ipt.ps1 "Out-File" by default in PowerShell version "3.0" on platform "Microsoft Windows Server 2012 Datacenter"

det här säger oss att:

  • Import-Module stöder inte -FullyQualifiedName I PowerShell 3.0;
  • Get-FileHash finns inte i PowerShell 3.0;
  • Split-Path har inte -LeafBase I PowerShell 5.1 eller PowerShell 3.,0;
  • Compress-Archive är inte tillgängligt i PowerShell 3.0, och;
  • Out-File stöder inte -NoNewline I PowerShell 3.0

en sak du kommer att märka är att funktionen Get-FoldersToArchive inte stöder -NoNewline I PowerShell 3.0

att bli varnad om. Detta beror på att kompatibilitetsreglerna är utformade för att ignorera användarstyrda kommandon; ett kommando kommer endast att markeras som inkompatibelt om det finns i någon profil och inte i något av dina mål.,

igen kan vi ändra skriptet för att åtgärda dessa varningar, men innan vi gör det vill jag visa dig hur du gör det till en mer kontinuerlig upplevelse. när du ändrar ditt skript vill du veta om ändringarna du gör break kompatibilitet, och det är lätt att göra med stegen nedan.

använda en inställningsfil för upprepad anrop

det första vi vill är att göra psscriptanalyzer anrop mer automatiserad och reproducerbar. Ett trevligt steg mot detta tar inställningarna hashtable vi gjorde och omvandlar den till en deklarativ datafil, som skiljer ut ”vad” från ”hur”.,

PSScriptAnalyzer kommer att acceptera en sökväg till en PSD1 i parametern -Settings, så allt vi behöver göra är att göra vår hashtable till en PSD1-fil, som vi ska göra ./PSScriptAnalyzerSettings.psd1. Lägg märke till att vi kan slå samman inställningarna för både PSUseCompatibleSyntax och PSUseCompatibleCommands:

Nu kan vi köra psscriptanalyzer igen på skriptet med inställningsfilen:

Invoke-ScriptAnalyzer -Path ./archiveScript.ps1 -Settings ./PSScriptAnalyzerSettings.psd1

det här ger utmatningen:

RuleName Severity ScriptName Line Message-------- -------- ---------- ---- -------PSUseCompatibleCommands Warning archiveScr 1 The parameter "FullyQualifiedName" is not available for ipt.ps1 command "Import-Module" by default in PowerShell version "3.0" on platform "Microsoft Windows Server 2012 Datacenter"PSUseCompatibleCommands Warning archiveScr 9 The command "Get-FileHash" is not available by default in ipt.ps1 PowerShell version "3.0" on platform "Microsoft Windows Server 2012 Datacenter"PSUseCompatibleCommands Warning archiveScr 12 The parameter "LeafBase" is not available for command ipt.ps1 "Split-Path" by default in PowerShell version "3.0" on platform "Microsoft Windows Server 2012 Datacenter"PSUseCompatibleCommands Warning archiveScr 12 The parameter "LeafBase" is not available for command ipt.ps1 "Split-Path" by default in PowerShell version "5.1.17763.316" on platform "Microsoft Windows Server 2019 Datacenter"PSUseCompatibleCommands Warning archiveScr 13 The command "Compress-Archive" is not available by ipt.ps1 default in PowerShell version "3.0" on platform "Microsoft Windows Server 2012 Datacenter"PSUseCompatibleCommands Warning archiveScr 16 The parameter "NoNewline" is not available for command ipt.ps1 "Out-File" by default in PowerShell version "3.0" on platform "Microsoft Windows Server 2012 Datacenter"PSUseCompatibleSyntax Warning archiveScr 6 The constructor syntax ipt.ps1 "]::new()" is not available by default in PowerShell versions 3,4

nu är vi inte beroende av några variabler längre, och har en separat Spefication av den analys du vill ha., Med hjälp av detta kan du lägga detta i kontinuerliga integreringsmiljöer för att till exempel kontrollera att ändringar i skript inte bryter kompatibilitet.

men vad vi verkligen vill är att veta att PowerShell-skript är kompatibla när du redigerar dem. Det är vad inställningsfilen bygger på, och även där det är lättast att göra de ändringar du behöver för att göra ditt skript kompatibelt. För det vill vi integrera med vscode PowerShell-förlängningen.,

att Integrera med VSCode för on-the-fly kompatibilitet kontrollera

Som förklaras i början av detta inlägg, VSCode PowerShell förlängning har inbyggt stöd för PSScriptAnalyzer. Faktum är att från och med version 1.12.0 levereras PowerShell-förlängningen med PSScriptAnalyzer 1.18, vilket betyder att du inte behöver göra något annat än att skapa en inställningsfil för att göra kompatibilitetsanalys.

Vi har redan vår inställningsfil redo att gå från det sista steget, så allt vi behöver göra är att peka på PowerShell-tillägget till filen i vscode-inställningarna.,

Du kan öppna inställningarna med Ctrl+, (använd cmd istället för Ctrl på macOS). I inställningsvyn vill vi PowerShell > Script Analysis: Settings Path. I settings.json visa detta är "powershell.scriptAnalysis.settingsPath"., Ange en relativ sökväg här kommer att hitta en inställningsfil i vår arbetsyta, så vi bara sätta ./PSScriptAnalyzerSettings.psd1:

i settings.json visa detta kommer att se ut:

"powershell.scriptAnalysis.settingsPath": "./PSScriptAnalyzerSettings.psd1"

nu öppnar manuset i vscode vi ser ”gröna squigglies” för kompatibilitetsvarningar:

i problemfönstret får du en fullständig desrciption av alla inkompatibiliteter:

låt oss åtgärda syntaxproblemet först., Om du kommer ihåg, psscriptanalyzer levererar en föreslagen korrigering av detta problem. VSCode integrerar med PSScriptAnalyzer s förslag på korrigeringar och kan tillämpa dem om du klickar på glödlampa eller med Ctrl+Mellanslag när regionen är under markören:

att Tillämpa denna förändring, manuset är nu:

andra fel inte har korrigerats, för nu PSUseCompatibleCommands vet vilka kommandon som finns tillgängliga på varje plattform, men inte vad jag ska ersätta med när ett kommando inte är tillgängligt., Så vi behöver bara tillämpa vissa PowerShell-kunskaper:

vi slutar med något så här (den specifika implementeringen är obetydlig, men vi har något som kommer att fungera i alla versioner):

Du bör märka att när du skriver visar VSCode ny analys av vad du skriver och de gröna squiggliesna faller bort. När vi är klara får vi en ren hälsoräkning för scriptkompatibilitet:

det betyder att du nu kan använda det här scriptet i alla PowerShell-versioner du behöver rikta in dig på., Bättre, du har nu en konfiguration i din arbetsyta så när du skriver fler skript, det finns kontinuerlig kontroll för kompatibilitet. Och om dina kompatibilitetsmål ändras behöver du bara ändra konfigurationsfilen på ett ställe för att peka på dina önskade mål, då får du analys för dina uppdaterade målplattformar.

sammanfattning

förhoppningsvis i det här blogginlägget fick du en uppfattning om de nya kompatibilitetsreglerna som följer med PSScriptAnalyzer 1.18.,

Vi har täckt hur du konfigurerar och använder kontrollregeln för syntaxkompatibilitet, PSUseCompatibleSyntax och kontrollregeln för kommandot, PSUseCompatibleCommands, både med hjälp av en hashtable konfiguration och en PSD1-fil för inställningar.

Vi har också tittat på att använda kompatibilitetsreglerna med PowerShell-tillägget för VSCode, där de som standard kommer från version 1.12.0.

om du har den senaste versionen av PowerShell-tillägget för VSCode (1.12.1) kan du ställa in konfigurationsfilen och omedelbart få kompatibilitetskontroll.,

i nästa blogginlägg tittar vi på hur du använder dessa Regler och PSUseCompatibleTypes (som kontrollerar om.Net-typer och statiska metoder finns tillgängliga på målplattformar) kan användas för att hjälpa dig att skriva skript som fungerar plattformsoberoende över Windows och Linux med både Windows PowerShell och PowerShell Core.

Rob Holt

mjukvaruingenjör

PowerShell Team


Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *