Powershell ISE内の別のPS1スクリプトからPowerShellスクリプトPS1を呼び出す


138

Powershell ISE内の2番目のmyScript2.ps1スクリプト内のmyScript1.ps1スクリプトの呼び出し実行が必要です。

MyScript2.ps1内の次のコードは、Powershell管理からは正常に機能しますが、PowerShell ISE内では機能しません。

#Call myScript1 from myScript2
invoke-expression -Command .\myScript1.ps1

PowerShell ISEからMyScript2.ps1を実行すると、次のエラーが表示されます。

「。\ myScript1.ps1」という用語は、コマンドレット、関数、スクリプトファイル、または操作可能なプログラムの名前として認識されません。名前のスペルを確認するか、パスが含まれていた場合は、パスが正しいことを確認して、再試行してください。

回答:


83

スクリプトの場所を見つけるには、を使用しますSplit-Path $MyInvocation.MyCommand.Path(必ずスクリプトコンテキストで使用してください)。

このスクリプトを使用して、他に何も使用しない理由を説明できます。

## ScriptTest.ps1
Write-Host "InvocationName:" $MyInvocation.InvocationName
Write-Host "Path:" $MyInvocation.MyCommand.Path

結果は次のとおりです。

PS C:\ Users \ JasonAr>。\ ScriptTest.ps1
InvocationName:。\ ScriptTest.ps1
パス:C:\ Users \ JasonAr \ ScriptTest.ps1

PS C:\ Users \ JasonAr>。。\ ScriptTest.ps1
InvocationName:。
パス:C:\ Users \ JasonAr \ ScriptTest.ps1

PS C:\ Users \ JasonAr>& "。\ ScriptTest.ps1"
InvocationName:&
パス:C:\ Users \ JasonAr \ ScriptTest.ps1

PowerShell 3.0以降では、自動変数を使用することができます$PSScriptRoot

## ScriptTest.ps1
Write-Host "Script:" $PSCommandPath
Write-Host "Path:" $PSScriptRoot
PS C:\ Users \ jarcher>。\ ScriptTest.ps1
スクリプト:C:\ Users \ jarcher \ ScriptTest.ps1
パス:C:\ Users \ jarcher

最近の追加:アボットの分散が心配な場合(または、実際には単に「充実した」コードが必要な場合)、「Write-Host」ではなく「Write-Output」を使用することをお勧めします。
KlaymenDK 2015年

20
答えにSplit-Pathの使用例を見るとよいでしょう。また、実際に別のスクリプト内でスクリプトを呼び出すことも示す必要があります。
ジェレミー

37

MyScript1.ps1の現在のパスは、myScript2.ps1と同じではありません。MyScript2.ps1のフォルダーパスを取得し、それをMyScript1.ps1に連結して実行できます。両方のスクリプトは同じ場所にある必要があります。

## MyScript2.ps1 ##
$ScriptPath = Split-Path $MyInvocation.InvocationName
& "$ScriptPath\MyScript1.ps1"

$ MyInvocation変数を初期化する方法を教えてください。
Nicola Celiento 2011

そうではありません、それは自動変数です。
シェイ・レヴィ

機能しますが、呼び出されたスクリプトを実際に実行する前に次のエラーを取得します。Split-Path:空の文字列であるため、引数をパラメーター 'Path'にバインドできません。行:4 char:25 + $ ScriptPath = Split-Path <<<< $ MyInvocation.InvocationName + CategoryInfo:InvalidData:(:) [Split-Path]、ParameterBindingValidationException + FullyQualifiedErrorId:ParameterArgumentValidationErrorEmptyStringNotAllowed、Microsoft.PowerShell.Commands.SplitPathCommand
ニコラセリエント

その中に新しいスクリプトput:$ MyInvocation.InvocationNameを作成し、スクリプトを実行します。スクリプトのパスはわかりますか?
Shay Levy

@JasonMArcher-なぜ代わりに?私が知る限り、両方が同じ出力を出しますか?
manojlds '25

36

myScript2.ps1からmyScript1.ps1を呼び出しています。

スクリプトの両方が同じ場所にあると仮定すると、最初に次のコマンドを使用してスクリプトの場所を取得します。

$PSScriptRoot

次に、呼び出すスクリプト名を次のように追加します。

& "$PSScriptRoot\myScript1.ps1"

これはうまくいくはずです。


3
& "$PSScriptRoot\myScript1.ps1"十分です

19

1行のソリューション:

& ((Split-Path $MyInvocation.InvocationName) + "\MyScript1.ps1")

これはすばらしいことですが& '.\MyScript1.ps'、スクリプトが同じディレクトリにあるだけではどうでしょうか。
JoePC、

