2016-04-25 7 views
1

Я использую Invoke-Command для выполнения выражения powershell на удаленном сервере. При выполнении команды возникает ошибка регулярного выражения. Кажется, что PowerShell использует RegEx внутренне для анализа аргументов, но по какой-то причине он не работает в этом сценарии.Powershell Invoke-Command в результате ошибки RegEx

Что особенно смущает то, что переменная, которая, как представляется, вызывает ошибку синтаксического анализа, вообще не используется в вызове Invoke-Command. Я предполагаю, что происходит какой-то захват переменных, поэтому переменные можно ссылаться в удаленном исполняемом скрипте (через область «использование»), и это не работает для моего параметра $ ArtifactDirectory. Я знаю, что параметр $ ArtifactDirectory вызывает проблему только потому, что значение для выражения «выражение регулярного выражения» в исключении - это значение параметра $ 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 Release):

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

Я думаю, что вижу пример того, как вы делаете '$ someFancyCommand' с' $ ArtifactDirectory'? Я предполагаю, что ошибка отличается, если вы на самом деле выполняли приведенную выше команду. Также почему 'invoke-expression'? Почему бы не просто '-Command'? – Matt

+0

$ ArtifactDirectory не используется * вообще * для $ someFancyCommand.Этот $ ArtifactDirectory используется в другом месте в MyScript.ps1 долго после вызова Invoke-Command. Выполняемое выражение в основном представляет собой командную строку TopShelf для запуска/остановки/установки и т. Д. Службы Windows. Само выражение будет выглядеть как «&» c: \ myapp \ host.exe «start». Как я уже упоминал в своем сообщении, сама команда, похоже, не имеет значения - я могу заменить ее простым Write-Host, который вообще не использует никаких переменных, и он все еще терпит неудачу. Когда вы говорите «почему бы не просто« комманда », о чем вы говорите? – RMD

+0

Если ошибка связана с '$ ArtifactDirectory', тогда почему мы не видим ее в использовании (если ошибка исходила от PowerShell)? Я предположил, что они связаны друг с другом и что вы просто запускаете какой-то exe, поэтому я поставил под сомнение ваше использование IEX. 'Invoke-Command -Command' работал бы так же хорошо в этом случае ... Снова я пытался выяснить отношение переменной к вашему коду. Я ничего не имею о TFS, так что это может быть просто мое невежество. Ошибка при выходе из управления выпуском TFS? – Matt

ответ

0

Я пробовал и работает с обычным PowerShell. Как вы отметили в своем вопросе, это определенно кажется проблемой управления выпуском TFS, и это обработка входных аргументов.

Разрешение/действие: Попробуйте выполнить все специальные символы на пути "C:\MSAgent\_work\66f1e4ebb\Cc - (WIP)\CC - My Cool App". Управляющая последовательность в PowerShell - это символ \.

Для вашего удобства здесь, как путь должен выглядеть с управляющей последовательностью:

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

Я в конечном итоге переписывания весь сценарий, и волшебно, ошибка ушла. Как указывали другие, попытка простой версии сценария выше работает отлично. Действительно, он отлично работает как вручную, так и выполняется через TFS Release.

В конце концов, ошибка, похоже, связана с операцией копирования файлов позже в сценарии - и все же операция копирования файла работала нормально , если вышеупомянутый вызов Invoke-Command был удален.

Так что я не уверен, что происходит, но было некоторое взаимодействие между выполнением удаленного управления и последующего выполнения следующего сценария:

Get-ChildItem -Path $sourceDirectory -Recurse -Exclude $exclude | 
    Copy-Item -Destination { 
     if ($_.PSIsContainer) { 
      Join-Path $ArtifactDirectory $_.Parent.FullName.Substring($sourceDirectory.length) 
     } else { 
      Join-Path $ArtifactDirectory $_.FullName.Substring($sourceDirectory.length) 
     } 
    } -Force -Exclude $exclude -Verbose 

Во всяком случае, я переработан выше скрипт в модуль/функцию, и проблема полностью исчезла.