Een EXE-bestand uitvoeren in PowerShell met parameters met spaties en aanhalingstekens

Hoe voer je de volgende opdracht uit in PowerShell?

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


Antwoord 1, autoriteit 100%

Als PowerShell een opdracht ziet die begint met een tekenreeks, evalueert het alleen de tekenreeks, dat wil zeggen, het echoot het meestal naar het scherm, bijvoorbeeld:

PS> "Hello World"
Hello World

Als u wilt dat PowerShell de tekenreeks interpreteert als een opdrachtnaam, gebruikt u de oproepoperator (&) als volgt:

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

Daarna hoeft u waarschijnlijk alleen parameter-/argumentparen aan te halen die spaties en/of aanhalingstekens bevatten. Wanneer u een EXE-bestand als dit aanroept met complexe opdrachtregelargumenten, is het meestal erg handig om een ​​tool te hebben die u laat zien hoe PowerShell de argumenten naar het EXE-bestand stuurt. De PowerShell Community Extensions heeft zo’n tool. Het wordt echoargs genoemd. U vervangt gewoon het EXE-bestand door echoargs – laat alle argumenten op hun plaats, en het zal u laten zien hoe het EXE-bestand de argumenten zal ontvangen, bijvoorbeeld:

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>

Met echoargs kun je experimenteren totdat je het goed hebt gedaan, bijvoorbeeld:

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

Het bleek dat ik eerder te hard mijn best deed om de dubbele aanhalingstekens rond de verbindingsreeks te behouden. Blijkbaar is dat niet nodig, want zelfs cmd.exe zal die verwijderen.

BTW, petje af voor het PowerShell-team. Ze waren erg behulpzaam bij het tonen van de specifieke bezwering van single & dubbele aanhalingstekens om het gewenste resultaat te krijgen – als u de interne dubbele aanhalingstekens op hun plaats wilt houden. 🙂 Ze beseffen ook dat dit een pijngebied is, maar ze worden gedreven door het aantal mensen dat door een bepaald probleem wordt getroffen. Als dit een pijnpunt voor u is, stem dan alstublieft op deze PowerShell-bug inzending.

Voor meer informatie over hoe PowerShell parseert, bekijk mijn Effectieve PowerShell-blogreeks – specifiek item 10 – “Inzicht in PowerShell-parseermodi”

UPDATE 4/4/2012: deze situatie wordt veel gemakkelijker af te handelen in PowerShell V3. Zie dit blogbericht voor details.


Antwoord 2, autoriteit 18%

Voeg gewoon de operator & toe voor de .exe-naam.
Hier is een opdracht om SQL Server Express in stiltemodus te installeren:

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

Antwoord 3, autoriteit 17%

Ik had spaties in zowel de opdracht als de parameters, en dit is wat voor mij werkte:

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

Het is eigenlijk hetzelfde als Akira’s antwoord, maar dit werkt als je dynamisch je commandoparameters opbouwt en ze in een variabele plaatst.


Antwoord 4, autoriteit 12%

Er zijn nogal wat methoden die u kunt gebruiken om dit te doen.

Er zijn andere methoden, zoals het gebruik van de Call Operator (&), Invoke-Expression cmdlet enz. Maar deze worden als onveilig beschouwd. Microsoft raadt het gebruik van Start-Process aan.

Methode 1

Een eenvoudig voorbeeld

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

In jouw geval

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"

Bij deze methode scheidt u elke parameter in de ArgumentList met komma’s.

Methode 2

Eenvoudig voorbeeld

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

In jouw geval

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"

Deze methode is gemakkelijker omdat u uw parameters in één keer kunt typen.

