概要
#Require
ステートメントにバージョンやモジュールなどを指定することで、スクリプトの実行要件を満たさない環境での実行を制限することができます。
テスト用スクリプト作成
適当に PowerShell スクリプトを作成します。
Write-Output -InputObject "Hello World!"
> .\TestScript.ps1
Hello World!
Requires Version
スクリプトの実行に必要なミニマムのバージョンを指定します。
#Requires -Version 5.1
Write-Output -InputObject "Hello World!"
PowerShell 5.1 で実行してみます。問題なく実行できますね。
> .\TestScript.ps1
Hello World!
PowerShell 7.1 でも実行してみます。ミニマムバージョンを指定しているので PowerShell 7.1 でも問題ありません。
> .\TestScript.ps1
Hello World!
必要なバージョンを 7.1 にあげてみましょう。
#Requires -Version 7.1
Write-Output -InputObject "Hello World!"
Powershell 5.1 で実行するとバージョンが合ってないので怒られます。
> .\TestScript.ps1
.\TestScript.ps1 : スクリプト 'TestScript.ps1' を実行できません。このスクリプトには Windows PowerShell 7.1 用の "#requires" ステートメントがありますが、このスクリプトで必要な Windows PowerShell のバージョンが、現在実行されている Windows PowerShell のバージョン 5.1.19041.1023 と一致しません。
発生場所 行:1 文字:1
+ .\TestScript.ps1
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (TestScript.ps1:String) [], ScriptRequiresException
+ FullyQualifiedErrorId : ScriptRequiresUnmatchedPSVersion
PowerShell 7.1 だと問題なく実行できます。
> .\TestScript.ps1
Hello World!
Requires PsEdition
Windows PowerShell(PowerShell 5.1 以前)か PowerShell Core(PowerShell 6.0 以降)を指定します。設定値は Windows PowerShell の場合は Desktop
、PowerShell Core の場合は Core
です。
Desktop
を指定してみます。
#Requires -PsEdition Desktop
Write-Output -InputObject "Hello World!"
PowerShell 5.1 では問題なく実行できます。
> .\TestScript.ps1
Hello World!
PowerShell 7.1 で実行するとエディションが違うと言って怒られます。
> .\TestScript.ps1
.\TestScript.ps1: The script 'TestScript.ps1' cannot be run because it contained a "#requires" statement for PowerShell editions 'Desktop'. The edition of PowerShell that is required by the script does not match the currently running PowerShell Core edition.
Core
を指定してみます。
#Requires -PsEdition Core
Write-Output -InputObject "Hello World!"
PowerShell 5.1 で実行するとエディションが違うと言って怒られます。
> .\TestScript.ps1
.\TestScript.ps1 : スクリプト 'TestScript.ps1' を実行できません。このスクリプトには PowerShell エディション 'Core' 用の "#requires" ステートメントがありますが、このスクリプトで必要な PowerShell のエディションが、現在実行されている PowerShell の Desktop エディションと一致しません。
発生場所 行:1 文字:1
+ .\TestScript.ps1
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (TestScript.ps1:String) [], RuntimeException
+ FullyQualifiedErrorId : ScriptRequiresUnmatchedPSEdition
PowerShell 7.1 だと問題なく実行できます。
> .\TestScript.ps1
Hello World!
Require RunAsAdministrator
管理者権限でないと実行できないようにします。
#Requires -RunAsAdministrator
Write-Output -InputObject "Hello World!"
一般ユーザー権限で実行すると PowerShell 5.1/7.1 ともに失敗します。
> .\TestScript.ps1
.\TestScript.ps1 : スクリプト 'TestScript.ps1' を実行できません。このスクリプトには管理者として実行する "#requires" ステートメントが含まれています。現在の Windows PowerShell セッションは管理者として実行されていません。[管理者として実行]オプションを使用して Windows PowerShell を起動し、スクリプトを再度実行してください。
発生場所 行:1 文字:1
+ .\TestScript.ps1
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (TestScript.ps1:String) [], ScriptRequiresException
+ FullyQualifiedErrorId : ScriptRequiresElevation
> .\TestScript.ps1
.\TestScript.ps1: The script 'TestScript.ps1' cannot be run because it contains a "#requires" statement for running as Administrator. The current PowerShell session is not running as Administrator. Start PowerShell by using the Run as Administrator option, and then try running the script again.
管理者権限だとどちらも問題なく実行できます。
> .\TestScript.ps1
Hello World!
> .\TestScript.ps1
Hello World!
Requires Modules
モジュールを指定します。必要なモジュールがない場合、スクリプトの実行に失敗します。PowerShell 5.1/7.1 ともに Az
モジュールインストール済みの環境で実行してみます。
#Requires -Modules Az.Accounts
Write-Output -InputObject "Hello World!"
PowerShell 5.1/7.1 ともに実行できました。実行時に Requires に指定されたモジュールが自動的にインポートされます。
> Get-Module -Name Az.Accounts
> .\TestScript.ps1
Hello World!
> Get-Module -Name Az.Accounts
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 2.5.1 Az.Accounts {Add-AzEnvironment, Clear-AzContext, Clear-AzDefault, Conn...
> Get-Module -Name Az.Accounts
> .\TestScript.ps1
Hello World!
> Get-Module -Name Az.Accounts
ModuleType Version PreRelease Name ExportedCommands
---------- ------- ---------- ---- ----------------
Script 2.5.1 Az.Accounts {Add-AzEnvironment, Clear-AzContext, Clear-AzDefa…
インストールされていないモジュールを指定してみましょう。
#Requires -Modules AzureAd
Write-Output -InputObject "Hello World!"
そんなモジュールないよ!って怒られます。
> .\TestScript.ps1
.\TestScript.ps1 : スクリプト 'TestScript.ps1' を実行できません。このスクリプトの #requires ステートメントで指定された次のモジュールがありません: AzureAd。
発生場所 行:1 文字:1
+ .\TestScript.ps1
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (TestScript.ps1:String) [], ScriptRequiresException
+ FullyQualifiedErrorId : ScriptRequiresMissingModules
> .\TestScript.ps1
.\TestScript.ps1: The script 'TestScript.ps1' cannot be run because the following modules that are specified by the "#requires" statements of the script are missing: AzureAd.
モジュールのバージョンを指定することもできます。
最小バージョンを指定する場合。
#Requires -Modules @{ ModuleName="Az.Accounts"; ModuleVersion="2.5.1" }
Write-Output -InputObject "Hello World!"
特定のバージョンを指定する場合。
#Requires -Modules @{ ModuleName="Az.Accounts"; RequiredVersion="2.5.1" }
Write-Output -InputObject "Hello World!"
最大バージョンを指定する場合。
#Requires -Modules @{ ModuleName="Az.Accounts"; MaximumVersion="2.5.1" }
Write-Output -InputObject "Hello World!"
補足:Az を指定した場合の PowerShell 5.1 と PowerShell 7.1 の挙動の違い
Requires に Az を指定すると…
#Requires -Modules Az
Write-Output -InputObject "Hello World!"
PowerShell 5.1 では Az モジュールがインストールされていても実行に失敗します。あらかじめ Az モジュールをインポートしておく必要があります。
> Get-InstalledModule -Name Az
Version Name Repository Description
------- ---- ---------- -----------
6.2.1 Az PSGallery Microsoft Azure PowerShell - Cmdlets t...
> .\TestScript.ps1
.\TestScript.ps1 : スクリプト 'TestScript.ps1' を実行できません。このスクリプトの #requires ステートメントで指定された次のモジュールがありません: Az。
発生場所 行:1 文字:1
+ .\TestScript.ps1
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (TestScript.ps1:String) [], ScriptRequiresException
+ FullyQualifiedErrorId : ScriptRequiresMissingModules
> Import-Module Az
> .\TestScript.ps1
Hello World!
一方 PowerShell 7.1 では問題なく実行できます(Az の関連モジュールが自動的にインポートされます)。
> .\TestScript.ps1
Hello World!
そもそもルート Az モジュールをインポートすることは推奨されません(関連モジュールが大量にインポートされてパフォーマンスの問題が発生する可能性があるため)。互換性の問題もありそうなので Az に関わらず必要なモジュールだけを指定するようにしましょう。
まとめ
他にもいくつか指定できる条件はありますが、主に使いそうなのはこんなところかと。現状 PowerShell Core(7 系)への移行の過渡期で、旧環境でしか動かないモジュールやスクリプトもまだまだあるので、できるだけ実行環境を明示しておきたいですね。