2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PowerShell 第5回 他のPowerShell Scriptを実行

Posted at

はじめに

今回は、他のPowerShellのScriptを実行するPowerShell Scriptを作成します。
PowerShellでいくつか簡単なツールを作ります。
ツールAを実行して、ツールBを実行するみたいに、複数のツールをシーケンシャルに実行したくなります。
ということで、調べてみるとできそうということなので、サンプルを備忘としてまとめます。

今回実施する内容

今回は、参照元のScriptと参照先のScript(RefferredScript.ps1)を作成し、参照元から参照先のScriptを参照します。
実行方法を2つ見つけたのでその2つで実施します。
なお、2つのScriptは同階層に存在するものとします。

・.(ドット)を使用して実現
・Invoke-Expressionを使用して実現

ソースコード(Git Hub)

PowerShell_05_ReferredScript

環境

OS: Windows 10 JP (64bit)
PowerShell version: 5.1.19041.1

参考

なし

用語

.(ドット)を使用して実現

シンプルな関数の読み込み

Script 説明
BaseScript.ps1 参照元Script。参照先Scriptの関数を呼び出す。
ReferredScript.ps1 参照先Script。ターミナルに文字列を出力する関数だけ定義。

参照元Scriptから参照先Scriptの関数を呼び出して実行します。
単に文字列をターミナルに出力するだけです。

ソースコード

BaseScript.ps1
try {
    . .\referredScript.ps1
    ShowMessage("参照元Scriptで、参照先Scriptの関数を参照して実行します。")
} catch {
    Write-Host $Error[0]
}
ReferredScript.ps1
function ShowMessage {
	[CmdletBinding()]
	param (
		[Parameter(Mandatory = $true)]
		[string]$Message
	)
	Write-Host $Message
}
<実行結果>
参照元Scriptの関数を参照して実行します。

ソースコードの説明

2つのScriptは同じ階層に置きます。
参照先Scriptは単にWrite-Hostで$Messageをターミナルに表示するだけのシンプルな関数です。
参照元Scriptでは、
. .\referredScript.ps1
で、referredScript.ps1を実行します。といっても実行文はなく関数記載だけのため、関数の読み込みだけ実施されます。
その後ShowMessageで、参照元Scriptから参照先Scriptの関数を実行します。

.(ドット)の説明

これでいけるということですね。最初の**「.」**がなじみがなかったので調べてみると、
PowerShell用語集

|期間|定義|
|:--|:--|
ドット ソース| PowerShell では、コマンドの前にドットとスペースを入力することによってコマンドを開始すること。 ドット ソースのコマンドは、新しいスコープではなく、現在のスコープで実行されます。 コマンドが作成するすべての変数、エイリアス、関数、またはドライブは、現在のスコープで作成され、コマンドが完了すると使用できるようになります。|

なるほど。これでコマンド開始することになるんですね。そしてスコープは現在のスコープと。
「期間」は単なる翻訳のミスですね。ただしくは「Term」なので「用語」ですね。

参照先Scriptで実行文がある場合の動作

実際に使用するとなると、最初に試したようなライブラリ的な使い方もすると思いますが、別のツール(別のScript)を実行するという使い方もすると思います。
ということで、参照先Scriptに実行文を入れた場合の動作を試します。

Script 説明
BaseScript2.ps1 参照元Script。参照先Scriptの関数を呼び出す。
ReferredScript2.ps1 参照先Script。ターミナルに文字列を出力する関数を定義。加えてその関数を実行

ソースコード

BaseScript2.ps1
try {
    . .\referredScript2.ps1
    ShowMessage("参照元Scriptで、参照先Scriptの関数を参照して実行します。")
} catch {
    Write-Host $Error[0]
}
ReferredScript2.ps1
function ShowMessage {
	[CmdletBinding()]
	param (
		[Parameter(Mandatory = $true)]
		[string]$Message
	)
	Write-Host $Message
}

ShowMessage("参照先Scriptです。ShowMessageを実行します。")
<実行結果>
参照先Scriptです。ShowMessageを実行します。
参照元Scriptの関数を参照して実行します。

ソースコードの説明

これを実行すると参照先Scriptの実行文が実行された後、参照元Scriptの読み込んだShowMessageが実行されるということです。
結局両方実行されるってことですね。
これなら、単体で参照先Scriptを使ってもよいし、参照元Scriptから読み込んで使ってもよいし、期待通りです。

Invoke-Expressionを使用して実現

シンプルな関数の読み込み

Script 説明
BaseScript3.ps1 参照元Script。参照先Scriptの関数を呼び出す。
ReferredScript3.ps1 参照先Script。ターミナルに文字列を出力する関数だけ定義。

