WPF PowerShell GUIs erstellen: Funktionen, Eingaben und Ergebnisse

PowerShell ist ein Befehlszeilentool, aber wussten Sie, dass es auch als Basis für grafische Benutzeroberflächen verwendet werden kann? Manchmal ist die Befehlszeile nicht die beste Art von Schnittstelle für einen bestimmten Fall. Der Aufbau einer PowerShell-GUI für Ihren Service Desk ist ein großartiges Beispiel dafür. Dies ist einer dieser Fälle, in denen es angemessener ist, grafische Werkzeuge zu erstellen.

Not a reader? Watch this related video.

Erzwingen Sie die Benutzerverifizierung beim Zurücksetzen von Passwörtern am Helpdesk. Verringern Sie Ihre Anfälligkeit für Social Engineering mit Specops Secure Service Desk. Kontaktieren Sie uns für eine Demo!

PowerShell kann .NET-Funktionalität und -Funktionen nutzen und freigeben. Dadurch ist es möglich, GUI-Frontends für die von Ihnen erstellten Skripte zu schreiben. Der Aufbau von PowerShell-GUIs mag kompliziert erscheinen, insbesondere wenn Sie Anfänger sind.

Aber wenn Sie grundlegende Erfahrungen mit PowerShell-Skripting haben, gibt es keinen Grund, warum Sie nicht lernen und die Praxis der Erstellung von GUIs für Ihre Skripte anpassen sollten.

In diesem Beitrag erfahren Sie, wie Sie eine PowerShell GUI mit dem Windows Presentation Framework (WPF) erstellen können.

Voraussetzungen

Bevor Sie sich darauf einlassen, stellen Sie bitte sicher, dass Sie die folgenden Anforderungen erfüllen:

  1. Visual Studio 2017 oder höher – Sie verwenden dies, um die grafische Benutzeroberfläche mit WPF zu erstellen. Sie können eine kostenlose/community-Version herunterladen.
  2. A script editor – I use Visual Studio Code, but you can also use another text editor of your choice. Some other options are Notepad++ and the built-in PowerShell ISE
  3. A Windows 10 computer with Windows PowerShell 5.1.

Das Skript erstellen

In diesem Beitrag erstellen Sie ein einfaches Skript namens Main.ps1. In dem Skript schreiben Sie Code, der Informationen über Laufwerke von einem lokalen oder Remote-System abruft, indem er die WMI-Klasse Win32_LogicalDisk abfragt.

Sie benötigen ein Skript, um zuerst eine GUI zu erstellen. Ich habe mich für ein Skript entschieden, das es Ihnen ermöglicht, einen Computernamen anzugeben und Informationen über Laufwerke abzufragen. Dies ist jedoch keineswegs erforderlich, um eine GUI zu erstellen. Verwenden Sie die Techniken, die Sie in diesem Beitrag lernen, um Ihre GUIs an Ihre eigenen Skripte anzupassen.

Als Beispiel-Skript werde ich eine Funktion erstellen, die folgende Aktionen ausführt:

  1. Eingabe des Computernamens, der abgefragt werden soll
  2. Den Computer abfragen und die Informationen über die festen Laufwerke in einer Variablen speichern
  3. Die Ergebnisse zurückgeben

Die Funktion schreiben

Hier ist die Funktion, die Sie für dieses Projekt verwenden werden, passenderweise Get-FixedDisk genannt. Der Zweck dieses Projekts besteht darin, Informationen über die nicht entfernbaren oder festen Laufwerke auf der Zielmaschine zu erhalten.

Obwohl dieses Code-Stück so verwendet werden kann, ist es vorteilhaft, eine GUI zu erstellen, wenn Sie nur eine schnelle Abfrage durchführen möchten, ohne die Funktion zu dot sourcen und jedes Mal manuell die Befehle einzugeben.

