Identify the boot device for a VMware ESXi host

With vSphere 7  VMware is moving away from supporting SD cards and USB as boot media. ESXi Boot configuration with only SD card or USB drive, without any persistent device, is deprecated with vSphere 7 Update 3. In future vSphere releases, it will be an unsupported configuration!

Move from SD cards and USB devices to local persistent disk(s) such as SATA, SAS (including SATADOM), SSD disks as a boot device for example. The minimum disk size is 32 GB, the recommended size is 128 GB. Another option is to use boot from SAN.

More information can be found here link.

The general support period for vSphere 6.7 will end on October 15, 2022. So make sure to upgrade before October 15, 2022, to VMware vSphere 7.

To identify what boot media (does not work for boot from SAN)  is used I created a PowerCLI script that identifies the boot device for every VMware ESXi host in a cluster. After entering the vCenter Server and credentials it will list all the clusters available in the vCenter environment, select the cluster and the boot device per VMWare ESXi host will be identified.

<#
.SYNOPSIS
    This script list the boot device for every VMware ESXi host
.DESCRIPTION
    VMware is moving away from the support of SD cards and USB drives as boot media.
    ESXi Boot configuration with only SD card or USB drive, without any persistent device, is deprecated with vSphere 7 Update 3. 
    In future vSphere releases, it will be an unsupported configuration.
    More information:
    https://blogs.vmware.com/vsphere/2021/09/esxi-7-boot-media-consideration-vmware-technical-guidance.html
.NOTES
    Version:        1.0
    Author:         Ivo Beerens
    Creation Date:  2021 November
    Change:         Creation
#>

# Import the PowerCLI module
Import-Module VMware.PowerCLI

# Variables
$datefile = ( get-date ).ToString('yyyy-MM-dd-hhmmss')
$file = New-Item -type file "C:\Temp\bootdevices$datefile.csv"
$vcenterserver = Read-Host "Enter the vCenter server name"

# Connect to the vCenter Server
Connect-VIServer  $vcenterserver

$cluster = Get-Cluster | Out-GridView -Title "Select the cluster" -OutputMode Single
$allhosts = $cluster | Get-VMHost | where {$_.ConnectionState -eq "Connected"}

$result = @()

foreach ($allhost in $allhosts) {
    $esxcli = Get-EsxCli -V2 -VMHost $allhost
    $result += $esxcli.storage.core.device.list.invoke() | Where {$_.IsBootDevice -match "true"} | Select @{N="Cluster";E={$cluster.Name}},@{N="VMhost";E={$allhost.Name}}, Vendor, Model, IsBootDevice, IsLocal, IsSAS, IsSSD, IsUSB, Device 
}

# Display the output
$result | FT

# Export the output to a CSV file
$result | Export-Csv $file -NoTypeInformation -Force

# Disconnect the vCenter server session 
Disconnect-VIserver -Confirm:$false

The output will be displayed on the screen and saved to a CSV file.

This script makes it easy to identify the boot devices of every VMware ESXi host in a cluster.

Create a Site-to-Site VPN to Microsoft Azure

I have a Visual Studio Enterprise subscription in Azure. I use this subscription for testing new Azure stuff. From my on-premises environment, I want to create a Site-To-Site (S2S) VPN connection to Microsoft Azure. I have a physical Ubiquiti Edge Router in my on-premises network. When searching the internet I found a lot of information that was outdated or not completed. After figuring out how to configure all the steps I decided to create a blog post about the configuration steps. All the information is not limited to the Ubiquiti Edge Router but can be used for other vendors.

In this example, I create a Site-to-Site VPN between my on-premises network and Azure. From my on-premises network, I’m able to connect to the spoke network where my Domain Controller resides.

Requirements

  • Create a network topology drawing. This makes it easier to set up and troubleshoot.

The main steps are

  • Step 1: Configure the Azure VPN gateway
  • Step 2: Configure the Ubiquiti Edge Router.
  • Step 3: Create the network peerings
  • Step 4: Open the firewall on the VMs

Step 1: Configuring the Azure VPN Gateway

First, we begin in Azure by configuring the VPN Gateway. Microsoft has a good article that describes the process that can be found here. I use PowerShell to configure the VPN gateway configuration.

  • Fill in the variables with the correct values of your environment
