Como executar um ficheiro EXE em PowerShell com parâmetros com espaços e aspas

Como se executa o seguinte comando em PowerShell?

C:\Program ficheiros\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=administrador, password=adminpass "

Author: Peter Mortensen, 2009-11-04

14 answers

Quando o PowerShell vê um comando a começar por uma cadeia, apenas avalia a cadeia, isto é, normalmente ecoa-a na tela, por exemplo:

PS> "Hello World"
Hello World

Se quiser que o PowerShell interprete o texto como um nome de comando, então use o operador de chamadas ( & ) assim:

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

Depois disso, provavelmente só terá de citar pares de parâmetros/argumentos que contenham espaços e/ou caracteres de citação. Quando invoca um ficheiro EXE como este com argumentos complexos da linha de comandos, é normalmente muito útil para ter uma ferramenta que lhe mostrará como PowerShell envia os argumentos para o arquivo EXE. O PowerShell Community Extensions tem tal ferramenta. Chama-se echoargs. Basta substituir o ficheiro EXE por echoargs-deixando todos os argumentos no lugar, e ele mostrar-lhe-á como o ficheiro EXE irá receber os argumentos, por exemplo:

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>

Usando echoargs pode experimentar até acertar, por exemplo:

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;>
Parece que eu estava a esforçar-me demais. para manter as aspas em torno do texto da ligação. Aparentemente isso não é necessário porque até o cmd.a exe tira - os. Já agora, tiro o chapéu à equipa PowerShell. Eles foram bastante úteis em me mostrar o encantamento específico de aspas simples e duplas para obter o resultado desejado-se você precisava manter as aspas internas no lugar. :- ) Eles também percebem que esta é uma área de dor, mas eles são impulsionados pelo número de pessoas são afetadas por uma questão particular. Se isto for uma área de dor para si, então, por favor, vote esta submissão PowerShell bug [[11]].

Para mais informações sobre como o PowerShell analisa, veja a minha série de PowerShell blog - especificamente item 10 - "compreender os modos de análise PowerShell"

Atualização 4/4/2012: esta situação fica muito mais fácil de lidar em PowerShell V3. Veja este post no blog para mais detalhes .

 263
Author: Keith Hill, 2015-07-11 23:22:30

Basta adicionar o & operadora antes de ... nome exe. Aqui está um comando para instalar o servidor SQL Express No modo Silêncio:

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

& $fileExe  /CONFIGURATIONFILE=$CONFIGURATIONFILE
 47
Author: nonolde1er, 2013-09-19 04:13:42

Eu tinha espaços tanto no comando como nos parâmetros, e foi isto que funcionou para mim:

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

$Prms = $Parms.Split(" ")
& "$Command" $Prms
É basicamente a mesma resposta de Akira, mas isso funciona se você construir dinamicamente seus parâmetros de comando e colocá-los em uma variável.
 33
Author: Microb, 2014-03-07 11:10:48
Isto funcionou comigo.
& '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')

Basta colocar caminhos ou cadeias de ligação em um item de array e dividir as outras coisas em um item de array cada.

Há muitas outras opções aqui: https://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx

A Microsoft deve tornar esta forma mais simples e compatível com a sintaxe da linha de comandos.

 13
Author: Akira Yamamoto, 2013-11-28 17:43:07

Ver esta página: http://edgylogic.com/blog/powershell-and-external-commands-done-right/

Resumo usando o vshadow como executável externo:

$exe = "H:\backup\scripts\vshadow.exe"
&$exe -p -script=H:\backup\scripts\vss.cmd E: M: P:
 10
Author: Baodad, 2012-09-10 18:44:18

Consegui pôr o meu comando similar a funcionar usando a seguinte abordagem:

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

Para o seu comando( não que ajude muito agora), as coisas seriam algo parecido com isto:

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

Os pontos-chave são:

  • usar aspas em torno do argumento de origem e remover as aspas incorporadas em torno do texto de ligação
  • Use os nomes de chaves alternativos na construção do texto de ligação SQL que não tem espaços neles. Por exemplo, use " UID " em vez de "User Id", " Server "instead of" Data Source"," Trusted_Connection "instead of" Integrated Security", and so forth. Só consegui pô-lo a funcionar quando removi todos os espaços da corda de ligação.

Eu não tentei adicionar a parte do "computername" no final da linha de comando, mas espero que esta informação ajude os outros a ler isto agora chegar mais perto do seu resultado desejado.

 8
Author: G-Mac, 2011-01-11 17:07:50
No caso de alguém querer saber como executar um ficheiro executável:

..... > .\arquivo.exe

Ou

......> \ localização completa\para\Ficheiro.exe

 6
Author: darkgaze, 2018-02-20 11:00:23

Nova corda de escape em PowerShell V3, citada de novas funcionalidades da linguagem V3:

