PowerShell の試験的機能の使用

PowerShell の試験的機能のサポートは、試験的機能を PowerShell または PowerShell モジュールの既存の安定した機能と共存させるためのメカニズムを提供します。

試験的機能は、設計が未完成です。 この機能は、ユーザーがテストしてフィードバックを提供するために使用できます。 試験的機能が完成すると、設計の変更が破壊的変更になります。

注意事項

試験的機能は、変更が破壊的になる可能性があるため、運用環境で使用することは想定されていません。 試験的機能は正式にはサポートされていません。 しかし、フィードバックとバグ レポートは歓迎いたします。 GitHub ソース リポジトリでイシューを送信できます。

これらの機能を有効または無効にする方法の詳細については、「about_Experimental_Features」を参照してください。

利用可能な機能

この記事では、使用可能な試験的機能と、その機能の使用方法について説明します。

凡例

  • ✔️ - PowerShell のバージョンに試験的機能があることを示します
  • ✅ - 試験的機能がメインストリームに組み込まれた PowerShell のバージョンを示します
  • ❌ - 試験的機能が削除された PowerShell のバージョンを示します
名前 7.0 7.1 7.2 7.3
PSNullConditionalOperators ✔️
PSUnixFileStat (Windows 以外) ✔️ ✔️
Microsoft.PowerShell.Utility.PSManageBreakpointsInRunspace ✔️ ✔️
PSCultureInvariantReplaceOperator ✔️
PSNotApplyErrorActionToStderr ✔️
PSImplicitRemotingBatching ✔️ ✔️
PSCommandNotFoundSuggestion ✔️ ✔️ ✔️ ✔️
PSDesiredStateConfiguration.InvokeDscResource ✔️ ✔️ ✔️ ✔️
PSNativePSPathResolution ✔️ ✔️ ✔️
PSSubsystemPluginModel ✔️ ✔️ ✔️
PSNativeCommandArgumentPassing ✔️ ✔️
PSAnsiRenderingFileInfo ✔️ ✔️
PSLoadAssemblyFromNativeCode ✔️ ✔️
PSCleanBlock ✔️
PSExec ✔️
PSNativeCommandErrorActionPreference ✔️
PSStrictModeAssignment ✔️
PSAMSIMethodInvocationLogging ✔️

Microsoft.PowerShell.Utility.PSManageBreakpointsInRunspace

注意

この機能は、PowerShell 7.2 でメインストリームになりました。

PowerShell 7.0 では、この試験的機能によって、Debug-Runspace および Debug-Job コマンドレットの BreakAll パラメーターが有効になり、デバッガーをアタッチするときに PowerShell を現在の場所ですぐに中断するかどうかをユーザーが決定できます。

PowerShell 7.1 では、この試験的機能によって、*-PSBreakpoint コマンドレットに Runspace パラメーターも追加されます。

  • Disable-PSBreakpoint
  • Enable-PSBreakpoint
  • Get-PSBreakpoint
  • Remove-PSBreakpoint
  • Set-PSBreakpoint

Runspace パラメーターによって、Runspace オブジェクトを指定し、指定した実行空間内のブレークポイントと対話できます。

Start-Job -ScriptBlock {
    Set-PSBreakpoint -Command Start-Sleep
    Start-Sleep -Seconds 10
}

$runspace = Get-Runspace -Id 1

$breakpoint = Get-PSBreakPoint -Runspace $runspace

この例では、ジョブが開始され、Set-PSBreakPoint の実行時に中断するようにブレークポイントが設定されます。 実行空間は変数に格納され、Runspace パラメーターを使用して Get-PSBreakPoint コマンドに渡されます。 その後、$breakpoint 変数内のブレークポイントを調べることができます。

PSAMSIMethodInvocationLogging

Windows マルウェア対策スキャン インターフェイス (AMSI) は、アプリケーションのアクションをマルウェア対策スキャナー (Windows Defender など) に渡して、悪意のあるペイロードを検出することができる API です。 PowerShell 5.1 以降、Windows 10 (以降) で実行される PowerShell では、すべてのスクリプト ブロックが AMSI に渡されます。

この実験的な機能によって、検査のために AMSI に送信されるデータが拡張されます。 この機能を有効にすると、PowerShell では .NET メソッド メンバーのすべての呼び出しが追加されます。

この実験は、PowerShell 7.3 で追加されました。

AMSI の詳細については、AMSI が役立つしくみに関する記事を参照してください。

PSAnsiRenderingFileInfo