# Variables
$rg_vpn = "VPN-RG"
$vnetname = "VPN-VNET"
$location = "WestEurope"
$addressspacehub = "10.2.0.0/16"
$subnetname = "Frontend"
$subnet = "10.2.0.0/24"
$gatewaysubnet = "10.2.255.0/27"
$public_ip_onprem = "31.151.12.226"
$allowd_onprem_networks1 = "192.168.249.0/24"
$allowd_onprem_networks2 = "192.168.13.0/24"
$gatewayname = "VPN-GW"
$vpntype = "RouteBased"
# https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsku
$sku = "VpnGw1"
$gatewayType = "Vpn"
$connectionname = "VPN-VNetToOnPrem"
$vpnpip_azure = "VPN-AZURE-PIP"
$vpnconnection = "VPN-IPSEC-S2S"
$sharedkey = "!ThisisASecret!"
  • Connect to Azure
Connect-AzAccount
  • Create the Azure VPN gateway
# Create Azure Resource Group
Write-Host "Create a Resource Group called $rg_vpn" -ForegroundColor Green
New-AzResourceGroup -Name $rg_vpn -Location $Location

# Create networks
$subnet1 = New-AzVirtualNetworkSubnetConfig -Name 'GatewaySubnet' -AddressPrefix $gatewaysubnet
$subnet2 = New-AzVirtualNetworkSubnetConfig -Name $subnetname -AddressPrefix $subnet

# Create VNet
$vnet = New-AzVirtualNetwork -Name $vnetname -ResourceGroupName $rg_vpn `
-Location $location -AddressPrefix $addressspacehub -Subnet $subnet1,$subnet2
$vnet | Set-AzVirtualNetwork

# Create a local network gateway
New-AzLocalNetworkGateway -Name $connectionname -ResourceGroupName $rg_vpn `
-Location $location -GatewayIpAddress $public_ip_onprem -AddressPrefix $allowd_onprem_networks1,$allowd_onprem_networks2

# Request a public IP Address
$gwpip= New-AzPublicIpAddress -Name $vpnpip_azure -ResourceGroupName $rg_vpn -Location $location -AllocationMethod Dynamic

# Create Gatway IP addressing
$vnet = Get-AzVirtualNetwork -Name $vnetname -ResourceGroupName $rg_vpn
$subnet = Get-AzVirtualNetworkSubnetConfig -Name 'GatewaySubnet' -VirtualNetwork $vnet
$gwipconfig = New-AzVirtualNetworkGatewayIpConfig -Name gwipconfig1 -SubnetId $subnet.Id -PublicIpAddressId $gwpip.Id

# Create a Site to Site VPN gateway
Write-Host "Creating  the VPN gateway. This can take up to 45 minutes!" -ForegroundColor Green
New-AzVirtualNetworkGateway -Name $gatewayname -ResourceGroupName $rg_vpn `
-Location $location -IpConfigurations $gwipconfig -GatewayType $gatewayType `
-VpnType $vpntype -GatewaySku $sku

# Configure the VPN Connection configuration
$gateway1 = Get-AzVirtualNetworkGateway -Name $gatewayname -ResourceGroupName $rg_vpn
$local = Get-AzLocalNetworkGateway -Name $connectionname -ResourceGroupName $rg_vpn

New-AzVirtualNetworkGatewayConnection -Name $vpnconnection -ResourceGroupName $rg_vpn `
-Location $location -VirtualNetworkGateway1 $gateway1 -LocalNetworkGateway2 $local `
-ConnectionType IPsec -RoutingWeight 10 -SharedKey $sharedkey
  • When all the parts are created you see the following resources in the resource group.

  • Click on the “VPN-IPSEC-S2S” Connection and click on Download configuration. For various vendors such as Cisco, Allied Telesis, Juniper and Ubiquiti there are sample configuration templates available. If the vendor is not listed you can choose a generic sample configuration.

  • Select “download configuration” and the configuration will be downloaded as text file.

Step 2: Configure the Ubiquiti Edge Router

  • Create a SSH session to the Edge router and log in
  • Set the router in config mode by using the following command
configure
  • Copy the downloaded sample configuration, starting from  the line that begins with “set vpn ipsec auto-firewall-nat-exclude enable ” sample configuration
set vpn ipsec auto-firewall-nat-exclude enable

set vpn ipsec esp-group FOO0 lifetime 3600
set vpn ipsec esp-group FOO0 pfs disable
set vpn ipsec esp-group FOO0 proposal 1 encryption aes256
set vpn ipsec esp-group FOO0 proposal 1 hash sha1

set vpn ipsec ike-group FOO0 key-exchange ikev2
set vpn ipsec ike-group FOO0 lifetime 3600

