powershell $PSScriptRoot和$MyInvocation之间的功能差异

bksxznpy  于 11个月前  发布在  Shell
关注(0)|答案(3)|浏览(120)

问题
我正在使用Jenkins远程部署PowerShell脚本。因此,我试图弄清楚使用$MyInvocation.MyCommand.Path获取当前脚本根目录是否会出现问题。

详情

一位同事告诉我,使用$PSScriptRoot对于远程功能来说是一个坏主意,因为我可能偶尔会发现它在运行时由于某种原因没有返回预期的值,即使它以前工作过。但是,无法解释为什么会这样。
在我的研究中,我没有发现任何可以进一步解释这一点的东西,或者避免这种问题的最佳实践方法是什么。然而,$PSScriptRoot只能在PowerShell v3或更高版本中使用。通过你们中的一些人的帮助,我还了解到$MyInvocation有不同的情况,允许它根据范围和模块进行更改。但我仍然没有发现这是否或为什么会是PowerShell Remoting的问题。

  • 实施例001*

所以我在Jenkins中有一个PowerShell脚本,它使用$PSScriptRoot作为查找我希望通过相对路径调用的脚本的方法。我是否能够依赖于此始终为所述脚本提供相同/预期的路径?

  • 实施例002*

使用由Jenkins启动的PowerShell脚本调用的PowerShell脚本,我是否能够期望$PSScriptRoot能够为我提供该脚本实际所在的路径,或者它会给予我一个基于Jenkins的路径?
就我个人而言,我希望$PSScriptRoot能为我提供正在运行的脚本的实际物理位置,而不是根据调用它的初始脚本而变化的相对路径。
因为有了这种理解将帮助保存我很多时间和头痛,我希望像你这样的程序员可以帮助启发我,如果这是真的,为什么会发生这样的问题。
问题
我想知道使用$PSScriptRoot是否会在PowerShell Remoting中导致问题,从而使使用$MyInvocation成为更可行的选择?

vsdwdz23

vsdwdz231#

$PSScriptRoot.GetType().FullName
> System.String
$PSScriptRoot
> C:\Temp

字符串
$PSScriptRoot是一个自动变量,它只保存当前脚本目录的字符串对象。

$MyInvocation.GetType().FullName
> System.Management.Automation.InvocationInfo
$MyInvocation
> MyCommand             : test.ps1
> BoundParameters       : {}
> UnboundArguments      : {}
> ScriptLineNumber      : 0
> OffsetInLine          : 0
> HistoryId             : 4
> ScriptName            : 
> Line                  : 
> PositionMessage       : 
> PSScriptRoot          : 
> PSCommandPath         : 
> InvocationName        : C:\Temp\test.ps1
> PipelineLength        : 2
> PipelinePosition      : 1
> ExpectingInput        : False
> CommandOrigin         : Internal
> DisplayScriptPosition : 

$MyInvocation | Get-Member -Force
   TypeName: System.Management.Automation.InvocationInfo

Name                      MemberType   Definition                                                             
----                      ----------   ----------                                                             
pstypenames               CodeProperty System.Collections.ObjectModel.Collection`1[[System.String, mscorlib...
psadapted                 MemberSet    psadapted {MyCommand, BoundParameters, UnboundArguments, ScriptLineN...
psbase                    MemberSet    psbase {MyCommand, BoundParameters, UnboundArguments, ScriptLineNumb...
psextended                MemberSet    psextended {}                                                          
psobject                  MemberSet    psobject {BaseObject, Members, Properties, Methods, ImmediateBaseObj...
Equals                    Method       bool Equals(System.Object obj)                                         
GetHashCode               Method       int GetHashCode()                                                      
GetType                   Method       type GetType()                                                         
get_BoundParameters       Method       System.Collections.Generic.Dictionary[string,System.Object] get_Boun...
get_CommandOrigin         Method       System.Management.Automation.CommandOrigin get_CommandOrigin()         
get_DisplayScriptPosition Method       System.Management.Automation.Language.IScriptExtent get_DisplayScrip...
get_ExpectingInput        Method       bool get_ExpectingInput()                                              
get_HistoryId             Method       long get_HistoryId()                                                   
get_InvocationName        Method       string get_InvocationName()                                            
get_Line                  Method       string get_Line()                                                      
get_MyCommand             Method       System.Management.Automation.CommandInfo get_MyCommand()               
get_OffsetInLine          Method       int get_OffsetInLine()                                                 
get_PipelineLength        Method       int get_PipelineLength()                                               
get_PipelinePosition      Method       int get_PipelinePosition()                                             
get_PositionMessage       Method       string get_PositionMessage()                                           
get_PSCommandPath         Method       string get_PSCommandPath()                                             
get_PSScriptRoot          Method       string get_PSScriptRoot()                                              
get_ScriptLineNumber      Method       int get_ScriptLineNumber()                                             
get_ScriptName            Method       string get_ScriptName()                                                
get_UnboundArguments      Method       System.Collections.Generic.List[System.Object] get_UnboundArguments()  
set_DisplayScriptPosition Method       void set_DisplayScriptPosition(System.Management.Automation.Language...
ToString                  Method       string ToString()                                                      
BoundParameters           Property     System.Collections.Generic.Dictionary[string,System.Object] BoundPar...
CommandOrigin             Property     System.Management.Automation.CommandOrigin CommandOrigin {get;}        
DisplayScriptPosition     Property     System.Management.Automation.Language.IScriptExtent DisplayScriptPos...
ExpectingInput            Property     bool ExpectingInput {get;}                                             
HistoryId                 Property     long HistoryId {get;}                                                  
InvocationName            Property     string InvocationName {get;}                                           
Line                      Property     string Line {get;}                                                     
MyCommand                 Property     System.Management.Automation.CommandInfo MyCommand {get;}              
OffsetInLine              Property     int OffsetInLine {get;}                                                
PipelineLength            Property     int PipelineLength {get;}                                              
PipelinePosition          Property     int PipelinePosition {get;}                                            
PositionMessage           Property     string PositionMessage {get;}                                          
PSCommandPath             Property     string PSCommandPath {get;}                                            
PSScriptRoot              Property     string PSScriptRoot {get;}                                             
ScriptLineNumber          Property     int ScriptLineNumber {get;}                                            
ScriptName                Property     string ScriptName {get;}                                               
UnboundArguments          Property     System.Collections.Generic.List[System.Object] UnboundArguments {get;} 

Function Example { $MyInvocation } Example

MyCommand             : Example
BoundParameters       : {}
UnboundArguments      : {}
ScriptLineNumber      : 8
OffsetInLine          : 1
HistoryId             : 6
ScriptName            : C:\Temp\test.ps1
Line                  : Example
PositionMessage       : At C:\Temp\test.ps1:8 char:1
                        + Example
                        + ~~~~~~~
PSScriptRoot          : C:\Temp
PSCommandPath         : C:\Temp\test.ps1
InvocationName        : Example
PipelineLength        : 1
PipelinePosition      : 1
ExpectingInput        : False
CommandOrigin         : Internal
DisplayScriptPosition :


$MyInvocation是一个自动变量,有着非常不同的类型,为每个作用域生成。它的成员和实用程序因作用域而异。

  • 在PSv5.1、Windows 7 SP1* 上完成的测试
kgsdhlau

kgsdhlau2#

记住,这两个变量都指向正在执行的 file。如果没有file,它们就是空的。
在远程处理中,就像使用Invoke-Command -ScriptBlock { }时一样,没有文件。
如果您在远程处理会话中调用模块中的函数,并且该函数使用$PSScriptRoot$MyInvocaton...,则它可能会返回它所在的任何文件。
Jenkins创建了一个临时文件,并从该文件中运行代码,因此该文件将被返回。

qybjjes1

qybjjes13#

虽然(Split-Path -Parent ($MyInvocation.MyCommand.Path))是返回路径的两个命令选项中较长的一个,正如@'Maximilian Burszley'指出的那样,$PSScriptRoot是一个简单的字符串,如果你从一个模块或子脚本中调用,而不是与主脚本位于同一路径中,那么$PSScriptRoot可能会返回一个错误的路径。
更大的陷阱(IMO)是从子作用域调用任何一个命令,就像上面指出的使用Invoke-Command -ScriptBlock { }时一样。

相关问题