none
VM Switches abrufen und weiterverwenden RRS feed

  • Frage

  • Hallo Zusammen,

    Ich mache gerade eine Weiterbildung "Windows Server 2019 Administrator" und habe die ersten Berührungen mit der Powershell.

    Ich möchte bei dem Thema VM nun mir folgendes Script schreiben und bräuchte eure Hilfe:

    Was soll passieren:

    1. Vm-Switches abfragen und auflisten lassen.

    2. Durch ein Untermenü kann ich nun einen existenten Switch wählen

    3. ebenfalls im Untermenü soll der Punkt sein neuen Switch erstellen (der sollte fürs erste gelöst sein)


    Mein Ansatz:

    $VMMenu = Read-Host -Prompt " 
    `n   1. vorhandener Switch x
    `n   2. vorhandener Switch y
    `n   3. neuen Switch erstellen
    `nPlease select a number"

    switch($VMMenu){
        1{Switch x landet in der Variablen $Switchverwenden
            }
        2{Switch y landet in der Variablen $Switchverwenden
            }
        3{exit}      }


    $Netzwerk = read-host "wie soll das Netzwerk heißen?"
        
       $PrivateVirtualSwitchExists = ((Get-VMSwitch | where {$_.name -eq $Netzwerk}).count -ne 0)
              if ($PrivateVirtualSwitchExists -eq "True")
              {
              write-host "$Netzwerk existiert bereits" -ForegroundColor green
              }
              else
              {
              $Switch_type = Read-Host -Prompt "Welcher Switch-Typ soll erstellt werden?
                `n1. Extern
                `n2. Intern
                `n3. Privat
                `nBitte wähle eine Nummer"

              switch($Switch_type){

              1{
              New-VMSwitch -SwitchName $Netzwerk -SwitchType External | Out-Null
              write-host "$Netzwerk wurde erstellt" -ForegroundColor green
              }
              2{
              New-VMSwitch -SwitchName $Netzwerk -SwitchType Internal | Out-Null
              write-host "$Netzwerk wurde erstellt" -ForegroundColor green
              }
              3{
              New-VMSwitch -SwitchName $Netzwerk -SwitchType Private | Out-Null
              write-host "$Netzwerk wurde erstellt" -ForegroundColor green
              }
              }}

    Wie kann ich die vorhanden Switches via Abfrage in das Menü einbinden?

    Komme ich hier mit dem Befehlt get-VM-Switches weiter?

    Vielen dank für die Hilfe!

    Viele Grüße

    Kice88




    • Bearbeitet Kice88 Montag, 11. Januar 2021 09:06 unvollständiger code
    Montag, 11. Januar 2021 09:04

Antworten

  • Das mit dem Index habe ich nicht ganz verstanden, .....

    Wenn Du mit einem Powershell Befehl ein Array erzeugst, hat das ja nicht automatisch einen eingebauten festen Index. Den musst Du also selbst erzeugen. So z.B.:

    $Index = 0
    $ChooseList = 
    Get-ChildItem | 
    ForEach-Object {
        [PSCustomObject]@{
            Index = $index++
            Name  = $_.Name
        }
    }
    $ChooseList
    Jetzt hast Du in $ChooseList einen Index, den Du zur Anzeige und zur Auswahl nutzen kannst. ;-) 

    .... Ich stocke nun an der Stelle, dass der Name in einem komischen Format übergeben wird:

    zb von einem vorhandenen Switch "ISCSI2" wird übergeben "@{Name=ISCSI2}"

    In Powershell arbeiten wir mit Objekten und deren Eigenschaften. Du speicherst das Ergebnis-Objekt, welches von Out-GridView ausgegeben wird in einer Variablen Names $Chosensite. Jetzt willst Du aber nicht das ganze Objekt ausgeben, sondern eine Eigenschaft mit dem Namen "Name". Dafür kannst Du die sogenannte Dot-Notation verwenden. Also $Chosensite.Name.

    Wenn ich mich nicht verguckt habe, hast Du noch einen Logik-Fehler in Deinem Code. Du erzeugst eine Auswahl mit zwei Optionen "[N] Netzwerk wählen" und "[N] Neues Netzwerk erstellen". Beides wird mit einem "[N]" ausgewählt!!  ... ich könnte mir vorstellen, dass das den ein oder anderen Anwender verwirrt. ;-) 


    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    Dienstag, 12. Januar 2021 10:16

