我使用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()]
答案 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"