Как запустить EXE-файл в PowerShell с параметрами с пробелами и кавычками

Как запустить следующую команду в PowerShell?

C: \ Program Files \ IIS \ Microsoft Web Deploy \ msdeploy.exe -verb: sync -source: dbfullsql = "Источник данных = mysource; Интегрированная безопасность = false; ID пользователя =sa;Pwd=sapass!; База данных =mydb;" -dest:dbfullsql="Источник данных =. \ mydestsource; Интегрированная безопасность = false; ID пользователя =sa;Pwd=sapass!; База данных =mydb;", имя_компьютера =10.10.10.10, имя пользователя = администратор, пароль = adminpass "

21 ответ

Когда PowerShell видит команду, начинающуюся со строки, он просто оценивает строку, то есть обычно выводит ее на экран, например:

PS> "Hello World"
Hello World

Если вы хотите, чтобы PowerShell интерпретировал строку как имя команды, используйте оператор вызова (&) следующим образом:

PS> & 'C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe'

После этого вам, вероятно, нужно только заключить в кавычки пары параметр / аргумент, содержащие пробелы и / или символы кавычек. Когда вы вызываете такой EXE-файл со сложными аргументами командной строки, обычно очень полезно иметь инструмент, который покажет вам, как PowerShell отправляет аргументы в EXE-файл. Расширения сообщества PowerShell имеют такой инструмент. Это называется эхомарки. Вы просто замените EXE-файл на echoargs, оставив все аргументы на месте, и он покажет вам, как EXE-файл получит эти аргументы, например:

PS> echoargs -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass

Arg 0 is <-verb:sync>
Arg 1 is <-source:dbfullsql=Data>
Arg 2 is <Source=mysource;Integrated>
Arg 3 is <Security=false;User>
Arg 4 is <ID=sa;Pwd=sapass!;Database=mydb;>
Arg 5 is <-dest:dbfullsql=Data>
Arg 6 is <Source=.\mydestsource;Integrated>
Arg 7 is <Security=false;User>
Arg 8 is <ID=sa;Pwd=sapass!;Database=mydb; computername=10.10.10.10 username=administrator password=adminpass>

Используя echoargs, вы можете экспериментировать, пока не поймете это правильно, например:

PS> echoargs -verb:sync "-source:dbfullsql=Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;"
Arg 0 is <-verb:sync>
Arg 1 is <-source:dbfullsql=Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;>

Оказывается, я слишком старался, чтобы сохранить двойные кавычки вокруг строки подключения. Очевидно, что в этом нет необходимости, потому что даже cmd.exe удалит их.

Кстати, снимаю шляпу перед командой PowerShell. Они очень помогли мне показать конкретное заклинание одинарных и двойных кавычек, чтобы получить желаемый результат - если вам нужно было сохранить внутренние двойные кавычки на месте.:-) Они также понимают, что это область боли, но они движимы количеством людей, затронутых конкретной проблемой. Если это для вас проблема, пожалуйста, проголосуйте за эту ошибку PowerShell.

Для получения дополнительной информации о синтаксическом анализе PowerShell см. Мою серию блогов Effective PowerShell - в частности, пункт 10 - "Общие сведения о режимах синтаксического анализа PowerShell".

ОБНОВЛЕНИЕ 4/4/2012: С этой ситуацией намного легче справиться в PowerShell V3. Смотрите этот блог для деталей.

У меня были пробелы как в команде, так и в параметрах, и вот что у меня сработало:

$Command = "E:\X64\Xendesktop Setup\XenDesktopServerSetup.exe"
$Parms = "/COMPONENTS CONTROLLER,DESKTOPSTUDIO,DESKTOPDIRECTOR,LICENSESERVER,STOREFRONT /PASSIVE /NOREBOOT /CONFIGURE_FIREWALL /NOSQL"

$Prms = $Parms.Split(" ")
& "$Command" $Prms

По сути, это то же самое, что и ответ Акиры, но это работает, если вы динамически строите параметры своей команды и помещаете их в переменную.

Просто добавьте оператор & перед именем.exe. Вот команда для установки SQL Server Express в режиме молчания:

$fileExe = "T:\SQLEXPRADV_x64_ENU.exe"
$CONFIGURATIONFILE = "T:\ConfSetupSql2008Express.ini"

& $fileExe  /CONFIGURATIONFILE=$CONFIGURATIONFILE

Есть немало методов, которые вы можете использовать для этого.

Существуют и другие методы, такие как использование оператора вызова (&), командлета Invoke-Expression и т. Д. Но они считаются небезопасными. Microsoft рекомендует использовать Start-Process.

Способ 1

Простой пример

Start-Process -NoNewWindow -FilePath "C:\wamp64\bin\mysql\mysql5.7.19\bin\mysql" -ArgumentList "-u root","-proot","-h localhost"

В твоем случае

Start-Process -NoNewWindow -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync","-source:dbfullsql=`"Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`"","-dest:dbfullsql=`"Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`"","computername=10.10.10.10","username=administrator","password=adminpass"

В этом методе вы разделяете каждый параметр в ArgumentList с помощью запятых.

Способ 2

Простой пример

Start-Process -NoNewWindow -FilePath "C:\wamp64\bin\mysql\mysql5.7.19\bin\mysql" -ArgumentList "-u root -proot -h localhost"

В твоем случае

Start-Process -NoNewWindow -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync -source:dbfullsql=`"Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`" -dest:dbfullsql=`"Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;`",computername=10.10.10.10,username=administrator,password=adminpass"

Этот метод проще, так как позволяет вводить параметры за один раз.

Обратите внимание, что в PowerShell для представления кавычки ( ") в строке необходимо вставить серьезный акцент (`) (это клавиша над клавишей Tab на клавиатуре США).

ПараметрNoNewWindow используется для отображения нового процесса в текущем окне консоли. По умолчанию Windows PowerShell открывает новое окно.

Ссылки: Powershell / Scripting / Start-Process

Это сработало для меня:

& 'D:\Server\PSTools\PsExec.exe' @('\\1.1.1.1', '-accepteula', '-d', '-i', $id, '-h', '-u', 'domain\user', '-p', 'password', '-w', 'C:\path\to\the\app', 'java', '-jar', 'app.jar')

Просто поместите пути или строки соединения в один элемент массива и разбейте остальные элементы в одном элементе массива каждый.

Здесь есть много других вариантов: https://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx

Microsoft должна сделать этот способ более простым и совместимым с синтаксисом командной строки.

В случае, если кому-то интересно, как запустить исполняемый файл:

.....>. \ file.exe

или же

......> full\path\to\file.exe

Смотрите эту страницу: http://edgylogic.com/blog/powershell-and-external-commands-done-right/

Сводка с использованием vshadow в качестве внешнего исполняемого файла:

$exe = "H:\backup\scripts\vshadow.exe"
&$exe -p -script=H:\backup\scripts\vss.cmd E: M: P:

Вы можете использовать:

Start-Process -FilePath "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -ArgumentList "-verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"

Ключевым моментом здесь является то, что FilePath должен находиться в позиции 0, согласно справочному руководству. Чтобы вызвать справочное руководство для командлета, просто введитеGet-Help <Commandlet-name> -Detailed. В данном случае этоGet-Help Start-Process -Detailed.

Новая escape-строка в PowerShell V3, процитированная из New V3 Language Features:

Более простое повторное использование командных строк из Cmd.exe

В Интернете полно командных строк, написанных для Cmd.exe. Эти командные строки работают достаточно часто в PowerShell, но когда они содержат определенные символы, например, точку с запятой (;), знак доллара ($) или фигурные скобки, вы должны внести некоторые изменения, возможно, добавив некоторые кавычки. Это казалось источником многих незначительных головных болей.

Чтобы помочь решить этот сценарий, мы добавили новый способ "избежать" анализа командных строк. Если вы используете магический параметр -%, мы прекращаем обычный синтаксический анализ вашей командной строки и переключаемся на что-то гораздо более простое. Мы не сопоставляем кавычки. Мы не останавливаемся на точке с запятой. Мы не расширяем переменные PowerShell. Мы расширяем переменные среды, если вы используете синтаксис Cmd.exe (например,%TEMP%). Кроме этого, аргументы до конца строки (или канала, если вы передаете по трубопроводу) передаются как есть. Вот пример:

PS> echoargs.exe --% %USERNAME%,this=$something{weird}
Arg 0 is <jason,this=$something{weird}>

Мне удалось заставить мою подобную команду работать, используя следующий подход:

msdeploy.exe -verb=sync "-source=dbFullSql=Server=THESERVER;Database=myDB;UID=sa;Pwd=saPwd" -dest=dbFullSql=c:\temp\test.sql

Для вашей команды (не то, чтобы это сильно помогло сейчас) все будет выглядеть примерно так:

msdeploy.exe -verb=sync "-source=dbfullsql=Server=mysource;Trusted_Connection=false;UID=sa;Pwd=sapass!;Database=mydb;" "-dest=dbfullsql=Server=mydestsource;Trusted_Connection=false;UID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass

Ключевые моменты:

  • Используйте кавычки вокруг исходного аргумента и удаляйте встроенные кавычки вокруг строки подключения
  • Используйте альтернативные имена ключей при построении строки подключения SQL, в которой нет пробелов. Например, используйте "UID" вместо "User Id", "Server" вместо "Source Data", "Trusted_Connection" вместо "Integrated Security" и т. Д. Я смог заставить его работать только после удаления всех пробелов из строки подключения.

Я не пытался добавить часть "computername" в конце командной строки, но, надеюсь, эта информация поможет другим, читающим это, приблизиться к желаемому результату.

Я использую этот простой, чистый и эффективный метод.

Я помещаю аргументы в массив, по 1 на строку. Таким образом, его очень легко читать и редактировать. Затем я использую простой прием передачи всех аргументов внутри двойных кавычек в функцию с одним единственным параметром. Это объединяет их, включая массивы, в одну строку, которую я затем выполняю, используя PS "Invoke-Expression". Эта директива специально предназначена для преобразования строки в команду runnable. Работает хорошо:

                    # function with one argument will flatten 
                    # all passed-in entries into 1 single string line
Function Execute($command) {
                    # execute:
    Invoke-Expression $command;
                    # if you have trouble try:
  # Invoke-Expression "& $command";
                    # or if you need also output to a variable
  # Invoke-Expression $command | Tee-Object -Variable cmdOutput;

}

#  ... your main code here ...

               # The name of your executable app
$app = 'my_app.exe';
               # List of arguments:
               #    Notice the type of quotes - important !
               #    Those in single quotes are normal strings, like 'Peter'
$args = 'arg1',
        'arg2',
        $some_variable,
        'arg4',
        "arg5='with quotes'",
        'arg6',
        "arg7 \ with \ $other_variable",
        'etc...';

               # pass all arguments inside double quotes
Execute "$app $args";

Вы можете запускать exe-файлы в PowerShell различными способами. Например, если вы хотите запустить unrar.exe и извлечь файл.rar, вы можете просто написать в powershell это:

$extract_path = "C:\Program Files\Containing folder";
$rar_to_extract = "C:\Path_to_arch\file.rar"; #(or.exe if its a big file)  
C:\Path_here\Unrar.exe x -o+ -c- $rar_to_extract $extract_path;

Но иногда это не работает, поэтому вы должны использовать параметр &, как показано выше: Например, с vboxmanage.exe (инструментом для управления виртуальными машинами virtualbox) вы должны вызывать параметры вне строки, например, без кавычек:

> $vmname = "misae_unrtes_1234123"; #(name too long, we want to change this)
> & 'C:\Program Files\Oracle\VirtualBox\VBoxManage.exe' modifyvm $vmname --name UBUNTU;

Если вы хотите просто вызвать заархивированный файл winrar как файлы.exe, вы также можете разархивировать его с помощью командлета invoke-command и параметра Silent /S (он будет извлечен в той же папке, в которой он был сжат).

> Invoke-Command -ScriptBlock { C:\Your-path\archivefile.exe /S };

Таким образом, существует несколько способов запуска файлов.exe с аргументами в powershell.

Иногда нужно найти обходной путь, чтобы заставить его работать должным образом, что может потребовать дополнительных усилий и усилий:) в зависимости от того, как.exe был скомпилирован или сделан его создателями.

