Public/New-WindowsServerLabVM.ps1

function New-WindowsServerLabVM {
    [CmdletBinding()]  
    param(
        [Parameter (Mandatory = $True, ValueFromPipeline = $true)]
        [string[]]$Name,

        [Parameter (Mandatory = $True)]
        [string]$ParentVHDPath,

        [Parameter (Mandatory = $True)]
        [string]$RootPath, 

        [Parameter (Mandatory = $True)]
        [int]$RamMB,

        [string]$VirtualSwitchName,

        [switch]$Force,

        [switch]$Start,
        
        [switch]$PassThru
    )
    BEGIN {}
    PROCESS {
        foreach ($n in $Name) {
            try {
                if (Get-VM $n -ErrorAction SilentlyContinue) {
                    if ($Force -eq $false) {
                        Write-Warning "A vm named `'$n`' already exists."
                        continue
                    }
                    else {
                        Remove-WindowsServerLabVM -Name $n -RemoveDisk
                    }
                }
                if (Test-Path "$RootPath\$n") {
                    throw "The directory `'$RootPath\$n`' already exists"   
                }
                New-Item -Name $n -Path $RootPath -ItemType Directory | Out-Null
                $VHDPath = $RootPath + "\$n\Virtual Hard Disks\$n.vhdx"
                New-VHD -ParentPath $ParentVHDPath -Path $VHDPath -Differencing | Out-Null
                $VMParams = @{Name     = $n
                    Generation         = 2
                    MemoryStartupBytes = $RamMB * 1048576
                    Path               = $RootPath
                    VHDPath            = $VHDPath
                }      
                $result = New-VM @VMParams
                if (Get-VMSwitch -Name $VirtualSwitchName -ErrorAction 'SilentlyContinue') {
                    Get-VM -Name $n | Get-VMNetworkAdapter | Connect-VMNetworkAdapter -SwitchName $VirtualSwitchName | Out-Null
                }
                if ($Start) {
                    Start-VM -Name $n | Out-Null
                }
                if ($PassThru) {
                    Write-Output $result
                }
            }
            catch {
                $PSCmdlet.ThrowTerminatingError($_)
            }
        }
    }
    END {}
}