Function Get-FixedDisk {
    [CmdletBinding()]
    # Dieser Param()-Block gibt den Beginn der Parameterdeklaration an
    param (
        <# 
            Dieser Parameter akzeptiert den Namen des Zielcomputers.
            Er ist auch als obligatorisch festgelegt, damit die Funktion nicht ohne Angabe des Werts ausgeführt wird.
        #>
        [Parameter(Mandatory)]
        [string]$Computer
    )
    <#
        WMI-Abfragebefehl, der die Liste aller logischen Laufwerke abruft und die Ergebnisse in einer Variablen namens $DiskInfo speichert
    #>
    $DiskInfo = Get-WmiObject Win32_LogicalDisk -ComputerName $Computer -Filter 'DriveType=3'
   $DiskInfo
}

Sie sehen, dass ich einen param()-Block im Code hinzugefügt habe. Dies dient dazu, die Funktion anzuweisen, Eingaben basierend auf dem angegebenen Datentyp zu akzeptieren.

In diesem Beispiel habe ich einen Computer-Parameter hinzugefügt, der einen Zeichenfolgenwert akzeptiert. Durch Hinzufügen des Mandatory-Parameterattributs wird sichergestellt, dass die Funktion nicht ausgeführt wird, wenn der Computer-Parameter zur Laufzeit nicht angegeben wird.

Anschließend zeigt Zeile 18 den tatsächlichen WMI-Abfragebefehl, der die Liste aller logischen Laufwerke abruft und die Ergebnisse in einer Variablen namens $DiskInfo speichert. Ich habe auch einen Filter hinzugefügt, um nur die Laufwerke mit DriveType=3 zu erhalten. Dieser Filter stellt sicher, dass nur Informationen über lokale Festplatten angezeigt werden.

Importieren des Codes (Dot Sourcing)

An diesem Punkt haben Sie nun ein funktionierendes Skript und sind bereit, es zu testen. Bevor Sie das Skript jedoch testen können, müssen Sie den Code in eine PowerShell-Sitzung importieren. Eine Möglichkeit, Code in eine PowerShell-Sitzung zu laden, ist das Dot-Sourcing.

Um ein Skript zu dot-sourcen, geben Sie einen Punkt (.) und ein Leerzeichen vor dem Skriptpfad ein. Wenn sich das Skript im Ordner C:\PoshGUI-sample befinden würde, könnten Sie es wie unten dargestellt dot-sourcen.

PS C:\PoshGUI-sample> . .\Main.ps1

Sie können auch den vollständigen Pfad angeben, wenn Sie sich nicht im aktuellen Arbeitsverzeichnis befinden. Im folgenden Beispielcode sehen Sie den vollständigen Pfad des Skripts.

PS C:>. C:\PoshGUI-sample\Main.ps1

Jetzt, da wir den Code in den Speicher importiert haben, können wir mit dem Testen der von uns erstellten Funktion fortfahren. Im folgenden Beispiel wird gezeigt, dass die Funktion Get-FixedDisk verwendet wird, um den Computer poshLabExc abzufragen.

PS51> Get-FixedDisk -Computer poshLabExc

DeviceID     : C:
DriveType    : 3
ProviderName :
FreeSpace    : 53037772800
Size         : 135838822400
VolumeName   : Windows

DeviceID     : D:
DriveType    : 3
ProviderName :
FreeSpace    : 14872641536
Size         : 17178750976
VolumeName   : Temporary Storage

DeviceID     : E:
DriveType    : 3
ProviderName :
FreeSpace    : 488202240
Size         : 524283904
VolumeName   : System Reserved

Erstellen der PowerShell-GUI

An diesem Punkt haben Sie die Skriptdatei mit dem Namen Main.ps1 erstellt und in dem Skript die Funktion Get-FixedDisk erstellt. Sie konnten auch testen und bestätigen, dass die Funktion funktioniert.

Jetzt, da Sie wissen, dass das Skript funktioniert, können Sie mit dem Erstellen der GUI beginnen.

Gestaltung des PowerShell-GUI-Formulars

Planen Sie zunächst, wie Sie die GUI aussehen lassen möchten und welche Elemente Sie verwenden möchten. Für dieses einfache Beispiel wird unsere GUI folgendes enthalten:

  • a text box where the computer name can be entered
  • a button to execute the function
  • a text box where we can display the results

