什么是确定当前PowerShell脚本位置的最佳方法?
无论何时我需要引用一个通用的模块或脚本,我都喜欢使用相对于当前脚本文件的path,这样,我的脚本就可以随时在库中find其他脚本。
那么,确定当前脚本目录的最佳标准方法是什么? 目前,我正在做:
$MyDir = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)
我知道在模块(.psm1)中,您可以使用$PSScriptRoot
来获取这些信息,但是这并不是在普通脚本(即.ps1文件)中设置的。
获取当前PowerShell脚本文件位置的规范方法是什么?
PowerShell 3+
# This is an automatic variable set to the current file's/module's directory $PSScriptRoot
PowerShell 2
在PowerShell 3之前,没有比查询一般脚本的MyInvocation.MyCommand.Definition
属性更好的方法。 我有基本上每个PowerShell脚本的顶部的以下行:
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
如果您正在创buildV2模块,则可以使用名为$PSScriptRoot
的自动variables。
从PS>帮助automatic_variable
$ PSScriptRoot 包含正在执行脚本模块的目录。 这个variables允许脚本使用模块path来访问其他的 资源。
对于PowerShell 3.0
$PSCommandPath Contains the full path and file name of the script that is being run. This variable is valid in all scripts.
该function是:
function Get-ScriptDirectory { Split-Path -Parent $PSCommandPath }
也许我错过了这里的东西…但是如果你想要目前的工作目录,你可以使用这个: (Get-Location).Path
为一个string,或Get-Location
为一个对象。
除非你指的是这样的东西,我再次阅读这个问题后,我明白了。
function Get-Script-Directory { $scriptInvocation = (Get-Variable MyInvocation -Scope 1).Value return Split-Path $scriptInvocation.MyCommand.Path }
我需要知道脚本名称以及它从哪里执行。
当从主脚本和导入的.PSM1库文件的主线调用MyInvocation结构前缀“$ global:”时,将返回完整path和脚本名称。 它也可以在导入库中的函数中使用。
经过大量的摆弄之后,我决定使用$ global:MyInvocation.InvocationName。 它可以在CMD启动,运行Powershell和ISE的情况下可靠运行。 本地和UNC发射都返回正确的path。
我使用自动variables $ ExecutionContext,它从PowerShell 2和更高版本。
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath('.\')
$ ExecutionContext包含表示Windows PowerShell主机的执行上下文的EngineIntrinsics对象。 您可以使用此variables查找可用于cmdlet的执行对象。
花了我一段时间去开发一些接受了答案的东西,并把它变成一个强大的function。
不知道其他人,但我在一个与PowerShell版本2和3机器的环境中工作,所以我需要处理这两个。 以下函数提供了优雅的回退:
Function Get-PSScriptRoot { $ScriptRoot = "" Try { $ScriptRoot = Get-Variable -Name PSScriptRoot -ValueOnly -ErrorAction Stop } Catch { $ScriptRoot = Split-Path $script:MyInvocation.MyCommand.Path } Write-Output $ScriptRoot }
这也意味着该function是指脚本的范围,而不是由Michael Sorens在其博客中概述的父母的范围
非常类似已经发布的答案,但pipe道似乎更像PS。
$PSCommandPath | Split-Path -Parent
对于Powershell 3+
function Get-ScriptDirectory { if ($psise) {Split-Path $psise.CurrentFile.FullPath} else {$global:PSScriptRoot} }
我已经把这个function放在我的档案中。 在ISE中使用F8 / Run Selection也可以工作。
如果其他任何方法失败,您也可以考虑使用split-path -parent $psISE.CurrentFile.Fullpath
。 特别是,如果您运行一个文件来加载一堆函数,然后在ISE shell中执行这些函数(或者如果您select运行),那么上面的Get-Script-Directory
函数似乎不起作用。
function func1() { $inv = (Get-Variable MyInvocation -Scope 1).Value #$inv.MyCommand | Format-List * $Path1 = Split-Path $inv.scriptname Write-Host $Path1 } function Main() { func1 } Main