Jere's Techblog

PowerCLI: Create VM Engine

Here is an example of how to make automated VM’s with PowerCLI. You can customize the vLAN, DiskType, etc.

If you reuse the Script below, I would recommend to look at the parameters and adapt them to your environment, e.g. network/storage config like the vLan,ESXI Hosts or the adapter type you are using its VMWare.


Create-CustomVirtualMachine -Hostname 'MyServer' -NumCPU 6 -DiskSize 80 -RAMinGB 12 -OS Srv2016

Ensure you are using this script with PowerCLI or with the PowerCLI Module / Assemblys.

The script can also be saved and imported as a module (.psm1).

Import-Module "Path:\to\your\module\share\Create-VM_onFreeDatastore.psm1" -Verbose

Script to create VMs on Hypervisor with enough free ressources

#by J.Kühnis 06.11.2019
    $VmHostArray = @()

    Class VMHost {

Function Get-VMHostVirtualMachineVMs {
        [Parameter(Mandatory = $true)][String] $VMhost,
    IF ($ExtendedProperties -eq $true) {
        IF ($global:VMhostsVM = (Get-VMHost -Name $VMhost | Get-VM | select MemoryGB, VMHost, Name)) {
            return $global:VMhostsVM
    Else {
        IF ($global:VMhostsVM = ((Get-VMHost -Name $VMhost | Get-VM).Name | sort)) {
            return $global:VMhostsVM
    return $false
Function Get-vmHostDataStore {
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
    $global:DatastoreID = (get-datastore -Id $DatastoreIDList)           
    return  $global:DatastoreID
Function Create-VMEngine {
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]

    write-host "Hypervisor Parameters:" $VMName $EsxiHost $Datastore $MemoryGB $Vlan
    write-host (get-date -f HH:mm:ss)"Start VM Creation $VmName, please wait..."
    If (Get-VM *$VMName*) {
        Write-Host "VM $VMName already exists!!!, Skip this Hostname." -ForegroundColor RED -BackgroundColor Black

    IF ($OS -eq 'Win10') {
        New-VM -Name $VmName -ResourcePool $EsxiHost -Datastore $Datastore -NumCPU $NumCPUCore -MemoryGB $MemoryGB -NetworkName $Vlan -GuestID windows9_64Guest -DiskGB $DiskSize -DiskStorageFormat $HDFormat
    Else {
        New-VM -Name $VmName -ResourcePool $EsxiHost -Datastore $Datastore -NumCPU $NumCPUCore -MemoryGB $MemoryGB -NetworkName $Vlan -GuestID windows9Server64Guest -DiskGB $DiskSize -DiskStorageFormat $HDFormat

    # Set SCSI Controller
    Get-ScsiController -VM $VmName | Set-ScsiController -Type VirtualLsiLogicSAS >$NULL -WarningAction SilentlyContinue
    Write-host "Configure VM $VMName"
    # Configure vCPU & Core
    $VmName = Get-VM -name $VmName
    set-vm -vm $VmName -numcpu $TotalCpu -Confirm:$false >$NULL

    # Configure MAC-Address and Adapter Type
    $vm = Get-VM -Name $vmName
    $nic = Get-NetworkAdapter -VM $vm
    $global:spec = New-Object VMware.Vim.VirtualMachineConfigSpec
    $devSpec = New-Object VMware.Vim.VirtualDeviceConfigSpec
    $devSpec.Device = $nic.ExtensionData
    $devSpec.operation = "edit"
    $spec.DeviceChange += $devSpec
    Set-NetworkAdapter -NetworkAdapter $nic -Type Vmxnet3 -Confirm:$false >$NULL

    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec
    $spec.Firmware = [VMware.Vim.GuestOsDescriptorFirmwareType]::bios
    try {
    catch {

    #special Parameters
    New-AdvancedSetting -Entity $vm -Name ethernet0.pciSlotNumber -Value 192 -Confirm:$false -Force:$true >$NULL -WarningAction SilentlyContinue
    Write-host "VM Config finished"
    write-host (get-date -f HH:mm:ss)"VM Creation $VmName finished!" -ForegroundColor "Green"


Function Create-CustomVirtualMachine {
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$Hostname,
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][ValidateRange(1, 16)][int]$NumCPU,
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][ValidateRange(1, 250)][int]$DiskSize,
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][ValidateRange(1, 32)][int]$RAMinGB,
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][ValidateSet('Win10', 'Srv2016')][string]$OS

    Write-host "------------------------"`n"| Start VmWare Section |"`n"------------------------"  -ForegroundColor WHITE
    (get-vmhost, | select Name, State, Parent, DatastoreIdList, MemoryTotalGB, MemoryUsageGB) | % {
        #$FreetoUseMemory = ("{0:N0}" -f $_.MemoryTotalGB) - ("{0:N0}" -f $_.MemoryUsageGB)
        $myhost = New-Object VMhost -Property @{Name = $_.Name; State = $_.State; Parent = $_.Parent; DatastoreIdList = $_.DatastoreIdList; MemoryTotalGB = $_.MemoryTotalGB; MemoryUsageGB = $_.MemoryUsageGB; }
        $VmHostArray += $myhost
    Foreach ($VmWareHost in $VmHostArray) {
        $VmWareHost.ReservedVMmemory = ((Get-VMHostVirtualMachineVMs $VmWareHost.Name -ExtendedProperties $true).MemoryGB | Measure-Object -sum).sum
        $VmWareHost.FreetoUseMemory = ("{0:N0}" -f $VmWareHost.MemoryTotalGB) - ("{0:N0}" -f $VmWareHost.ReservedVMmemory);

    $VmHostArray = $VmHostArray | Sort-Object -Property FreetoUseMemory -Descending

    #Check RAM Space on ESXI Host with 10GB reserves on Host
    IF (($VmHostArray[0].FreetoUseMemory - 10) -ge ($RAM)) {
        #Check if Disk has 10GB Free Storage
        IF (get-vmHostDataStore -DatastoreIDList $VmHostArray[0].DatastoreIdList) {
            $specVMDatastore = (get-vmHostDataStore -DatastoreIDList $VmHostArray[0].DatastoreIdList | Sort-Object -Property FreeSpaceGB -Descending)
            [int]$a = ("{0:N0}" -f $specVMDatastore[0].FreeSpaceGB).Replace("'", "")
            IF ($a -ge ($DiskSize + 10) ) {
                $specVMDatastore = $specVMDatastore[0].Name
                $VMName = $Hostname
                $EsxiHost = $VmHostArray[0].Name
                $Datastore = $specVMDatastore
                [int]$NumCPUCore = 1
                $Vlan = 'Some_VlanName'
                $HDFormat = "Thin"
                [int]$TotalCPU = $NumCPU

                # Create VM on Host
                Create-VMEngine -VMName $VMName -EsxiHost $EsxiHost -Datastore $Datastore -MemoryGB $RAMinGB -Vlan $Vlan -NumCPUCore $NumCPUCore -HDFormat $HDFormat -TotalCPU $TotalCPU -DiskSize $DiskSize -OS $OS
                Write-host "----------------------"`n"| End VmWare Section |"`n"----------------------"  -ForegroundColor WHITE
            Else {
                Write-host $Hostname "| not enough storage on ESXI Host! Action stopped." -ForegroundColor Yellow -BackgroundColor Black
        Else {
            Write-host $Hostname "| No Datastore found. Action stopped" -ForegroundColor Yellow -BackgroundColor Black
    Else {
        Write-Host $Hostname "| not enough on ESXI Host. Action stopped" -ForegroundColor Yellow -BackgroundColor Black

Continue reading...

Verify Citrx HostedMachineID with VmWare Hypervisor

Sometimes the HostedMachineID of Citrix does not match that of VmWare. This is often the case when cloning or moving machines. In Citrix Studio you will see the Powerstate of this machines as unknow and you can’t do any VM actions like reboot in the console.

With this script snippet it can be checked. To do this the variable “Broker” must be adjusted in the Script and the PowerCli and CitrixModule (BrokerSnapIn) must be loaded. Furthermore, the connection to the vCenter must be initiated via “Connect-VIServer vCName“.

#25.09.2019by J.Kühnis - Verfiy HostedMachineID with VmWare ESXi Hypervisoer

$Broker = "Enter your BrokerName"
$Brokermachines = Get-BrokerMachine -AdminAddress $Broker | Select MachineName,DNSName,HostedMachineID

Foreach ($Machine in $Brokermachines){
    IF(get-vm $Machine.DnsName -ErrorAction SilentlyContinue){
        IF($Machine.HostedMachineID -eq (Get-View -id (get-vm $machine.DNSName).id).config.uuid){
            Write-Host $Machine.DnsName "HostedMachineID is matching" $Machine.HostedMachineId -ForegroundColor Green
            Write-host $Machine.DnsName "Mismatch ID: VmWare UUID =" (Get-View -id (get-vm $machine.DNSName).id).config.uuid "; Citrix HostedMachineID =" $Machine.HostedMachineID -ForegroundColor Yellow

        Write-host $Machine.DnsName "MachineName not Found on ESXi" -ForegroundColor Yellow

Now that the machines have been read out, the connections can be fixed.

vCenter Cert thumbprint update:

# Open an admin POSH console, load the Citrix Modules (asnp citrix*) and cd to XDHyp:/Connections and run ls. Check the SSLThumbprints entry.
asnp citrix*
cd XDHyp:/Connections
Set-Item -LiteralPath "XDHyp:\Connections\vCenters Name" -sslthumbprint "123456789ABCD123456789ABCDE123456789ABCD" -hypervisorAddress https://vcenter-name/sdk

The letters in SSL-Thumbprint must be uppercase.

In this blog the problem is also discussed in detail:

Continue reading...

Hyper-V Create Machine

I’d like to share a mini Script to create VirtualMachines with Hyper-V and Powershell. It is certainly not enterprise diveable. But it’s enough to create a VM for testing.

#by JKU 02.08.2019

#VM Base Information
$VMName = "TestVM2"
$DataPath = "C:\temp"
$DataVMPath = $DataPath + "\" + $VMName
$DiskDataPath = $DataPath + "\" + $VMName + "\" + $VMName + ".vhdx"
$Memory = 2GB
$Disk = 12GB
$CPUCores = 4
$VMGeneration = 2   #Options are "1","2"   -> If you don't have any idea, please let this at Value 2

$MountIso = "true"
$StartVMaftreCreation = "true"
$IsoPath = "C:\Cloud_JK\NextCloud\\OS\win10\SW_DVD5_Win_Pro_10_64BIT_German_MLF_X20-25597.ISO"

IF(Get-VM -Name $VMName -ErrorAction SilentlyContinue){
    Write-Warning "$VMName : Machine already exists! Please verify your Values."
IF(Test-Path $DataVMPath){
    Write-Warning "$DataVMPath : Folder already exists! Please verify your Values."

Write-Host "Start to create VM $VMName" -foregroudcolor yellow
New-VM -Name $VMName -path $DataPath -MemoryStartupBytes $Memory -NewVHDSizeBytes $Disk -NewVHDPath $DiskDataPath -Generation $VMGeneration

$Vm = (Get-VM -Name $VMName)
Set-VM -VM $Vm -ProcessorCount $CPUCores

IF($MountIso -eq "true"){
    $DVD = Add-VMDvdDrive -VMName ($Vm).Name -Path $ISOPath -Passthru
    Set-VMFirmware -VM $VM -FirstBootDevice $DVD
IF($StartVMaftreCreation -eq "true"){
    Start-VM -Name $VMName

Write-Host "Script End"

Below are two links to similar topics.

To create a virtual machine from a specific template (Hyper V)

Continue reading...