Powershell Invoke-Command导致RegEx错误

时间:2016-04-25 14:10:59

标签: powershell release-management tfs2015

我使用Invoke-Command在远程服务器上执行powershell表达式。我在命令执行时收到正则表达式错误。似乎powershell在内部使用RegEx来解析参数,但出于某种原因,它在这种情况下失败了。

特别令人困惑的是,在Invoke-Command调用中根本没有使用似乎导致解析错误的变量。我的猜测是发生某种变量捕获,以便可以在远程执行脚本中引用变量(通过"使用"范围),这对于我的$ ArtifactDirectory参数来说是失败的。我知道$ ArtifactDirectory param导致问题只是因为"正则表达式的值#34;异常是$ 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()]

2 个答案:

答案 0 :(得分:1)

我最终重写了整个脚本,神奇地说,错误消失了。正如其他人所指出的,尝试上面脚本的简单版本可以正常工作。实际上,它可以通过TFS Release手动执行和执行。

最后,错误似乎与稍后在脚本中的文件复制操作有关 - 但是如果上面的Invoke-Command调用被删除,那么文件复制操作正常

所以我不确定发生了什么,但是执行远程命令和后续执行以下脚本之间存在一些交互:

select d.report_date, s.security_id,
       (select top 1 t.return_usd
        from t
        where t.report_date <= d.report_date and t.security_id = d.security_id and
              t.return_usd is not null
        order by t.report_date desc
       ) as return_usd
from (select distinct report_date from t) d cross join
     (select distinct security_id from t) s left join
     t
     on t.report_date = d.report_date and t.security_id = s.security_id;

无论如何,我将上面的脚本重构为一个模块/函数,问题完全消失了。

答案 1 :(得分:0)

我试过,它适用于普通的PowerShell。正如您在问题中所指出的,这肯定是TFS Release管理问题,它是对输入参数的处理。

解决方案/解决方法:请尝试转义路径"C:\MSAgent\_work\66f1e4ebb\Cc - (WIP)\CC - My Cool App"中的所有特殊字符。 PowerShell中的转义序列是字符\

为方便起见,这里的路径应该是如何使用转义序列:

"C:\\MSAgent\\_work\\66f1e4ebb\\Cc - \(WIP\)\\CC - My Cool App"