我想调用myScript1的执行。第二个myScript2中的ps1脚本。Powershell ISE中的ps1脚本。

下面是MyScript2中的代码。ps1,从Powershell管理工作很好,但不工作在Powershell ISE:

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

当我执行MyScript2时,我得到了以下错误。ps1来自PowerShell ISE:

术语“。\myScript1.”Ps1’不能识别为cmdlet、函数、脚本文件或可操作程序的名称。检查名称的拼写,或者如果包含了路径,请验证路径是否正确,然后重试。


当前回答

为了找到脚本的位置,使用Split-Path $MyInvocation.MyCommand。路径(确保在脚本上下文中使用该路径)。

您应该使用它而不是其他任何东西的原因可以通过这个示例脚本来说明。

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

以下是一些结果。

PS C:\Users\JasonAr> .\ScriptTest.ps1
InvocationName: .\ScriptTest.ps1
Path: C:\Users\JasonAr\ScriptTest.ps1

PS C:\Users\JasonAr> . .\ScriptTest.ps1
InvocationName: .
Path: C:\Users\JasonAr\ScriptTest.ps1

PS C:\Users\JasonAr> & ".\ScriptTest.ps1"
InvocationName: &
Path: 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
Script: C:\Users\jarcher\ScriptTest.ps1
Path: C:\Users\jarcher

其他回答

你可能已经找到了答案,但下面是我要做的。

我通常把这一行放在安装脚本的开头:

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)

在你的情况下,你可以替换

起动过程……与

Invoke-Expression PSScriptRoot \ ScriptName.ps1美元

您可以在Microsoft网站https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_automatic_variables上阅读有关$MYINVOCATION和$PSScriptRoot自动变量的更多信息

我也遇到过类似的问题,用这种方法解决了。

我的工作目录是一个通用脚本文件夹和几个特定的脚本文件夹在同一根,我需要调用特定的脚本文件夹(其中调用通用脚本与特定问题的参数)。 工作目录是这样的

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

solution1和solution2调用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"

要轻松地执行与调用者相同文件夹(或子文件夹)中的脚本文件,您可以使用以下命令:

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

# Execute script at location:
&"$ScriptRoute"

还可以使用以下命令:

$Patch = Join-Path -Path $PSScriptRoot -ChildPath "\patch.ps1"<br>
Invoke-Expression "& `"$Patch`""

I had a problem with this. I didn't use any clever $MyInvocation stuff to fix it though. If you open the ISE by right clicking a script file and selecting edit then open the second script from within the ISE you can invoke one from the other by just using the normal .\script.ps1 syntax. My guess is that the ISE has the notion of a current folder and opening it like this sets the current folder to the folder containing the scripts. When I invoke one script from another in normal use I just use .\script.ps1, IMO it's wrong to modify the script just to make it work in the ISE properly...