我正在使用Invoke-Command在遠程服務器上執行PowerShell表達式。執行命令時出現正則表達式錯誤。看起來好像powershell在內部使用RegEx來分析參數,但由於某種原因,它在這種情況下失敗。Powershell調用命令導致RegEx錯誤
特別令人困惑的是,在Invoke-Command調用中根本沒有使用看起來導致解析錯誤的變量。我的猜測是某種變量捕獲正在發生,因此可以在遠程執行的腳本中引用變量(通過「使用」範圍),並且這對我的$ ArtifactDirectory參數是失敗的。我知道這是導致問題的$ ArtifactDirectory param,只是因爲異常中「regex表達式」的值是$ ArtifactDirectory參數的值。
另一個重要的注意事項是我可以在TFS正在執行的同一臺機器上手動運行腳本(使用完全相同的參數值),而不會出錯。這告訴我這是某種會話選項,導致TFS構建/部署代理正在設置的問題。
下面是PowerShell腳本的相關部分:
param(
[string] $ArtifactDirectory,
[string] $ComputerName
)
$someFancyCommand = "this does not seem to matter"
Invoke-Command -ComputerName $ComputerName -ScriptBlock {
Invoke-Expression "$using:someFancyCommand"
}
這裏是我如何執行它(在這種情況下,通過TFS發佈管理):
MyScript.ps1 -ArtifactDirectory "C:\MSAgent\_work\66f1e4ebb\Cc - (WIP)\CC - My Cool App" -ComputerName "SomeComputer"
這裏完整的堆棧跟蹤:
2016-04-25T13:53:28.6024146Z [Exception:System.Management.Automation.RuntimeException: The regular
2016-04-25T13:53:28.6024146Z expression pattern {{C:\MSAgent\_work\66f1e4ebb\Cc - (WIP)\CC - My Cool App}} is not valid. --->
2016-04-25T13:53:28.6024146Z System.ArgumentException: parsing "{{C:\MSAgent\_work\66f1e4ebb\Cc - (WIP)\CC - My Cool App}}" -
2016-04-25T13:53:28.6024146Z Unrecognized escape sequence \M.
2016-04-25T13:53:28.6024146Z at System.Text.RegularExpressions.RegexParser.ScanCharEscape()
2016-04-25T13:53:28.6024146Z at System.Text.RegularExpressions.RegexParser.ScanBasicBackslash()
2016-04-25T13:53:28.6024146Z at System.Text.RegularExpressions.RegexParser.ScanRegex()
2016-04-25T13:53:28.6024146Z at System.Text.RegularExpressions.RegexParser.Parse(String re, RegexOptions op)
2016-04-25T13:53:28.6024146Z at System.Text.RegularExpressions.Regex..ctor(String pattern, RegexOptions options, TimeSpan matchTimeout, Boolean
2016-04-25T13:53:28.6024146Z useCache)
2016-04-25T13:53:28.6024146Z at System.Text.RegularExpressions.Regex..ctor(String pattern, RegexOptions options)
2016-04-25T13:53:28.6024146Z at System.Management.Automation.ParserOps.NewRegex(String patternString, RegexOptions options)
2016-04-25T13:53:28.6024146Z at System.Management.Automation.ParserOps.ReplaceOperator(ExecutionContext context, IScriptExtent errorPosition,
2016-04-25T13:53:28.6226512Z Object lval, Object rval, Boolean ignoreCase)
2016-04-25T13:53:28.6226512Z --- End of inner exception stack trace ---
2016-04-25T13:53:28.6226512Z at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception
2016-04-25T13:53:28.6226512Z exception)
2016-04-25T13:53:28.6226512Z at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
2016-04-25T13:53:28.6226512Z at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
2016-04-25T13:53:28.6226512Z at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
2016-04-25T13:53:28.6226512Z at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
2016-04-25T13:53:28.6226512Z at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
2016-04-25T13:53:28.6336645Z at System.Management.Automation.ScriptBlock.InvokeWithPipeImpl(ScriptBlockClauseToInvoke clauseToInvoke, Boolean
2016-04-25T13:53:28.6336645Z createLocalScope, Dictionary`2 functionsToDefine, List`1 variablesToDefine, ErrorHandlingBehavior
2016-04-25T13:53:28.6336645Z errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Pipe outputPipe, InvocationInfo
2016-04-25T13:53:28.6336645Z invocationInfo, Object[] args)
2016-04-25T13:53:28.6336645Z at System.Management.Automation.ScriptBlock.<>c__DisplayClassa.<InvokeWithPipe>b__8()
2016-04-25T13:53:28.6336645Z at System.Management.Automation.Runspaces.RunspaceBase.RunActionIfNoRunningPipelinesWithThreadCheck(Action action)
2016-04-25T13:53:28.6336645Z at System.Management.Automation.ScriptBlock.InvokeWithPipe(Boolean useLocalScope, ErrorHandlingBehavior
2016-04-25T13:53:28.6336645Z errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Pipe outputPipe, InvocationInfo
2016-04-25T13:53:28.6336645Z invocationInfo, Boolean propagateAllExceptionsToTop, List`1 variablesToDefine, Dictionary`2 functionsToDefine, Object[]
2016-04-25T13:53:28.6336645Z args)
2016-04-25T13:53:28.6336645Z at System.Management.Automation.ScriptBlock.InvokeUsingCmdlet(Cmdlet contextCmdlet, Boolean useLocalScope,
2016-04-25T13:53:28.6336645Z ErrorHandlingBehavior errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Object[] args)
2016-04-25T13:53:28.6336645Z at Microsoft.PowerShell.Commands.ForEachObjectCommand.ProcessRecord()
2016-04-25T13:53:28.6336645Z at System.Management.Automation.CommandProcessor.ProcessRecord()]
我想看看你如何用'$ ArtifactDirectory'生成'$ someFancyCommand'的例子嗎?我想如果你真的運行了上面列表中的命令,錯誤是不同的。還有爲什麼'invoke-expression'?爲什麼不只是「命令」? – Matt
對於$ someFancyCommand,$ ArtifactDirectory不被使用*。該$ ArtifactDirectory在Invoke-Command調用後的很長時間內在MyScript.ps1中的其他地方使用。正在執行的表達式基本上是一個TopShelf命令行來啓動/停止/安裝等Windows服務。表達式本身看起來像「&'c:\ myapp \ host.exe'start」。正如我在我的文章中提到的那樣,命令本身似乎並不重要 - 我可以用一個簡單的寫主機代替它,它根本不使用變量,它仍然失敗。 當你說「爲什麼不只是 - 命令」,你指的是什麼? – RMD
如果錯誤與'$ ArtifactDirectory'相關,那我們爲什麼不看它在使用中(如果錯誤來自PowerShell)?我假設他們是相關的,並且你只是運行一些exe文件,所以我質疑你對IEX的使用。 'Invoke-Command -Command'在這種情況下也會起作用......我又試圖弄清楚變量與代碼的關係。我對TFS一無所知,這可能只是我的無知。錯誤來自TFS發佈管理嗎? – Matt