A small powershell script that i make to test powershell script with gui. In this gui a can see all my hyper-v guest i have. I can start/stop, connect and delete machines in this gui.

<#
 Solution: Hyper-V 
 Purpose: Hyper-V GUI
 Version: 2.0.1
    Date: 08 Mars 2021 

  Author: Tomas Johansson
 Twitter: @Deploymentdude
     WWW: www.4thcorner.net

 This script is provided "AS IS" with no warranties, confers no rights and 
 is not supported by the author
#>

# Check for elevation
If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole( `
    [Security.Principal.WindowsBuiltInRole] "Administrator")) {
    Write-Warning "Oupps, you need to run this script from an elevated PowerShell prompt!`nPlease start the PowerShell prompt as an Administrator and re-run the script."
	Write-Warning "Aborting script..."
    Break
}

# Check hyper-v module installed
if(!(get-module -ListAvailable -Name "hyper-v")) {
    throw "Hyper-V module not found. Please run this tool on a server that has the Hyper-V management tools installed"
}

# Add needed Assemblys
Add-Type -AssemblyName PresentationCore
Add-Type -AssemblyName PresentationFramework
Add-Type -AssemblyName System.Drawing  
Add-Type -AssemblyName System.Windows.Forms
[void] [System.Windows.Forms.Application]::EnableVisualStyles() 

[xml]$XAML = @'
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Virtual Machines in Hyper-V" Height="450" Width="740">
        <Grid Name="grid" Margin="20,0,25,0.5">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Label Name="Information" Content="Hyper-V Machines on:" Grid.Row="1" />
        <Label Name="Machine" Content="Machines" Grid.Row="1" Grid.ColumnSpan="2" Margin="125,0,0,0" />
        <ListView Name="ListViewMain" HorizontalAlignment="Left" Height="280" Width="680" Margin="0" VerticalAlignment="Top"  Grid.Row="2">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Hyper-V VM Name" DisplayMemberBinding="{Binding VMName}" />
                    <!--<GridViewColumn Header="VMName" DisplayMemberBinding ="{Binding VMName}"/>-->
                    <GridViewColumn Header="State" DisplayMemberBinding ="{Binding VMState}"/>
                    <GridViewColumn Header="CPU Usage" DisplayMemberBinding ="{Binding VMCPUUsage}"/>
                    <GridViewColumn Header="Assigned Memory MB" DisplayMemberBinding ="{Binding VMMemoryAssigned}"/>
                    <GridViewColumn Header="Version" DisplayMemberBinding ="{Binding VMVersion}"/>
                    <!--<GridViewColumn Header="VM Path" DisplayMemberBinding ="{Binding VMPath}"/>-->
                    <GridViewColumn Header="VM Uptime" DisplayMemberBinding ="{Binding VMUptime}"/>
                    <!--<GridViewColumn Header="VM" DisplayMemberBinding="{Binding VM}" />-->
                </GridView>
            </ListView.View>
        </ListView>
        <StackPanel Grid.Row="3" HorizontalAlignment="Left" Grid.ColumnSpan="2" Width="300">
            <Label Name="LabelAction" Content="Actions:" />
        </StackPanel>
        <GroupBox Name="groupBox_Hyper_V_Start_Stop" Header="Start/Stop VM" HorizontalAlignment="Left" Margin="0,30,0,0" Grid.Row="3" VerticalAlignment="Top" Height="64">
            <StackPanel VerticalAlignment="Top" HorizontalAlignment="Left" Orientation="Horizontal">
                <Button Name="buttonStart" Content="Start" Width="75" Margin="10,10,0,10" />
                <Button Name="buttonStop" Content="Stop" Width="75" Margin="20,10,10,10" HorizontalAlignment="Left"/>
            </StackPanel>
        </GroupBox>
        <GroupBox Name="groupBoxConnect" Header="Console" HorizontalAlignment="Left" Margin="220,30,0,0" Grid.Row="3" VerticalAlignment="Top">
            <Button Name="buttonConnect" Content="Connect" HorizontalAlignment="Center" Width="75" Margin="10"/>
        </GroupBox>
        <Button Name="buttonRefresh" Content="Refresh" HorizontalAlignment="Left" Margin="500,65,0,0" Grid.Row="3" VerticalAlignment="Top" Width="75"/>
        <Button Name="buttonCancel" Content="Cancel" HorizontalAlignment="Right" Margin="0,65,10,0" Grid.Row="3" VerticalAlignment="Top" Width="74"/>
        <GroupBox x:Name="groupBoxDelete" Header="Delete VM" HorizontalAlignment="Left" Margin="350,30,0,0" Grid.Row="3" VerticalAlignment="Top">
            <Button Name="buttonDeleteVM" Content="Delete" HorizontalAlignment="Left" Width="75" Margin="10"/>
        </GroupBox>
    </Grid>
</Window>
'@

# Read XAML
$Reader = New-Object System.Xml.XmlNodeReader $XAML
$Form = [Windows.Markup.XamlReader]::Load($Reader)
foreach ($Name in ($XAML | Select-Xml '//*/@Name' | ForEach-Object { $_.Node.Value})) {
    New-Variable -Name $Name -Value $Form.FindName($Name) -Force
}

Function LoadListView {
$VMInfos = @()
$VMs = get-vm

    foreach ($VM in $VMs) {
        $VMInfo = New-Object -TypeName PSObject
        $VMInfo | Add-Member -MemberType NoteProperty -Name VMName -Value $VM.Name
        $VMInfo | Add-Member -MemberType NoteProperty -Name Name -Value $VM.Name
        $VMInfo | Add-Member -MemberType NoteProperty -Name VMState -Value $VM.State
        $VMInfo | Add-Member -MemberType NoteProperty -Name VMCPUUsage -Value $VM.CPUUsage
        $VMInfo | Add-Member -MemberType NoteProperty -Name VMMemoryAssigned -Value ($VM.MemoryAssigned/1MB)
        $VMInfo | Add-Member -MemberType NoteProperty -Name VMVersion -Value $VM.Version
        $VMInfo | Add-Member -MemberType NoteProperty -Name VMPath -Value $VM.Path
        $VMInfo | Add-Member -MemberType NoteProperty -Name VMUptime -Value ("{0:D1}" -f $VM.Uptime.Days +  '.' + "{0:D2}" -f $VM.Uptime.Hours +  ':' + "{0:D2}" -f $VM.Uptime.Minutes +  ':' + "{0:D2}" -f $VM.Uptime.Seconds)
        $VMInfo | Add-Member -MemberType NoteProperty -Name VM -Value $VM
        $VMInfos += $VMInfo
    }
    $ListViewMain.ItemsSource = $VMInfos
}

# Event Handlers
$Form.Add_Loaded({

})

# Sort event handler
$Form.Add_SourceInitialized({
    [System.Windows.RoutedEventHandler]$ColumnSortHandler = {

        If ($_.OriginalSource -is [System.Windows.Controls.GridViewColumnHeader]) {
           
            If ($_.OriginalSource -AND $_.OriginalSource.Role -ne 'Padding') {

                $Column = $_.Originalsource.Column.DisplayMemberBinding.Path.Path
                                                
                # And now we actually apply the sort to the View
                $ListViewMain_DefaultView = [System.Windows.Data.CollectionViewSource]::GetDefaultView($ListViewMain.ItemsSource)
                # Change the sort direction each time they sort
                    Switch($ListViewMain_DefaultView.SortDescriptions[0].Direction)
                    {
                        "Decending" { $Direction = "Ascending" }
                        "Ascending" { $Direction = "Descending" }
                            Default { $Direction = "Ascending" }
                    }           
                $ListViewMain_DefaultView.SortDescriptions.Clear()
                $ListViewMain_DefaultView.SortDescriptions.Add((New-Object System.ComponentModel.SortDescription $Column, $Direction))
                $ListViewMain_DefaultView.Refresh()  
            }
        }
    }
    # Attach the Event Handler
    $ListViewMain.AddHandler([System.Windows.Controls.GridViewColumnHeader]::ClickEvent, $ColumnSortHandler)
})

# Stop selected VMs
$ButtonStop.Add_Click({
    $Form.Topmost = $false
    Stop-VMs -VM $ListViewMain.SelectedItems
})

# Start selected VMs
$buttonStart.Add_Click({
    $Form.Topmost = $false
    Start-VMs -VM $ListViewMain.SelectedItems
})

# Connect to Conole on selected VM
$buttonConnect.Add_Click({
    $Form.Topmost = $false

    if ([string]::IsNullOrEmpty($ListViewMain.SelectedItem.Name)) {
        $ButtonType = [System.Windows.MessageBoxButton]::OK
        $MessageboxTitle = "Connect to Console"
        $Messageboxbody = "Please select a Machine to connect to!"
        $MessageIcon = [System.Windows.MessageBoxImage]::Exclamation
        [System.Windows.MessageBox]::Show($Messageboxbody,$MessageboxTitle,$ButtonType,$messageicon)

    }
    Else {
        Start-Process -FilePath  "$env:windirsystem32vmconnect.exe" -ArgumentList $env:COMPUTERNAME,$ListViewMain.SelectedItem.Name
    }
})

$buttonDeleteVM.Add_Click({
    $Form.Topmost = $false

    if ([string]::IsNullOrEmpty($ListViewMain.SelectedItem.Name)) {
        $ButtonType = [System.Windows.MessageBoxButton]::OK
        $MessageboxTitle = "Delete Virtula Macine"
        $Messageboxbody = "Please select a Machine to Delete!"
        $MessageIcon = [System.Windows.MessageBoxImage]::Exclamation
        [System.Windows.MessageBox]::Show($Messageboxbody,$MessageboxTitle,$ButtonType,$messageicon)

    }
    Else {
        Delete-VM -VM $ListViewMain.SelectedItems
    }
})