Als nächstes können Sie mit dem Erstellen beginnen!

Um mit der Erstellung der GUI zu beginnen, öffnen Sie Visual Studio und erstellen Sie ein neues Projekt.

Sobald Visual Studio geöffnet ist, klicken Sie auf Datei (1) –> Neu (2) –> Projekt (3).

Creating a new Visual Studio project

Unter dem Neues Projekt-Fenster wählen Sie Visual C# (1), wählen Sie WPF App (.NET Framework) (2), ändern Sie den Namen in PoshGUI-sample (3) und klicken Sie auf OK.

Choosing a Visual Studio project

Sobald das Projekt erstellt ist, wird ein leeres Formular mit dem Namen MainWindow.xaml angezeigt.

Visual Studio MainWindow.xaml

Sie müssen dieses Formular nun nach unseren Anforderungen formatieren. Unten finden Sie die Steuerelemente und das Format, die Sie hinzufügen müssen.

  • Fenster
    • Titel: Datenträgerinformationen
    • Höhe: 326
    • Breite: 403
  • Steuerelemente (4)
    • Label
      • Inhalt: „Computername:“
      • Abstand: 10, 10, 0, 0
    • TextBox
      • Name: txtComputer
      • Text: „“
      • Höhe: 23
      • Breite: 174
    • Button
      • Name: btnQuery
      • Inhalt: Abfragen
      • Abstand: 0, 13, 12, 0
    • TextBox
      • Name: txtResults
      • Text: „“
      • Ist Schreibgeschützt: True
      • Abstand: 10, 60, 0, 0
      • Höhe: 225
      • Breite: 373

Das endgültige Erscheinungsbild des Formulars sollte ähnlich wie im folgenden Bild dargestellt sein. Sie können das Layout Ihres Fensters anders anordnen. Seien Sie kreativ!

PowerShell GUI Template

Kombinieren des Skripts und der PowerShell GUI

Sobald Sie mit Ihrem Design zufrieden sind, können Sie es nun in das Skript integrieren.

PowerShell kann Formulare nicht nativ anzeigen. Um das Formular anzeigen zu können, müssen wir eine Codezeile ganz oben in unser Skript einfügen, um die Darstellung des WPF-Formulars zu unterstützen.

Add-Type -AssemblyName PresentationFramework

Fügen Sie dann Code hinzu, um die folgenden Aktionen auszuführen:

  1. Importieren und Lesen des XAML-Codes des Formulars.
  2. Dynamisches Erstellen von Variablen, die jedem benannten Steuerelement zugeordnet sind.
  3. Das Formular anzeigen.

Nachfolgend finden Sie den aktualisierten Code in Ihrem Skript.

Hinweis: Stellen Sie sicher, dass Sie die Zeile $xamlFile ändern und auf den vollständigen Pfad Ihrer MainWindow.xaml-Datei verweisen.

Add-Type -AssemblyName PresentationFramework

Function Get-FixedDisk {
    [CmdletBinding()]
    # Dieser param()-Block kennzeichnet den Beginn der Parameterdeklaration
    param (
        <# 
            Dieser Parameter akzeptiert den Namen des Zielcomputers.
            Er ist auch als obligatorisch gekennzeichnet, damit die Funktion nicht ohne Angabe des Werts ausgeführt wird.
        #>
        [Parameter(Mandatory)]
        [string]$Computer
    )
    <#
        WMI-Abfragebefehl, der die Liste aller logischen Laufwerke abruft und die Ergebnisse in einer Variablen mit dem Namen $DiskInfo speichert.
    #>
    $DiskInfo = Get-WmiObject Win32_LogicalDisk -ComputerName $Computer -Filter 'DriveType=3'
    $DiskInfo
}

# Wo befindet sich die XAML-Datei?
$xamlFile = "C:\PoshGUI-sample\MainWindow.xaml"

