emeriks
Goto Top

PowerShell - Invoke-Command in neuem PowerShell-Fenster ausführen und Variablenname übergeben, ohne diesen zu expandieren

Hi,
wie der Titel schon sagt, will ich mit Invoke-Command auf einem anderen Computer einen ScriptBlock ausführen lassen. Das funktioniert auch soweit. Nun will ich diesen Block aber in einem separaten PowerShell-Fenster ausführen. Und da komme ich gerade nicht weiter.

Mit
Invoke-Command -ComputerName 'Server1' -ScriptBlock {  
  Write-Host "$env:ComputerName"  
}
bekomme ich die Ausgabe des Remote-Servernamens
Server1

Mit
Start-Process powershell.exe -argument "-NoExit -Command ""  
  Write-Host ""Hallo Welt!""  
  ""  
"  
Gibt er mir in neuem Fenster "Hallo Welt!" aus.

Prima. Aber wir bekomme ich das jetzt zusammen?

Dieser Versuch
Start-Process powershell.exe -argument "-NoExit -Command ""  
  Invoke-Command -ComputerName 'Server1' -ScriptBlock {  
    Write-Host '$env:ComputerName'  
  }
  ""  
"  
liefert mir im neuen Fenster den Namen des lokalen Rechners, nicht den des entfernten Rechners, wie gewünscht. Weil er die Variable erst expandiert und dann das Kommando als Argument an Start-Process übergibt. Schon klar.

Nur, wie muss ich das nun anstellen, wenn ich einen Variablennamen ohne Expansion übergeben will?

E.

Content-Key: 564895

Url: https://administrator.de/contentid/564895

Printed on: April 23, 2024 at 19:04 o'clock

Member: TK1987
TK1987 Apr 15, 2020 updated at 13:26:29 (UTC)
Goto Top
Moin,

Zitat von @emeriks:
Dieser Versuch
 Start-Process powershell.exe -argument "-NoExit -Command ""  
   Invoke-Command -ComputerName 'Server1' -ScriptBlock {  
     Write-Host '$env:ComputerName'  
   }
   ""  
 "  
 
liefert mir im neuen Fenster den Namen des lokalen Rechners, nicht den des entfernten Rechners, wie gewünscht. Weil er die Variable erst expandiert und dann das Kommando als Argument an Start-Process übergibt. Schon klar.

Nur, wie muss ich das nun anstellen, wenn ich einen Variablennamen ohne Expansion übergeben will?
Wie wäre es denn damit:
 Start-Process powershell.exe -argument "-NoExit -Command ""  
   Invoke-Command -ComputerName 'Server1' -ScriptBlock {  
     Write-Host $('$env:ComputerName')  
   }
   ""  
 "  
 

