Public/Build-FMTTestVM.ps1

function Build-FMTTestVM {
    param(
        [parameter(Mandatory)]
        [ValidateSet('Windows','RHEL','SQL','SQLDev','Debian','Ubuntu','OEL8')]
        [string] $image,
        [parameter()]
        [string] $rg,
        [parameter()]
        [string] $vnetRG = $rg,
        [parameter(Mandatory)]
        [string] $vmName,
        [parameter()]
        [string] $vnet,
        [parameter()]
        [string] $subNet,
        [parameter()]
        [string] $dataSubnet,
        [parameter()]
        [switch] $publicIP,
        [parameter()]
        [string] $subscriptionName,
        [parameter(Mandatory)]
        [System.Management.Automation.PSCredential] $adminCreds,
        [parameter()]
        [string] $size = 'Standard_D32s_v5',
        [parameter()]
        [int] $zone,
        [parameter()]
        [ValidateSet(1,2)]
        [int] $generation = 1
    )

    # Check AZ context

    $session = New-FMTSession
    if (!$session) {
        $message = '-- stopping --'
        return $message
    }

    if ($subscriptionName) {
        try {
            Get-AzSubscription -SubscriptionName $subscriptionName | Set-AzContext
        } catch {
            $error[0]
            exit
        }
    }
    
    # Fill in the gaps in parameter list

    if (!$rg) {
        $rgArray = Get-AzResourceGroup | Select-Object resourcegroupname,location | Sort-Object resourcegroupname
        $rg = Build-MenuFromArray -array $rgArray -property resourcegroupname -message "Select the desired resource group"
    }    
    
    if (!$vnetRG) {
        $vnetRG = $rg
        $rg = Build-MenuFromArray -array $rgArray -property resourcegroupname -message "Select the desired resource group"
    }

    if (!$vnet) {
        $vnetArray = Get-AzVirtualNetwork -ResourceGroupName $vnetRG | Select-Object name,location | Sort-Object name
        $vnetArray = Get-AzVirtualNetwork | Select-Object name,location | Sort-Object name
        $vnet = Build-MenuFromArray -array $vnetArray -property name -message "Select the desired Virtualnetwork"
    }

    if (!$subNet) {
        $subnetArray = Get-AzVirtualNetwork -Name $vnet -ResourceGroupName $vnetRG  | Get-AzVirtualNetworkSubnetConfig | Select-Object name
        $subnet = Build-MenuFromArray -array $subnetArray -property name -message "Select the desired management subnet"
    }

    if (!$dataSubnet) {
        $dataSubnetArray = Get-AzVirtualNetwork -Name $vnet -ResourceGroupName $vnetRG | Get-AzVirtualNetworkSubnetConfig | Select-Object name
        $dataSubnet = Build-MenuFromArray -array $dataSubnetArray -property name -message "Select the desired data subnet. Leave blank for no data interface."
    }


    # Get location data
    $rgData = Get-AzResourceGroup -ResourceGroupName $rg

    # create a PIP
    if ($publicIP) {
        $pipName = $vmName + '-pip'
        $pip = Get-AzPublicIpAddress -ResourceGroupName $rg -Name $pipName -ErrorAction SilentlyContinue
        if (!$pip) {
            Write-Host -ForegroundColor yellow "-- Public IP not found, setting one up for use..."
            if ($zone) {
                $pip = New-AzPublicIpAddress -Name $pipName -ResourceGroupName $rg -Location $rgData.Location -Sku Standard -AllocationMethod Static -Zone $zone
            } else {
                $pip = New-AzPublicIpAddress -Name $pipName -ResourceGroupName $rg -Location $rgData.Location -Sku Standard -AllocationMethod Static 
            }
        }    
    }

    # Create Data interface(s)
    $nic1Name = $vmName + '-mgmt'
    $nic1subnet = Get-AzVirtualNetwork -ResourceGroupName $vnetRG -Name $vnet | Get-AzVirtualNetworkSubnetConfig | where-object {$_.name -eq $subNet}
    if ($publicIP) {
        $mgmtNic = New-AzNetworkInterface -Subnet $nic1subnet -Name $nic1Name -ResourceGroupName $rg -Location $rgData.Location -EnableAcceleratedNetworking -PublicIpAddress $pip
    } else {
        $mgmtNic = New-AzNetworkInterface -Subnet $nic1subnet -Name $nic1Name -ResourceGroupName $rg -Location $rgData.Location -EnableAcceleratedNetworking 
    }

    if ($dataSubnet) {
        Write-Host '-- Adding Data interface --'
        $nic2Name = $vmName + '-data'
        $nic2subnet = Get-AzVirtualNetwork -ResourceGroupName $vnetRG -Name $vnet | Get-AzVirtualNetworkSubnetConfig | where-object {$_.name -eq $dataSubnet}
        $dataNic = New-AzNetworkInterface -Subnet $nic2subnet -Name $nic2Name -ResourceGroupName $rg -Location $rgData.Location -EnableAcceleratedNetworking
    }

    # Create the user credential
    $cred = $adminCreds

    # create the VM config
    if ($zone) {
        $vmConfig = New-AzVMConfig -VMName $vmName -VMSize $size -Zone $zone 

    } else {
        $vmConfig = New-AzVMConfig -VMName $vmName -VMSize $size 

    }

    if ($image -eq 'Windows') {
        Write-Host '-- Setting OS for Windows --'
        $vmConfig | Set-AzVMOperatingSystem -Windows -ComputerName $vmName -Credential $cred 
        if ($generation -eq 1) {
            $vmConfig | Set-AzVMSourceImage -PublisherName "MicrosoftWindowsServer" -Offer "WindowsServer" -Skus "2022-datacenter" -Version "latest"
        } elseif ($generation -eq 2) {
            $vmConfig | Set-AzVMSourceImage -PublisherName "MicrosoftWindowsServer" -Offer "WindowsServer" -Skus "2022-datacenter-g2" -Version "latest"
        }
    } elseif ($image -eq 'SQL') {
        Write-Host '-- Setting OS for Windows SQL --'
        $vmConfig | Set-AzVMOperatingSystem -Windows -ComputerName $vmName -Credential $cred 
        $vmConfig | Set-AzVMSourceImage -PublisherName "microsoftsqlserver" -Offer "sql2022-ws2022" -Skus "enterprise-gen2" -Version "latest"
    } elseif ($image -eq 'SQLDev') {
        Write-Host '-- Setting OS for Windows SQL Dev --'
        $vmConfig | Set-AzVMOperatingSystem -Windows -ComputerName $vmName -Credential $cred 
        if ($generation -eq 1) {
            $vmConfig | Set-AzVMSourceImage -PublisherName "microsoftsqlserver" -Offer "sql2019-ws2019" -Skus "sqldev" -Version "latest"
        } elseif ($generation -eq 2) {
            $vmConfig | Set-AzVMSourceImage -PublisherName "microsoftsqlserver" -Offer "sql2019-ws2019" -Skus "sqldev-gen2" -Version "latest"
        }
    } elseif ($image -eq 'RHEL') {
        Write-Host '-- Setting OS for RHEL --'
        $vmConfig | Set-AzVMOperatingSystem -Linux -ComputerName $vmName -Credential $cred 
        $vmConfig | Set-AzVMSourceImage -PublisherName "RedHat" -Offer "RHEL" -Skus "87-gen2" -Version "latest"
    } elseif ($image -eq 'Debian') {
        Write-Host '-- Setting OS for Debian --'
        $vmConfig | Set-AzVMOperatingSystem -Linux -ComputerName $vmName -Credential $cred 
        $vmConfig | Set-AzVMSourceImage -PublisherName "debian" -Offer "debian-11" -Skus "11-gen2" -Version "latest"
    } elseif ($image -eq 'Ubuntu') {
        Write-Host '-- Setting OS for Debian --'
        $vmConfig | Set-AzVMOperatingSystem -Linux -ComputerName $vmName -Credential $cred 
        $vmConfig | Set-AzVMSourceImage -PublisherName "canonical" -Offer "0001-com-ubuntu-server-focal" -Skus "20_04-lts-gen2" -Version "latest"
    } elseif ($image -eq 'OEL8') {
        Write-Host '-- Setting OS for OEL --'
        $vmConfig | Set-AzVMOperatingSystem -Linux -ComputerName $vmName -Credential $cred 
        $vmConfig | Set-AzVMSourceImage -PublisherName "Oracle" -Offer "Oracle-Linux" -Skus "ol88-lvm-gen2" -Version "latest"
    } else {
        Write-Host '-- Setting OS for Linux --'
        $vmConfig | Set-AzVMOperatingSystem -Linux -ComputerName $vmName -Credential $cred
        $vmConfig | Set-AzVMSourceImage -PublisherName "Canonical" -Offer "0001-com-ubuntu-server-focal" -Skus "20_04-lts" -Version "latest"
    }
    $vmConfig | Add-AzVMNetworkInterface -Id $mgmtNic.Id

    if ($dataSubnet) {
        $vmConfig.NetworkProfile.NetworkInterfaces[0].Primary = $true
        $vmConfig | Add-AzVMNetworkInterface -Id $dataNic.Id
    }

    # Create a VM using the abov config
    if ($zone) {
        New-AzVm -ResourceGroupName $rg -Location $rgData.Location -Zone $zone -VM $vmConfig 
    } else {
        New-AzVm -ResourceGroupName $rg -Location $rgData.Location -VM $vmConfig

    }
}