この実験は、PowerShell 7.2 で追加されました。 この機能により、$PSStyle.FileInfo メンバーが追加され、特定のファイルの種類の色分けが有効になります。

  • $PSStyle.FileInfo.Directory - ディレクトリの色を指定する組み込みメンバー
  • $PSStyle.FileInfo.SymbolicLink - シンボリック リンクの色を指定する組み込みメンバー
  • $PSStyle.FileInfo.Executable - 実行可能ファイルの色を指定する組み込みメンバー
  • $PSStyle.FileInfo.Extension - このメンバーを使用して、さまざまなファイル拡張子の色を定義します。 Extension メンバーには、アーカイブと PowerShell ファイルの拡張機能があらかじめ含まれています。

詳細については、「about_Automatic_Variables」を参照してください。

注意

この機能は、標準機能になった PSAnsiRendering 機能に依存しています。

PSCleanBlock

clean ブロックは、beginprocess、および end ブロックにまたがっているリソースをクリーンアップする場合に便利です。 これは、スクリプト関数またはスクリプト コマンドレットの他のすべての名前付きブロックをカバーする finally ブロックと意味的に似ています。 リソースのクリーンアップは、次のシナリオに適用されます。

  1. エラーを終了せずに、パイプラインの実行が正常に終了するとき
  2. パイプラインの実行がエラーの終了よって中断されたとき
  3. パイプラインが Select-Object -First によって停止されたとき
  4. パイプラインが Ctrl+c または StopProcessing() によって停止されているとき

注意事項

clean ブロックの追加は、破壊的変更です。 clean はキーワードとして解析されるため、ユーザーは clean という名前のコマンドをスクリプト ブロックの最初のステートメントとして直接呼び出すことができなくなります。 ただし、実際にはほとんどの場合これは問題にならず、問題になったとしても、呼び出し演算子 (& clean) を使用してコマンドを依然として呼び出せます。

この試験的な機能について詳しくは、PowerShell/PowerShell-RFC リポジトリの RFC0059 を参照してください。

PSCommandNotFoundSuggestion

CommandNotFoundException 後にあいまい一致検索に基づいて、可能性のあるコマンドを推奨します。

PS> get
get: The term 'get' is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct
and try again.

Suggestion [4,General]: The most similar commands are: set, del, ft, gal, gbp, gc, gci, gcm, gdr,
gcs.

PSCultureInvariantReplaceOperator

-replace 演算子ステートメントの左側のオペランドが文字列でない場合、そのオペランドは文字列に変換されます。

この機能が無効になっている場合、-replace 演算子は、カルチャに依存した文字列変換を行います。 たとえば、カルチャがフランス語 (fr) に設定されている場合、1.2 の値は文字列 1,2 に変換されます。

PS> [cultureinfo]::CurrentCulture = 'fr'
PS> 1.2 -replace ','
12
PS> [cultureinfo]::CurrentCulture = 'en'
PS> 1.2 -replace ','
1.2

機能が有効になっている場合:

PS> [cultureinfo]::CurrentCulture = 'fr'
PS> 1.2 -replace ','
1.2

PSDesiredStateConfiguration.InvokeDscResource

Windows 以外のシステムで MOF へのコンパイルを有効にし、LCM を使用せずに Invoke-DSCResource を使用できるようにします。

PowerShell 7.2 の以前のプレビューでは、この機能は既定で有効でした。 PowerShell 7.2-preview7 以降では、PSDesiredStateConfiguration モジュールが削除され、この機能が既定で無効になっています。 この機能を有効にするには、PowerShell ギャラリーから PSDesiredStateConfiguration v2.0.5 モジュールをインストールし、Enable-ExperimentalFeature を使用してこの機能を有効にする必要があります。

PSExec

一部のネイティブ Unix コマンドでは、何らかの操作 (ssh など) を実行し、bash の組み込みのコマンド exec を使用して、現在のものを置き換える新しいプロセスを生成します。 既定では、exec は、PowerShell の有効なコマンドではありません。 これは、AzCLI の copy-ssh-id や一部のサブコマンドなど、いくつかの既知のスクリプトに影響します。

PSExec の試験的な機能により、新しい Switch-Process コマンドレットが exec の別名として追加されます。 コマンドレットは、POSIX シェルと同様の動作を提供するために execv() 関数を呼び出します。

このコマンドレットを使用できるようにするには、PSExec の試験的な機能を有効にする必要があります。 このコマンドレットは、Windows 以外のシステムでのみ使用できます。

PSImplicitRemotingBatching

注意

この試験的機能は PowerShell 7.2 で削除され、サポートされていません。

この機能は、シェルで入力されたコマンドを検査します。すべてのコマンドが、単純なパイプラインを形成する暗黙のリモート処理プロキシ コマンドである場合は、コマンドがまとめられ、1 つのリモート パイプラインとして呼び出されます。

例:

# Create remote session and import TestIMod module
$s = nsn -host remoteMachine
icm $s { ipmo 'C:\Users\user\Documents\WindowsPowerShell\Modules\TestIMod\TestIMod.psd1' }
Import-PSSession $s -mod testimod

$maxProcs = 1000
$filter = 'pwsh','powershell*','wmi*'

# Without batching, this pipeline takes approximately 12 seconds to run
Measure-Command { Get-AllProcesses -MaxCount $maxProcs | Select-Custom $filter | Group-Stuff $filter }
Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 12
Milliseconds      : 463

# But with the batching experimental feature enabled, it takes approximately 0.20 seconds
Measure-Command { Get-AllProcesses -MaxCount $maxProcs | Select-Custom $filter | Group-Stuff $filter }
Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 209

前述のように、バッチ処理機能を有効にすると、3 つの暗黙的なリモート処理プロキシ コマンド (Get-AllProcessesSelect-CustomGroup-Stuff) がすべてリモート セッションで実行され、パイプラインからの結果がクライアントに返される唯一のデータになります。 これにより、クライアントとリモート セッションの間で送受信されるデータの量が減少し、オブジェクトのシリアル化と逆シリアル化の量も少なくなります。

PSLoadAssemblyFromNativeCode

ネイティブ コードからのアセンブリの読み込みを許可する API を公開します。

PSNativeCommandArgumentPassing

この実験的な機能が有効になっていると、PowerShell は、ネイティブの実行可能ファイルを呼び出すときに、文字列を再構築する現在の機構ではなく、StartProcessInfo オブジェクトの ArgumentList プロパティを使用します。

注意事項

新しい動作は、現在の動作からの 破壊的変更 です。 これにより、ネイティブ アプリケーションを呼び出す際のさまざまな問題に対処するスクリプトと自動化が中断される場合があります。 歴史的に、引用符をエスケープする必要があり、ネイティブ アプリケーションに空の引数を指定することはできません。

この機能によって、実行時に動作を選択できる新しい自動変数 $PSNativeCommandArgumentPassing が追加されます。 有効な値は、LegacyStandardWindows です。 Legacy は過去の動作です。 実験的な機能が有効になっている場合の既定値は、新しい Standard 動作です。

ユーザー設定の変数が Windows に設定されている場合、次のファイルの呼び出しでは、Legacy スタイルの引数渡しが自動的に使用されます。

  • cmd.exe
  • cscript.exe
  • wscript.exe
  • .bat で終わる
  • .cmd で終わる
  • .js で終わる
  • .vbs で終わる
  • .wsf で終わる

$PSNativeArgumentPassingLegacy または Standard のいずれかに設定されている場合、これらのファイルのチェックは行われません。 既定の動作は、プラットフォームに固有です。 Windows プラットフォームの場合、既定の設定は Windows で、Windows 以外のプラットフォームでは Standard です。

この変更によって利用可能になった新しい動作は次のとおりです。

  • リテラルまたは展開可能な文字列に引用符が埋め込まれ、その引用符が保持されるようになりました。

    PS > $a = 'a" "b'
    PS > $PSNativeCommandArgumentPassing = "Legacy"
    PS > testexe -echoargs $a 'a" "b' a" "b
    Arg 0 is <a b>
    Arg 1 is <a b>
    Arg 2 is <a b>
    PS > $PSNativeCommandArgumentPassing = "Standard"
    PS > testexe -echoargs $a 'a" "b' a" "b
    Arg 0 is <a" "b>
    Arg 1 is <a" "b>
    Arg 2 is <a b>
    
  • 空の文字列が引数として保持されるようになりました。

    PS>  $PSNativeCommandArgumentPassing = "Legacy"
    PS> testexe -echoargs '' a b ''
    Arg 0 is <a>
    Arg 1 is <b>
    PS> $PSNativeCommandArgumentPassing = "Standard"
    PS> testexe -echoargs '' a b ''
    Arg 0 is <>
    Arg 1 is <a>
    Arg 2 is <b>
    Arg 3 is <>
    

新しい動作では、次のような呼び出しは変更されません。

PS> $PSNativeCommandArgumentPassing = "Legacy"
PS> testexe -echoargs -k com:port=\\devbox\pipe\debug,pipe,resets=0,reconnect
Arg 0 is <-k>
Arg 1 is <com:port=\\devbox\pipe\debug,pipe,resets=0,reconnect>
PS> $PSNativeCommandArgumentPassing = "Standard"
PS> testexe -echoargs -k com:port=\\devbox\pipe\debug,pipe,resets=0,reconnect
Arg 0 is <-k>
Arg 1 is <com:port=\\devbox\pipe\debug,pipe,resets=0,reconnect>