set vpn ipsec ike-group FOO0 proposal 1 dh-group 2
set vpn ipsec ike-group FOO0 proposal 1 encryption aes256
set vpn ipsec ike-group FOO0 proposal 1 hash sha1

set vpn ipsec site-to-site peer 51.124.215.67 authentication mode pre-shared-secret
set vpn ipsec site-to-site peer 51.124.215.67 authentication pre-shared-secret !ThisisASecret!
set vpn ipsec site-to-site peer 51.124.215.67 connection-type respond
set vpn ipsec site-to-site peer 51.124.215.67 description IPsecAzure
set vpn ipsec site-to-site peer 51.124.215.67 ike-group FOO0
set vpn ipsec site-to-site peer 51.124.215.67 local-address 31.151.12.227

set vpn ipsec site-to-site peer 51.124.215.67 vti bind vti0
set vpn ipsec site-to-site peer 51.124.215.67 vti esp-group FOO0
set interfaces vti vti0
set protocols static interface-route 10.2.0.0/16 next-hop-interface vti0

set firewall options mss-clamp interface-type vti
set firewall options mss-clamp mss 1350
set system offload ipsec enable 
  • In this example, we don’t use dynamic routing protocols such as BGP, so we must create static routes in the Edge Router for all the subnets we want to connect to. In this example, we connect the 10.1.0.0/24 subnet in Azure from the on-premises network. This subnet contains the Domain Controllers. The routing goes through Virtual Tunnel Interface 0 defined in the Edge Router.
set protocols static interface-route 10.1.0.0/24 next-hop-interface vti0
  • Commit and save the changes
commit ; save ; exit
  • Check if the tunnel is up. This can take a while
show vpn ipsec sa

  • The IPSEC tunnel must be ESTABLISHED

Step 3: Create the network peerings

Connecting the spoke network where the Domain Controller resides is not possible because network peering is not configured yet.

  • Open the PowerShell Window that is still authenticated to Azure
  • Change the variables if Needed
  • Execute the PowerShell script
# Variables
$rg_vpn = "VPN-RG"
$rg_dc = "vm-dc-rg"
$peernamevpn = "peer-vpn-to-dc"
$peernamedc = "peer-dc-to-vpn"
$vnetvpnname = "VPN-VNET"
$vnetdcname = "vm-dc-rg-vnet"

$vnetvpn = Get-AzVirtualNetwork -Name $vnetvpnname -ResourceGroupName $rg_vpn
$vnetdc = Get-AzVirtualNetwork -Name $vnetdcname -ResourceGroupName $rg_dc

# Use this virtual network's gateway or Route Server

Add-AzVirtualNetworkPeering `
  -Name $peernamevpn `
  -VirtualNetwork $vnetvpn `
  -RemoteVirtualNetworkId $vnetdc.Id -AllowGatewayTransit:$true
  
Add-AzVirtualNetworkPeering `
  -Name $vnetdcname `
  -VirtualNetwork $vnetdc `
  -RemoteVirtualNetworkId $vnetvpn.Id -UseRemoteGateways:$true 
  • Check the status of the VNet peering
  Get-AzVirtualNetworkPeering -ResourceGroupName $rg_vpn `
  -VirtualNetworkName $vnetvpn.Name | Format-Table VirtualNetworkName, peeringState

  Get-AzVirtualNetworkPeering -ResourceGroupName $rg_dc `
  -VirtualNetworkName $vnetdc.Name | Format-Table VirtualNetworkName, peeringState
  • For both VNets the peeringState must be Connected

Step 4: Open the firewall on the VMs

The first test I perform is a ping test.

  • To ping a VM , ICMP in the Windows firewall needs to be opened. This can be done by using the following PowerShell command.
New-NetFirewallRule –DisplayName "Allow ICMPv4-In" –Protocol ICMPv4

After this change, you must be able to ping (from the 192.168.249.0/24 and 192.168.13.0/24 subnets) to the 10.1.0.0/24 subnet in Azure where the Domain Controller resides.

Wrap-up

Configuring a Site-to-site VPN tunnel involves a lot of steps as you can see in this blog post. I hope by reading this post it will give great insight into how to set up a Site-to-Site VPN to Azure.

Use Packer to install Windows 11 and enable vTPM and VBS

I use Packer for building images for VMware VDI environments. With the latest version (when writing this blog Packer version 1.7.7 is the latest version) it is not possible to configure a TPM in the Hashicorp Configuration Languag (HCL) config file. TPM 2.0 is required to install Windows 11. A vTPM emulates a physical TPM 2.0 and is available in VMware vSphere.

