Maak WPF PowerShell GUI’s: Functies, Invoer en Resultaten

PowerShell is een command-line tool, maar wist je dat het ook gebruikt kan worden als basis voor grafische interfaces? Soms is de command-line niet het beste soort interface voor een specifieke situatie. Het bouwen van een PowerShell GUI voor je service desk is een goed voorbeeld. Dit is een van die momenten waarop het meer geschikt is om grafische tools te bouwen.

Not a reader? Watch this related video.

Handhaaf verificatie van eindgebruikers bij het resetten van wachtwoorden bij de helpdesk. Verminder je kwetsbaarheid voor social engineering met Specops Secure Service Desk. Neem contact met ons op voor een demo!

PowerShell kan gebruikmaken van en .NET functionaliteit en features blootstellen. Hierdoor is het mogelijk om GUI front-ends te schrijven voor de scripts die je maakt. Het bouwen van PowerShell GUI’s kan ingewikkeld lijken, vooral als je een beginner bent.

Maar als je basiskennis hebt van PowerShell scripting, is er geen reden om niet te leren en de praktijk van het maken van een GUI voor je scripts aan te passen.

In deze post leer je hoe je een PowerShell GUI kunt maken met behulp van het Windows Presentation Framework (WPF).

Vereisten

Voordat je begint, zorg ervoor dat je voldoet aan de volgende vereisten:

  1. Visual Studio 2017 of nieuwer – Hiermee maak je de grafische gebruikersinterface met behulp van WPF. Je kunt een gratis/community versie downloaden.
  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.

Het Script Bouwen

In deze post maak je een eenvoudig script genaamd Main.ps1. In het script schrijf je code die schijfinformatie ophaalt van een lokaal of extern systeem door de Win32_LogicalDisk WMI-klasse te bevragen.

Je hebt een script nodig om eerst een GUI omheen te wikkelen. Ik heb ervoor gekozen om een script te gebruiken waarmee je een computernaam kunt opgeven en schijfinformatie kunt opvragen. Dit is absoluut niet nodig om een GUI te bouwen. Gebruik de technieken die je in deze post leert om je GUI’s aan te passen aan je eigen scripts.

Als voorbeeldscript zal ik een functie maken die de volgende handelingen uitvoert:

  1. Invoer accepteren voor de naam van de computer om te bevragen
  2. De computer bevragen en de informatie over vaste schijven opslaan in een variabele
  3. De resultaten retourneren

De Functie Schrijven

Hieronder staat de functie die je zult gebruiken voor dit project, toepasselijk genaamd Get-FixedDisk. Het doel van dit project is om informatie te verkrijgen over de niet-verwijderbare of vaste schijven op het doelsysteem.

Hoewel dit stuk code zoals het is kan worden gebruikt, zou het handig zijn om een GUI te maken als je snel een query wilt uitvoeren zonder telkens de functie te laden en de opdrachten handmatig in te typen.

Function Get-FixedDisk {
    [CmdletBinding()]
    # Deze param() blok geeft het begin aan van de declaratie van parameters
    param (
        <# 
            Deze parameter accepteert de naam van de doelcomputer.
            Het is ook ingesteld als verplicht zodat de functie niet wordt uitgevoerd zonder de waarde op te geven.
        #>
        [Parameter(Mandatory)]
        [string]$Computer
    )
    <#
        WMI-queryopdracht die de lijst van alle logische schijven ophaalt en de resultaten opslaat in een variabele met de naam $DiskInfo
    #>
    $DiskInfo = Get-WmiObject Win32_LogicalDisk -ComputerName $Computer -Filter 'DriveType=3'
   $DiskInfo
}

Je kunt zien dat ik een param() blok aan de code heb toegevoegd. Dit is om de functie te instrueren invoer te accepteren op basis van het aangegeven gegevenstype.

In het voorbeeld heb ik een Computer-parameter toegevoegd die een tekenreekswaarde accepteert. Door ook de Mandatory-parameterattribuut toe te voegen, wordt ervoor gezorgd dat de functie niet wordt uitgevoerd als de Computer-parameter niet is gespecificeerd tijdens runtime.

Vervolgens toont regel 18 de daadwerkelijke WMI-queryopdracht die de lijst van alle logische schijven ophaalt en de resultaten opslaat in een variabele met de naam $DiskInfo. Ik heb ook een filter toegevoegd om alleen de schijven met DriveType=3 op te halen. Dit filter zorgt ervoor dat alleen de informatie over lokale vaste schijven wordt weergegeven.

Importeren van de Code (Dot Sourcing)

Op dit moment heb je een werkend script en ben je klaar om het te testen. Maar voordat je het script kunt testen, moet je de code importeren in een PowerShell-sessie. Een manier om code in een PowerShell-sessie te laden, is door het te dot sourcen.