また、パラメーター トレースが提供され、Trace-Command によってデバッグに役立つ情報が提供されるようになりました。

PS> $PSNativeCommandArgumentPassing = "Legacy"
PS> trace-command -PSHOST -Name ParameterBinding { testexe -echoargs $a 'a" "b' a" "b }
DEBUG: 2021-02-01 17:19:53.6438 ParameterBinding Information: 0 : BIND NAMED native application line args [/Users/james/src/github/forks/jameswtruher/PowerShell-1/test/tools/TestExe/bin/testexe]
DEBUG: 2021-02-01 17:19:53.6440 ParameterBinding Information: 0 :     BIND argument [-echoargs a" "b a" "b "a b"]
DEBUG: 2021-02-01 17:19:53.6522 ParameterBinding Information: 0 : CALLING BeginProcessing
Arg 0 is <a b>
Arg 1 is <a b>
Arg 2 is <a b>
PS> $PSNativeCommandArgumentPassing = "Standard"
PS> trace-command -PSHOST -Name ParameterBinding { testexe -echoargs $a 'a" "b' a" "b }
DEBUG: 2021-02-01 17:20:01.9829 ParameterBinding Information: 0 : BIND NAMED native application line args [/Users/james/src/github/forks/jameswtruher/PowerShell-1/test/tools/TestExe/bin/testexe]
DEBUG: 2021-02-01 17:20:01.9829 ParameterBinding Information: 0 :     BIND cmd line arg [-echoargs] to position [0]
DEBUG: 2021-02-01 17:20:01.9830 ParameterBinding Information: 0 :     BIND cmd line arg [a" "b] to position [1]
DEBUG: 2021-02-01 17:20:01.9830 ParameterBinding Information: 0 :     BIND cmd line arg [a" "b] to position [2]
DEBUG: 2021-02-01 17:20:01.9831 ParameterBinding Information: 0 :     BIND cmd line arg [a b] to position [3]
DEBUG: 2021-02-01 17:20:01.9908 ParameterBinding Information: 0 : CALLING BeginProcessing
Arg 0 is <a" "b>
Arg 1 is <a" "b>
Arg 2 is <a b>

PSNativeCommandErrorActionPreference

ネイティブ コマンドは、通常、呼び出し元のアプリケーションに対して、成功した場合は 0、失敗した場合は 0 以外の終了コードを返します。 ただし、現在のところ、ネイティブ コマンドは、PowerShell エラー ストリームに参加していません。 リダイレクトされた stderr 出力が、PowerShell エラー ストリームと同じように解釈されることはありません。 多くのネイティブ コマンドでは、stderr を、情報または詳細ストリームとして使用するため、終了コードのみが重要となります。 スクリプトでネイティブ コマンドを使用するユーザーは、次の例に似たものを使用して、各呼び出しの後で終了ステータスをチェックする必要があります。

if ($LASTEXITCODE -ne 0) {
    throw "Command failed. See above errors for details"
}

エラー ストリームを通じて単にエラーに依存することは、解決策にはなりません。 この例は、コマンドレットまたは関数のエラーが発生した場合に $? が false となり、$LASTEXITCODE が古いものとなるすべてのケースをサポートしていません。

ネイティブ コマンドによって生成されたエラーを PowerShell エラーとすることができるユーザー設定変数が、この機能によって実装されます。 これにより、ネイティブ コマンド エラーによって、エラー オブジェクトが生成され、余分な処理を行わずにスクリプトの実行を終了させることができる PowerShell エラー ストリームに追加されます。

この機能を有効にするには、次のコマンドを実行します。

Enable-ExperimentalFeature PSNativeCommandErrorActionPreference

この変更を有効にするには、新しい PowerShell セッションを開始する必要があります。 新しいセッションでは、新しいユーザー設定変数を設定する必要があります。

$PSNativeCommandUseErrorActionPreference = $true

PSNativePSPathResolution

FileSystem プロバイダーを使用する PSDrive パスがネイティブ コマンドに渡されると、解決されたファイル パスがネイティブ コマンドに渡されます。 これは、code temp:/test.txt のようなコマンドが期待どおりに動作することを意味します。

また、Windows の ~ で始まるパスは、完全なパスに解決され、ネイティブ コマンドに渡されます。 どちらの場合も、パスは、関連するオペレーティング システムのディレクトリ区切り記号に正規化されます。

  • パスが PSDrive または ~ (Windows) でない場合、パスの正規化は行われません
  • パスが単一引用符で囲まれている場合、そのパスは解決されず、リテラルとして扱われます

