$ PSScriptRoot和$ MyInvocation

时间:2017-08-10 13:32:49

标签: powershell powershell-remoting automatic-variable

问题

我正在与Jenkins合作远程部署PowerShell脚本。因此,我试图找出使用$PSScriptRoot而不是$MyInvocation.MyCommand.Path来获取当前脚本根目录的问题。

详细信息

一位同事告诉我,利用$PSScriptRoot对于远程功能来说是一个坏主意,因为我偶尔会发现它在运行时由于某种原因没有返回预期值,即使它之前有效。但是,无法解释为什么会这样。

在我的研究中,我没有发现任何可以进一步解释这一点的内容或者避免这种问题的最佳实践方法。我主要发现这两个基本上是可以互换的;但是,$PSScriptRoot只能 才能在PowerShell v3或更高版本中使用。通过你们中的几个人的帮助,我也开始了解$MyInvocation具有允许它根据范围和模块进行更改的情境差异。但我仍然没有发现PowerShell Remoting是否存在问题或原因。

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

示例002
使用由Jenkins启动的PowerShell脚本调用的PowerShell脚本,我能够期望$PSScriptRoot能够为我提供该脚本实际所在位置的路径,还是会给我一个基于路径的路径詹金斯?

就个人而言,我期望两者都是$PSScriptRoot将为我提供正在运行的脚本的实际物理位置,而不是基于调用它的初始脚本而改变的相对路径。

由于有了这样的理解会帮助我省下很多时间和头痛,我希望像你这样的程序员可以帮助启发我,如果这是真的,以及为什么会出现这样的问题。

问题

我试图找出使用$PSScriptRoot是否会导致我在PowerShell Remoting中出现问题会导致使用$MyInvocation更可行的选项?

2 个答案:

答案 0 :(得分:3)

$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上完成测试

答案 1 :(得分:3)

请记住,这两个变量都是指正在执行的文件。如果没有文件,则为空。

在远程处理中,就像使用Invoke-Command -ScriptBlock { }时一样,没有文件。

如果您正在调用远程会话中的模块中的函数,它可能会有效,并且该函数使用$PSScriptRoot$MyInvocaton...,在这种情况下它可能会返回它所在的文件。

在詹金斯之类的情况下,这不是远程的。 Jenkins创建一个临时文件并运行你的代码,这就是要返回的文件。