PowerShell 7.1開発の多くはモジュールで進む

先日、PowerShell 7.1へ向けた3つ目のプレビュー版が公開された。このバージョンから.NET 5のプレビューリリースと連動してリリースが行われるようになった。PowerShellは.NETに強く依存している。.NET 5のプレビューに合わせてPowerShell 7.1のプレビューをリリースしていくというのは自然な流れだ。ようやく自然な状態のリリースエンジニアリングが行われるようになったとも言えるだろう。

PowerShell 7.1 Preview 3の主な変更点は一時的に利用するディレクトリを配置する「temp: PSDrive」が導入された点と、こうした仮想ドライブがネイティブコマンドでも動作するようになった点にある。実験的な機能なので試すには手動で機能を有効化する必要があるが、この機能が動作すると「notepad temp:/test.ps1」とか「vim temp:/test.ps1」といったコマンドも利用できるようになる。

また、ホームディレクトリを意味する「~」も同じようにネイティブコマンドに対して利用できるようになった。つまり、「notepad ~\Documents\typescript.xml」といったコマンドが動作するということである。仮想ドライブと「~」がネイティブコマンドに対して利用できるようになったのは、PowerShell 7.1がネイティブコマンドに引数を与える前にパス展開を行うようになったためだ。

しかし、プレビュー版としてリリースされたにもかかわらず、この変更は小粒だ。実はPowerShell 7.1の開発はPowerShell 7.1本体よりも、外部モジュールに対して行われている。外部モジュールで行われている開発はまだ本体にはマージされていない(または同梱されていない)のだ。今回はそうした機能の1つとして「PSScriptAnalyzer」を取り上げる。

PSScriptAnalyzer


PSScriptAnalyzerはPowerShellモジュールおよびPowerShellスクリプト向けの静的コードチェッカー。一連のルールに従ってモジュールやスクリプトの評価を行い、品質のチェックに使用することができる。このモジュールを使用することで、バグや問題を生み出す潜在的なコードの欠陥を見つけられるとされている。

例えばPSScriptAnalyzerには、初期化されていない変数のチェック、PSCredentialタイプの使用、Invoke-Expressionの使用など、PowerShellのコードをさまざまな側面からチェックするためのルールコレクションが用意されている。特定のルールを除外したり、逆に追加したりすることも可能になっており、必要に応じてチェックルールを変更することもできる。

PSScriptAnalyzerは最近、最新版となる「PSScriptAnalyzer version 1.19.0」が公開された。このリリースでは書式設定が大幅に改善されたほか、新しいスクリプト分析ルールの追加が行われた。一見、マイナーバージョンリリースのように見えるが、今回のバージョンは結構重要なリリースとなっている。

1つ前のリリースとなる「PSScriptAnalyzer version 1.18.3」が公開されたのは、2019年9月17日(米国時間)だ。その際も、ちょっとした内容の変更だけで、実質的に新規リリースにはなっていない。過去リリースされたバージョンのうち、直近で機能追加を伴う大きなリリースだったのは2019年3月23日(米国時間)に公開された「PSScriptAnalyzer version 1.18.0」となる。つまり、今回のリリースは実質的に1年2カ月ぶりのリリースに当たる。

今回のリリースでは、新たに次の5つのルールが追加されている。全てユーザーからのコントリビュートだ。

  • UseUsingScopeModifierInNewRunspaces
  • ReviewUnusedParameter
  • AvoidOverwritingBuiltInCmdlets
  • UseProcessBlockForPipelineCommand
  • AvoidLongLines


これ以外にもルール強化としてPSAvoidAssignmentToAutomaticVariables自動変数の追加や、次のような互換性向上も取り込まれている。

  • CompatibilityCollectorをシングルバージョンStringもパースできるように変更
  • 互換プロファイルをPowerShell 7対応へ更新
  • Ps7シンタックス追加
  • Ps3シンタックスチェックを修正
  • UseCompatibleSyntaxにPS7を追加
  • UseCompatibleSyntax設定ドキュメントを修正
  • UseCompatibleTypesをアップデート
  • UseCompatibleCommandsドキュメントを更新
  • AzFプロファイルを使いやすいようにアップデート


次の3つのフォーマッターに関しても修正やアップデートが行われている。

  • UseCorrectCasing
  • UseConsistentIndentation
  • UseConsistentWhitespace


さらに今回のバージョンで特に注目なのはFormatterのパフォーマンスが改善されている点にある。ユースケースによるのだが、数倍の高速化が実現されている。数千行規模のスクリプトを分析する場合には、この高速化が威力を発揮するだろう。今回実現された主な高速化ポイントは次の通りだ。

  • 初期化オーバーヘッドの解除で最大50%の時間短縮
  • ルールオペレーションの最適化によるスケーリングの改善で約50%の高速化
  • 正規表現のオーバヘッド削除でAvoidTrailingWhitespaceを2.5%高速化
  • UseConsistentIndentationの改善で10%~35%の高速化
  • TokenOperationsコンストラクタのLinkedListの遅延初期化適用で7%の高速化
  • Invoke-Formatterにおける50%のパフォーマンス向上


この新しいPSScriptAnalyzerを試すには、このバージョンのモジュールをインストールする必要がある。現在開発段階にあるPowerShellGet 3.0を使っているなら、次のようにInstall-PSResourceコマンドレットを使ってインストールを実施する。

Install-PSResource PSScriptAnalyzer

PSScriptAnalyzerのインストール例

静的アナライザという特性からわかるように、PSScriptAnalyzerはPowerShellで使用するというよりも、Visual Studio Codeのような統合開発環境で利用することが想定されている。開発チームは今後の開発フォーカスを「Visual Studio Codeにおけるパフォーマンス向上」としており、Visual Studio Codeでのコーディングに焦点を当てていることがわかる。

例えば、次のスクリーンショットはViual Studio CodeでMicrosoftが開発しているPowerShell拡張機能を使っている場面だが、この状態で「Alt」+「F8」を押すとPSScriptAnalyzerが動作して分析結果が表示される。

「Alt」+「F8」を押して分析結果を表示させる

「Alt」+「F8」を押すと、次のように分析結果が表示されている。この例では、スクリプトに書いた「dir」というコマンドレットが実際には「Get-ChildItem」へのエイリアスであり、エイリアスはスクリプトでは問題になるので変更したほうがよい、といったアドバイスが表示されている。

スクリプトではエイリアスは使わないほうがよいというアドバイスが表示されている

この状態で「Ctrl」+「.」を押すと、PSScriptAnalyzerによる解決案がいくつか表示される。今回のケースでは、「Get-ChildItem」へ置き換えるという提案が適切だ。

解決方法も提案されており、選択すればその解決方法が適用される

解決方法を選択した後は、次のように自動的にスクリプトが書き換わる。

PSScriptAnalyzerによる解決方法の適用後

このようにPSScriptAnalyzerはPowerShellスクリプトの開発においてとても重要な役割を果たしてくれる。とりあえずPSScriptAnalyzerの提案する修正に従っておけば、それなりに問題の出にくいソースコードになるというわけだ。

そして使っていけばわかるのだが、PSScriptAnalyzerは常に動作して問題を探すため、スクリプトのサイズが大きくなるにつれて動作がもっさりしてくる。そもそも、PowerShell自体がそれほどパフォーマンスが発揮できるタイプのスクリプトではないので当然なのだが、使っていくうちに高速化してほしいという思いが募るのだ。

現在のPowerShell開発チームはこの点をよく認識しており、Visual Studio Codeでの開発がより快適になるようにPSScriptAnalyzerの開発に取り組んでいる。1年以上ほとんどリリースがないような状態だったので、今後活発に開発が行われていく見通しなのは嬉しいところだ。これからどこまでパフォーマンスが引き上げられていくのか、注目したい。