3
スクリプトディレクトリではなく、現在のディレクトリを使用しています。確かにそれらはしばしば同じです...しかし常にではありません!
noelicus

9

これは、引数を別のファイルに渡すための回答に対する追加情報です

議論を期待するところ

PrintName.ps1

Param(
    [Parameter( Mandatory = $true)]
    $printName = "Joe"    
)


Write-Host $printName

ファイルを呼び出す方法

Param(
    [Parameter( Mandatory = $false)]
    $name = "Joe"    
)


& ((Split-Path $MyInvocation.InvocationName) + "\PrintName.ps1") -printName $name

入力を提供しない場合、デフォルトで「Joe」になり、これが引数としてPrintName.ps1ファイルのprintName引数に渡され、「Joe」文字列が出力されます。


4

あなたはすでにその答えを見つけたかもしれませんが、これが私がすることです。

通常、この行はインストールスクリプトの先頭に配置します。

if(!$PSScriptRoot){ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent } #In case if $PSScriptRoot is empty (version of powershell V.2).  

次に、次の例のように、$ PSScriptRoot変数を現在のスクリプト(パス)の場所として使用できます。

if(!$PSScriptRoot){ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent } #In case if $PSScriptRoot is empty (version of powershell V.2).  

Try {
If (Test-Path 'C:\Program Files (x86)') {
    $ChromeInstallArgs= "/i", "$PSScriptRoot\googlechromestandaloneenterprise64_v.57.0.2987.110.msi", "/q", "/norestart", "/L*v `"C:\Windows\Logs\Google_Chrome_57.0.2987.110_Install_x64.log`""
    Start-Process -FilePath msiexec -ArgumentList $ChromeInstallArgs -Wait -ErrorAction Stop
    $Result= [System.Environment]::ExitCode
} Else {
    $ChromeInstallArgs= "/i", "$PSScriptRoot\googlechromestandaloneenterprise_v.57.0.2987.110.msi", "/q", "/norestart", "/L*v `"C:\Windows\Logs\Google_Chrome_57.0.2987.110_Install_x86.log`""
    Start-Process -FilePath msiexec -ArgumentList $ChromeInstallArgs -Wait -ErrorAction Stop
    $Result= [System.Environment]::ExitCode
    }

} ### End Try block


Catch  {
    $Result = [System.Environment]::Exitcode
    [System.Environment]::Exit($Result)
   }
[System.Environment]::Exit($Result)

あなたの場合、あなたは交換することができます

[スタート] -プロセス... とライン

呼び出し式$ PSScriptRoot \ ScriptName.ps1

$ MYINVOCATIONおよび$ PSScriptRoot自動変数の詳細については、Microsoftのサイトをご覧ください。https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_automatic_variables


4

呼び出し元と同じフォルダー(またはそのサブフォルダー)内のスクリプトファイルを簡単に実行するには、次のように使用できます。

# Get full path to the script:
$ScriptRoute = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, "Scriptname.ps1"))

# Execute script at location:
&"$ScriptRoute"

3

これに問題がありました。私は$MyInvocationそれを修正するためにどんな賢いものも使用しませんでした。スクリプトファイルを右クリックしてISEを開き、ISE editから2番目のスクリプトを選択して開くと、通常の。\ script.ps1構文を使用して、一方から他方を呼び出すことができます。私の推測では、ISEには現在のフォルダーの概念があり、このように開くと、現在のフォルダーがスクリプトを含むフォルダーに設定されます。通常の使用で1つのスクリプトを別のスクリプトから呼び出す場合、。\ script.ps1を使用するだけです。IMOは、ISEで正しく機能するようにスクリプトを変更するのは誤りです...


2

同様の問題があり、この方法で解決しました。

私の作業ディレクトリは、同じルートにある一般的なスクリプトフォルダーとサーバーの特定のスクリプトフォルダーです。特定のスクリプトフォルダー(特定の問題のパラメーターで一般的なスクリプトを呼び出す)を呼び出す必要があります。だから作業ディレクトリはこのようなものです

\Nico\Scripts\Script1.ps1
             \Script2.ps1
      \Problem1\Solution1.ps1
               \ParameterForSolution1.config
      \Problem2\Solution2.ps1
               \ParameterForSolution2.config

Solutions1とSolutions2は、ScriptsフォルダーでPS1を呼び出し、ParameterForSolutionに格納されているパラメーターをロードします。Powershell ISEでは、このコマンドを実行します

.\Nico\Problem1\Solution1.PS1

そして、Solution1.PS1内のコードは次のとおりです。

# This is the path where my script is running
$path = split-path -parent $MyInvocation.MyCommand.Definition