# Refresh ListView
$ButtonRefresh.Add_Click({
    LoadListView
})

# Close dialog window
$ButtonCancel.add_click({ 
    $Form.Close() 
})

$objForm = New-Object System.Windows.Forms.Form 
$objForm.KeyPreview = $True

$objForm.Add_KeyDown({
    If ($_.KeyCode -eq "Escape") {
        $objForm.Close()
    }
})

# Action Stop Virtual Machines
function Stop-VMs
{
    [CmdletBinding()]
    [Alias()]
    [OutputType([int])]
    Param
    (
        # Param1 help description
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [Object] $VM
    )
    Begin {
    }
    Process
    {
     write-warning "Shutting down VM: $($VM.VMName) ($($VM.Name))"
     Stop-VM -Name $VM.Name
    }
    End {
        LoadListView
    }
}

# Action Start Virtual Machines
Function Start-VMs {
    [CmdletBinding()]
    [Alias()]
    [OutputType([int])]
    Param
    (
        # Param1 help description
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [Object] $VM
    )
    Begin {
    }
    Process
    {
     write-warning "Starting VM: $($VM.VMName) "
     Start-VM -Name $VM.VMName
    }

    End {
        LoadListView
    }
}

# Delete Selected Virtual Machines
Function Delete-VM {
    [CmdletBinding()]
    [Alias()]
    [OutputType([int])]
    Param (
        # Param1 help description
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [Object] $VM
    )
    Begin {
    }
    Process {
        write-warning "Deleting VM: $($VM.VMName) ($($VM.Name))"
        $VM2Delete  = $VM
        ForEach ($VMDelet in $VM2Delete) {
            $ButtonType = [System.Windows.MessageBoxButton]::YesNo
            $MessageboxTitle = “ Delete Virtual Machine”
            $Messageboxbody = “Do you really want to delete this machine:`n`n$($VMDelet.Name)"
            $MessageIcon = [System.Windows.MessageBoxImage]::Question
            $Result = [System.Windows.MessageBox]::Show($Messageboxbody,$MessageboxTitle,$ButtonType,$messageicon)
            If ($Result -eq "YES") {
                DoDeleteOfVM -MachineName $VMDelet.Name
                $ButtonType = [System.Windows.MessageBoxButton]::OK
                $MessageboxTitle = “ Virtual Machine Deleted”
                $Messageboxbody = “Virtual Machine: $($VMDelet.Name) Deleted!"
                $MessageIcon = [System.Windows.MessageBoxImage]::Information
                [System.Windows.MessageBox]::Show($Messageboxbody,$MessageboxTitle,$ButtonType,$messageicon)
            }
        }
    }
    End {
        LoadListView
    }
}

# Doing Deleting ov selected VirtualMachine
Function DoDeleteofVM {
    [CmdletBinding()]
    [Alias()]
    [OutputType([int])]
    Param (
        # Param1 help description
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [String]$MachineName
    )
    Begin {
    }
    Process {
        Try {
        # Get VM information
        $VM = Get-VM -Name $MachineName -ErrorAction stop
        Write-Host  -ForegroundColor Green "Virtual machine: $($MachineName.ToUpper()) Exist on host"

        # Shutdown machine if running
        If ($VM.State -eq "Running")  {
            Write-Host  -ForegroundColor Yellow "Virtual machine: $($MachineName.ToUpper()) Running"
            DO {
                Stop-VM -Name $MachineName -TurnOff
                $VM = Get-VM -Name $MachineName -ErrorAction stop
    
            } While ($VM.State -eq "Running")
            Write-Host  -ForegroundColor Green "Virtual machine: $($MachineName.ToUpper()) is Stopped"
        }

        #Get Path for machine to delete
        $VMPath = $VM.Path

        # Removing machine from hyper-v host
        Remove-VM –vmname $MachineName -Force

        # Remove Directorys and files
        If (Test-Path $VMPath) {
            Get-ChildItem -Path $VMPath -Include * | remove-Item -recurse
            If (Test-Path $VMPath) { 
                Remove-Item -Path $VMPath
            }
        }
            Write-Host -ForegroundColor Green "Virtual machine: $($MachineName.ToUpper()) Deleted from host"
        }
        Catch
        {
            Write-Host -ForegroundColor Yellow "No Virtual machine: $($MachineName.ToUpper()) Exist on host"
        }
    }
}

# Set Lable Machine Content
$Machine.Content = $env:COMPUTERNAME

# Load Listview with data
LoadListView

# Launch the window
$Form.WindowStartupLocation="CenterScreen"
$Form.Add_Loaded( {
    $this.TopMost = $true
})

# Show the window
$Form.ShowDialog() | out-null

Link to repository on github