PowerShell:从脚本的目录运行命令

时间:2011-01-18 12:55:41

标签: powershell

我有一个PowerShell脚本,可以使用脚本的当前目录来完成一些操作。因此,当在该目录中时,运行.\script.ps1可以正常工作。

现在我想从不同的目录调用该脚本,而不更改脚本的引用目录。所以我想调用..\..\dir\script.ps1并仍然希望该脚本的行为与从其目录中调用它一样。

我该怎么做,或者如何修改脚本以便它可以从任何目录运行?

7 个答案:

答案 0 :(得分:175)

您的意思是您想要脚本自己的路径,以便您可以引用脚本旁边的文件吗?试试这个:

$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
Write-host "My directory is $dir"

您可以从$ MyInvocation及其属性中获取大量信息。

如果要引用当前工作目录中的文件,可以使用Resolve-Path或Get-ChildItem:

$filepath = Resolve-Path "somefile.txt"

编辑(根据OP的评论):

# temporarily change to the correct folder
Push-Location $folder

# do stuff, call ant, etc

# now back to previous directory
Pop-Location

使用Invoke-Command可能还有其他方法可以实现类似的功能。

答案 1 :(得分:31)

如果您正在调用本机应用,则需要担心[Environment]::CurrentDirectory而不是PowerShell的$PWD当前目录。由于某些原因,我逃脱了PowerShell does not set the process' current working directory when you Set-Location or Push-Location,所以如果你正在运行期望它被设置的应用程序(或cmdlet),你需要确保这样做。

在脚本中,您可以这样做:

Push-Location $MyInvocation.MyCommand.Path
[Environment]::CurrentDirectory = $PWD
##  Your Script Code ...
Pop-Location
[Environment]::CurrentDirectory = $PWD

没有万无一失的替代品。我们中的许多人在我们的提示函数中设置了一行来设置[Environment] :: CurrentDirectory ...但是当您在脚本中更改位置时,这对您没有帮助。

最后注意事项:$PWD并不总是合法的CurrentDirectory(例如,您可能会将CD放入注册表提供程序中),因此如果要将其放入提示中,或者放入* -Location的包装函数中cmdlet,您需要使用:

[Environment]::CurrentDirectory = Get-Location -PSProvider FileSystem

答案 2 :(得分:29)

有大量投票的答案,但是当我读到你的问题时,我认为你想知道脚本所在的目录,而不是脚本运行的位置。您可以使用powershell的自动变量获取信息

$PSScriptRoot - the directory where the script exists, not the target directory the script is running in
$PSCommandPath - the full path of the script

例如,我有$ profile脚本找到visual studio解决方案文件并启动它。一旦解决方案文件启动,我想存储完整路径。但我想保存原始脚本所在的文件。所以我使用了$ PsScriptRoot。

答案 3 :(得分:12)

我经常使用以下代码导入一个与正在运行的脚本位于同一目录下的模块。它将首先获取运行powershell的目录

  

$ currentPath = Split-Path((Get-Variable   MyInvocation -Scope   0)。价值).MyCommand.Path

     

import-module“$ currentPath \ sqlps.ps1”

答案 4 :(得分:3)

这样可以正常工作。

Push-Location $PSScriptRoot

Write-Host CurrentDirectory $CurDir

答案 5 :(得分:2)

好吧,我一直在寻找解决方案,没有任何来自CLI的脚本。我是这样做的xD:

  • 导航到您要运行脚本的文件夹(重要的是您有标签完成)

    ..\..\dir

  • 现在使用双引号包围位置,并在其中添加cd,因此我们可以调用另一个powershell实例。

    "cd ..\..\dir"

  • 添加另一个命令来运行由;分隔的脚本,在powershell中是一个命令分隔符

    "cd ..\..\dir\; script.ps1"

  • 最后使用另一个powershell实例

    运行它

    start powershell "cd..\..\dir\; script.ps1"

这将打开新的PowerShell窗口,转到..\..\dir,运行script.ps1并关闭窗口。


请注意";"只是分开命令,就像你一个一个地键入命令,如果第一次失败则第二次运行,下一次运行,接下来运行后......如果你想保持新的PowerShell窗口打开,你可以在传递的命令中添加-noexit。请注意,我首先导航到所需的文件夹,以便我可以使用制表符完成(你不能用双引号)。

start powershell "-noexit cd..\..\dir\; script.ps1"

使用双引号"",这样就可以传递名称中包含空格的目录,例如。,

start powershell "-noexit cd '..\..\my dir'; script.ps1"

答案 6 :(得分:0)

我用@JohnL的解决方案制成了单线纸:

$MyInvocation.MyCommand.Path | Split-Path | Push-Location