Я перепробовал все предложения, но все равно не смог запустить msiexec.exe с параметрами, содержащими пробелы. Таким образом, мое решение в конечном итоге с использованием System.Diagnostics.ProcessStartInfo:

# can have spaces here, no problems
$settings = @{
  CONNECTION_STRING = "... ..."
  ENTITY_CONTEXT = "... ..."
  URL = "..."
}

$settingsJoined = ($settings.Keys | % { "$_=""$($settings[$_])""" }) -join " "
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.WorkingDirectory = $ScriptDirectory
$pinfo.FileName = "msiexec.exe"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "/l* install.log /i installer.msi $settingsJoined"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$stdout = $p.StandardOutput.ReadToEnd()

Cmd может справиться с запуском указанного в кавычках exe, но Powershell - нет. Я просто займусь запуском самого exe, так как у меня его нет. Если вам буквально нужно отправить двойные кавычки в аргумент внешней команды, это еще одна проблема, о которой говорилось в другом месте.

1) добавьте папку exe на свой путь, возможно, в вашем профиле $

$env:path += ';C:\Program Files\IIS\Microsoft Web Deploy\'
msdeploy

2) цитируйте пробелы:

C:\Program` Files\IIS\Microsoft` Web` Deploy\msdeploy.exe

Это сработало для меня:

PowerShell.exe -Command "& ""C:\Some Script\Path With Spaces.ps1"""

Кажется, что ключ заключается в том, что вся команда заключена во внешние кавычки, амперсанд "&" используется для указания того, что выполняется другой дочерний файл команды, а затем, наконец, экранированные (doubled-double-) кавычки вокруг имени пути / файла с пробелами Вы хотели выполнить в первую очередь.

Это также завершение единственного обходного пути к проблеме подключения MS, при котором -File не передает обратно ненулевые коды возврата и -Command является единственной альтернативой. Но до сих пор считалось ограничением -Command то, что он не поддерживает пробелы. Я тоже обновил этот элемент обратной связи.

http://connect.microsoft.com/PowerShell/feedback/details/750653/powershell-exe-doesn-t-return-correct-exit-codes-when-using-the-file-option

Альтернативный ответ - использовать кодированный командный ключ Base64:

powershell -EncodedCommand "QwA6AFwAUAByAG8AZwByAGEAbQAgAEYAaQBsAGUAcwBcAEkASQBTAFwATQBpAGMAcgBvAHMAbwBmAHQAIABXAGUAYgAgAEQAZQBwAGwAbwB5AFwAbQBzAGQAZQBwAGwAbwB5AC4AZQB4AGUAIAAtAHYAZQByAGIAOgBzAHkAbgBjACAALQBzAG8AdQByAGMAZQA6AGQAYgBmAHUAbABsAHMAcQBsAD0AIgBEAGEAdABhACAAUwBvAHUAcgBjAGUAPQBtAHkAcwBvAHUAcgBjAGUAOwBJAG4AdABlAGcAcgBhAHQAZQBkACAAUwBlAGMAdQByAGkAdAB5AD0AZgBhAGwAcwBlADsAVQBzAGUAcgAgAEkARAA9AHMAYQA7AFAAdwBkAD0AcwBhAHAAYQBzAHMAIQA7AEQAYQB0AGEAYgBhAHMAZQA9AG0AeQBkAGIAOwAiACAALQBkAGUAcwB0ADoAZABiAGYAdQBsAGwAcwBxAGwAPQAiAEQAYQB0AGEAIABTAG8AdQByAGMAZQA9AC4AXABtAHkAZABlAHMAdABzAG8AdQByAGMAZQA7AEkAbgB0AGUAZwByAGEAdABlAGQAIABTAGUAYwB1AHIAaQB0AHkAPQBmAGEAbABzAGUAOwBVAHMAZQByACAASQBEAD0AcwBhADsAUAB3AGQAPQBzAGEAcABhAHMAcwAhADsARABhAHQAYQBiAGEAcwBlAD0AbQB5AGQAYgA7ACIALABjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQA9ADEAMAAuADEAMAAuADEAMAAuADEAMAAsAHUAcwBlAHIAbgBhAG0AZQA9AGEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIALABwAGEAcwBzAHcAbwByAGQAPQBhAGQAbQBpAG4AcABhAHMAcwAiAA=="

После декодирования вы увидите, что это оригинальный фрагмент OP со всеми аргументами и двойными кавычками.

powershell.exe -EncodedCommand

Accepts a base-64-encoded string version of a command. Use this parameter
to submit commands to Windows PowerShell that require complex quotation
marks or curly braces.

Оригинальная команда:

 C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"

Это превращается в это, когда закодировано как Base64:

QwA6AFwAUAByAG8AZwByAGEAbQAgAEYAaQBsAGUAcwBcAEkASQBTAFwATQBpAGMAcgBvAHMAbwBmAHQAIABXAGUAYgAgAEQAZQBwAGwAbwB5AFwAbQBzAGQAZQBwAGwAbwB5AC4AZQB4AGUAIAAtAHYAZQByAGIAOgBzAHkAbgBjACAALQBzAG8AdQByAGMAZQA6AGQAYgBmAHUAbABsAHMAcQBsAD0AIgBEAGEAdABhACAAUwBvAHUAcgBjAGUAPQBtAHkAcwBvAHUAcgBjAGUAOwBJAG4AdABlAGcAcgBhAHQAZQBkACAAUwBlAGMAdQByAGkAdAB5AD0AZgBhAGwAcwBlADsAVQBzAGUAcgAgAEkARAA9AHMAYQA7AFAAdwBkAD0AcwBhAHAAYQBzAHMAIQA7AEQAYQB0AGEAYgBhAHMAZQA9AG0AeQBkAGIAOwAiACAALQBkAGUAcwB0ADoAZABiAGYAdQBsAGwAcwBxAGwAPQAiAEQAYQB0AGEAIABTAG8AdQByAGMAZQA9AC4AXABtAHkAZABlAHMAdABzAG8AdQByAGMAZQA7AEkAbgB0AGUAZwByAGEAdABlAGQAIABTAGUAYwB1AHIAaQB0AHkAPQBmAGEAbABzAGUAOwBVAHMAZQByACAASQBEAD0AcwBhADsAUAB3AGQAPQBzAGEAcABhAHMAcwAhADsARABhAHQAYQBiAGEAcwBlAD0AbQB5AGQAYgA7ACIALABjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQA9ADEAMAAuADEAMAAuADEAMAAuADEAMAAsAHUAcwBlAHIAbgBhAG0AZQA9AGEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIALABwAGEAcwBzAHcAbwByAGQAPQBhAGQAbQBpAG4AcABhAHMAcwAiAA==

а вот как это сделать дома:

$command = 'C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb:sync -source:dbfullsql="Data Source=mysource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;" -dest:dbfullsql="Data Source=.\mydestsource;Integrated Security=false;User ID=sa;Pwd=sapass!;Database=mydb;",computername=10.10.10.10,username=administrator,password=adminpass"'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
$encodedCommand

#  The clip below copies the base64 string to your clipboard for right click and paste.
$encodedCommand | Clip

Для исполняемого имени можно использовать командлет new-alias, чтобы избежать использования пробелов или необходимости добавлять исполняемый файл в среду $PATH.

PS> new-alias msdeploy "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe"
PS> msdeploy ...

Чтобы перечислить или изменить псевдонимы PS также см.

PS> get-alias
PS> set-alias

От Джеффри Хикс

Другие ответы касаются аргументов.

Если вам просто нужно запустить файл в текущем каталоге и не хочется указывать весь путь по буквам, используйте Get-Location:

      & "$(Get-Location)\example.exe" arg1 arg2 arg3

Обратите внимание &на старте. Аргументы, разделенные пробелами, следует ставить после кавычек.

У меня был следующий код отлично работает на моем ноутбуке:

& $msdeploy `
-source:package="$publishFile" `
-dest:auto,computerName="$server",includeAcls="False",UserName="$username",Password="$password",AuthType="$auth" `
-allowUntrusted  `
-verb:sync  `
-enableRule:DoNotDeleteRule `
-disableLink:AppPoolExtension  `
-disableLink:ContentExtension  `
-disableLink:CertificateExtension  `
-skip:objectName=filePath,absolutePath="^(.*Web\.config|.*Environment\.config)$" `
-setParam:name=`"IIS Web Application Name`",value="$appName"