Gruß Thomas
Mitglied: 143728
143728 Apr 15, 2020 updated at 14:44:54 (UTC)
Goto Top
start powershell -ArgumentList "-NoExit -Command `"invoke-command -ComputerName Server1 -ScriptBlock {`$env:Computername}`""  
Erst wenn ich den ScriptBlock ändere, dann geht das. Das will ich eigentlich vermeiden.
oder auch
$scriptblock = {
    $env:Computername
}

start powershell -ArgumentList "-NoExit -Command `"invoke-command -ComputerName Server1 -ScriptBlock $($scriptblock.StartPosition.Content)`""  
Member: emeriks
emeriks Apr 15, 2020 at 13:47:57 (UTC)
Goto Top
Zitat von @TK1987:
Wie wäre es denn damit:
Danke, damit komme ich weiter. Aber verstehen tue ich das immer noch nicht ganz. Ich habe meinen o.g. Bsp. stark gekürzt.

Wenn ich ausführe:
Write-Host "$($env:ComputerName): Hallo Welt"  
dann gibt er mir den Namen des lokalen Servers aus. Ist klar.

bei:
Invoke-Command -ComputerName 'Server1' -ScriptBlock {  
  Write-Host "$($env:ComputerName): Hallo Welt"  
}
den des entfernten Computers. Ist auch klar.

Nur in der Combi geht das dann nicht, egal wie ich in "" setze.
Start-Process powershell.exe -argument "-NoExit -Command ""  
  Invoke-Command -ComputerName 'Server1' -ScriptBlock {  
    Write-Host "$('$env:ComputerName'): Hallo Welt"  
  }
  ""  
"  

Erst wenn ich den ScriptBlock ändere, dann geht das. Das will ich eigentlich vermeiden.
Start-Process powershell.exe -argument "-NoExit -Command ""  
  Invoke-Command -ComputerName 'Server1' -ScriptBlock {  
    Write-Host $('$env:ComputerName')': Hallo Welt'  
  }
  ""  
"  
Member: TK1987
TK1987 Apr 15, 2020 updated at 14:00:42 (UTC)
Goto Top
Zitat von @emeriks:
Aber verstehen tue ich das immer noch nicht ganz.
...
Nur in der Combi geht das dann nicht, egal wie ich in "" setze.
Das Problem ist folgendes: Wenn du einen Scriptblock in curly Brackets postest wie hier
Invoke-Command -ComputerName 'Server1' -ScriptBlock {  
  Write-Host "$($env:ComputerName): Hallo Welt"  
}
wird der Block so wie er ist übergeben, ohne das die Variablen expandiert werden. Da du das Ganze aber nun in Anführungszeichen setzt, werden die curly brackets im Prinzip außer kraft gesetzt bzw sind nur noch teile eines strings.
Und Variablen in Double-Quotes werden dann halt interpretiert.
Member: emeriks
emeriks Apr 15, 2020 updated at 14:01:41 (UTC)
Goto Top
Bzw.

Start-Process powershell.exe -argument "-NoExit -Command ""  
  Invoke-Command -ComputerName 'Server1' -ScriptBlock {  
    $A = 1
    Write-Host $A
    }
  }
  ""  
"  

Das bekomme ich auch nicht auf die Reihe. Wie muss ich hier das "$A" verpacken, damit er das 1:1 übergibt, ohne es zu expandieren?
Member: TK1987
Solution TK1987 Apr 15, 2020 updated at 14:24:21 (UTC)
Goto Top
Zitat von @emeriks:
Das bekomme ich auch nicht auf die Reihe. Wie muss ich hier das "$A" verpacken, damit er das 1:1 übergibt, ohne es zu expandieren?
Auf die selbe Art und Weise face-wink
  Start-Process powershell.exe -argument "-NoExit -Command ""  
    Invoke-Command -ComputerName 'Server1' -ScriptBlock {  
      $('$A') = 1  
      Write-Host $('$A')  
      }
    ""  
  "  
    
Variablen in Double-Quotes werden ja expandiert, welche in SingleQuotes hingegen nicht. Da das Ganze nun in Double Quotes gesetzt ist, musst du das Verhalten im Prinzip umkehren, indem du $() auswerten lässt. Da die Variable innerhalb in SingleQuotes steht, wird sie nun nicht mehr expandiert.

Edit: Eine weitere, gerade bei sehr vielen Variablen vielleicht deutlich einfachere Möglichkeit wäre, einfach den kompletten Scriptblock in $('') zu setzen, dann kannst du innerhalb wie gewohnt fortfahren
  Start-Process powershell.exe -argument "-NoExit -Command ""  
    Invoke-Command -ComputerName 'Server1' -ScriptBlock $('{  
      $A = 1
      Write-Host $A
      }')  
    ""  
  "  
    
Mitglied: 143728
143728 Apr 15, 2020 updated at 14:53:09 (UTC)
Goto Top
Zitat von @emeriks:
Das bekomme ich auch nicht auf die Reihe. Wie muss ich hier das "$A" verpacken, damit er das 1:1 übergibt, ohne es zu expandieren?
Siehe mein Kommentar oben, dann ist auch keine Anpassung nötig, den Skriptblock selbst einfach nur als String übergeben (inkl. geschweifter Klammern)...
Member: emeriks
emeriks Apr 15, 2020 at 19:17:03 (UTC)
Goto Top
Boah eh! Das ist sehr trickreich.
Da habe ich dann aber noch einen ....

Start-Process powershell.exe -argument "-NoExit -Command ""  
  Invoke-Command -ComputerName 'Server1' -ScriptBlock $('{  
    Write-Host "$($env:ComputerName): prüfe ConfigurationFile (Bitte Warten)"  
  }')  
  ""  
"  
meckert an:
Die Benennung "Bitte" wurde nicht als Name eines Cmdlet, einer Funktion, einer Skriptdatei oder eines ausführbaren  
Programms erkannt. Überprüfen Sie die Schreibweise des Namens, oder ob der Pfad korrekt ist (sofern enthalten), und
wiederholen Sie den Vorgang.
    + CategoryInfo          : ObjectNotFound: (Bitte:String) , CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
    + PSComputerName        : Server1

Ich kapiere es nicht ...
Mitglied: 143728
143728 Apr 15, 2020 updated at 19:29:38 (UTC)
Goto Top
Sieh dir das oben nochmal genau an, du darfst den kompletten originalen Skriptblock nicht expandieren lassen sondern ihn nur als reinen String übergeben, du führst ihn mit der Subexpression ja bereits aus, deswegen kommt es zu den Fehlern...
Member: emeriks
emeriks Apr 15, 2020 updated at 19:37:26 (UTC)
Goto Top
Sorry, kann nicht folgen.
Folgendes funktioniert nicht:
Start-Process powershell.exe -argument "-NoExit -Command ""  
  Invoke-Command -ComputerName 'Server1' -ScriptBlock $('{  
      $A = "doof"  
      Write-Host $A
  }')  
  ""  
"  
Da kommt wieder:
Die Benennung "doof" wurde nicht als Name eines Cmdlet, einer Funktion, einer Skriptdatei oder eines ausführbaren  
Programms erkannt. Überprüfen Sie die Schreibweise des Namens, oder ob der Pfad korrekt ist (sofern enthalten), und
wiederholen Sie den Vorgang.
    + CategoryInfo          : ObjectNotFound: (doof:String) , CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
    + PSComputerName        : Server1

Oben im Bsp. mit einer Zahl funktioniert das aber schon.

Ich verstehe einfach die Logik dahinter nicht. Komplett sinnlos ...
Member: emeriks
emeriks Apr 15, 2020 updated at 19:57:57 (UTC)
Goto Top
Mein Bsp. habe ich jetzt hinbekommen.
Start-Process powershell.exe -argument "-NoExit -Command ""  
  Invoke-Command -ComputerName 'Server1' -ScriptBlock $('{  
      $A = \"doof\"  
      Write-Host $A
  }')  
  ""  
"  

Nur - mein konkreter Fall hat da noch etwas spezielles:
Im String sind Hochkomma enthalten. Ich brauche
$A = "Type='rund'"  

Die Umsetzung mit
$A = \"Type='rund'\"  
oder
$A = \"Type=\'rund\'\"  
funktionieren beide aber nicht.
Member: emeriks
emeriks Apr 15, 2020 updated at 20:05:49 (UTC)
Goto Top
Aber so geht's:
Start-Process powershell.exe -argument "-NoExit -Command ""  
  Invoke-Command -ComputerName 'Server1' -ScriptBlock $('{  
    $A = \"Type=$([char]39)rund$([char]39)\"  
    Write-Host $A
  }')  
  ""  
"  

Dämlich, aber es funktioniert.