Alle Antworten

  • Wie kann ich die vorhanden Switches via Abfrage in das Menü einbinden?

    Komme ich hier mit dem Befehlt get-VM-Switches weiter?

    Wenn Du bei dem cmdlet den zweiten Bindestrich wegläßt und die Endung "es", kommst Du damit weiter. ;-)

    Du müsstest die Ausgabe des cmdlets mit einem Index versehen, den Du dann im Menü nutzen kannst.

    Alternativ gäbe es die Möglichkeit, das cmdlet Out-Gridview mit dem Parameter -Passthru oder -OutputMode zu nutzen. Dann hast Du ein grafisches Auswahl-Menü, welches ein nutzbares Object ausgibt, anstatt nur einer Zahl. Dafür müsstest Du natürlich Deine Menü-Logik ein wenig umstellen.


    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    • Bearbeitet BOfH-666 Montag, 11. Januar 2021 09:23
    Montag, 11. Januar 2021 09:23
  • Du müsstest die Ausgabe des cmdlets mit einem Index versehen, den Du dann im Menü nutzen kannst.

    Alternativ gäbe es die Möglichkeit, das cmdlet Out-Gridview mit dem Parameter -Passthru oder -OutputMode zu nutzen. Dann hast Du ein grafisches Auswahl-Menü, welches ein nutzbares Object ausgibt, anstatt nur einer Zahl. Dafür müsstest Du natürlich Deine Menü-Logik ein wenig umstellen.


    Das mit dem Index habe ich nicht ganz verstanden, aber die Out-Gridview konnte mich ein wenig weiterbringen. Ich stocke nun an der Stelle, dass der Name in einem komischen Format übergeben wird:

    zb von einem vorhandenen Switch "ISCSI2" wird übergeben "@{Name=ISCSI2}"

    #Netzwerk-Abfrage
            $Title = "Netzwerk-Auswahl"
            $Info = "Soll ein vorhandenes Netzwerk verwendet werden?"
      
            $net_options = [System.Management.Automation.Host.ChoiceDescription[]] @("&Netzwerk wählen", "&Neues Netzwerk erstellen")
            [int]$defaultchoice = 0
            $opt = $host.UI.PromptForChoice($Title , $Info , $net_Options,$defaultchoice)
            switch($opt)
                {
                0 { $Chosensite = ($Netzwerk = Get-VMSwitch | Select-Object -Property Name | Out-GridView -PassThru)
                    Write-Host "`n$Netzwerk wird verwendet" -ForegroundColor yellow}
                1 {$Netzwerk= Read-Host -Prompt "Wie soll das Netzwerk heißen?"
            $PrivateVirtualSwitchExists = ((Get-VMSwitch | where {$_.name -eq $Netzwerk}).count -ne 0)
            if ($PrivateVirtualSwitchExists -eq "True")
              {
              write-host "$Netzwerk existiert bereits" -ForegroundColor green
              } 
              else
              {
              $Switch_type = Read-Host -Prompt "Welcher Switch-Typ soll erstellt werden? 
                `n1. Extern
                `n2. Intern
                `n3. Privat
                `nBitte wähle eine Nummer"
    
              switch($Switch_type){
    
              1{
              New-VMSwitch -SwitchName $Netzwerk -SwitchType External | Out-Null
              write-host "$Netzwerk wurde erstellt" -ForegroundColor green
              }
              2{
              New-VMSwitch -SwitchName $Netzwerk -SwitchType Internal | Out-Null
              write-host "$Netzwerk wurde erstellt" -ForegroundColor green
              }
              3{
              New-VMSwitch -SwitchName $Netzwerk -SwitchType Private | Out-Null
              write-host "$Netzwerk wurde erstellt" -ForegroundColor green
              }
              }}}
                  }
    
    

    Bekomme ich nochmal einen Denk- bzw Google-anstoß? :D


    • Bearbeitet Kice88 Dienstag, 12. Januar 2021 07:05 verschrieben
    Dienstag, 12. Januar 2021 06:49
  • Das mit dem Index habe ich nicht ganz verstanden, .....

    Wenn Du mit einem Powershell Befehl ein Array erzeugst, hat das ja nicht automatisch einen eingebauten festen Index. Den musst Du also selbst erzeugen. So z.B.:

    $Index = 0
    $ChooseList = 
    Get-ChildItem | 
    ForEach-Object {
        [PSCustomObject]@{
            Index = $index++
            Name  = $_.Name
        }
    }
    $ChooseList
    Jetzt hast Du in $ChooseList einen Index, den Du zur Anzeige und zur Auswahl nutzen kannst. ;-) 

    .... Ich stocke nun an der Stelle, dass der Name in einem komischen Format übergeben wird:

    zb von einem vorhandenen Switch "ISCSI2" wird übergeben "@{Name=ISCSI2}"

    In Powershell arbeiten wir mit Objekten und deren Eigenschaften. Du speicherst das Ergebnis-Objekt, welches von Out-GridView ausgegeben wird in einer Variablen Names $Chosensite. Jetzt willst Du aber nicht das ganze Objekt ausgeben, sondern eine Eigenschaft mit dem Namen "Name". Dafür kannst Du die sogenannte Dot-Notation verwenden. Also $Chosensite.Name.

    Wenn ich mich nicht verguckt habe, hast Du noch einen Logik-Fehler in Deinem Code. Du erzeugst eine Auswahl mit zwei Optionen "[N] Netzwerk wählen" und "[N] Neues Netzwerk erstellen". Beides wird mit einem "[N]" ausgewählt!!  ... ich könnte mir vorstellen, dass das den ein oder anderen Anwender verwirrt. ;-) 


    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    Dienstag, 12. Januar 2021 10:16
  • Super! Vielen dank! Das war sehr hilfreich :))

    ich habe es fürs Erste so nun gelöst:

    $Title = "Netzwerk-Auswahl"
            $Info = "Soll ein vorhandenes Netzwerk verwendet werden?"
      
            $net_options = [System.Management.Automation.Host.ChoiceDescription[]] @("&Netzwerk wählen", "&Neues Netzwerk erstellen")
            [int]$defaultchoice = 0
            $opt = $host.UI.PromptForChoice($Title , $Info , $net_Options,$defaultchoice)
            switch($opt)
                {
                0 { $Chosensite = ($Netzwerk = Get-VMSwitch | Select-Object -Property Name | Out-GridView -PassThru)
                    $Netzwerk = $Chosensite.Name
                    Write-Host "`n$Netzwerk wird verwendet" -ForegroundColor yellow}
                1 {$Netzwerk= Read-Host -Prompt "Wie soll das Netzwerk heißen?"
            $PrivateVirtualSwitchExists = ((Get-VMSwitch | where {$_.name -eq $Netzwerk}).count -ne 0)
            if ($PrivateVirtualSwitchExists -eq "True")
              {
              write-host "$Netzwerk existiert bereits" -ForegroundColor green
              } 
              else
              {
              $Switch_type = Read-Host -Prompt "Welcher Switch-Typ soll erstellt werden? 
                `n1. Extern
                `n2. Intern
                `n3. Privat
                `nBitte wähle eine Nummer"
    
              switch($Switch_type){
    
              1{
              New-VMSwitch -SwitchName $Netzwerk -SwitchType External | Out-Null
              write-host "$Netzwerk wurde erstellt" -ForegroundColor green
              }
              2{
              New-VMSwitch -SwitchName $Netzwerk -SwitchType Internal | Out-Null
              write-host "$Netzwerk wurde erstellt" -ForegroundColor green
              }
              3{
              New-VMSwitch -SwitchName $Netzwerk -SwitchType Private | Out-Null
              write-host "$Netzwerk wurde erstellt" -ForegroundColor green
              }
              }}}
                  }
            

    Das mit dem Index muss ich erstmal richtig verstehen und dann versuchen anzuwenden. Wie man wahrscheinlich gut erkennen kann, ist es sehr stupide was ich da zusammenbaue...aber gut, aller Anfang ist schwer ;).

    Das "N" habe ich mir so bei google rausgesucht gehabt und "erzwinge" eine neue Zeile...also mit Abstand. Also reine Schönheitssache.

    Viele Grüße

    Donnerstag, 14. Januar 2021 09:11
  • Super. Den Logik-Fehler hast Du aber immernoch drin. ;-)

    Und für Dein "Menü" solltest Du Dir mal "Here-Strings" ansehen ... 

    $HereString = @'
      Hier kannst Du Dich mit 
        der "Formatierung" austoben
          und brauchst keine "Steuerzeichen" einfügen.
    '@
    $HereString

    Hier noch was zum Nachlesen:

    https://devblogs.microsoft.com/scripting/powertip-use-here-strings-with-powershell

    https://powershell.org/2019/04/hear-hear-for-here-strings

    ! Achtung ! Je nachdem, ob Du einfache oder doppelte Anführungszeichen verwendest, verhalten sich eingebettete Variablen unterschiedlich.


    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    Donnerstag, 14. Januar 2021 11:31
  • Du hattest Recht...den Logik-Fehler habe ich fürs Erste ganz stupide ausgebügelt :D (Da muss ich mich weiter mit beschäftigten, wie das ein wenig schicker geht.

    Danke für den "HereString" Tip ...das werde ich mir auch gleich mal anschauen.

    Immerhin läuft das Script nun :))

    Danke nochmals! eine kleine Frage noch: Ich könnte mir gut vorstellen dass ich wieder eine Frage habe bzgl. Werten die ich übergeben möchte. Soll ich am besten dann hier weiterposten oder einen neuen Threat aufmachen?

    Grüße!

    #Netzwerk-Abfrage
            $Title = "Netzwerk-Auswahl"
            $Info = "Soll ein vorhandenes Netzwerk verwendet werden?"
      
            $net_options = [System.Management.Automation.Host.ChoiceDescription[]] @("&Wähle Netzwerk", "&Neues Netzwerk erstellen")
            [int]$defaultchoice = 0
            $opt = $host.UI.PromptForChoice($Title , $Info , $net_Options,$defaultchoice)
            switch($opt)
                {
                0 { $Chosensite = ($Netzwerk = Get-VMSwitch | Select-Object -Property Name | Out-GridView -PassThru)
                    $Netzwerk = $Chosensite.Name
                    Write-Host "`n$Netzwerk wird verwendet" -ForegroundColor yellow}
                1 {$Netzwerk= Read-Host -Prompt "Wie soll das Netzwerk heißen?"
            $PrivateVirtualSwitchExists = ((Get-VMSwitch | where {$_.name -eq $Netzwerk}).count -ne 0)
            if ($PrivateVirtualSwitchExists -eq "True")
              {
              write-host "$Netzwerk existiert bereits" -ForegroundColor green
              } 
              else
              {
              $Switch_type = Read-Host -Prompt "Welcher Switch-Typ soll erstellt werden? 
                `n1. Extern
                `n2. Intern
                `n3. Privat
                `nBitte wähle eine Nummer"
    
              switch($Switch_type){
    
              1{
              New-VMSwitch -SwitchName $Netzwerk -SwitchType External | Out-Null
              write-host "$Netzwerk wurde erstellt" -ForegroundColor green
              }
              2{
              New-VMSwitch -SwitchName $Netzwerk -SwitchType Internal | Out-Null
              write-host "$Netzwerk wurde erstellt" -ForegroundColor green
              }
              3{
              New-VMSwitch -SwitchName $Netzwerk -SwitchType Private | Out-Null
              write-host "$Netzwerk wurde erstellt" -ForegroundColor green
              }
              }}}
                  }

    • Bearbeitet Kice88 Donnerstag, 28. Januar 2021 16:13 falsch formartiert
    Donnerstag, 28. Januar 2021 16:09
  • ..den Logik-Fehler habe ich fürs Erste ganz stupide ausgebügelt :D

    Du musst auch nicht zwingend den ersten Buchstaben benutzen, um die Wahlmöglichkeiten zu unterscheiden.

    @("Netzwerk &wählen", "Neues Netzwerk &erstellen", "&Nichts von beidem")

    würde auch funktionieren. Alle 3 Optionen fangen mit dem Buchstaben "N" an, haben aber andere "Auswahl-Trigger".

    ... wie das ein wenig schicker geht.

    NOCH schicker?? Wenn Du dieses Script Leuten anbietest, die mit der Powershell oder CLIs im Allgemeinen prinzipiell vertraut sind, ist es meiner Meinung nach das Beste, dass Dein Script genauso funktioniert und aussieht, als wäre es von MSFT.

    Also den Choice-Prompt zu benutzen, finde ich in einem solchen Fall am professionellsten, weil er genauso funktioniert, wie andere eingebaute Auswahl-Abfragen. Deshalb würde ich auch die zweite Auswahl eher auf die gleiche Weise gestallten. Bei einem einfachen ungeprüften Read-Host, kannst Du nie sicher sein, was der Benutzer Deines Scripts eingibt. Deshalb wäre es dann auch empfehlenswert, wenn Du beim nachfolgenden switch-Statement einen "Default"-Zweig benutzt. So kannst Du verhindern, dass unerwartete Fehleingaben unerwartete Ergebnisses liefern.

    Ich könnte mir gut vorstellen dass ich wieder eine Frage habe bzgl. Werten die ich übergeben möchte. Soll ich am besten dann hier weiterposten oder einen neuen Threat aufmachen?

    Das bleibt am Ende Dir überlassen. Wenn es thematisch immernoch zu Deiner Überschrift bzw. zu Deiner Eingangsfrage passt, kannst Du natürlich auch hier weitermachen. Aber je länger so ein Thread wird, desto unübersichtlicher wird er auch für Andere, die vielleicht auf der Suche nach einer Lösung für ihr ähnlich gelagertes Problem sind. Deine Eingangsfrage wurde ja quasi beantwortet, oder? ;-)

    So, und jetzt noch ein bissl nörgeln ... Bei dem von Dir geposteten Code fehlt die abschließende geschweifte Klammer. ;-) Und ich würde Dir dringend empfehlen, VSCode für die Entwicklung Deiner Scripte zu verwenden. Mit der dafür verfügbaren Powershell-Erweiterung hast Du dann eine eingebaute Funktion, die Dir den Code vernünftig formatiert und ihn so übersichtlicher und lesbarer macht. Auch weist es Dich auf viele kleine Fehler oder Nachlässigkeiten gleich beim Schreiben des Codes hin.


    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    • Bearbeitet BOfH-666 Donnerstag, 28. Januar 2021 21:26
    Donnerstag, 28. Januar 2021 21:26