# Hyper-V

## Virtual Machine Creator

This example uses [PowerShell Universal Dashboard](https://docs.powershelluniversal.com/v1/dashboard/about).

This example can be used to create virtual machines on a Hyper-V host. This dashboard assumes it's being run on the host in question. You could adjust the dashboard script to run on a remote host.

```
Start-PSUServer -Port 8080 -Configuration {
    New-PSUDashboard -Name 'Hyper-V' -BaseUrl '/' -Framework 'UniversalDashboard:Latest' -Content {

        $HostRam = Get-WMIObject -class Win32_PhysicalMemory | Measure-Object -Property capacity -Sum | % {[Math]::Round(($_.sum / 1GB *0.97),0)-1}
        $HostName=hostname
        $SwitchList = @()
        Get-VMSwitch | Select-Object -ExpandProperty name | ForEach-Object {
            $SwitchList += $_
        }

        function Run-Checks
        {
            $VMHostInfo= Get-VMHost

            $BootISOTextBoxText = (Get-UDElement -Id 'VMBootISO')['value']
            $VHDRootTextBoxText = (Get-UDElement -Id 'VMVHDRoot')['value']
            $VMNameTextBoxText = (Get-UDElement -Id 'VMName')['value']
            $Generation = (Get-UDElement -Id 'VMGeneration')['value']
            $SwitchNameComboBoxText = (Get-UDElement -Id 'VMSwitch')['value']
            $RAMinGBTextBoxText = (Get-UDElement -Id 'VMRam')['value']
            $CPUCountTextBoxText = (Get-UDElement -Id 'VMCPU')['value']
            [int64]$VLANIDTextBoxText = (Get-UDElement -Id 'VMVLan')['value']

            #Paths and Gen Sets    
            if ($BootISOTextBoxText -and $BootISOTextBoxText -ne "") {$ISOFilePathValid = test-path $BootISOTextBoxText}
            if ($VHDRootTextBoxText -and $VHDRootTextBoxText -ne "") {$VHDBootPathValid = test-path $VHDRootTextBoxText}
            if ($Generation -eq 'Gen1') { $VMGeneration = 1 } else { $VMGeneration = 2 } 

            if ($VMNameTextBoxText.Length -ne 0) { $VMExists = Get-VM -name $VMNameTextBoxText -ErrorAction SilentlyContinue }

            if (-not (Test-Path $VMHostInfo.VirtualMachinePath) ) {Show-UDToast -Message  "Default Virtual Machine path is not valid in HyperV Host Settings"}
            elseif (-not (Test-Path $VMHostInfo.VirtualHardDiskPath) ) {Show-UDToast -Message  "Default Virtual Harddisk path is not valid in HyperV Host Settings"}
            elseif ($VMExists) {Show-UDToast -Message  "VM with that name already exists"}
            elseif ($VMNameTextBoxText.Length -eq 0) {Show-UDToast -Message  "Please Enter VM Name"}
            elseif ($SwitchNameComboBoxText -eq "Switch Name") {Show-UDToast -Message  "Please Select a Switch Name"}
            elseif ($ISOFilePathValid -eq $False) {Show-UDToast -Message  "ISO File path in invaild"}
            elseif ($VHDRootTextBoxText -eq "") {Show-UDToast -Message  "VHD Root path is blank.  Please enter a valid path"}
            elseif ($VHDBootPathValid -eq $False) {Show-UDToast -Message  "VHD Root path in invaild"}
            elseif ($RAMinGBTextBoxText.Length -eq 0) {Show-UDToast -Message  "Please Enter Ram Amount in GB"}
            elseif ([int64]$RAMinGBTextBoxText -lt 1) {Show-UDToast -Message  "Please Enter Ram Amount of at least 1GB"}
            elseif ([int64]$RAMinGBTextBoxText -gt $HostRam) {Show-UDToast -Message  "Please Enter Ram Amount of "+ $HostRam + "GB or bellow"}
            elseif ($CPUCountTextBoxText.Length -eq 0) {Show-UDToast -Message  "Please Enter a CPU Count"}
            elseif ([int64]$CPUCountTextBoxText.Length -eq 0) {Show-UDToast -Message  "Please Enter a CPU Count"}
            elseif ([int64]$CPUCountTextBoxText -lt 1) {Show-UDToast -Message  "Please Enter a CPU Count of at least 1"}
            elseif ([int64]$CPUCountTextBoxText -gt 64) {Show-UDToast -Message  "Please Enter a CPU Count of 64 or below"}
            elseif ([int64]$VLANIDTextBoxText -gt 999 -or [int64]$VLANIDTextBoxText -lt 1) {Show-UDToast -Message  "Please Enter VLAN ID between 1 and 999."}
            else 
            {
                (65..90) | ForEach-Object { 
                    $DriveLetter = [char]$_  

                    [int64]$value = (Get-UDElement -Id "Drive$DriveLetter")['value']

                    if ($value -gt 65536)
                    {
                        Show-UDToast -Message  "For $DriveLetter Drive please Enter a Disk Size of 65536 GB or below"
                        return $false
                    }
                } 

                Show-UDToast -Message  "Looking Good Man ;)"

                return $true
            }

            return $false
        }

        function Create-VMs
        {
            Run-Checks

            $BootISOTextBoxText = (Get-UDElement -Id 'VMBootISO')['value']
            $VHDRootTextBoxText = (Get-UDElement -Id 'VMVHDRoot')['value']
            $VMNameTextBoxText = (Get-UDElement -Id 'VMName')['value']
            $Generation = (Get-UDElement -Id 'VMGeneration')['value']
            [int]$SwitchNameComboBoxIndex = (Get-UDElement -Id 'VMSwitch')['value']
            $SwitchNameComboBoxText = $SwitchList[$SwitchNameComboBoxIndex]
            Show-UDToast -message ((Get-UDElement -Id 'VMSwitch') | ConvertTo-Json)
            $RAMinGBTextBoxText = (Get-UDElement -Id 'VMRam')['value']
            $CPUCountTextBoxText = (Get-UDElement -Id 'VMCPU')['value']
            $VLANIDTextBoxText = (Get-UDElement -Id 'VMVLan')['value']

            if ($Generation -eq 'Gen1') { $VMGeneration = 1 } else { $VMGeneration = 2 } 

            #Create VM

            try
            {
                New-VM -Name $VMNameTextBoxText -MemoryStartupBytes ([int]$RAMinGBTextBoxText*1073741824) -SwitchName $SwitchNameComboBoxText -Generation $VMGeneration -ErrorAction Stop
            }
            catch
            {
                $VMCrateFailed=$True
                Show-UDToast -Message ("VM " + $VMNameTextBoxText + " Failed to Create :( $($_.Exception.Message)")
            }


            if (-Not($VMCrateFailed -eq $True))
            {
                (65..90) | ForEach-Object { 
                    $DriveLetter = [char]$_  
                    [int64]$value = (Get-UDElement -Id "Drive$DriveLetter")['value']
                    if ($value -gt 0)
                    {
                        $Path = $VHDRootTextBoxText+"\"+$VMNameTextBoxText+"\"+$VMNameTextBoxText+"-"+$value+".vhdx"
                        if (-not (test-path $Path)) 
                        {
                            New-VHD -Path $Path -SizeBytes (Invoke-Expression ("$($Value)GB")) -Dynamic
                        } 
                        else 
                        {
                            $VHDPathExisted = $true
                        }
                    }
                } 

            Get-VM $VMNameTextBoxText | Set-VMProcessor -Count $CPUCountTextBoxText
            Get-VM $VMNameTextBoxText | set-VMNetworkAdapterVlan -Access -vlanId $VLANIDTextBoxText

            (65..90) | ForEach-Object { 
                $DriveLetter = [char]$_  
                [int64]$value = (Get-UDElement -Id "Drive$DriveLetter")['value']
                $Path = $VHDRootTextBoxText+"\"+$VMNameTextBoxText+"\"+$VMNameTextBoxText+"-"+$value+".vhdx"

                if (Test-Path $Path)
                {
                    Add-VMHardDiskDrive -VMName $VMNameTextBoxText -Path $Path -ControllerType SCSI -ControllerNumber 0
                }
            } 

            # 
            #  REMOVING NETWORK FROM THE BOOT ORDER

            #Set New Boot order
            if ($VMGeneration -eq "2")
                {
                    $old_boot_order = Get-VMFirmware -VMName $VMNameTextBoxText -ComputerName $HostName | Select-Object -ExpandProperty BootOrder
                    $new_boot_order = $old_boot_order | Where-Object { $_.BootType -ne "Network" }
                    Set-VMFirmware -VMName $VMNameTextBoxText -ComputerName $HostName -BootOrder $new_boot_order
                }


            #  ADD DVD Drive with ISO Attached
            if ($BootISOTextBoxText -ne "")
            {
                Get-VM $VMNameTextBoxText | Add-VMDvdDrive -Path $BootISOTextBoxText
            }

            if ($VHDPathExisted) {
                Show-UDToast -Message ("VM " + $VMNameTextBoxText + " Created OK, but at least one VHD already existed and was just reattached")
            }
            else 
            {
                Show-UDToast -Message ("VM " + $VMNameTextBoxText + " Created OK")}
            }
        }


        New-UDDashboard -Title "Hyper-V VM Creator" -Content {
            New-UDContainer -Children {
                New-UDTypography -Text "Hyper-V VM Creator" -Variant h3 

                New-UDRow -Columns {
                    New-UDColumn -LargeSize 6 -Content {
                        New-UDRow -Columns {
                            New-UDTextbox -Label 'VM Name' -Id 'VMName'
                        }
                        New-UDRow -Columns {
                            New-UDTextbox -Id 'VMRam' -Label 'RAM in GB' -Value $HostRam
                        }
                        New-UDRow -Columns {
                            New-UDTextbox -Id 'VMCPU' -Label 'CPU Count' -Value 2
                        }

                        New-UDRadioGroup -Label 'Generation' -Id 'VMGeneration' -Children {
                            New-UDRadio -Label 'Gen 1' -Value 'Gen1'
                            New-UDRadio -Label 'Gen 2' -Value 'Gen2'
                        } -Value 'Gen1'
                    }
                    New-UDColumn -LargeSize 6 -Content {
                        New-UDRow -Columns {
                            New-UDSelect -Id 'VMSwitch' -Label 'Switch Name' -Option {
                                $i = 0
                                $SwitchList | ForEach-Object {
                                    New-UDSelectOption -Value $i -Name $_
                                    $i++
                                }
                            }
                        }

                        New-UDTextbox -Id 'VMVLan' -Label 'VLAN ID'
                    }
                }

                New-UDRow -Columns {
                    New-UDColumn -LargeSize 12 -Content {
                        New-UDTextbox -Id 'VMBootISO' -Label 'Boot ISO'
                    }
                }

                New-UDRow -Columns {
                    New-UDColumn -LargeSize 12 -Content {
                        New-UDTextbox -Id 'VMVHDRoot' -Label 'VHD Root'
                    }
                }

                New-UDTypography -Text 'Drives' -Variant h4

                New-UDRow -Columns {
                    New-UDColumn -LargeSize 6 -Content {
                        New-UDRow -Columns {
                            # Loop through each letter of the alphabet
                            (65..90) | ForEach-Object { 
                                New-UDColumn -LargeSize 6 -Content {
                                    $DriveLetter = [char]$_  
                                    New-UDTextbox -Id "Drive$DriveLetter" -Placeholder $DriveLetter
                                }
                            } 
                        }
                    }
                    New-UDColumn -LargeSize 6 -Content {
                        New-UDButton -Text 'Do Some Checks' -OnClick { Run-Checks }
                        New-UDButton -Text 'Im feeling lucky Create Vm' -OnClick { Create-VMs }
                    }
                }
            }
        }
    }

}
```

![](https://2374445323-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M6jY7sXTmhiAIMGYw_m%2F-MN1Y5gLi5po9csxQx1O%2F-MN1Y_WO8CZmCx9X2N00%2Fimage.png?alt=media\&token=f8ff73d5-3de4-49bd-af53-3cbcaf113155)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.powershelluniversal.com/v1/examples/hyper-v.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