PSNotApplyErrorActionToStderr

この試験的機能を有効にすると、ネイティブ コマンドからリダイレクトされるエラー レコード (リダイレクト演算子 (2>&1) を使用する場合のように) が、$Error 変数に書き込まれず、ユーザー設定変数 $ErrorActionPreference はリダイレクトされた出力に影響しません。

多くのネイティブ コマンドでは、追加情報の代替ストリームとして stderr に書き込みが行われます。 この動作により、エラーを探すときに混乱が生じる可能性があります。または、$ErrorActionPreference が出力をミュートする状態に設定されている場合は、ユーザーに対する追加の出力情報が失われる可能性があります。

ネイティブ コマンドの終了コードがゼロ以外の場合、$?$false に設定されます。 終了コードがゼロの場合、$?$true に設定されます。

PSNullConditionalOperators

Null 条件付きメンバー アクセス演算子 (?. および ?[]) 用の新しい演算子が導入されています。 Null メンバー アクセス演算子は、スカラー型および配列型で使用できます。 変数が null でない場合は、アクセスされるメンバーの値を返します。 変数の値が null の場合は、null を返します。

$x = $null
${x}?.propname
${x?}?.propname

${x}?[0]
${x?}?[0]

${x}?.MyMethod()

プロパティ propname にアクセスし、$x が null でない場合にのみ値が返されます。 同様に、インデクサーは $x が null でない場合にのみ使用されます。 $x が null の場合、null が返されます。

?. 演算子と ?[] 演算子はメンバー アクセス演算子であり、変数名と演算子の間にスペースを使用することはできません。

PowerShell では変数名の一部として ? が許可されるため、変数名と演算子の間にスペースを使用せずに演算子を使用する場合はあいまいさを解消する必要があります。 あいまいさを解消するには、変数が ${x?}?.propertyName${y}?[0] などの変数名を囲む {} を使用する必要があります。

注意

この機能は試験段階から移行され、PowerShell 7.1 以降のメインストリーム機能になりました。

PSStrictModeAssignment

PowerShell 7.3-preview.2 では、StrictMode パラメーターを Invoke-Command に追加して、コマンドをローカルで呼び出すときに厳格モードを指定できるようにします。 StrictMode パラメーターは、プロセスの提供されたバージョンを設定します。 プロセスが完了すると、StrictMode のバージョンが Invoke-Command の前のものに戻ります。

この機能は、リモート マシン上の非同期ジョブをサポートしていません。

PSUnixFileStat

この機能では、Unix の stat API のデータを含めることで、Unix に似たファイルの一覧を提供します。 これにより、Unix の stat(2) API からの情報のレンダリングを含む UnixStat という名前のファイル システム プロバイダーに新しいメモ プロパティが追加されます。

Get-ChildItem からの出力は次のようになります。

dir | select -first 4 -skip 5


    Directory: /Users/jimtru/src/github/forks/JamesWTruher/PowerShell-1

UnixMode   User      Group           LastWriteTime        Size Name
--------   ----      -----           -------------        ---- ----
drwxr-xr-x jimtru    staff        10/23/2019 13:16         416 test
drwxr-xr-x jimtru    staff         11/8/2019 10:37         896 tools
-rw-r--r-- jimtru    staff         11/8/2019 10:37      112858 build.psm1
-rw-r--r-- jimtru    staff         11/8/2019 10:37      201297 CHANGELOG.md

注意

この機能は試験段階から移行され、PowerShell 7.1 以降のメインストリーム機能になりました。

PSSubsystemPluginModel

この機能により、PowerShell でサブシステム プラグイン モデルが有効になります。 この機能により、System.Management.Automation.dll のコンポーネントを、独自のアセンブリに存在する個々のサブシステムに分けることができます。 この分割により、コア PowerShell エンジンのディスク占有領域が削減され、これらのコンポーネントを最小限の PowerShell インストールに対するオプション機能にすることができます。

現時点では、CommandPredictor サブシステムのみがサポートされています。 このサブシステムは、カスタム予測プラグインを提供するために、PSReadLine モジュールと共に使用されます。 今後、JobCommandCompleterRemoting などのコンポーネントは、System.Management.Automation.dll 外のサブシステム アセンブリに分割される可能性があります。

この試験的機能には、新しいコマンドレット Get-PSSubsystem が含まれています。 このコマンドレットは、機能が有効になっている場合にのみ使用できます。 このコマンドレットを使用すると、システムで使用可能なサブシステムに関する情報が返されます。