Reutilização mais fácil das linhas de comando do Cmd.exe

A web está cheia de linhas de comando escritas para o Cmd.exe. Estas linhas de comandos funcionam muitas vezes o suficiente em PowerShell, mas quando eles incluem certos caracteres, por exemplo, um ponto e vírgula (;), um sinal de dólar ($), ou Chavetas, você tem que fazer algumas alterações, provavelmente adicionando algumas citações. Esta parecia ser a fonte de muitos pequenas dores de cabeça.

Para ajudar a resolver este cenário, adicionámos uma nova forma de" escapar " ao processamento das linhas de comando. Se você usar um parâmetro mágico--%, nós paramos nosso processamento normal de sua linha de comando e mudamos para algo muito mais simples. Não combinamos aspas. Não paramos no ponto e vírgula. Não expandimos variáveis PowerShell. Nós expandimos variáveis de ambiente se você usar Cmd.sintaxe exe (por exemplo, %TEMP%). Além disso, os argumentos até o final da linha (ou tubo, se você estiver piping) são passou como está. Aqui está um exemplo:

PS> echoargs.exe --% %USERNAME%,this=$something{weird}
Arg 0 is <jason,this=$something{weird}>
 5
Author: Loïc MICHEL, 2015-07-11 23:25:00
Isto funcionou comigo.
PowerShell.exe -Command "& ""C:\Some Script\Path With Spaces.ps1"""

A chave parece ser que todo o comando está incluído entre aspas exteriores, o " & " ampersand é usado para indicar que outro ficheiro de comando-filho está a ser executado, e então finalmente escapou (duplo-duplo -) aspas à volta do nome do local/ficheiro com espaços em que queria executar em primeiro lugar.

Esta é também a conclusão do único trabalho de volta à questão MS connect que-File não passa-back códigos de retorno não-zero e-Command é o único alternativa. Mas até agora pensava-se que uma limitação de comando era que não suportava espaços. Também actualizei esse item de feedback.

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

 3
Author: Tony Wall, 2015-07-13 15:14:22

Tentei todas as sugestões, mas ainda não consegui executar msiexec.exe com parâmetros que continham espaços. Então a minha solução acabou por usar 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()
 3
Author: Daniel Lidström, 2016-02-16 14:30:10

Uma resposta alternativa é usar um Base64 comutador de comandos codificado:

powershell -EncodedCommand "QwA6AFwAUAByAG8AZwByAGEAbQAgAEYAaQBsAGUAcwBcAEkASQBTAFwATQBpAGMAcgBvAHMAbwBmAHQAIABXAGUAYgAgAEQAZQBwAGwAbwB5AFwAbQBzAGQAZQBwAGwAbwB5AC4AZQB4AGUAIAAtAHYAZQByAGIAOgBzAHkAbgBjACAALQBzAG8AdQByAGMAZQA6AGQAYgBmAHUAbABsAHMAcQBsAD0AIgBEAGEAdABhACAAUwBvAHUAcgBjAGUAPQBtAHkAcwBvAHUAcgBjAGUAOwBJAG4AdABlAGcAcgBhAHQAZQBkACAAUwBlAGMAdQByAGkAdAB5AD0AZgBhAGwAcwBlADsAVQBzAGUAcgAgAEkARAA9AHMAYQA7AFAAdwBkAD0AcwBhAHAAYQBzAHMAIQA7AEQAYQB0AGEAYgBhAHMAZQA9AG0AeQBkAGIAOwAiACAALQBkAGUAcwB0ADoAZABiAGYAdQBsAGwAcwBxAGwAPQAiAEQAYQB0AGEAIABTAG8AdQByAGMAZQA9AC4AXABtAHkAZABlAHMAdABzAG8AdQByAGMAZQA7AEkAbgB0AGUAZwByAGEAdABlAGQAIABTAGUAYwB1AHIAaQB0AHkAPQBmAGEAbABzAGUAOwBVAHMAZQByACAASQBEAD0AcwBhADsAUAB3AGQAPQBzAGEAcABhAHMAcwAhADsARABhAHQAYQBiAGEAcwBlAD0AbQB5AGQAYgA7ACIALABjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQA9ADEAMAAuADEAMAAuADEAMAAuADEAMAAsAHUAcwBlAHIAbgBhAG0AZQA9AGEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIALABwAGEAcwBzAHcAbwByAGQAPQBhAGQAbQBpAG4AcABhAHMAcwAiAA=="

Quando descodificado, verá que é o excerto original da operação com todos os argumentos e aspas preservadas.

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.

O comando original:

 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"