# Fenster erstellen
$inputXML = Get-Content $xamlFile -Raw
$inputXML = $inputXML -replace 'mc:Ignorable="d"', '' -replace "x:N", 'N' -replace '^<Win.*', '<Window'
[XML]$XAML = $inputXML

# XAML lesen
$reader = (New-Object System.Xml.XmlNodeReader $xaml)
try {
    $window = [Windows.Markup.XamlReader]::Load( $reader )
} catch {
    Write-Warning $_.Exception
    throw
}

# Variablen basierend auf den Namen der Formularsteuerelemente erstellen.
# Die Variable wird 'var_<Steuerelementname>' genannt.

$xaml.SelectNodes("//*[@Name]") | ForEach-Object {
    #"Element $($_.Name) wird versucht"
    try {
        Set-Variable -Name "var_$($_.Name)" -Value $window.FindName($_.Name) -ErrorAction Stop
    } catch {
        throw
    }
}
Get-Variable var_*

$Null = $window.ShowDialog()

Hinweis: $Null = $window.ShowDialog() muss immer die letzte Zeile Code in Ihrem Skript sein.

Wenn Sie diesen Code ausführen, indem Sie das Skript Main.ps1 ausführen, sollten Sie die untenstehende Beispiel-Ausgabe sehen.

PowerShell GUI variable and field mappings

Wie Sie sehen können, wurden den drei benannten Steuerelementen ihre Variablen zugewiesen. Diese Variablennamen werden später im Skript referenziert, wenn wir den Steuerungslogikcode hinzufügen.

  • var_btnQuery
  • var_btnComputer
  • var_txtResults

Beachten Sie, dass das Skript an dieser Stelle nur das Formular anzeigen kann, aber die Steuerelemente nutzlos sind, da Sie den Code noch nicht hinzugefügt haben.

Hinzufügen des Ereigniscodes für den Klick auf die Schaltfläche

Jetzt, da Sie das Skript erfolgreich geändert haben, um die GUI zu importieren und anzuzeigen, fügen Sie den Code zu den Steuerelementen hinzu, um die Datenträgerinformationsdaten abzurufen und anzuzeigen.

In diesem Projekt wird nur die Schaltfläche btnQuery einer Aktion zugewiesen. Die anderen Steuerelemente dienen nur als Eingabe- und Ausgabesteuerungen. Das bedeutet, dass wir nur einen Klick-Ereigniscode zu btnQuery hinzufügen müssen.

Um die Klick-Aktion zu btnQuery hinzuzufügen, weisen Sie den folgenden Code der entsprechenden Variablennamen $var_btnQuery zu. Kopieren Sie den folgenden Code und fügen Sie ihn zwischen den Verweisen Get-Variable var_* und $Null = $window.ShowDialog() im Skript ein.

$var_btnQuery.Add_Click( {
   #leeren Sie das Ergebnisfeld
   $var_txtResults.Text = ""
       if ($result = Get-FixedDisk -Computer $var_txtComputer.Text) {
           foreach ($item in $result) {
               $var_txtResults.Text = $var_txtResults.Text + "DeviceID: $($item.DeviceID)`n"
               $var_txtResults.Text = $var_txtResults.Text + "VolumeName: $($item.VolumeName)`n"
               $var_txtResults.Text = $var_txtResults.Text + "FreeSpace: $($item.FreeSpace)`n"
               $var_txtResults.Text = $var_txtResults.Text + "Size: $($item.Size)`n`n"
           }
       }       
   })

$var_txtComputer.Text = $env:COMPUTERNAME

Testen der fertigen PowerShell GUI

Mit allen Teilen abgedeckt, hier ist der vollständige Code für unser Skript, der die Funktion und die von uns entworfene PowerShell GUI enthält.

Add-Type -AssemblyName PresentationFramework

