我正在使用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