# Change to root dir
cd "$path\..\.."

$script = ".\Script\Script1.PS1"

$parametro = "Problem1\ParameterForSolution1.config"
# Another set of parameter Script1.PS1 can receive for debuggin porpuose
$parametro +=' -verbose'

Invoke-Expression "$script $parametro"

2

検討のために自分の例を提出します。これは、私が作成したツールのコントローラースクリプトからコードを呼び出す方法です。作業を行うスクリプトもパラメーターを受け入れる必要があるため、この例では、パラメーターを渡す方法を示します。呼び出されるスクリプトがコントローラースクリプト(呼び出しを行うスクリプト)と同じディレクトリにあると想定しています。

[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string[]]
$Computername,

[Parameter(Mandatory = $true)]
[DateTime]
$StartTime,

[Parameter(Mandatory = $true)]
[DateTime]
$EndTime
)

$ZAEventLogDataSplat = @{
    "Computername" = $Computername
    "StartTime"    = $StartTime
    "EndTime"      = $EndTime
}

& "$PSScriptRoot\Get-ZAEventLogData.ps1" @ZAEventLogDataSplat

上記は、3つのパラメーターを受け入れるコントローラースクリプトです。これらはparamブロックで定義されます。次に、コントローラースクリプトはGet-ZAEventLogData.ps1という名前のスクリプトを呼び出します。例として、このスクリプトは同じ3つのパラメーターも受け入れます。コントローラースクリプトが作業を行うスクリプトを呼び出すとき、それを呼び出してパラメーターを渡す必要があります。上記は私がスプラッティングによってそれを行う方法を示しています。


1

スクリプト内でPowerShell組み込みスクリプトをどのように実行しますか?

次のような組み込みスクリプトをどのように使用しますか

Get-Location
pwd
ls
dir
split-path
::etc...

これらはコンピュータによって実行され、スクリプトのパスを自動的にチェックします。

同様に、スクリプトブロックにスクリプトの名前を入力するだけで、カスタムスクリプトを実行できます。

::sid.ps1 is a PS script I made to find the SID of any user
::it takes one argument, that argument would be the username
echo $(sid.ps1 jowers)


(returns something like)> S-X-X-XXXXXXXX-XXXXXXXXXX-XXX-XXXX


$(sid.ps1 jowers).Replace("S","X")

(returns same as above but with X instead of S)

powershellコマンドラインに移動して、次のように入力します。

> $profile

これにより、アプリを開くたびにPowerShellコマンドラインが実行するファイルへのパスが返されます。

このようになります

C:\Users\jowers\OneDrive\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1

ドキュメントに移動し、WindowsPowerShellディレクトリが既にあるかどうかを確認します。私はしなかったので

> cd \Users\jowers\Documents
> mkdir WindowsPowerShell
> cd WindowsPowerShell
> type file > Microsoft.PowerShellISE_profile.ps1

PowerShellアプリを開くたびに起動するスクリプトを作成しました。

これを行ったのは、すべてのカスタムスクリプトを保持する独自のフォルダーを追加できるようにするためです。そのフォルダーを作成して、Mac / Linuxがスクリプトを保持するディレクトリにちなんで「Bin」という名前を付けます。

> mkdir \Users\jowers\Bin

$env:pathアプリを開くたびにそのディレクトリを変数に追加したいので、ディレクトリに戻りWindowsPowerShell

> start Microsoft.PowerShellISE_profile.ps1

次にこれを追加します

$env:path += ";\Users\jowers\Bin"

スクリプトをその「Bin」ディレクトリに保存している限り、シェルはコマンドを自動的に見つけます。

powershellを再起動すると、最初に実行されるスクリプトの1つになるはずです。

リロード後にコマンドラインでこれを実行して、パス変数に新しいディレクトリを表示します。

> $env:Path

これで、コマンドラインから、または次のように別のスクリプト内からスクリプトを呼び出すことができます。

$(customScript.ps1 arg1 arg2 ...)

ご覧のとおり.ps1、エイリアスを作成するまで、拡張子を付けて呼び出す必要があります。ファンシーになりたいなら。


わあ、ありがとう、ここにはたくさんあります。しかし、ここにはすでに9つの答えがあります。これはどう違いますか?それはどのような追加情報を提供していますか?
スティーブンラウフ

これにより、組み込みスクリプトをスクリプト内で使用するのと同じように、他のスクリプト内でカスタムスクリプトを使用できます。これを行い、パスに配置したディレクトリにスクリプトを保存する限り、コマンドラインまたは別のスクリプトでカスタムスクリプトを使用すると、コンピューターはカスタムスクリプトのパスを自動的に検索します
Tyler Curtis Jowers
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.