PowerShell Invoke-Command -ScriptBlock (und Handhabung von Leerzeichen?)

Piktogramm

Admiral
Registriert
Okt. 2008
Beiträge
8.858
Ziel: Ein String zusammenbasteln, der den Pfad zu einer .exe Ethält, den String um Parameter erweitern und den String schlussendlich als Befehl ausführen. Im Beispiel nur ein Parameter
PowerShell:
$cmdstring = -join ('"c:\Program Files\Program Name\foobar.exe"', " ")
$cmdstring = -join (cmdstring, "/parameter batz ")

Invoke-Command -ScriptBlock {&$cmdstring}

Gibt folgende Fehlermeldung beim Aufführen von Zeile 4
Code:
The term '"c:\Program Files\Program Name\foobar.exe" /parameter batz ' is not recognized as a name of a
cmdlet, function, script file, or executable program. Check the spelling of the name, or if a path was included,
verify that the path is correct and try again.

Rufe ich in der Powershell, also außerhalb des Scripts jedoch & "c:\Program Files\Program Name\foobar.exe" /parameter batz auf läufts.

Ok es liegt die Vermtung nahe $cmdstring = -join ("c:\Program Files\Program Name\foobar.exe", " ") zu schreiben, also die Hochklammer '' wegzulassen. Dann versucht Powershell aber "c:\Program" auszuführen und "Files\Program" als ersten Paramater zu übergeben, was reichlich sinnlos ist.

Meine Frage ist also, wie bekomme ich den Inhalt von $cmdstring ausgeführt? Was explizit gewünscht ist, ist eine weitere Powershellinstanz zu öffnen und den Befehl darin auszurühren.
 
Piktogramm schrieb:
Was explizit gewünscht ist, ist eine weitere Powershellinstanz zu öffnen und den Befehl darin auszurühren.
Sollte damit klappen:
PowerShell:
$processOptions = @{
    FilePath = "C:\Program Files (x86)\KeePass Password Safe 2\KeePass.exe"
    ArgumentList = @(
        "-useraccount",
        "filename"
    )
}
Start-Process @processOptions


PowerShell:
& 'C:\Program Files (x86)\KeePass Password Safe 2\KeePass.exe' -useraccount filename
Klappt bei mir auch im Script
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Art Vandelay
Und auch mit dynamischen Parametern:
Code:
$args = 1,2,3
$args += 4,5,6

& foo.exe $args
 
@KitKat::new() @Yuuri

Der springende Punkt ist tatsächlich, die Argumente in ein Array zu packen. Zumindest bisher, ich muss mal testen, ob das für alle Fälle funktioniert.

KitKat::new() schrieb:
PowerShell:
& 'C:\Program Files (x86)\KeePass Password Safe 2\KeePass.exe' -useraccount filename
Klappt bei mir auch im Script

Das weicht halt von meinem Beispiel deutlich ab. Der Pfad in deinem Beispiel, ist ja explizit gegeben und nicht Teil einer Variable. Dein Beispiel angepasst:

PowerShell:
$cmd='C:\Program Files (x86)\KeePass Password Safe 2\KeePass.exe' -useraccount filename
& $cmd
Was die Powershell aufgrund eines Syntaxfehlers beim Zuweisen der Variable nicht schlucken wird.

Daher:
PowerShell:
$cmd='"C:\Program Files (x86)\KeePass Password Safe 2\KeePass.exe" -useraccount filename'
& $cmd
Hier kann die Variable gescheit belegt werden und das Leerzeichen im Pfad zur .exe ist escaped. Jedoch expandiert die Powershell die Zeile & $cmd in diesem Fall zu einem & '"C:\Program Files (x86)\KeePass Password Safe 2\KeePass.exe" -useraccount filename', was natürlich nicht geht, da PS versucht alles zwischen den einfachen Hochklammern als einen Befehl zu interpretieren anstatt dem Befehl eine .exe zu starten und Argumente zu übergeben.


Yuuri schrieb:
Und auch mit dynamischen Parametern:
Code:
$args = 1,2,3
$args += 4,5,6

& foo.exe $args

Ein Array über die Argumente zu bauen funktioniert im ersten Test. Ich muss aber noch schauen, wie es mit komplexeren Parameteraufrufen klappt. Duplicati frisst ja auch Regex und wenn Powershell dann die Argumente auch zu '"foo?bar"' expandiert, habe ich das nächste Problem..
 
  • Gefällt mir
Reaktionen: KitKat::new()
Piktogramm schrieb:
Duplicati frisst ja auch Regex und wenn Powershell dann die Argumente auch zu '"foo?bar"' expandiert, habe ich das nächste Problem..
Du kannst dir zum Debuggen auch echoargs aus dem PSCX Package ziehen, das gibt die übergebenen Parameter einfach nur aus.
 
@Yuuri
Ich hänge mit dem Debugger[1] dran. Ich sehe da auf den ersten Blick keinen größeren Gewinn. Was Imho fehlt ist die Möglichkeit expandierte Befehle zu sehen, bevor bzw. nachdem sie aufgeführt werden.
Eigentlich steht das ja in $$, wird der Spaß aber innerhalb eines Scripts aufgerufen, ist $$ dauerhaft mit dem Pfad zum Script gefüllt, anstatt dem zu was auch immer & $cmd expandiert wurde. Was etwas ärgerlich ist, da $? den Returncode von & $cmd enthält..


[1] Visual Studio Code mit offiziellem Powershell Plugin
 
Zurück
Oben