PowerShell 7.4がリリースされました

2023.11.17

しばたです。

先日の.NET 8の正式リリースを受けPowerShell 7.4がリリースされました。

PowerShell Teamからのアナウンスは以下となります。

リリース種別とサポートサイクル

PowerShell 7.4は基盤にリリースされたばかりの.NET 8を使用しておりサポートサイクルも.NET 8のそれに従います。
本日時点では以下のサポート予定です。

バージョン サポートポリシー EOL
7.4 LTS (Current) 2026年11月15日 (修正あり)
7.3 Stable (non-LTS) 2024年5月8日
7.2 LTS (Previous) 2024年11月8日
7.1 - (non-LTS) サポート切れ
7.0 LTS (Previous) サポート切れ

.NET 8はLTSリリースのためPowerShell 7.4もLTSとなります。
最新のLTSリリースとなるので積極的に移行していくと良いでしょう。  

PowerShell 7.4 の入手方法、更新方法

PowerShell 7.4の入手方法やアップデート方法はPowerShell 7 ~ 7.3の時と基本的に同じです。
GitHubリポジトリおよび各種パッケージマネージャからインストール可能です。
詳細な手順はGitHubにある手順をご覧ください。

対応プラットフォーム

PowerShell 7.4を利用可能なプラットフォームは7.2や7.3の時からほとんど変わっていませんでしたが、RHEL 7系が非対応になりRHEL 8~RHEL 9のみの対応となっています。

プラットフォーム毎の詳細についてはMicrosoftのドキュメントでご確認ください。

PowerShell 7.4 新機能

PowerShell 7.4はPowerShell 7.2からの方針を継続しており、シェルとしての動作を改善することにフォーカスしています。 このため目立った新機能はありませんが前述のPowerShell Team BlogやWhat's Newからいくつか気になるものをピックアップしておきます。

PSResourceGet 1.0

PowerShell本体の話ではないんですが、これがここ最近のPowerShell界隈で一番大きな更新だと思います。

かつてPowerShellGet v3として開発されてきたものがPSResourceGet(モジュール名はMicrosoft.PowerShell.PSResourceGet)と言う形で名を変え先月GAしました。

互換性維持のためPowerShell 7.4.0では

  • PowerShellGet Ver.2.2.5
  • Microsoft.PowerShell.PSResourceGet Ver.1.0.1

の両モジュールが同梱されています。

モジュール名変更の経緯やPSResourceGetの簡単な使い方について過去に記事を書いてますのでこちらもご覧ください。

PSReadLine 2.3

PowerShell 7.4.0に同梱されるPSReadLineのバージョンが2.3に更新されています。

こちらはバグフィックスや安定性向上の改善がメインとなっており、あと、ListView形式での表示が少し改善されています。

試験的な機能からの昇格

いくつかの試験的な機能がPowerShell 7.4で本機能に昇格しています。

PSConstrainedAuditLogging

PowerShell 7.4はWindows Defenderアプリケーション制御(WDAC)に対応し、モードに応じて監査ログを出力する様になったそうです。
「そもそもこんな機能あったっけ?」と思ったのですが割と最近追加されたものでした。

PSCustomTableHeaderLabelDecoration

まずはこの機能を説明する前に必要なPowerShellの基本について解説します。

PowerShellは.NETのオブジェクトを扱うシェルであり、コマンドを実行すると.NETのオブジェクトが独自のストリームを流れます。
そのオブジェクトは最終的に決められたフォーマットに従ってコンソールに表示される仕組みとなっています。

このため実オブジェクトのプロパティ名と画面に表示される名称が異なることがあり特にテーブル形式で表示するときに顕著です。
たとえば下図の様にGet-Processした場合、CPU使用率はプロパティ名としてはCPUなのですが、テーブル形式で表示される時のヘッダはCPU(s)となっています。

この様な実プロパティと表示名が異なるものに独自のスタイル(デフォルトではイタリック指定)を適用するのが本機能となります。

(NPM(K), PM(M), WS(M), CPU(s)がイタリックになっているのが見て取れる)

このスタイルの制御は$PSStyle.Formatting.CustomTableHeaderLabelで可能です。

PSWindowsNativeCommandArgPassing

こちらはPowerShell 7.3で正式機能になったPSNativeCommandArgumentPassingのデフォルト設定を変えるものです。

PowerShell 7.4からはデフォルトが以下の様になる...というのがドキュメント上の記述ですが、実際にはPowerShell 7.3の時点で既に変更されています。

# Windows環境の場合
$PSNativeCommandArgumentPassing = 'Windows' # PowerShell 7.2時点は Legacy がデフォルトだった

# 非Windows環境の場合
$PSNativeCommandArgumentPassing = 'Standard' # こちらは変更なし

PSNativeCommandErrorActionPreference

こちらはPowerShell 7.3リリース時に解説した試験的な機能が昇格した形になります。

新たに$PSNativeCommandUseErrorActionPreferenceという変数が増え、この値を$trueにするとネイティブコマンドが0以外の戻り値で終了した場合に例外となります。
$PSNativeCommandUseErrorActionPreferenceの値は試験的な機能だった時はデフォルト$trueでしたが、互換性維持のため本機能に昇格する際にデフォルト$falseに変更されています。

PSNativeCommandPreserveBytePipe

PSCustomTableHeaderLabelDecorationの節で説明した様にPowerShellは.NETのオブジェクトがストリームを流れる仕組みとなっています。
このためPowerShell 1.0リリース当初からパイプやリダイレクトでバイナリデータを扱うのを不得手としていました。
(意図せずバイナリデータをStringとして扱ってしまう)

PowerShell 7.4からはこの挙動が改善され、ネイティブコマンドがパイプやリダイレクトを扱う際にバイナリデータを適切に扱う様になります。

# PowerShell 7.3までは以下の様なリダイレクトやパイプラインを使うコマンドが意図した動作にならない
# PowerShell 7.4から期待通りに動作する

$uri = 'https://github.com/PowerShell/PowerShell/releases/download/v7.3.4/powershell-7.3.4-linux-arm64.tar.gz'
# バイナリデータをリダイレクトする場合
curl.exe -s -L $uri > powershell.tar.gz
# バイナリデータをパイプする場合
curl.exe -s -L $uri | tar.exe -xzvf - -C .

これはほんとうに長い間利用者からの不満が多かった点なので「遂に改善された!」というお気持ちです。

破壊的変更

