PSScriptAnalyzerを使用してPowerShellバージョンの互換性をチェックする
PSScriptAnalyzerバージョン1.18は最近リリースされ、PowerShellスクリプトに他のPowerShellバージョンや環境との非互換性をチェックできる強力な新しいルールが付属しています。
このブログ記事では、シリーズの最初に、これらの新しいルールを使用して、PowerShell3、5.1、および6で実行されている問題のスクリプトをチェックする方法
待って、PSScriptAnalyzerは何ですか?,
PSScriptAnalzyerは、PowerShellの静的分析(またはリンティング)と動的分析(環境の状態に基づいて)を提供するモジュールです。 C#コンパイラが警告を出し、実行前にC#コードでエラーを見つける方法と同様に、PowerShellスクリプトを作成するときに問題を見つけて悪い習慣を修正するこ,P>
PSScriptAnalyzerをインストールして、独自のスクリプトで使用できます。
Install-Module PSScriptAnalyzer -Scope CurrentUser
div psscriptanalyzerは、スクリプトに対して一連のルールを実行することによって機能し、それぞれが独立していくつかの問題を評価します。, たとえば、AvoidUsingCmdletAliases
はエイリアスがスクリプトで使用されていないことをチェックし、MisleadingBackticks
は行末のバッククリックに空白が続かないことをチェックします。
詳細については、PSScriptAnalyzer deep diveブログシリーズを参照してください。
互換性チェックルールの紹介
新しい互換性チェック機能は、
- PSUseCompatibleSyntaxという三つの新しいルールによって提供されます。,
- PSUseCompatibleCommandsスクリプトで使用されるコマンドが他のPowerShell環境で使用できるかどうかをチェックします。
- PSUseCompatibleTypesは、.NET型と静的メソッド/プロパティが他のPowerShell環境で使用できるかどうかを確認します。
構文チェックルールには、対象とするPowerShellバージョンのリストが必要で、スクリプトで使用される構文がそれらのバージョンのいずれでも機能しないかどうかがわかります。,
コマンドおよびタイプチェックルールはより洗練されており、一般的に使用されるPowerShellプラットフォームのプロファイル(使用可能なコマンドとタイプ これらのプロファイルを使用するには設定が必要です。
この記事では、PSUseCompatibleSyntaxとPSUseCompatibleCommandsを構成して使用して、スクリプトが異なるバージョンのPowerShellで動作することを確認します。 PSUseCompatibleTypesはPSUseCompatibleCommandsと非常によく似ていますが、後の投稿でPSUseCompatibleTypesを見ていきます。,
作業例:小さなPowerShellスクリプト
小さな(そして不自然な)アーカイブスクリプトが.\archiveScript.ps1
:
このスクリプトはPowerShell6.2で書かれており、そこで動作することをテストしました。 そのうちのいくつかはPowerShell5.1を実行し、そのうちのいくつかはPowerShell3.0を実行する他のマシンでも実行したいと考えています。
理想的には、他のプラットフォームでテストしますが、できるだけ多くのバグを事前に解決しようとすることができればいいでしょう。,
PSUseCompatibleSyntaxを使用した構文のチェック
最初に適用する最も簡単なルールはPSUseCompatibleSyntaxです。 PSScriptAnalyzerの設定をいくつか作成してルールを有効にし、スクリプトで分析を実行して互換性に関する診断を取り戻します。
PSScriptAnalyzerの実行は簡単です。, これはPowerShellモジュールとして提供されているので、モジュールパスにインストールされたら、次のようにInvoke-ScriptAnalyzer
でファイルを呼び出すだけです。
Invoke-ScriptAnalyzer -Path ".\archiveScript.ps1`
このような非常に単純な呼び出しでは、PSScriptAnalyzerがポイントするスクリプトのデフォルトのルールと構成を使用してPSScriptAnalyzerを実行します。
ただし、よりターゲットを絞った構成が必要なため、互換性ルールはデフォルトでは有効になっていません。 代わりに、構文チェックルールを実行するための設定を提供する必要があります。, 特に、PSUseCompatibleSyntaxには、スクリプトでターゲットとするPowerShellバージョンのリストが必要です。
これを実行すると、次の出力が表示されます。
これは、]::new()
使用した構文がPowerShell3では機能しないことを示しています。 それよりも良い、この場合、ルールは実際に修正を提案しました:
$diagnostics = Invoke-ScriptAnalyzer -Path .\archiveScript.ps1 -Settings $settings$diagnostics.SuggestedCorrections
推奨される修正は、代わりにNew-Object
を使用することです。, これが提案されている方法は、すべての位置情報でここでは少し役に立たないように見えるかもしれませんが、これがなぜ役に立つのか後で見て
この辞書の例はもちろん(hashtableがより自然に来るので)少し人工的ですが、::new()
のためにPowerShell3または4でスパナをスローすることは珍しいことではありません。 PSUseCompatibleSyntaxルールは、作成するPowerShellのバージョンに応じて、クラス、ワークフロー、およびusing
ステートメントについても警告します。,
提案された変更はまだ行いません。
PSUseCompatibleCommandsでコマンドの使用状況を確認する
ここで、コマンドを確認します。 コマンドの互換性は構文よりも少し複雑なので(コマンドの可用性は実行されているPowerShellのバージョン以上に依存するため)、代わりにプロファイルをターゲットにする必要があります。
プロファイルは、一般的なPowerShell環境を実行している株式マシンから取得した情報のカタログです。, PSScriptAnalyzerに同梱されているものは、作業環境と常に完全に一致するとは限りませんが、かなり近くにあります(後のブログ記事で詳述されている独自のプロファイルを生成する方法もあります)。 この場合、Windows上でPowerShell3.0、PowerShell5.1、およびPowerShell6.2をターゲットにしようとしています。 最初の二つのプロファイルがありますが、最後のケースでは代わりに6.1を対象とする必要があります。 これらのターゲットは非常に近いため、PowerShell6.2の使用に関する警告は引き続き関連します。 後で6.2プロファイルが利用可能になると、それに切り替えることができます。,
デフォルトで利用可能なプロファイルのリストについては、PSUseCompatibleCommandsのドキュメントの下で調べる必要があります。
右側の長い名前は正規のプロファイル識別子であり、これは設定で使用します。
ルールはカタログをキャッシュにロードする必要があるため、初めてこれを実行すると遅延が発生する可能性があります。 PowerShellプラットフォームの各カタログには、すべてのモジュールの詳細と.,これには、1700個のコマンドと15,000個のパラメーター、100個のアセンブリと10,000個のタイプがあります。 しかし、一度ロードされると、さらなる互換性の分析が高速になります。 次のような出力が得られます。
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"
これは次のことを示しています。
-
Import-Module
は-FullyQualifiedName
PowerShell3.0ではサポートしていません。 -
Get-FileHash
PowerShell3.0には存在しません。 -
Split-Path
には-LeafBase
powershell5.1またはpowershell3ではありません。,0; -
Compress-Archive
はPowerShell3.0では使用できません。 -
Out-File
は-NoNewline
PowerShell3.0では
気づくことの一つは、Get-FoldersToArchive
関数はサポートされていません。について警告されている。 これは、互換性ルールがユーザーが提供するコマンドを無視するように設計されているためです。,
再び、我々はこれらの警告を修正するためにスクリプトを変更することができますが、我々は行う前に、私はこれをより継続的な経験にする方法をお見せしたいと思います;あなたのスクリプトを変更すると、あなたが行った変更が互換性を破るかどうかを知りたい、そしてそれは以下の手順で簡単に行うことができます。
繰り返し呼び出しのための設定ファイルの使用
最初に必要なのは、PSScriptAnalyzer呼び出しをより自動化され、再現可能にすることです。 これに向けた良いステップは、私たちが作った設定ハッシュテーブルを取り、それを宣言型データファイルに変えて、”何”と”どのように”を分離することです。,
PSScriptAnalyzerは、-Settings
パラメータでPSD1へのパスを受け入れるので、hashtableをPSD1ファイルに変換して、./PSScriptAnalyzerSettings.psd1
にするだけです。 PsusecompatiblesyntaxとPSUseCompatibleCommandsの両方の設定をマージできることに注意してください。
これで、設定ファイルを使用してスクリプトでPSScriptAnalyzerを再度実行できます。
Invoke-ScriptAnalyzer -Path ./archiveScript.ps1 -Settings ./PSScriptAnalyzerSettings.psd1
これにより、出力が得られます。
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
これで、PSScriptAnalyzerに依存しないようになりました。もうすべての変数、およびあなたが望む分析の別のSpeficationを持っています。, これを使用すると、スクリプトの変更が互換性を損なわないことを確認するなど、これを継続的な統合環境に入れることができます。
しかし、私たちが本当に欲しいのは、PowerShellスクリプトを編集するときに互換性があることを知ることです。 これが設定ファイルのビルド先であり、スクリプトを互換性のあるものにするために必要な変更を行うのが最も簡単な場所でもあります。 そのために、Vscode PowerShell拡張機能と統合したいと考えています。,
オンザフライ互換性チェックのためのVSCodeとの統合
この記事の冒頭で説明したように、VSCode PowerShell extensionはPSScriptAnalyzerを組み込んでサポートしています。 実際、バージョン1.12.0以降、PowerShell拡張機能にはPSScriptAnalyzer1.18が付属しているため、互換性の分析を行うための設定ファイルを作成する以外に何もする必要はあ
最後のステップから設定ファイルを準備する準備ができているので、PowerShell拡張機能をvscode設定のファイルにポイントするだけです。,
Ctrl+で設定を開くことができます(macOSではCtrlの代わりにCmdを使用します)。 設定ビューでは、PowerShell > Script Analysis: Settings Path
が必要です。 settings.json
ビューでは、これは"powershell.scriptAnalysis.settingsPath"
です。, ここに相対パスを入力すると、ワークスペースに設定ファイルが見つかるので、./PSScriptAnalyzerSettings.psd1
:
settings.json
これは次のようになります。
"powershell.scriptAnalysis.settingsPath": "./PSScriptAnalyzerSettings.psd1"
vscodeでスクリプトを開くと、互換性の警告については”緑色の波線”が表示されます。
問題ペインでは、すべての非互換性の完全なdesrciptionが得られます。
まず構文の問題を修正しましょう。, あなたが覚えていれば、PSScriptAnalyzerはこの問題に対する推奨される修正を提供します。 VSCodeはPSScriptAnalyzerの提案された修正と統合され、リージョンがカーソルの下にあるときに電球をクリックしたり、Ctrl+Spaceを押したりすると適用できます。
この変更を適用すると、スクリプトは次のようになります。
他の非互換性には修正がありません。現在のところPSUseCompatibleCommandsは各プラットフォームで使用できるコマンドを知っていますが、どのコマンドを置き換えるかはわかりません。コマンドは使用できません。, したがって、PowerShellの知識を適用するだけです。
このようなものになります(特定の実装は重要ではありませんが、すべてのバージョンで動作するものがあります)。
入力すると、VSCodeはあなたが書いているものの新しい分析を表示し、緑色の波線が消えてしまうことに気づくはずです。 完了すると、スクリプトの互換性のための正常性のクリーンな法案が得られます。
これは、ターゲットに必要なすべてのPowerShellバージョンでこのスクリプトを使用できるようになることを意味します。, より良いことに、ワークスペースに設定があるので、より多くのスクリプトを書くと、互換性のチェックが継続的に行われます。 また、互換性ターゲットが変更された場合は、設定ファイルを一箇所に変更して目的のターゲットを指すように変更するだけで、更新されたターゲットプラットフォームの分析が行われます。
Summary
このブログ記事では、PSScriptAnalyzer1.18に付属する新しい互換性ルールについていくつかのアイデアが得られました。,
ハッシュテーブル構成と設定PSD1ファイルの両方を使用して、構文互換性チェックルールPSUseCompatibleSyntaxとコマンドチェックルールPSUseCompatibleCommandsを設定および使用する方法についてまた、VscodeのPowerShell拡張機能での互換性ルールの使用についても検討しましたが、デフォルトではバージョン1.12.0から提供されています。
Vscode用のPowerShell拡張機能(1.12.1)の最新リリースを入手した場合は、構成ファイルを設定してすぐに互換性チェックを取得できます。,
次のブログ記事では、これらのルールの使用方法と、Windows PowerShellとPowerShell Coreの両方を使用して、WindowsとLinuxの間でクロスプラットフォームで動作するスクリプトを書くのに役立つPSUseCompatibleTypes(.NET型と静的メソッドがターゲットプラットフォームで利用できるかどうかをチェックする)を見ていきます。
ロブ-ホルト
ソフトウェアエンジニア
PowerShellチーム