Merk op dat in powershell om het aanhalingsteken ( ” ) in een tekenreeks weer te geven, u het grave-accent (` ) moet invoegen (dit is de toets boven de Tab-toets in het Amerikaanse toetsenbord).

-NoNewWindow
parameter wordt gebruikt om het nieuwe proces in het huidige consolevenster weer te geven. Standaard opent Windows PowerShell een nieuw venster.

Referenties: Powershell/Scripting/Start-proces


Antwoord 5, autoriteit 10%

Dit werkte voor mij:

& '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')

Plaats paden of verbindingsreeksen in één array-item en splits de andere dingen elk in één array-item.

Er zijn hier veel andere opties: https://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx

Microsoft zou deze manier eenvoudiger en compatibel moeten maken met de syntaxis van de opdrachtprompt.


Antwoord 6, autoriteit 5%

In het geval dat iemand zich afvraagt ​​hoe je een uitvoerbaar bestand kunt uitvoeren:

….. > .\file.exe

of

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


Antwoord 7, autoriteit 5%

Zie deze pagina:
https://slai.github.io/posts/powershell- and-external-commands-done-right/

Samenvatting met vshadow als extern uitvoerbaar bestand:

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

Antwoord 8, autoriteit 3%

U kunt gebruiken:

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"

Het belangrijkste om op te merken is dat FilePath op positie 0 moet staan, volgens de Helpgids. Om de Help-gids voor een commandlet op te roepen, typt u gewoon Get-Help <Commandlet-name> -Detailed . In dit geval is het Get-Help Start-Process -Detailed.


Antwoord 9, autoriteit 2%

Ik kon mijn vergelijkbare opdracht werkend krijgen met de volgende aanpak:

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

Voor je commando (niet dat het nu veel helpt), zouden de dingen er ongeveer zo uitzien:

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

De belangrijkste punten zijn:

  • Gebruik aanhalingstekens rond het bronargument en verwijder de ingesloten aanhalingstekens rond de verbindingsreeks
  • Gebruik de alternatieve sleutelnamen bij het samenstellen van de SQL-verbindingsreeks die geen spaties bevat. Gebruik bijvoorbeeld “UID” in plaats van “Gebruikers-ID”, “Server” in plaats van “Gegevensbron”, “Trusted_Connection” in plaats van “Geïntegreerde beveiliging”, enzovoort. Ik kreeg het pas werkend nadat ik alle spaties uit de verbindingsreeks had verwijderd.

Ik heb niet geprobeerd het gedeelte “computernaam” aan het einde van de opdrachtregel toe te voegen, maar hopelijk helpt deze informatie anderen die dit lezen nu dichter bij het gewenste resultaat te komen.


Antwoord 10, autoriteit 2%

Nieuwe escape-tekenreeks in PowerShell V3, geciteerd uit Nieuwe V3-taalfuncties:

Gemakkelijker hergebruik van opdrachtregels van Cmd.exe

Het web staat vol met opdrachtregels die zijn geschreven voor Cmd.exe. Deze opdrachtregels werken vaak genoeg in PowerShell, maar als ze bepaalde tekens bevatten, bijvoorbeeld een puntkomma (;), een dollarteken ($) of accolades, moet u enkele wijzigingen aanbrengen, waarschijnlijk door enkele aanhalingstekens toe te voegen. Dit leek de bron van veel kleine hoofdpijnen te zijn.

Om dit scenario aan te pakken, hebben we een nieuwe manier toegevoegd om te ‘ontsnappen’ aan het ontleden van opdrachtregels. Als u een magische parameter –% gebruikt, stoppen we onze normale ontleding van uw opdrachtregel en schakelen we over naar iets veel eenvoudigers. We komen niet overeen met offertes. We stoppen niet bij een puntkomma. We breiden PowerShell-variabelen niet uit. We breiden omgevingsvariabelen uit als u de Cmd.exe-syntaxis gebruikt (bijv. %TEMP%). Anders dan dat, worden de argumenten tot aan het einde van de regel (of pijp, als je aan het pipen bent) doorgegeven zoals ze zijn. Hier is een voorbeeld:

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

Antwoord 11

Ik heb alle suggesties geprobeerd, maar kon msiexec.exe nog steeds niet uitvoeren met parameters die spaties bevatten. Dus mijn oplossing gebruikte uiteindelijk 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()

Antwoord 12

Ik gebruik deze eenvoudige, schone en effectieve methode.

Ik plaats argumenten in een array, 1 per regel. Op deze manier is het heel gemakkelijk te lezen en te bewerken.
Dan gebruik ik een eenvoudige truc om alle argumenten tussen dubbele aanhalingstekens door te geven aan een functie met 1 enkele parameter. Dat maakt ze plat, inclusief arrays, tot een enkele string, die ik vervolgens uitvoer met PS’s ‘Invoke-Expression’. Deze instructie is speciaal ontworpen om een ​​string om te zetten in een uitvoerbaar commando.
Werkt goed:

# 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";

Antwoord 13

U kunt exe-bestanden op verschillende manieren in powershell uitvoeren. Als u bijvoorbeeld unrar.exe wilt uitvoeren en een .rar-bestand wilt extraheren, kunt u dit eenvoudig in powershell schrijven:

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

Maar soms werkt dit niet, dus moet u de & parameter zoals hierboven weergegeven:
Bijvoorbeeld, met vboxmanage.exe (een tool om virtualbox virtuele machines te beheren) moet je de parameters buiten de string als volgt aanroepen, zonder aanhalingstekens:

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

Als je gewoon een gearchiveerd winrar-bestand wilt aanroepen als .exe-bestanden, kun je het ook uitpakken met de invoke-command cmdlet en een Silent-parameter /S (het gaat zichzelf uitpakken in dezelfde map als waar het was gecomprimeerd).

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

Er zijn dus verschillende manieren om .exe-bestanden met argumenten in powershell uit te voeren.

Soms moet je een oplossing vinden om het goed te laten werken, wat wat meer moeite en pijn kan vergen 🙂 afhankelijk van de manier waarop de .exe is gecompileerd of gemaakt door de makers.


Antwoord 14

Cmd kan het uitvoeren van een geciteerde exe aan, maar Powershell niet. Ik ga me alleen bezighouden met het uitvoeren van de exe zelf, aangezien ik die niet heb. Als je letterlijk dubbele aanhalingstekens naar een argument van een externe opdracht moet sturen, is dat een ander probleem dat elders is behandeld.

1) voeg de exe-map toe aan je pad, misschien in je $profile

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

2) citeer de spaties terug:

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

Antwoord 15

Dit werkte voor mij:

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

De sleutel lijkt te zijn dat het hele commando tussen aanhalingstekens staat, de “&” ampersand wordt gebruikt om aan te geven dat een ander kind-opdrachtbestand wordt uitgevoerd, en ten slotte ontsnapte (verdubbelde-dubbele-) aanhalingstekens rond het pad/bestandsnaam met spaties die u in de eerste plaats wilde uitvoeren.

Dit is ook de voltooiing van de enige tijdelijke oplossing voor het MS connect-probleem dat -File geen niet-nul retourcodes doorgeeft en -Command het enige alternatief is. Maar tot nu toe werd gedacht dat een beperking van -Command was dat het geen spaties ondersteunde. Ik heb dat feedbackitem ook bijgewerkt.

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


Antwoord 17

Voor de naam van het uitvoerbare bestand kan de cmdlet new-alias worden gebruikt om te voorkomen dat er spaties worden gebruikt of dat het uitvoerbare bestand moet worden toegevoegd aan de $PATH-omgeving.

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

Voor het weergeven of wijzigen van PS-aliassen, zie ook

PS> get-alias
PS> set-alias

Van Jeffery Hicks-artikel

Andere antwoorden gaan over de argumenten.


Antwoord 18

Ik had de volgende code perfect werkend op mijn laptop:

& $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"

Toen ik dat vervolgens rechtstreeks op één server probeerde uit te voeren, kreeg ik die fouten "Unrecognized argument ...etc.... All arguments must begin with "-". "

Na alle mogelijke oplossingen te hebben geprobeerd (geen succes), kwam ik erachter dat Powershell op de server (Windows 2008 R2) versie 3.0 was, terwijl mijn laptop 5.0 heeft. (u kunt “$PSVersionTable” gebruiken om de versie te zien).

Na Powershell te hebben geüpgraded naar de nieuwste versie begon weer te werken.


Antwoord 19

Dus ik kwam een ​​soortgelijk probleem tegen en koos ervoor om het op deze manier op te lossen:

  1. Ontvang uw aanhalingstekens (“”) tekens met een backtick (`)
  2. Omring je nieuwe uitdrukking met aanhalingstekens (“)
  3. Gebruik de oproepoperator (&), geef het commando invoke-expression op de nieuwe string

Voorbeeldoplossing:

& { invoke-expression “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=mijndb;`” -dest:dbfullsql=`”Gegevensbron=.\mydestsource;Integrated Security=false;Gebruikers-ID=sa;Pwd=sapass!;Database=mijndb;`”,computernaam=10.10.10.10,gebruikersnaam =administrator,wachtwoord=adminpass`”” }

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes