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

2022.11.12

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

しばたです。

先日の.NET 7の正式リリースと足並みを揃える形でPowerShell 7.3がリリースされました。

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

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

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

バージョン サポートポリシー EOL
7.3 Non LTS 2024年5月8日 (予定)
7.2 LTS (Current) 2024年11月8日
7.1 Non LTS サポート切れ
7.0 LTS 2022年12月3日
6.x Non LTS サポート切れ

単純なサポート期間だけ見るとCurrent LTSであるPowerShell 7.2の方が少し長いのでサポート期間を重視する場合はご注意ください。

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

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

なお、Microsoft Store版をインストールしている場合は自動更新されますが、MSI版をインストールしMicrosoft Updateによる自動更新を選んでいる場合は自動更新されないとのことです。(おそらくLTSリリース内での自動更新がされると予想)
必要に応じて適宜手動で更新してください。

対応プラットフォーム

ちょっとまだドキュメントが更新されておらずPreview版時点の情報しかないもののPowerShell 7.2と同じプラットフォームで利用可能となっています。
具体的には以下のドキュメントを参照してください。

PowerShell 7.3 新機能

PowerShell 7.2から7.3への更新に際しPowerShell Teamとしてはシェルとしての動作を改善することにフォーカスした模様です。
私がGitHubのIssueを追う限りでもその傾向は有り、特に非Windows環境における動作改善に注力していた様に感じられました。

ここから主要な改善点について触れていきます。

起動時バナー

新機能とはちょっと違うものの、いちばんわかりやすい変化として起動時のバナーが簡素化されました。

こちらのIssueを発端に多くの議論を経てバージョン番号の表示のみとなりました。

PSNativeCommandArgumentPassing

PowerShell 7.2で試験的な機能だったPSNativeCommandArgumentPassingが正式にリリースされました。

この設定は$PSNativeCommandArgumentPassingグローバル変数で定義され、Windows環境であれば従来の動作と部分的に互換を持つWindowsに、非Windows環境では新しい動作となるStandardに初期設定されています。

