如何获取正在执行的cmdlet的当前目录

Sti*_*rez 195 powershell cmdlet

这应该是一个简单的任务,但我已经看到了几次尝试如何获取执行cmdlet所在目录的路径,并取得了成功.例如,当我执行C:\temp\myscripts\mycmdlet.ps1哪个有设置文件时,C:\temp\myscripts\settings.xml我希望能够存储C:\temp\myscripts在一个变量中mycmdlet.ps1.

这是一个有效的解决方案(虽然有点麻烦):

$invocation = (Get-Variable MyInvocation).Value
$directorypath = Split-Path $invocation.MyCommand.Path
$settingspath = $directorypath + '\settings.xml'
Run Code Online (Sandbox Code Playgroud)

另一个人建议这个解决方案只适用于我们的测试环境:

$settingspath = '.\settings.xml'
Run Code Online (Sandbox Code Playgroud)

我非常喜欢后一种方法,并且更喜欢每次都必须将文件路径解析为参数,但我不能让它在我的开发环境中工作.有没有人建议做什么?它与PowerShell的配置方式有关吗?

Gur*_*Kay 249

是的,应该工作.但如果您需要查看绝对路径,这就是您所需要的:

(Get-Item -Path ".\").FullName
Run Code Online (Sandbox Code Playgroud)

  • 这是错误的*.这将获取*process*的当前目录,该目录可以在任何地方.例如,如果我的命令行当前目录是`C:\ mydir`,并且我调用命令`C:\ dir1\dir2\dir3\mycmdlet.ps1`,那么这将解析为`C:\ mydir`,而不是`C:\ DIR1\DIR2\dir3`.调用新的可执行文件具有相同的问题,因为当前目录是从父进程继承的. (7认同)
  • 谢谢,这是从相对路径中找到完整路径的好方法.例如(Get-Item -Path $ myRelativePath -Verbose).FullName (4认同)

Jas*_*her 126

这样做的可靠方法就像你展示的那样$MyInvocation.MyCommand.Path.

使用相对路径将基于$ pwd,PowerShell,应用程序的当前目录或.NET API的当前工作目录.

  • 为什么不使用$ PSScriptRoot?似乎更可靠 (19认同)
  • 能告诉我你是如何找到房产的吗?$ MyInvocation.MyCommand | gm不会在成员列表中显示此类属性. (6认同)

小智 81

最简单的方法似乎是使用以下预定义变量:

 $PSScriptRoot
Run Code Online (Sandbox Code Playgroud)

about_Automatic_Variables并且about_Scripts都表明:

在PowerShell 2.0中,此变量仅在脚本模块(.psm1)中有效.从PowerShell 3.0开始,它在所有脚本中都有效.

我这样使用它:

 $MyFileName = "data.txt"
 $filebase = Join-Path $PSScriptRoot $MyFileName
Run Code Online (Sandbox Code Playgroud)

  • 它是特定于版本的.这至少需要Powershell 3.0. (12认同)

Ale*_*gas 43

您还可以使用:

(Resolve-Path .\).Path
Run Code Online (Sandbox Code Playgroud)

括号中的部分返回一个PathInfo对象.

(自PowerShell 2.0起可用.)

  • 这是*错误*。这将获取 *process* 的当前目录,该目录可以位于任何位置。例如,如果我的命令行当前目录是 `C:\mydir`,并且我调用命令 `C:\dir1\dir2\dir3\mycmdlet.ps1`,那么这将解析为 `C:\mydir`,而不是`C:\dir1\dir2\dir3`。调用新的可执行文件也有同样的问题,因为当前目录是从父进程继承的。 (4认同)
  • 谢谢!我也误解了这个问题的标题,而这个答案正是我所要的。但是...它没有回答问题。 (2认同)

Chr*_*lem 32

路径通常为空.此功能更安全.

function Get-ScriptDirectory
{
    $Invocation = (Get-Variable MyInvocation -Scope 1).Value;
    if($Invocation.PSScriptRoot)
    {
        $Invocation.PSScriptRoot;
    }
    Elseif($Invocation.MyCommand.Path)
    {
        Split-Path $Invocation.MyCommand.Path
    }
    else
    {
        $Invocation.InvocationName.Substring(0,$Invocation.InvocationName.LastIndexOf("\"));
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 您收到此错误是因为您没有父作用域.-Scope参数获取指定范围内的变量.在这种情况下,1是父范围.有关更多信息,请参阅有关Get-Variable的这篇technet文章(https://technet.microsoft.com/en-us/library/hh849899.aspx) (2认同)

Roh*_*rth 27

试试:

(Get-Location).path
Run Code Online (Sandbox Code Playgroud)

要么:

($pwd).path
Run Code Online (Sandbox Code Playgroud)

  • 每当我长时间不使用 powershell 时,我总是忘记 `$pwd`/`$PWD`!IMO 更有用...... (2认同)

Vee*_*asi 16

Get-Location 将返回当前位置:

$Currentlocation = Get-Location
Run Code Online (Sandbox Code Playgroud)

  • PS C:\Windows\system32> C:\powershell\checkfile.ps1 --> 这会给 c:\windows\system32 (5认同)

Fra*_*ood 12

我喜欢一线解决方案 :)

$scriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
Run Code Online (Sandbox Code Playgroud)


小智 9

试试这个:

$WorkingDir = Convert-Path .
Run Code Online (Sandbox Code Playgroud)


Bla*_*Spy 5

在 Powershell 3 及更高版本中,您可以简单地使用

$PSScriptRoot