参照元Scriptから参照先Scriptの関数を呼び出して実行します。
単に文字列をターミナルに出力するだけです。

ソースコード

BaseScript3.ps1
try {
    Invoke-Expression .\referredScript3.ps1
    ShowMessage("参照元Scriptで、参照先Scriptの関数を参照して実行します。")
} catch {
    Write-Host $Error[0]
}
ReferredScript3.ps1
function ShowMessage {
	[CmdletBinding()]
	param (
		[Parameter(Mandatory = $true)]
		[string]$Message
	)
	Write-Host $Message
}
<実行結果>
参照元Scriptの関数を参照して実行します。

Invoke-Expressionの説明

「.(ドット)を使用して実現」と結果は同じです。
動作は似たようなものかなと思いますが、PowershelのドキュメントInvoke-Expressionから引用すると、以下です。

###Example 2: Run a script on the local computer

Invoke-Expression -Command "C:\ps-test\testscript.ps1"
"C:\ps-test\testscript.ps1" | Invoke-Expression

These commands use Invoke-Expression to run a script, TestScript.ps1, on the local computer. The two commands are equivalent. The first uses the Command parameter to specify the command to run. The second uses a pipeline operator (|) to send the command string to Invoke-Expression.

コマンドを開始するといっているのでやはり同じようです。パイプラインも使えるようです。

参照先Scriptで実行文がある場合の動作

「.(ドット)を使用して実現」と同様に、参照先Scriptに実行文を入れた場合の動作を試します。

Script 説明
BaseScript4.ps1 参照元Script。参照先Scriptの関数を呼び出す。
ReferredScript4.ps1 参照先Script。ターミナルに文字列を出力する関数を定義。加えてその関数を実行

ソースコード

BaseScript4.ps1
try {
    Invoke-Expression .\referredScript4.ps1
    ShowMessage("参照元Scriptで、参照先Scriptの関数を参照して実行します。")
} catch {
    Write-Host $Error[0]
}
ReferredScript4.ps1
function ShowMessage {
	[CmdletBinding()]
	param (
		[Parameter(Mandatory = $true)]
		[string]$Message
	)
	Write-Host $Message
}

ShowMessage("参照先Scriptです。ShowMessageを実行します。")
<実行結果>
参照先Scriptです。ShowMessageを実行します。
参照元Scriptの関数を参照して実行します。

ソースコードの説明

これを実行すると参照先Scriptの実行文が実行された後、参照元Scriptの読み込んだShowMessageが実行されるということです。
結局両方実行されるってことですね。
結果は「.(ドット)を使用して実現」と同じですね。

参照先Scriptで実行文があって結果を参照元Scriptに戻す動作

参照元Scriptで参照先Scriptを呼び出す場合、その処理が正常に終わったかどうか参照したくなります。
例えば、ツールAを実行して正常に終了したならば、ツールBを実行というように、正常かどうかを示す戻り値を返したくなります。
ということで試してみます。

Script 説明
BaseScript5.ps1 参照元Script。参照先Scriptの関数を呼び出す。
ReferredScript5.ps1 参照先Script。ターミナルに文字列を出力する関数を定義。加えてその関数を実行

ソースコード

BaseScript5.ps1
try {
    $result = Invoke-Expression .\ReferredScript5.ps1
    if ($result -eq 1) {
        ShowMessage("参照元Scriptの関数の戻り値を取得成功。")
    } else {
        ShowMessage("参照元Scriptの関数の戻り値を取得失敗。")
    }
} catch {
    Write-Host $Error[0]
}
ReferredScript5.ps1
function ShowMessage {
	[CmdletBinding()]
	param (
		[Parameter(Mandatory = $true)]
		[string]$Message
	)
	Write-Host $Message
    1
}

ShowMessage("参照先Scriptです。ShowMessageを実行します。")
<実行結果>
参照先Scriptです。ShowMessageを実行します。
参照元Scriptの関数の戻り値を取得成功。

ソースコードの説明

PowerShell:BaseScript5.ps1では、ReferredScript5.ps1の実行文の戻り値を$resultに代入して、その値が1か判断し、ターミナルに出力します。
ReferredScript5.ps1では、ShowMessage関数内で、1を出力します。
ということで、戻り値1を$resultに代入ができて、それに応じた動作を実行できました。
期待通りです。

おわりに

今回は、他のPowerShellのScriptを実行するPowerShell Scriptを作成し、動作を確認しました。
期待通りの動作ができて満足です。
Invoke-Expressionのほうが、明示的でわかりやすいかなと思いました。
.(ドット)だと、戻り値がどうやって帰ってくるのかわからなかったですし。
これをベースにツールを複数実行するScriptを試してみることにします。
何かあればまた記事更新します。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?