Functions/New-HyperVAutopilotVM.ps1


function New-HyperVAutopilotVM {

    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)][string] $VMName,
        [parameter()] $Path = "C:\Hyper-V\",
        [Parameter()][string] $AutopilotJSONfile,
        [Parameter()][string] $ImageVHD,
        [parameter()][string] $IsoFile,
        [Parameter()]
        [ArgumentCompleter({
                [OutputType([System.Management.Automation.CompletionResult])]
                param(
                    [string] $CommandName,
                    [string] $ParameterName,
                    [string] $WordToComplete,
                    [System.Management.Automation.Language.CommandAst] $CommandAst,
                    [System.Collections.IDictionary] $FakeBoundParameters
                )

                $CompletionResults = [System.Collections.Generic.List[System.Management.Automation.CompletionResult]]::new()

                $CompletionResults = Get-VMSwitch "$wordToComplete*" | Select-Object -ExpandProperty Name

                return $CompletionResults
            })][string] $vSwitch = "AP",

        [Parameter()][int] [ValidateSet(1, 2)] $Gen = 2,
        [Parameter()][int] $CPU = 2,
        [Parameter()][int64] $RAM = 4,
        [Parameter()][int64] $DiskSizeGB = 70,
        [switch] $SecureBootDisabled,
        [switch] $DefaultResolution,
        [switch] $StartVM,
        [switch] $Connect
    )

    if (!$ImageVHD -and !$IsoFile) {
        Write-Host "Specify ImageVHD or IsoFile"
        break
    }

    if (Get-VM $VMName -ErrorAction 0) {
        Write-Error "VM with this name already exists"
        break
    }

    if ($ImageVHD) {
        $VHDFolder = "$Path\$($VMName)\Virtual Hard Disks\"
        $VHDDestination = "$VHDFolder\$($VMName).vhdx"

        New-Item $VHDFolder -ItemType Directory -Force

        Start-BitsTransfer -Source $ImageVHD -Destination $VHDDestination -Description "Copying VHD file" -DisplayName "Copying VHD file $($VMName)"

        if ($AutopilotJSONfile) {

            $Mount = (Mount-VHD -Path $VHDDestination -Passthru -Verbose | Get-Disk | Get-Partition | Get-Volume)

            $DriveLetter = $Mount | Where-Object { $_.Driveletter -notlike "" }

            $Dest = "$($DriveLetter.Driveletter):\Windows\Provisioning\Autopilot\"

            Copy-Item $AutopilotJSONfile $Dest -Verbose

            Dismount-VHD $VHDDestination -Verbose

        }
    }



    $RAM = ($RAM * 1024 * 1024 * 1024)

    $DiskSize = ($DiskSizeGB * 1024 * 1024 * 1024)

    if ($ImageVHD) {
        New-VM -Name $VMName -SwitchName $vSwitch -Generation $Gen -MemoryStartupBytes $RAM -Path $Path -VHDPath $VHDDestination -Verbose
    } else {
        New-VM -Name $VMName -SwitchName $vSwitch -Generation $Gen -MemoryStartupBytes $RAM -Path $Path -NewVHDPath "$($VMName).vhdx" -NewVHDSizeBytes $DiskSize -Verbose
    }
    Set-VMProcessor $VMName -Count $CPU -Verbose

    Set-VMMemory $VMName -DynamicMemoryEnabled $false -Verbose

    if ($IsoFile) {

        $vmDvdDrive = Get-VMDvdDrive $VMName
        if ($Gen -eq 1) {
            Set-VMDvdDrive $VMName -Path $IsoFile
            Set-VMBios $VMName -StartupOrder CD, IDE, LegacyNetworkAdapter, Floppy
        } else {
            Add-VMDvdDrive -VMName $VMName -Path $IsoFile
            $vmDvdDrive = Get-VMDvdDrive $VMName
            Set-VMFirmware $VMName -FirstBootDevice $vmDvdDrive
        }
        # Start-Job -ScriptBlock { Start-Sleep 2400; Set-VMDvdDrive -VMName $VMName -Path "" }
    }

    Enable-VMIntegrationService -VMName $VMName -Name "Guest Service Interface" -Verbose

    if ($Gen -eq 2) {
        Set-VMKeyProtector $VMName -NewLocalKeyProtector -Verbose

        Enable-VMTPM $VMName -Verbose

        if ($SecureBootDisabled) {
            Set-VMFirmware -VMName $VMName -EnableSecureBoot Off
        }
    }

    Set-VM $VMName -AutomaticStartAction Nothing -AutomaticStopAction ShutDown -AutomaticCheckpointsEnabled $false -Verbose

    if (!$DefaultResolution) {
        Set-VMVideo -VMName $VMName -ResolutionType Single -HorizontalResolution 1440 -VerticalResolution 900 -Verbose
    }

    if ($StartVM) {
        Start-VM $VMName -Verbose
    }


    Get-VM $VMName

    if ($Connect) {
        vmconnect.exe $env:COMPUTERNAME $VMName
    }

}