从Powershell ISE中的另一个PS1脚本调用PowerShell脚本PS1

时间:2011-07-25 12:55:22

标签: powershell

我希望在Powershell ISE内的第二个myScript2.ps1脚本中调用myScript1.ps1脚本。

MyScript2.ps1中的以下代码在Powershell Administration中运行良好,但在PowerShell ISE中不起作用:

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

从PowerShell ISE执行MyScript2.ps1时出现以下错误:

  

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

12 个答案:

答案 0 :(得分:72)

要查找脚本的位置,请使用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
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

答案 1 :(得分:30)

MyScript1.ps1的当前路径与myScript2.ps1不同。您可以获取MyScript2.ps1的文件夹路径并将其连接到MyScript1.ps1,然后执行它。两个脚本必须位于同一位置。

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

答案 2 :(得分:16)

一线解决方案:

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

答案 3 :(得分:15)

我从myScript2.ps1调用myScript1.ps1。

假设两个脚本都位于同一位置,请首先使用以下命令获取脚本的位置:

$PSScriptRoot

然后,添加您想要调用的脚本名称:

& "$PSScriptRoot\myScript1.ps1"

这应该有用。

答案 4 :(得分:5)

这只是答案的附加信息 为了将参数传递给另一个文件

您期望参数

<强> 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

如果您不提供任何输入,则默认为&#34; Joe&#34;这将作为参数传递到 PrintName.ps1 文件中的printName参数 这将打印出&#34; Joe&#34; 字符串

答案 5 :(得分: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)

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

使用

开始进程...

调用-Expression $ PSScriptRoot \ ScriptName.ps1

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

答案 6 :(得分:3)

我遇到了这个问题。我没有使用任何聪明的$MyInvocation东西来修复它。如果通过右键单击脚本文件并选择edit打开ISE,然后从ISE中打开第二个脚本,只需使用普通的。\ script.ps1 语法。 我的猜测是,ISE具有当前文件夹的概念并打开它,就像这样将当前文件夹设置为包含脚本的文件夹。 当我在正常使用中从另一个脚本调用一个脚本时,我只使用。\ script.ps1 ,IMO修改脚本以使其在ISE中正常工作是错误的...

答案 7 :(得分:3)

要在调用者的同一文件夹(或子文件夹)中轻松执行脚本文件,您可以使用此文件:

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

# Execute script at location:
&"$ScriptRoute"

答案 8 :(得分:1)

我有类似的问题并以这种方式解决了。

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

\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"

答案 9 :(得分:0)

如何在脚本中运行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,它应该是最早执行的脚本之一。

重新加载后在命令行上运行此命令,以在路径变量中查看新目录:

> $env:Path

现在,我们可以从命令行或从另一个脚本中调用脚本,如下所示:

$(customScript.ps1 arg1 arg2 ...)

如您所见,我们必须使用.ps1扩展名来调用它们,直到为它们创建别名为止。如果我们想花哨。

答案 10 :(得分:0)

我将我的示例提交考虑。这就是我在制作的工具中从控制器脚本中调用一些代码的方式。完成工作的脚本也需要接受参数,因此此示例说明了如何传递参数。它确实假定被调用的脚本与控制器脚本(进行调用的脚本)位于同一目录中。

[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个参数。当控制器脚本调用执行工作的脚本时,需要调用它并传递参数。上面显示了我如何通过喷溅来实现。

答案 11 :(得分:0)

您也可以使用以下命令:

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