确定当前 PowerShell 脚本位置的最佳方法是什么?
每当我需要引用公共模块或脚本时,我喜欢使用相对于当前脚本文件的路径。这样,我的脚本总能在库中找到其他脚本。
那么,确定当前脚本目录的最佳标准方法是什么?目前,我正在做:
$MyDir = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)
我知道在模块(.psm1)中您可以使用 $PSScriptRoot
来获取此信息,但这不会在常规脚本(即 .ps1 文件)中设置。
获取当前 PowerShell 脚本文件位置的规范方法是什么?
Whenever I need to reference a common module or script, I like to use paths relative to the current script file. That way, my script can always find other scripts in the library.
So, what is the best, standard way of determining the directory of the current script? Currently, I'm doing:
$MyDir = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)
I know in modules (.psm1) you can use $PSScriptRoot
to get this information, but that doesn't get set in regular scripts (i.e. .ps1 files).
What's the canonical way to get the current PowerShell script file's location?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
PowerShell 3+
PowerShell 2
在 PowerShell 3 之前,没有比查询更好的方法
通用脚本的
MyInspiration.MyCommand.Definition
属性。基本上我拥有的每个 PowerShell 脚本的顶部都有以下行:PowerShell 3+
PowerShell 2
Prior to PowerShell 3, there was not a better way than querying the
MyInvocation.MyCommand.Definition
property for general scripts. I had the following line at the top of essentially every PowerShell script I had:如果您正在创建 V2 模块,则可以使用名为的自动变量
$PSScriptRoot
。来自PS>帮助自动变量
If you are creating a V2 Module, you can use an automatic variable called
$PSScriptRoot
.From PS > Help automatic_variable
对于 PowerShell 3.0
则函数为:
For PowerShell 3.0
The function is then:
对于 PowerShell 3+,
我已将此函数放在我的个人资料中。它也可以在 ISE 中使用 F8/Run Selection 运行。
For PowerShell 3+
I've placed this function in my profile. It works in ISE using F8/Run Selection too.
也许我在这里遗漏了一些东西......但如果你想要当前的工作目录,你可以使用这个:
(Get-Location).Path
字符串,或Get-Location< /code> 对于一个对象。
除非你指的是这样的事情,我在再次阅读问题后明白了这一点。
Maybe I'm missing something here... but if you want the present working directory you can just use this:
(Get-Location).Path
for a string, orGet-Location
for an object.Unless you're referring to something like this, which I understand after reading the question again.
我使用 自动变量
$执行上下文
。它将在 PowerShell 2 及更高版本中运行。
I use the automatic variable
$ExecutionContext
.It will work from PowerShell 2 and later.
我使用所有这些答案和评论中的片段,将其放在一起,供将来看到这个问题的任何人使用。它涵盖了其他答案中列出的所有情况,并且我添加了我发现的另一种情况作为故障保护。
Using pieces from all of these answers and the comments, I put this together for anyone who sees this question in the future. It covers all of the situations listed in the other answers, and I've added another one I found as a fail-safe.
与已经发布的答案非常相似,但管道似乎更像 PowerShell:
Very similar to already posted answers, but piping seems more PowerShell-like:
我花了一段时间才开发出一些东西,将接受的答案变成一个强大的功能。
我不确定其他人的情况,但我在使用 PowerShell 版本 2 和 3 的计算机的环境中工作,因此我需要同时处理这两个版本。以下函数提供了一个优雅的后备:
这也意味着该函数引用脚本范围而不是 Michael Sorens 在他的一篇博客文章中。
It took me a while to develop something that took the accepted answer and turned it into a robust function.
I am not sure about others, but I work in an environment with machines on both PowerShell version 2 and 3, so I needed to handle both. The following function offers a graceful fallback:
It also means that the function refers to the Script scope rather than the parent's scope as outlined by Michael Sorens in one of his blog posts.
我总是使用这个适用于 PowerShell 和 ISE 的小片段方式 :
I always use this little snippet which works for PowerShell and ISE the same way :
我需要知道脚本名称及其执行位置。
当从主脚本和导入的 .PSM1 库文件的主行调用时,将“$global:”前缀添加到 MyInitation 结构将返回完整路径和脚本名称。它还可以在导入库的函数内工作。
经过多次摆弄后,我决定使用 $global:MyInitation.InvocableName。
它可以与 CMD 启动、Run With Powershell 和 ISE 一起可靠地工作。
本地和 UNC 启动都会返回正确的路径。
I needed to know the script name and where it is executing from.
Prefixing "$global:" to the MyInvocation structure returns the full path and script name when called from both the main script, and the main line of an imported .PSM1 library file. It also works from within a function in an imported library.
After much fiddling around, I settled on using $global:MyInvocation.InvocationName.
It works reliably with CMD launch, Run With Powershell, and the ISE.
Both local and UNC launches return the correct path.
如果要从相对于脚本运行位置的路径加载模块,例如从“lib”子文件夹”,则需要使用以下之一:
$PSScriptRoot
,当作为脚本,例如通过 PowerShell 命令$psISE.CurrentFile.FullPath
当您在 ISE 中运行时有效,但是如果您两者都不在,并且只是在 PowerShell shell 中输入,则可以使用:
pwd.Path< /code>
您可以根据您运行的环境将这三个变量之一分配给名为
$base
的变量,如下所示:然后在您的脚本中,您可以像这样使用它:
If you want to load modules from a path relative to where the script runs, such as from a "lib" subfolder", you need to use one of the following:
$PSScriptRoot
which works when invoked as a script, such as via the PowerShell command$psISE.CurrentFile.FullPath
which works when you're running inside ISEBut if you're in neither, and just typing away within a PowerShell shell, you can use:
pwd.Path
You can could assign one of the three to a variable called
$base
depending on the environment you're running under, like so:Then in your scripts, you can use it like so:
如果任何其他方法失败,您也可以考虑
split-path -parent $psISE.CurrentFile.Fullpath
。特别是,如果您运行一个文件来加载一堆函数,然后在 ISE shell 中执行这些函数(或者如果您运行选择),则似乎是Get-Script-Directory
函数如上所述不起作用。You might also consider
split-path -parent $psISE.CurrentFile.Fullpath
if any of the other methods fail. In particular, if you run a file to load a bunch of functions and then execute those functions with-in the ISE shell (or if you run-selected), it seems theGet-Script-Directory
function as above doesn't work.我发现此处发布的旧解决方案在 PowerShell V5 上对我不起作用。我想出了这个:
I found that the older solutions posted here didn't work for me on PowerShell V5. I came up with this: