Utilizzo di PSScriptAnalyzer per verificare la compatibilità della versione PowerShell
PSScriptAnalyzer versione 1.18 è stato rilasciato di recente, e viene fornito con nuove potenti regole che possono controllare gli script PowerShell per incompatibilità con altre versioni e ambienti PowerShell.
In questo post del blog, il primo di una serie, vedremo come utilizzare queste nuove regole per controllare uno script per problemi in esecuzione su PowerShell 3, 5.1 e 6.
Aspetta, cos’è PSScriptAnalyzer?,
PSScriptAnalzyer è un modulo che fornisce analisi statica (o linting) e alcune analisi dinamiche (in base allo stato dell’ambiente) per PowerShell. È in grado di trovare problemi e correggere cattive abitudini negli script PowerShell mentre li crei, in modo simile al modo in cui il compilatore c# ti darà avvisi e troverà errori nel codice c# prima che venga eseguito.,
Se si utilizza il VSCode PowerShell estensione, si potrebbe avere visto il “verde squigglies” e segnalazioni di problemi che PSScriptAnalyzer genera script autore:
È possibile installare PSScriptAnalyzer da utilizzare sul proprio script con:
Install-Module PSScriptAnalyzer -Scope CurrentUser
PSScriptAnalyzer funziona eseguendo una serie di regole sul script, ognuno dei quali indipendente valuta qualche problema., Ad esempioAvoidUsingCmdletAliases
controlla che gli alias non siano utilizzati negli script eMisleadingBackticks
controlla che i backtick alle estremità delle righe non siano seguiti da spazi bianchi.
Per ulteriori informazioni, vedere la serie di blog di immersione profonda PSScriptAnalyzer.
Introduzione delle regole di controllo della compatibilità
La nuova funzionalità di controllo della compatibilità è fornita da tre nuove regole:
- PSUseCompatibleSyntax, che controlla se una sintassi utilizzata in uno script funzionerà in altre versioni di PowerShell.,
- PSUseCompatibleCommands, che controlla se i comandi utilizzati in uno script sono disponibili in altri ambienti PowerShell.
- PSUseCompatibleTypes, che controlla se i tipi. NET e i metodi/proprietà statici sono disponibili in altri ambienti PowerShell.
La regola di controllo della sintassi richiede semplicemente un elenco di versioni di PowerShell che si desidera indirizzare e ti dirà se una sintassi utilizzata nello script non funzionerà in nessuna di queste versioni.,
Le regole di controllo dei comandi e dei tipi sono più sofisticate e si basano sui profili (cataloghi di comandi e tipi disponibili) delle piattaforme PowerShell di uso comune. Essi richiedono la configurazione di utilizzare questi profili, che andremo oltre sotto.
Per questo post, esamineremo la configurazione e l’utilizzo di PSUseCompatibleSyntax e PSUseCompatibleCommands per verificare che uno script funzioni con diverse versioni di PowerShell. Vedremo PSUseCompatibleTypes in un post successivo, anche se è configurato in modo molto simile a Psusecompatibletypes.,
Esempio di lavoro: un piccolo script PowerShell
Immaginate di avere un piccolo (e artificioso) script di archiviazione salvato in.\archiveScript.ps1
:
Questo script è stato scritto in PowerShell 6.2, e abbiamo testato che funziona lì. Ma vogliamo anche eseguirlo su altre macchine, alcune delle quali eseguono PowerShell 5.1 e alcune delle quali eseguono PowerShell 3.0.
Idealmente lo testeremo su quelle altre piattaforme, ma sarebbe bello se potessimo cercare di appianare quanti più bug possibili prima del tempo.,
Controllo della sintassi con PSUseCompatibleSyntax
La prima e più semplice regola da applicare è PSUseCompatibleSyntax. Stiamo andando a creare alcune impostazioni per PSScriptAnalyzer per abilitare la regola, e quindi eseguire l’analisi sul nostro script per ottenere indietro qualsiasi diagnostica sulla compatibilità.
L’esecuzione di PSScriptAnalyzer è semplice., Si presenta come un modulo PowerShell, quindi una volta installato sul percorso del modulo lo invochi semplicemente sul tuo file con Invoke-ScriptAnalyzer
, come questo:
Invoke-ScriptAnalyzer -Path ".\archiveScript.ps1`
Un’invocazione molto semplice come questa eseguirà PSScriptAnalyzer usando le sue regole e configurazioni predefinite sullo script a cui lo punti.
Tuttavia, poiché richiedono una configurazione più mirata, le regole di compatibilità non sono abilitate per impostazione predefinita. Invece, abbiamo bisogno di fornire alcune impostazioni per eseguire la regola di controllo della sintassi., In particolare, PSUseCompatibleSyntax richiede un elenco delle versioni di PowerShell che si stanno prendendo di mira con lo script.
L’esecuzione di questo ci presenterà il seguente output:
Questo ci sta dicendo che la sintassi]::new()
che abbiamo usato non funzionerà in PowerShell 3. Meglio di così, in questo caso la regola ha effettivamente proposto una correzione:
$diagnostics = Invoke-ScriptAnalyzer -Path .\archiveScript.ps1 -Settings $settings$diagnostics.SuggestedCorrections
La correzione suggerita è usare inveceNew-Object
., Il modo in cui questo è suggerito potrebbe sembrare leggermente inutile qui con tutte le informazioni sulla posizione, ma vedremo più avanti perché questo è utile.
Questo esempio di dizionario è un po ‘ artificiale ovviamente (dal momento che un hashtable verrebbe più naturalmente), ma avere una chiave inglese gettata nelle opere in PowerShell 3 o 4 a causa di un::new()
non è raro. La regola PSUseCompatibleSyntax ti avviserà anche delle classi, dei flussi di lavoro e delle istruzioni using
a seconda delle versioni di PowerShell per cui stai creando.,
Non faremo ancora la modifica suggerita, poiché c’è altro da mostrarti prima.
Controllo dell’utilizzo dei comandi con PSUseCompatibleCommands
Ora vogliamo controllare i comandi. Poiché la compatibilità dei comandi è un po ‘ più complicata della sintassi (poiché la disponibilità dei comandi dipende da più di quale versione di PowerShell viene eseguita), dobbiamo invece indirizzare i profili.
I profili sono cataloghi di informazioni tratte da macchine di serie che eseguono ambienti PowerShell comuni., Quelli spediti in PSScriptAnalyzer non possono sempre corrispondere perfettamente al tuo ambiente di lavoro, ma sono abbastanza vicini (c’è anche un modo per generare il tuo profilo, dettagliato in un post sul blog successivo). Nel nostro caso, stiamo cercando di indirizzare PowerShell 3.0, PowerShell 5.1 e PowerShell 6.2 su Windows. Abbiamo i primi due profili, ma nell’ultimo caso avremo bisogno di indirizzare 6.1 invece. Questi obiettivi sono molto vicini, quindi gli avvisi saranno ancora pertinenti all’utilizzo di PowerShell 6.2. Più tardi, quando un profilo 6.2 è reso disponibile, saremo in grado di passare a quello.,
Abbiamo bisogno di guardare sotto la documentazione PSUseCompatibleCommands per un elenco di profili disponibili per impostazione predefinita. Per i nostri obiettivi desiderati scegliamo:
I nomi lunghi sulla destra sono identificatori di profilo canonici, che usiamo nelle impostazioni:
Potrebbe esserci un ritardo la prima volta che lo esegui perché le regole devono caricare i cataloghi in una cache. Ogni catalogo di una piattaforma PowerShell contiene i dettagli di tutti i moduli e .,NET assembly disponibili per PowerShell su quella piattaforma, che può essere fino a 1700 comandi con 15.000 parametri e 100 assembly con 10.000 tipi. Ma una volta caricato, ulteriori analisi di compatibilità saranno veloci. Si ottiene un output simile a questo:
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"
Questo ci dice che:
-
Import-Module
non supporta-FullyQualifiedName
in PowerShell 3.0; -
Get-FileHash
non esiste in PowerShell 3.0; -
Split-Path
non-LeafBase
in PowerShell 5.1 o PowerShell 3.,0; -
Compress-Archive
non è disponibile in PowerShell 3.0, e; -
Out-File
non supporta-NoNewline
in PowerShell 3.0
Una cosa che noterete è che il Get-FoldersToArchive
funzione non viene avvertito. Questo perché le regole di compatibilità sono progettate per ignorare i comandi forniti dall’utente; un comando verrà contrassegnato come incompatibile solo se è presente in un profilo e non in uno dei target.,
Ancora una volta, possiamo cambiare lo script per correggere questi avvisi, ma prima di farlo, voglio mostrarti come rendere questa esperienza più continua; mentre cambi lo script, vuoi sapere se le modifiche apportate interrompono la compatibilità, e questo è facile da fare con i passaggi seguenti.
Utilizzando un file di impostazioni per l’invocazione ripetuta
La prima cosa che vogliamo è rendere l’invocazione PSScriptAnalyzer più automatizzata e riproducibile. Un bel passo verso questo sta prendendo le impostazioni hashtable che abbiamo fatto e trasformandolo in un file di dati dichiarativo, separando il “cosa” dal “come”.,
PSScriptAnalyzer accetterà un percorso per un PSD1 nel parametro-Settings
, quindi tutto ciò che dobbiamo fare è trasformare il nostro hashtable in un file PSD1, che faremo./PSScriptAnalyzerSettings.psd1
. Da notare che si può unire le impostazioni per entrambe le PSUseCompatibleSyntax e PSUseCompatibleCommands:
Ora siamo in grado di eseguire il PSScriptAnalyzer nuovamente lo script utilizzando il file di impostazioni:
Invoke-ScriptAnalyzer -Path ./archiveScript.ps1 -Settings ./PSScriptAnalyzerSettings.psd1
Questo dà l’output:
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
Ora non dipendono da più variabili, e sono separata spefication di analisi che si desidera., Utilizzando questo, è possibile inserirlo in ambienti di integrazione continua, ad esempio per verificare che le modifiche negli script non interrompano la compatibilità.
Ma quello che vogliamo veramente è sapere che gli script di PowerShell rimangono compatibili mentre li modifichi. Questo è ciò che il file delle impostazioni sta costruendo, e anche dove è più facile apportare le modifiche necessarie per rendere il tuo script compatibile. Per questo, vogliamo integrare con l’estensione VSCode PowerShell.,
Integrazione con VSCode per il controllo di compatibilità al volo
Come spiegato all’inizio di questo post, l’estensione VSCode PowerShell ha il supporto incorporato per PSScriptAnalyzer. In effetti, a partire dalla versione 1.12.0, l’estensione PowerShell viene fornita con PSScriptAnalyzer 1.18, il che significa che non è necessario fare altro che creare un file delle impostazioni per eseguire l’analisi della compatibilità.
Abbiamo già il nostro file delle impostazioni pronto per passare dall’ultimo passaggio, quindi tutto ciò che dobbiamo fare è puntare l’estensione PowerShell al file nelle impostazioni VSCode.,
Puoi aprire le impostazioni con Ctrl+, (usa Cmd invece di Ctrl su macOS). Nella vista Impostazioni, vogliamo PowerShell > Script Analysis: Settings Path
. Nella vistasettings.json
questo è"powershell.scriptAnalysis.settingsPath"
., Entrare in un percorso relativo, qui troverete un file di settings nel nostro lavoro, così abbiamo appena messo ./PSScriptAnalyzerSettings.psd1
:
Nel settings.json
visualizza assomiglierà a questo:
"powershell.scriptAnalysis.settingsPath": "./PSScriptAnalyzerSettings.psd1"
Ora, aprendo lo script in VSCode vediamo “verde squigglies” per la compatibilità avvertenze:
i problemi riquadro, si otterrà una completa desrciption di tutti i problemi di incompatibilità:
è possibile risolvere il problema di sintassi prima., Se ricordi, PSScriptAnalyzer fornisce una correzione suggerita a questo problema. VSCode si integra con PSScriptAnalyzer suggerito correzioni e può applicare se si fa clic sulla lampadina o con Ctrl+Spazio in cui la regione è sotto il cursore:
l’Applicazione di tale modifica, lo script è ora:
Le altre incompatibilità non hanno le correzioni; per ora PSUseCompatibleCommands sa quali comandi sono disponibili su ogni piattaforma, ma non è quello di sostituire con se un comando non è disponibile., Quindi abbiamo solo bisogno di applicare alcune conoscenze di PowerShell:
Finiamo con qualcosa di simile (l’implementazione specifica non è importante, ma abbiamo qualcosa che funzionerà in tutte le versioni):
Dovresti notare che mentre digiti, VSCode visualizza una nuova analisi di ciò che stai scrivendo e gli squigglies verdi cadono via. Quando abbiamo finito otteniamo una buona reputazione per la compatibilità degli script:
Questo significa che ora sarai in grado di utilizzare questo script in tutte le versioni di PowerShell che devi indirizzare., Meglio, ora hai una configurazione nel tuo spazio di lavoro in modo che mentre scrivi più script, ci sia un controllo continuo per la compatibilità. E se i tuoi obiettivi di compatibilità cambiano, tutto ciò che devi fare è cambiare il tuo file di configurazione in un unico punto per puntare ai tuoi obiettivi desiderati, a quel punto otterrai l’analisi per le tue piattaforme di destinazione aggiornate.
Sommario
Speriamo che in questo post del blog hai qualche idea delle nuove regole di compatibilità che vengono con PSScriptAnalyzer 1.18.,
Abbiamo spiegato come impostare e utilizzare la regola di controllo della compatibilità della sintassi, PSUseCompatibleSyntax, e la regola di controllo dei comandi, PSUseCompatibleCommands, entrambi utilizzando una configurazione hashtable e un file PSD1 delle impostazioni.
Abbiamo anche esaminato l’utilizzo delle regole di compatibilità con l’estensione PowerShell per VSCode, dove vengono di default dalla versione 1.12.0.
Se hai l’ultima versione dell’estensione PowerShell per VSCode (1.12.1), sarai in grado di impostare il tuo file di configurazione e ottenere immediatamente il controllo della compatibilità.,
Nel prossimo post del blog, vedremo come utilizzare queste regole e PSUseCompatibleTypes (che controlla se i tipi.NET e metodi statici sono disponibili su piattaforme di destinazione) possono essere utilizzati per aiutarti a scrivere script che funzionano multipiattaforma su Windows e Linux usando sia Windows PowerShell che PowerShell Core.la nostra azienda si occupa di: