Introduction
Hyper-V Shielded VMs on Windows Server 2016 protect virtual machines from malicious host administrators, rogue hypervisors, and unauthorised VM cloning. A Shielded VM is encrypted using BitLocker and can only run on trusted Hyper-V hosts that have passed attestation — a health verification process conducted by the Host Guardian Service (HGS). Even if an attacker gains access to the Hyper-V host or steals the VHDX file, they cannot read the VM’s data or launch it outside the approved fabric. This guide covers the complete HGS and Shielded VM deployment on Windows Server 2016.
Architecture Overview
The Shielded VM architecture has three components: (1) Host Guardian Service (HGS) — a dedicated server cluster that manages key protection and attestation for trusted Hyper-V hosts; (2) Guarded Hosts — Hyper-V servers that prove their identity and health to HGS and receive the key to start shielded VMs; and (3) Shielded VMs — virtual machines with BitLocker-encrypted virtual disks that require HGS authorisation to start. HGS can operate in two attestation modes: TPM-trusted attestation (production) or Admin-trusted attestation (lab).
Installing the Host Guardian Service
# Install HGS on a dedicated server (should be a separate forest/domain)
Install-WindowsFeature HostGuardianServiceRole -IncludeManagementTools
# Configure HGS as a new AD forest for strong isolation
$safeModePassword = ConvertTo-SecureString 'HGS@SafeMode2016!' -AsPlainText -Force
Install-HgsServer -HgsDomainName 'hgs.contoso.local' `
-SafeModeAdministratorPassword $safeModePassword
# After reboot, initialise the HGS cluster
Initialize-HgsServer -HgsServiceName 'hgs' `
-SigningCertificatePath 'C:HGSsigning.pfx' `
-SigningCertificatePassword (ConvertTo-SecureString 'Cert@Pass!' -AsPlainText -Force) `
-EncryptionCertificatePath 'C:HGSencryption.pfx' `
-EncryptionCertificatePassword (ConvertTo-SecureString 'Cert@Pass!' -AsPlainText -Force) `
-TrustTpm # or -TrustActiveDirectory for admin-trusted mode
# Verify HGS is running
Get-HgsServer
Configuring TPM-Trusted Attestation
# On each Guarded Host — collect the TPM identifier
$tpmInfo = Get-PlatformIdentifier -Name 'HVHOST01'
$tpmInfo | Export-Clixml 'C:HGSHVHOST01-TpmId.xml'
# Copy the XML to the HGS server, then register the host
Add-HgsAttestationTpmHost -Name 'HVHOST01' `
-Path 'C:HGSHVHOST01-TpmId.xml'
# Create a CI policy to define allowed boot configurations
New-CIPolicy -Level FilePublisher -Fallback Hash -FilePath 'C:HGSCI-Policy.xml' `
-UserPEs:$false
# Convert and apply the CI policy
ConvertFrom-CIPolicy 'C:HGSCI-Policy.xml' 'C:HGSCI-Policy.bin'
Add-HgsAttestationCIPolicy -Name 'DefaultPolicy' -Path 'C:HGSCI-Policy.bin'
# Register the TPM baseline from a reference host
Get-HgsAttestationBaselinePolicy -Path 'C:HGSbaseline.tcglog' -SkipValidation
Add-HgsAttestationTpmPolicy -Name 'StandardBaseline' -Path 'C:HGSbaseline.tcglog'
Configuring the Guarded Host
# On the Hyper-V guarded host — configure it to use the HGS
Set-HgsClientConfiguration -AttestationServerUrl 'https://hgs.contoso.local/Attestation' `
-KeyProtectionServerUrl 'https://hgs.contoso.local/KeyProtection'
# Test attestation from the Hyper-V host
Get-HgsClientConfiguration
# The host should show: AttestationStatus = Passed
# If failed, check event log for specific failure reason
Get-WinEvent -LogName 'Microsoft-Windows-HostGuardianService-Client/Operational' `
-MaxEvents 20 | Select-Object TimeCreated,Id,Message
Creating a Shielding Data File
The shielding data file (PDK) is created by the tenant and contains the secrets needed to provision the Shielded VM:
# Create an owner certificate for the tenant
$ownerCert = New-SelfSignedCertificate -Subject 'CN=ShieldedVM-Owner' `
-CertStoreLocation Cert:LocalMachineMy `
-KeyUsage DigitalSignature,DataEncipherment
# Create the shielding data file
$Guardian = Get-HgsGuardian -Name 'Fabrikam'
$Owner = New-HgsGuardian -Name 'TenantOwner' -GenerateCertificates
$KP = New-HgsKeyProtector -Owner $Owner -Guardian $Guardian -AllowUntrustedRoot
$params = @{
Policy = 'Shielded' # or 'EncryptionSupported'
SecureSettingsPath = 'C:ShieldingData'
Owner = $Owner
Guardian = $Guardian
AnswerFile = 'C:ShieldingDataunattend.xml'
RootCertificateThumbprint = $ownerCert.Thumbprint
}
New-ShieldingDataFile @params -Path 'C:ShieldingDataTenant.pdk'
Provisioning a Shielded VM
# On the guarded Hyper-V host — create a new shielded VM from a template disk
# The template disk must be prepared with New-VHD and sealed with Protect-Template
# Create a new VM from a shielded template
$vmParams = @{
Name = 'ShieldedApp01'
MemoryStartupBytes = 2GB
Path = 'D:VMs'
Generation = 2
}
New-VM @vmParams
# Apply the key protector from the PDK
$pdk = Get-Item 'C:ShieldingDataTenant.pdk'
$kp = (Import-ShieldingDataFile $pdk.FullName).KeyProtectors[0]
Set-VMKeyProtector -VMName 'ShieldedApp01' -KeyProtector $kp.RawData
# Enable vTPM for the shielded VM
Enable-VMTPM -VMName 'ShieldedApp01'
# Start the VM — Hyper-V requests the key from HGS
Start-VM -Name 'ShieldedApp01'
# Verify shielding status
Get-VMSecurity -VMName 'ShieldedApp01'
Summary
Hyper-V Shielded VMs on Windows Server 2016 provide the strongest available protection for virtual workloads in a shared hosting or multi-tenant environment. By combining BitLocker encryption, the Host Guardian Service, TPM attestation, and key protection, Shielded VMs ensure that only authorised, healthy Hyper-V hosts can run sensitive workloads. This architecture protects against compromised host administrators, VM theft, and live migration to untrusted hosts — making it the ideal choice for regulated, high-security environments.