Transforma-se nisto quando codificado como Base64:
QwA6AFwAUAByAG8AZwByAGEAbQAgAEYAaQBsAGUAcwBcAEkASQBTAFwATQBpAGMAcgBvAHMAbwBmAHQAIABXAGUAYgAgAEQAZQBwAGwAbwB5AFwAbQBzAGQAZQBwAGwAbwB5AC4AZQB4AGUAIAAtAHYAZQByAGIAOgBzAHkAbgBjACAALQBzAG8AdQByAGMAZQA6AGQAYgBmAHUAbABsAHMAcQBsAD0AIgBEAGEAdABhACAAUwBvAHUAcgBjAGUAPQBtAHkAcwBvAHUAcgBjAGUAOwBJAG4AdABlAGcAcgBhAHQAZQBkACAAUwBlAGMAdQByAGkAdAB5AD0AZgBhAGwAcwBlADsAVQBzAGUAcgAgAEkARAA9AHMAYQA7AFAAdwBkAD0AcwBhAHAAYQBzAHMAIQA7AEQAYQB0AGEAYgBhAHMAZQA9AG0AeQBkAGIAOwAiACAALQBkAGUAcwB0ADoAZABiAGYAdQBsAGwAcwBxAGwAPQAiAEQAYQB0AGEAIABTAG8AdQByAGMAZQA9AC4AXABtAHkAZABlAHMAdABzAG8AdQByAGMAZQA7AEkAbgB0AGUAZwByAGEAdABlAGQAIABTAGUAYwB1AHIAaQB0AHkAPQBmAGEAbABzAGUAOwBVAHMAZQByACAASQBEAD0AcwBhADsAUAB3AGQAPQBzAGEAcABhAHMAcwAhADsARABhAHQAYQBiAGEAcwBlAD0AbQB5AGQAYgA7ACIALABjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQA9ADEAMAAuADEAMAAuADEAMAAuADEAMAAsAHUAcwBlAHIAbgBhAG0AZQA9AGEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIALABwAGEAcwBzAHcAbwByAGQAPQBhAGQAbQBpAG4AcABhAHMAcwAiAA==
E aqui está como replicar em casa:
$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
 3
Author: Knuckle-Dragger, 2016-05-03 03:51:44
Existem alguns métodos que pode usar para o fazer.
Há outros métodos como usar o operador de chamadas.(&), Invoke-Expression cmdlet etc. Mas são considerados inseguros. A Microsoft recomenda o uso de Start-Process .

Método 1

Um exemplo simples

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

No seu caso

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"

Neste método, você separa cada parâmetro na lista de argumentos usando virgula.

Método 2

Exemplo Simples

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

No seu caso

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"

Este método é mais fácil, pois permite digitar os seus parâmetros de uma vez.

Note que, em powershell, para representar a marca de citação ( " ) num texto , deverá inserir o acento grave ( ` ) (esta é a tecla por cima da tecla Tab no teclado dos EUA).

-NoNewWindow o parâmetro é usado para mostrar o novo processo no actual janela da consola. Por omissão, O Windows PowerShell abre uma nova janela.

Referências: Powershell/Scripting/Start-Process

 1
Author: Missaka Iddamalgoda, 2018-03-07 06:05:28
Obrigado por colocar esta pergunta.

Você pode executar arquivos exe de diferentes maneiras. Por exemplo, se você quiser correr unrar.exe e extraia A.ficheiro rar você pode simplesmente escrever em powershell isto:

$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;

Mas, às vezes, isto não funciona, por isso, deve usar o & parâmetro como mostrado acima: Por exemplo, com vboxmanage.exe (uma ferramenta para gerir máquinas virtuais virtualbox) você deve chamar os paramterers para fora do texto como este, sem aspas:

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

Se você quer chamar simplesmente um arquivo arquivado winrar como .ficheiros exe, você também pode desbloqueá-lo com o comando invoce-cmdlet e um parâmetro /S silencioso (o seu ir extrair-se na mesma pasta do que onde foi comprimido).

> Invoke-Command -ScriptBlock { C:\Your-path\archivefile.exe /S };
Então há várias maneiras de correr .ficheiros exe com argumentos em powershell. Às vezes, é preciso encontrar uma solução para fazê-la funcionar corretamente, o que pode exigir algum esforço adicional e dor :) dependendo da forma como o .o exe foi compilado ou fabricado bi seus criadores.
 1
Author: Andy McRae, 2018-05-25 14:40:02
Então, encontrei um problema semelhante e escolhi resolvê-lo desta maneira.
  1. Escape da sua citação ( ") caracteres com um backtick ( ' )
  2. rodeie a sua nova expressão com aspas ( " )
  3. Usando o operador de chamadas ( & ), emite o comando {[[0]} no novo texto

Solução de exemplo:

& { invocar-expressão "C:\Program ficheiros\IIS\Microsoft Web Deploy\msdeploy.exe-verb: sync-source: dbfullsql= '" Data Source=mysource;Integrated Segurança=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=administrador, password=adminpass`""}

 0
Author: Randall Borck, 2017-08-08 18:35:52