Function Get-FixedDisk {
    [CmdletBinding()]
    # Diese param() Block zeigt den Beginn der Parameterdeklaration an
    param (
        <# 
            Dieser Parameter akzeptiert den Namen des Zielcomputers.
            Es ist auch als zwingend erforderlich festgelegt, damit die Funktion nicht ohne Angabe des Werts ausgeführt wird.
        #>
        [Parameter(Mandatory)]
        [string]$Computer
    )
    <#
        WMI-Abfragebefehl, der eine Liste aller logischen Laufwerke abruft und die Ergebnisse in einer Variablen namens $DiskInfo speichert.
    #>
    $DiskInfo = Get-WmiObject Win32_LogicalDisk -ComputerName $Computer -Filter 'DriveType=3'
   $DiskInfo
}

#Wo befindet sich die XAML-Datei?
$xamlFile = "C:\Users\june\source\repos\PoshGUI-sample\PoshGUI-sample\MainWindow.xaml"

#Fenster erstellen
$inputXML = Get-Content $xamlFile -Raw
$inputXML = $inputXML -replace 'mc:Ignorable="d"', '' -replace "x:N", 'N' -replace '^<Win.*', '<Window'
[xml]$XAML = $inputXML
#XAML lesen

$reader = (New-Object System.Xml.XmlNodeReader $xaml)
try {
    $window = [Windows.Markup.XamlReader]::Load( $reader )
}
catch {
    Write-Warning $_.Exception
    throw
}

#Variablen basierend auf den Namen der Formularsteuerelemente erstellen.
#Die Variable wird als 'var_<control name>' benannt werden.

$xaml.SelectNodes("//*[@Name]") | ForEach-Object {
    #"Versuche Element $($_.Name)";
    try {
        Set-Variable -Name "var_$($_.Name)" -Value $window.FindName($_.Name) -ErrorAction Stop
    } catch {
        throw
   }
}

Get-Variable var_*

$var_btnQuery.Add_Click( {
   #Lösche das Ergebnisfeld
   $var_txtResults.Text = ""
       if ($result = Get-FixedDisk -Computer $var_txtComputer.Text) {
           foreach ($item in $result) {
               $var_txtResults.Text = $var_txtResults.Text + "DeviceID: $($item.DeviceID)`n"
               $var_txtResults.Text = $var_txtResults.Text + "VolumeName: $($item.VolumeName)`n"
               $var_txtResults.Text = $var_txtResults.Text + "FreeSpace: $($item.FreeSpace)`n"
               $var_txtResults.Text = $var_txtResults.Text + "Size: $($item.Size)`n`n"
           }
       }       
   })

$var_txtComputer.Text = $env:COMPUTERNAME
$Null = $window.ShowDialog()

Wie Sie unten sehen können, nachdem das Skript in PowerShell aufgerufen wurde, erschienen die PowerShell GUI-Fenster. Dann können Sie einen gültigen Computernamen eingeben, um die Funktionalität zu testen.

PowerShell GUI Example Result

Überprüfen Sie Anrufer sicher mit Authentifizierungsmethoden, die die Möglichkeit der Benutzerimitation ausschließen. Blockieren Sie Helpdesk-Hacker mit Specops Secure Service Desk. Probieren Sie es kostenlos aus!

Zusammenfassung

In diesem Artikel haben Sie gelernt, wie man eine einfache Funktion erstellt, die Eingaben akzeptiert und Ergebnisse zurückgibt. Sie haben auch gelernt, wie man eine grundlegende WPF PowerShell GUI erstellt und importiert, um sie als Front-End für das erstellte PowerShell-Skript zu verwenden.

Dies ist nur eine einfache Kombination aus Skript und GUI. Es können zahlreiche Verbesserungen vorgenommen werden, wie z.B.:

  • Formatieren der Größe und des freien Speicherplatzes zur Anzeige als GB-Werte.
  • Ändern des Namens der angezeigten Eigenschaft.
  • Verwenden Sie GridView anstelle von TextBox, um die Ergebnisse anzuzeigen.
  • Fügen Sie eine Import-Schaltfläche hinzu, um eine Liste von Servern aus einer CSV-Datei zu durchlaufen.

Es liegt an Ihnen, die Funktionalität entsprechend Ihren Anforderungen anzupassen und hinzuzufügen.

Weiterführende Informationen

Source:
https://adamtheautomator.com/powershell-gui/