You can install Windows 11 using a registry hack (link) to bypass the TPM check:

reg ADD "HKLM\SYSTEM\Setup\LabConfig" /f /v BypassSecureBootCheck /t REG_DWORD /d 1

vCommunity member Sidney Laan from vEUCaddict wrote a nice blog about using Packer to install Windows 11 using this registry hack (link). When using this hack, it doesn’t enable vTPM or VBS.

For LAB environments, this is no issue but for production, environments you want to have a vTPM enabled and even Virtualization-Based Security (VBS) depending on the security requirements.

So what are TPM and VBS?

TPM

Trusted Platform Module (TPM) technology is designed to provide hardware-based, security-related functions. A TPM chip is a secure crypto-processor that helps you with actions such as generating, storing, and limiting the use of cryptographic keys.

VBS

Virtualization-based security, or VBS, uses hardware virtualization features to create and isolate a secure region of memory from the normal operating system. Windows can use this “virtual secure mode” to host a number of security solutions, providing them with greatly increased protection from vulnerabilities in the operating system, and preventing the use of malicious exploits which attempt to defeat protections.

source link

After the Windows 11 installation with Packer, it is possible to add a vTPM and even enable Virtualization-Based Security (VBS)  by using VMware PowerCLI.

Requirements

  • Use vCenter Server system versions 6.7 or later
  • Add a Key Provider (link)
  • Install PowerCLI by using the following command in PowerShell:
    • Install-Module VMware.PowerCLI -Scope CurrentUser
  • The Windows 11 VM must be powered off
  • Use VM hardware version 14 or higher
  • Don’t create a snapshot with Packer (create_snapshot = false)

PowerCLI Script

The following PowerCLI script can be executed after the Packer Windows 11 deployment. This script adds vTPM, enables VBS support, and creates a snapshot.

  • Change the variables for your environment.

# Import PowerCLI 
Import-Module VMware.PowerCLI

# Variables
$vcentername = "vcentername"
$VMTempName = "VMname"
$snapname = "v0.1"
$snapdescription = "Packer deployement with vTPM and VBS enabled"

# Connect to vCenter Server
Connect-VIServer -Server $vcentername

# Add vTPM
Write-Host 'Set vTPM' 
New-VTpm -VM $VMTempName

# Enable Virtualization Based Security (VBS)
Write-Host 'Enable VBS' 
$vm = Get-VM $VMTempName
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$spec.Firmware = [VMware.Vim.GuestOsDescriptorFirmwareType]::efi
$spec.NestedHVEnabled = $true
$boot = New-Object VMware.Vim.VirtualMachineBootOptions
$boot.EfiSecureBootEnabled = $true
$spec.BootOptions = $boot
$flags = New-Object VMware.Vim.VirtualMachineFlagInfo
$flags.VbsEnabled = $true
$flags.VvtdEnabled = $true
$spec.flags = $flags
$vm.ExtensionData.ReconfigVM($spec)

# Create Snapshot
Write-Host 'Create snapshot' -ForegroundColor green
Get-VM -Name $VMTempName | New-Snapshot -Name $snapname -Description $snapdescription
    
# Disconnect vCenter Server
Disconnect-VIServer -Server * -Confirm:$false
  • When the script is finished, vTPM and VBS support is added
  • Start the VM
  • Check if a TPM is displayed in Device Manager and with the TPM.MSC command

  • Using Powershell the command “Get-TPM” can check the presence of the TPM

    • For Enabling VBS (*1) go to “Device security” in Windows 11, select “Core isolation details” and enable “Memory Integrity”
        • Enabling VBS can also be done by using the following registry settings
reg add "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard" /v "EnableVirtualizationBasedSecurity" /t REG_DWORD /d 1 /f
reg add "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard" /v "RequirePlatformSecurityFeatures" /t REG_DWORD /d 1 /f
reg add "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard" /v "Locked" /t REG_DWORD /d 0 /f
reg add "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity" /v "Enabled" /t REG_DWORD /d 1 /f
reg add "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity" /v "Locked"

More info: Link

(*1) Adding VBS in Windows 11 can have a performance impact on the VM

  • Reboot the VM

  • When the VM is restarted run “msinfo32”
  • Scroll down and check if “Virtualization-Based Security” is running

Adding the PowerCLI script after the Packer deployment will enable vTPM and VBS for the Windows 11 VM. I hope the vTPM and VBS options will be added soon in Packer so we use the HCL config file without the need for an extra PowerCLI script.