Затем, когда я попытался запустить это непосредственно на одном сервере, я начал получать эти ошибки "Unrecognized argument ...etc.... All arguments must begin with "-". "

Перепробовав все возможные обходные пути (безуспешно), я обнаружил, что Powershell на сервере (Windows 2008 R2) был версии 3.0, а на моем ноутбуке - 5.0. (вы можете использовать "$PSVersionTable", чтобы увидеть версию).

После обновления Powershell до последней версии он снова начал работать.

Чтобы передать пакетный сценарий с помощью exiftool.exe в сценарий PowerShell, я должен был задать команде '-s, "-s и даже ${Filename}, а с другой стороны указать переменные в этих параметрах.

Для начала: замена использования «эхо-символов» великолепна. Он четко показывает, что сгруппировано как один параметр, а что заканчивается следующим параметром.

В PowerShell это похоже на Perl (и скрипты unix): используемые кавычки имеют свое значение.

  • строки между "-s. Строка будет интерпретирована (переменные заполнены)
  • Строки между буквами "-s". Строка не будет интерпретироваться (или очень ограничена)
  • escape-символ - это `(обратная кавычка). Следующий символ теряет свое особое значение. Сравнимо с \ (обратным ходом) в unix / linux / perl.

Несколько примеров:

      ${ExifArgs} += "-if `"`${FileName} !~ /desktop.ini/i`""
