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

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

C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe -verb: sync -source: dbfullsql = "Источник данных = mysource; Integrated Security = false; User ID = sa; Pwd = sapass!, Database = MYDB;" -dest: dbfullsql = "Источник данных =.\mydestsource; Integrated Security = false; User ID = sa; Pwd = sapass!, Database = mydb;", computername = 10.10.10.10, username = administrator, password = adminpass "

Ответ 1

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

PS> "Hello World"
Hello World

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

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

После этого вам, вероятно, нужно только указать пары параметров/аргументов, содержащие пробелы и/или цитаты. Когда вы вызываете EXE файл, подобный этому, с помощью сложных аргументов командной строки, обычно очень полезно иметь инструмент, который покажет вам, как PowerShell отправляет аргументы в EXE файл. В PowerShell Community Extensions есть такой инструмент. Это называется эхолотами. Вы просто заменяете EXE файл эхолотами - оставляя все аргументы на месте, и он покажет вам, как 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>

Используя эхо-сигналы, вы можете поэкспериментировать, пока не получите это правильно, например:

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 анализирует, просмотрите мою Эффективную серию блога PowerShell - в частности элемент 10 - "Общие сведения о синтаксическом анализе PowerShell"

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

Ответ 2

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

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

& $fileExe  /CONFIGURATIONFILE=$CONFIGURATIONFILE

Ответ 3

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

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

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

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

Ответ 4

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

& '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 должна сделать этот способ более простым и совместимым с синтаксисом командной строки.

Ответ 6

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

.....>.\file.exe

или же

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

Ответ 7

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

Существуют и другие методы, такие как использование оператора вызова (&), командлета 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

Ответ 8

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

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" и т.д. Мне удалось запустить его только после удаления всех пробелов из строки подключения.

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

Ответ 9

Новая escape-строка в PowerShell V3, приведенная в Новые функции языка V3:

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

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

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

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

Ответ 10

Я попробовал все предложения, но все еще не смог запустить 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()

Ответ 11

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

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

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

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

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

Ответ 12

Альтернативным ответом является использование 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

Ответ 13

Вы можете запускать 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 был скомпилирован или сделан его создателями.

Ответ 14

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

& $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 до последней версии он снова начал работать.

Ответ 15

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

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

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

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

Ответ 16

Для исполняемого имени можно использовать командлет 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

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

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

Ответ 17

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

Я помещаю аргументы в массив, по 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";

Ответ 18

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

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.