What's newにある破壊的変更を軽く解説します。

  • 共通パラメーターに-ProgressActionを追加
    • 他のAction系パラメーターはあれど進捗ダイアログの制御をするものだけ無かったため追加 (詳細)
    • このパラメーターにより$ProgressPreferenceの設定をコマンドレット個別で可能に
  • 幾つかのAPIの例外でArgumentExceptionの代わりにArgumentNullExceptionを吐く様に変更 (#19215)
    • ArgumentExceptionが来ることを期待するコードがある場合は注意が必要
  • #requires -pssnapinに関するコードを削除
    • もともとPowerShell 6からスナップインは非対応
    • コード削除によりエラーの挙動が変わる模様
  • Test-Jsonコマンドが内部でJson.Schema.Netを使う様に変更
    • もともとは内部でNewtonsoft.Json.Schemaを使っていた
    • この変更によりJSON Schema Draft 4以前は非サポートに
  • Test-Connection-TCPPortを指定した際の出力をより詳細に
    • どうやら#11452の変更の様だが、このプルリクでは最終的に-Detailedパラメーターを指定すると詳細情報を表示する様になっている
    • 専用の-Detailedパラメーターが増えているので破壊的変更では無い気がする...

しれっと書かれてますが-ProgressActionパラメーターはめちゃくちゃ嬉しいやつです!
以前から言われている進捗ダイアログを出すと性能劣化する件に対して、これまではグローバルに$ProgressPreferenceを設定するしかできなかったのがコマンド単位で制御できることになります。

# 進捗ダイアログを非表示にしたい場合、従来は $ProgressPreference をグローバルに変えるしかなかった
$currentProgressPreference = $ProgressPreference
try {
    $ProgressPreference = 'SilentlyContinue'
    Invoke-WebRequest -Uri https://github.com/PowerShell/PowerShell/releases/download/v7.4.0/PowerShell-7.4.0-win-x64.msi -OutFile .\PowerShell.msi
} finally {
    $ProgressPreference = $currentProgressPreference
}

# PowerShell 7.4 からはこういう書き方ができる様に
Invoke-WebRequest -Uri https://github.com/PowerShell/PowerShell/releases/download/v7.4.0/PowerShell-7.4.0-win-x64.msi -OutFile .\PowerShell.msi -ProgressAction SilentlyContinue

Windows PowerShellにもバックポートして欲しいです。

Web Cmdletの改善

What's newにあるWeb Cmdletの改善からいくつか気になったものをピックアップします。

  • デフォルトのcharsetがiso-8859-1からUTF-8に変更 (#18219)
    • 昨今の情勢を鑑みての変更でしょう
    • 個人的には破壊的変更に入るのでは?という気がしている...
  • HTTPヘッダで指定されたContent-Typeを考慮する様に修正
    • 従来は-ContentTypeパラメーターの指定のみ考慮されていた
  • リダイレクト先に対しても元のHTTPメソッドを呼び出すための-PreserveHttpMethodOnRedirectパラメーターを追加
    • リダイレクト先に対してもPOSTしたい時向け
  • HTTPSからHTTPへのリダイレクトの場合は明示的にエラーとする様に変更
    • 従来は無反応のまま処理が失敗していた
  • HTTPSからHTTPへのリダイレクトを許可するための-AllowInsecureRedirectパラメーターを追加
  • -TimeoutSecパラメーターを-ConnectionTimeoutSecondsに改名し、新たに-OperationTimeoutSecondsパラメーターを追加 (#19558)
    • 雑に言うとリクエストのタイムアウトが-ConnectionTimeoutSeconds、レスポンスのタイムアウトが-OperationTimeoutSeconds
    • 互換性維持のため-TimeoutSecパラメーターはそのまま残っている
  • レスポンスデータの受信中にCtrl+Cによるキャンセルを可能に (#19330)

その他Cmdletの改善

What's newにあるその他Cmdletの改善からいくつか気になったものをピックアップします。

  • ConvertTo-CsvExport-Csvコマンドに-NoHeaderパラメーターを追加
    • ヘッダ無しCSVファイルをより簡単に作れる様に
  • Get-Command-FuzzyMinimumDistanceパラメーターを追加
    • -UseFuzzyMatchingパラメーターを使った際の結果のフィルターに使用可能 (出力対象とする最小のレーベンシュタイン距離を指定)
    • デフォルト値は5
  • 各種コマンドの-Encodingパラメーター指定にANSIを指定可能に更新
    • -Encoding [CultureInfo]::CurrentCulture.TextInfo.ANSICodePage指定と等価
  • Copy-Itemコマンドで進捗状況が表示可能に (#18735)
    • 進捗状況を表示したくない場合は-ProgressActionパラメーターを指定する
  • Select-Objectコマンドで-Skipパラメーターと-SkipLastパラメーターが併用可能に
  • Get-SecureRandomコマンドを追加 (#19587)
    • 内部的にはGet-Randomとコードを共用しており、-SetSeedパラメーターの無いバージョンと考えて問題ない
    • Get-Randomでシードを指定した場合の挙動が「暗号としてセキュア」であると誤解されうることからコマンドを分けた模様
  • Set-Clipboard-AsOSC52パラメーターを追加 (#18222)
  • Select-ObjectGet-Uniqueコマンドに-CaseInsensitiveパラメーターを追加

エンジンの改善

What's newにあるエンジンの改善からいくつか気になったものをピックアップします。

  • リモート接続時も$PSStyle.OutputRenderingの内容を反映する様に改善
  • ValidateNotNullOrWhiteSpace属性を追加 (#17191)
    • 従来からあるのはValidateNotNullOrEmpty属性
  • 引数の扱いで互換性を維持するプログラムにgcloud, sqlcmd, wscriptを追加
    • これらのプログラムは$PSNativeCommandArgumentPassingの設定に依らず従来の挙動(Legacy)となる
  • cd~関数を追加 (#18308)
    • 内容としてはSet-Location ~してるだけ

最後に

以上となります。

地味ではあるものの大きな変更が入っておりけっこう驚いています。
PowerShell使いにとって嬉しい更新が多く、かつ、これはLTSリリースです。
良い機会ですのでぜひ最新のPowerShell 7.4を使ってみてください。