${ExifArgs} += '-dateFormat "%Y\%Y%m\%Y%m%d_%H%M%S"'
${ExifArgs} += ('"' + "-FileName<${NewFotos}\${SourceName}\" + '${DateTimeOriginal}_${ImageWidth}x${ImageHeight}_${Model;s/ //g}_${FileName;s/^.*([0-9]{4})[^0-9].*$/\1/}.%e' + '"')

Вызов echoargs с указанным выше дает следующий результат (номера взломаны для конфиденциальности):

      Arg 11 is <-if>
Arg 12 is <${FileName} !~ /desktop.ini/i>
Arg 13 is <-dateFormat>
Arg 14 is <%Y\%Y%m\%Y%m%d_%H%M%S>
Arg 15 is <-FileName<D:\Pictures\NewFotos\${DateTimeOriginal}_${ImageWidth}x${ImageHeight}_${Model;s/ //g}_${FileName;s/^.*([0-9]{4})[^0-9].*$/\1/}.%e>

Посмотрите, как первая строка производит arg 11 и 12: внешние "-s" удаляются, чтобы сохранить всю строку в массиве. Внутренние "-s", заключенные в кавычки, используются для сохранения аргумента (в то время как - если предыдущий аргумент)

Второй показывает аргументы 13 и 14: использование "-s" между "-s". Нет необходимости использовать "-s" для выхода.

В последней строке (с аргументом 15): одна строка создается с использованием powershell () -s и + -s для объединения пары строк в одну строку. Он использует строки с разделителями "и", чтобы som ${}-s заполнялись с помощью powershell, а некоторые - с помощью exiftool. И да, некоторые специальные символы PowerShell передаются в архивы.

Итак, я столкнулся с подобной проблемой и решил решить ее следующим образом:

  1. Избегайте кавычек (") с помощью символа обратной черты (`)
  2. Окружите свое новое выражение кавычками (")
  3. Используя оператор вызова (&), введите команду invoke-expression на новой строке

Пример решения:

& {invoke-expression "C: \ Program Files \ IIS \ Microsoft Web Deploy \ msdeploy.exe -verb: sync -source: dbfullsql =` "Источник данных = mysource; Интегрированная безопасность =false; ID пользователя =sa;Pwd=sapass!; База данных =mydb;`" -dest:dbfullsql=`" Источник данных =.\ Mydestsource; Интегрированная безопасность =false; ID пользователя =sa;Pwd=sapass!; База данных =mydb;`", имя_компьютера =10.10.10.10, имя пользователя = администратор, пароль =adminpass`"" }

Другие вопросы по тегам