Om een script te dot sourcen, typ je een punt (.) en een spatie vóór het scriptpad. Als het script in de map C:\PoshGUI-voorbeeld stond, zou je het als volgt kunnen dot sourcen.

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

Je kunt ook het volledige pad specificeren als je niet in de huidige werkmap bent. In de onderstaande voorbeeldcode zie je het volledige pad van het script.

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

Nu we de code in het geheugen hebben geïmporteerd, kunnen we doorgaan met het testen van de functie die we hebben gemaakt. In het onderstaande voorbeeld wordt getoond dat de functie Get-FixedDisk wordt gebruikt om de computer poshLabExc te bevragen.

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

Het bouwen van de PowerShell GUI

Op dit punt heb je het scriptbestand genaamd Main.ps1 gemaakt, en binnen het script de functie Get-FixedDisk aangemaakt. Je was ook in staat om te testen en te bevestigen dat de functie werkt.

Nu je weet dat het script werkt, kun je beginnen met het bouwen van de GUI.

Het ontwerpen van het PowerShell GUI-formulier

Plan eerst hoe je wilt dat de GUI eruitziet en welke elementen je wilt gebruiken. Voor dit eenvoudige voorbeeld zal onze GUI het volgende bevatten:

  • 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

Vervolgens kun je beginnen met bouwen!

Om te beginnen met het maken van de GUI, open Visual Studio en maak een nieuw project aan.

Eenmaal Visual Studio geopend is, klik op Bestand (1) –> Nieuw (2) –> Project (3).

Creating a new Visual Studio project

Onder het Nieuw Project venster, kies Visual C# (1), selecteer WPF App (.NET Framework) (2), wijzig de naam naar PoshGUI-sample (3) en klik op OK.

Choosing a Visual Studio project

Zodra het project is aangemaakt, wordt een leeg formulier weergegeven met de naam MainWindow.xaml.

Visual Studio MainWindow.xaml

U moet dit formulier nu opmaken om aan onze eisen te voldoen. Hieronder staan de besturingselementen en het formaat dat u moet toevoegen.

  • Window
    • Titel: Schijfinformatie
    • Hoogte: 326
    • Breedte: 403
  • Besturingselementen (4)
    • Label
      • Inhoud: “Computernaam:”
      • Marge: 10, 10, 0, 0
    • TextBox
      • Naam: txtComputer
      • Tekst: “”
      • Hoogte: 23
      • Breedte: 174
    • Knop
      • Naam: btnQuery
      • Inhoud: Query
      • Marge: 0, 13, 12, 0
    • TextBox
      • Naam: txtResults
      • Tekst: “”
      • IsAlleenLezen: True
      • Marge: 10, 60, 0, 0
      • Hoogte: 225
      • Breedte: 373

De uiteindelijke verschijning van het formulier moet vergelijkbaar zijn met wat wordt getoond in de onderstaande afbeelding. U kunt het ontwerp van uw venster anders indelen. Wees creatief!

PowerShell GUI Template

Het combineren van het script en de PowerShell GUI

Zodra u tevreden bent met uw ontwerp, kunt u nu beginnen met integreren met het script.

PowerShell kan formulieren niet standaard weergeven. Om het formulier te kunnen weergeven, moeten we een regel code toevoegen aan het begin van ons script om het renderen van het WPF-formulier te ondersteunen.

Add-Type -AssemblyName PresentationFramework

Voeg vervolgens code toe om de volgende acties uit te voeren:

  1. Importeer en lees de XAML-code van het formulier.
  2. Maak dynamisch variabelen aan die zijn toegewezen aan elk genoemd bedieningselement
  3. Formulier weergeven

Hieronder staat de bijgewerkte code in uw script.

Opmerking: Zorg ervoor dat u de regel $xamlFile aanpast en deze naar het volledige pad van uw MainWindow.xaml-bestand wijst.

Add-Type -AssemblyName PresentationFramework

Function Get-FixedDisk {
    [CmdletBinding()]
    # Deze param() blok geeft het begin van de parameters declaratie aan
    param (
        <# 
            Deze parameter accepteert de naam van de doelcomputer.
            Het is ook ingesteld als verplicht zodat de functie niet wordt uitgevoerd zonder de waarde op te geven.
        #>
        [Parameter(Mandatory)]
        [string]$Computer
    )
    <#
        WMI-query-opdracht die de lijst met alle logische schijven ophaalt en de resultaten opslaat in een variabele met de naam $DiskInfo
    #>
    $DiskInfo = Get-WmiObject Win32_LogicalDisk -ComputerName $Computer -Filter 'DriveType=3'
    $DiskInfo
}