ざっくり新しい挙動を説明すると、

  • 引数のリテラル内に引用符(")がある場合その値を保持する
    • 例 : 'a" "b'といった引数から"が消え去らなくなった
  • 空文字列を引数として渡せる様になっている
    • 例 : '' a b ''といった文字列を渡した場合に4引数(空文字列,a,b,空文字列)になる
  • PowerShellデバッグ用のトレース情報に個別の引数が表示される様になった

となります。より細かい挙動の違いは上記ドキュメントで確認してください。
そして、Windows環境の既定値である$PSNativeCommandArgumentPassing = Windowsでは

  • 以下の条件に該当する場合は従来の挙動(Legacy)のまま
    • cmd.exefind.execscript.exewscript.exeを呼び出す
    • 拡張子 .bat.cmd.js.vbs.wsfを呼び出す
  • 上記に該当しない場合は新しい挙動(Standard)を選択

という挙動になります。

Cleanブロック

おそらくこれが一番分かりやすい新機能だと思います。
以前に試験的な機能として導入されていたものがPowerShell 7.3で本機能に昇格しています。

PSExec

こちらは非Windows環境用の試験的な機能が本機能に昇格しています。

Unix系シェルにおけるexecに相当するSwitch-Processコマンドが追加されexecエイリアスも増えました。
コマンドレット内部でexecvシステムコールを呼び出します。

プレビュー版の時に少し試した限りではあまり期待した動作にならなかったのですが...こちらのIssueを見る限りでは次のリリースを待った方が良さそうに見えます。

次のリリースからはexecvシステムコールではなく環境変数を引き継ぐことのできるexecveシステムコールを呼び出す様になります。

PSReadLine 2.2.6

同梱されるPSReadLineのバージョンがVer.2.2.6に更新されており、デフォルトで入力補完の予測補完が有効になりました。

その他

その他の細かい機能変更については以下のドキュメントに記載されてますのでご覧ください。

本記事では個人的に気になった点をいくつかピックアップしておきます。

Web CmdletsでHTTPバージョンの指定が可能に

Invoke-WebRequestInvoke-RestMethodでHTTPのバージョンを指定する-HttpVersionパラメーターが追加されました。
このパラメーターでは1.0,1.1,2.0,3.0のバージョンを指定可能となります。
従来の挙動に合わせて1.1がデフォルト値です。

PS C:\> Invoke-RestMethod -Uri 'https://checkip.amazonaws.com' -Verbose
VERBOSE: HTTP/1.1 GET with 0-byte payload
VERBOSE: received 13-byte response of content type
VERBOSE: Content encoding: iso-8859-1
xx.xx.xx.xx

PS C:\> Invoke-RestMethod -Uri 'https://checkip.amazonaws.com' -HttpVersion 2.0 -Verbose
VERBOSE: HTTP/2.0 GET with 0-byte payload
VERBOSE: received 13-byte response of content type
VERBOSE: Content encoding: iso-8859-1
xx.xx.xx.xx

ConvertFrom-Json -AsHashtableの結果が[ordered]なハッシュテーブルに

従来ConvertFrom-Json -AsHashtableの結果返されるハッシュテーブルは通常のもの(Hashtable型)で順序不定でしたが、PowerShell 7.3からは[ordered]なハッシュテーブル(OrderedDictionary型)になります。

# PowerShell 7.2まで : 順序不定
C:\> '{ "a": 0, "b": 1, "c": 2 }' | ConvertFrom-Json -AsHashtable

Name                           Value
----                           -----
b                              1
c                              2
a                              0

# PowerShell 7.3から : 指定順を維持
C:\> '{ "a": 0, "b": 1, "c": 2 }' | ConvertFrom-Json -AsHashtable

Name                           Value
----                           -----
a                              0
b                              1
c                              2

[ordered]型アクセラレーターが追加されました

ハッシュテーブルにつける[ordered]は一見キャストの様に見えますがあくまで特別な属性であり、[ordered]という型があるわけではありませんでした。

PowerShell 7.3では[ordered] → [System.Collections.Specialized.OrderedDictionary]となる型アクセラレーターが追加され[ordered]を型として扱える様になりました。

# PowerShell 7.2まで : [ordered]は型ではない
C:\> [ordered]
InvalidOperation: Unable to find type [ordered].

# PowerShell 7.3から : [ordered]が型アクセラレーターに
C:\> [ordered]

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     OrderedDictionary                        System.Object

# これにより以下の様な比較が出来る様になった
C:\> [ordered]@{a=1} -is [ordered]
True

C:\> @{a=1} -is [ordered]
False

pwshの引数に -NoProfileLoadTime が増えました

PowerShellの起動時に表示される *1プロファイルのロード時間を非表示にする引数-NoProfileLoadTimeが増えました。

# -NoProfileLoadTime を付けてPowerShellを起動する
pwsh -NoProfileLoadTime

試験的な機能

PowerShell Team Blogではさも本機能の様に語られていますが、$PSNativeCommandUseErrorActionPreference変数を使ったネイティブコマンドのエラーハンドリングの改善は試験的な機能としての提供です。

# はじめに試験的な機能を有効にする必要がある
Enable-ExperimentalFeature -Name PSNativeCommandErrorActionPreference

# その上で $PSNativeCommandUseErrorActionPreference に trueを設定
$PSNativeCommandUseErrorActionPreference = $true

試験的な機能を有効にするとネイティブコマンドが0以外の戻り値で終了した場合に例外が発生する様になります。

# 戻り値 1 を返すテスト用アプリケーションを実行
# $PSNativeCommandUseErrorActionPreference = $true の場合例外となる
PS C:\sample> .\TestApp.exe
exit 1
NativeCommandExitException: Program "TestApp.exe" ended with non-zero exit code: 1.

PS C:\sample> $LASTEXITCODE
1

また、PowerShell 7.3で試験的な機能から本機能に昇格したものは以下となります。

  • (解説済み) PSNativeCommandArgumentPassing
  • (解説済み) PSCleanBlock
  • (解説済み) PSExec
  • PSAMSIMethodInvocationLogging
    • PowerShell内部のメソッド実行履歴をAMSIと連携する...らしい
  • PSAnsiRenderingFileInfo
    • ファイル種別ごと(Directory,SymbolicLink,Executable,Extension)で表示の色分けをする
  • PSRemotingSSHTransportErrorHandling
    • PowerShell Remoting for SSHで通信している際にstderr出力された場合にエラー扱いにしない

最後に

以上となります。

PowerShell 7.2のリリース時と比べるとドキュメント周りの整備が全然追いついておらず現時点で正しい仕様を追うのに非常に苦労しました。
この点はいずれ改善されると信じていますが安定を重視する方はLTSリリースであるPowerShell 7.2系でしばらく様子を見たほうが良いかもしれません。

脚注

  1. 正確にはプロファイルのロードに500ミリ秒以上かかった場合に表示される