# waar is het XAML-bestand?
$xamlFile = "C:\PoshGUI-sample\MainWindow.xaml"

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

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

# Maak variabelen op basis van de namen van de formulierbesturingselementen.
# De variabele krijgt de naam 'var_<naam van het besturingselement>'

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

$Null = $window.ShowDialog()

Opmerking: $Null = $window.ShowDialog() moet altijd de laatste regel code zijn in uw script.

Wanneer u deze code uitvoert door het script Main.ps1 uit te voeren, zou u de onderstaande voorbeelduitvoer moeten zien.

PowerShell GUI variable and field mappings

Zoals u kunt zien, zijn de drie genoemde besturingslementen aan hun variabelen toegewezen. Deze variabelenamen worden later in het script gebruikt wanneer we de controlelogica-code toevoegen.

  • var_btnQuery
  • var_btnComputer
  • var_txtResults

Houd er rekening mee dat het script op dit punt alleen het formulier kan weergeven, maar de bedieningselementen zijn nutteloos omdat je de code nog niet hebt toegevoegd.

Toevoegen van de knop Klikgebeurteniscode

Nu je met succes het script hebt aangepast om de GUI te importeren en weer te geven, begin je met het toevoegen van de code aan de bedieningselementen om de gegevens van de schijfinformatie op te halen en weer te geven.

In dit project krijgt alleen de btnQuery-knop een actie toegewezen. De andere bedieningselementen dienen alleen als invoer- en uitvoer-/weergavebedieningselementen. Dit betekent dat we alleen een click-gebeurteniscode aan btnQuery hoeven toe te voegen.

Om de click-actie toe te voegen aan btnQuery, wijs je de onderstaande code toe aan de overeenkomstige variabelenaam $var_btnQuery. Kopieer de onderstaande code en voeg deze in tussen de verwijzingen naar de code Get-Variable var_* en $Null = $window.ShowDialog() in het script.

$var_btnQuery.Add_Click( {
   #resultaatvak leegmaken
   $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 van de voltooide PowerShell GUI

Met alle onderdelen gedekt, hieronder staat de voltooide code voor ons script die de functie en de PowerShell GUI bevat die we hebben ontworpen.

Add-Type -AssemblyName PresentationFramework

Function Get-FixedDisk {
    [CmdletBinding()]
    # Dit param() blok geeft het begin van de parameterdeclaratie aan
    param (
        <# 
            Deze parameter accepteert de naam van de doelcomputer.
            Het is ook ingesteld als verplicht zodat de functie niet wordt uitgevoerd zonder de waarde op te geven.
        #>
        [Parameter(Mandatory)]
        [string]$Computer
    )
    <#
        WMI-queryopdracht die de lijst van alle logische schijven ophaalt en de resultaten opslaat in een variabele met de naam $DiskInfo
    #>
    $DiskInfo = Get-WmiObject Win32_LogicalDisk -ComputerName $Computer -Filter 'DriveType=3'
   $DiskInfo
}

#waar is het XAML-bestand?
$xamlFile = "C:\Users\june\source\repos\PoshGUI-sample\PoshGUI-sample\MainWindow.xaml"

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

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

#Variabelen maken op basis van de namen van de formulierbesturingselementen.
#Variabele zal worden genoemd als 'var_<control name>'

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

Get-Variable var_*

$var_btnQuery.Add_Click( {
   #het resultaatvak wissen
   $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()

Zoals je hieronder kunt zien, nadat het script in PowerShell is aangeroepen, verschenen de PowerShell GUI-vensters. Vervolgens kun je een geldige computernaam invoeren om de functionaliteit te testen.

PowerShell GUI Example Result

Verifieer veilig bellers met verificatiemethoden die de mogelijkheid tot gebruikersimitatie wegnemen. Blokkeer helpdesk hackers met Specops Secure Service Desk. Probeer het gratis!

Samenvatting

In dit artikel heb je geleerd hoe je een eenvoudige functie kunt maken die invoer accepteert en resultaten retourneert. Je hebt ook geleerd hoe je een eenvoudige WPF PowerShell GUI kunt maken en hoe je deze kunt importeren om als front-end te fungeren voor het PowerShell-script dat je hebt gemaakt.

Dit is slechts een eenvoudige combinatie van script en GUI. Talrijke verbeteringen zijn mogelijk, zoals:

  • Het formatteren van de grootte en vrije ruimte om weer te geven als GB-waarden.
  • De naam van de weergegeven eigenschap wijzigen.
  • Het gebruik van GridView in plaats van TextBox om de resultaten weer te geven.
  • Een importknop toevoegen om door een lijst met servers uit een CSV-bestand te lopen.

Het is aan jou om wijzigingen aan te brengen en functionaliteit toe te voegen op basis van jouw vereisten.

Verder lezen

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