Use the Azure PowerShell module to enable end-to-end encryption using encryption at host
Applies to: ✔️ Windows VMs
When you enable encryption at host, data stored on the VM host is encrypted at rest and flows encrypted to the Storage service. For conceptual information on encryption at host, and other managed disk encryption types, see Encryption at host - End-to-end encryption for your VM data.
Restrictions
- Supported for 4k sector size Ultra Disks and Premium SSD v2.
- Only supported on 512e sector size Ultra Disks and Premium SSD v2 if they were created after 5/13/2023.
- For disks created before this date, snapshot your disk and create a new disk using the snapshot.
- Can't be enabled on virtual machines (VMs) or virtual machine scale sets that currently or ever had Azure Disk Encryption enabled.
- Azure Disk Encryption can't be enabled on disks that have encryption at host enabled.
- The encryption can be enabled on existing virtual machine scale sets. However, only new VMs created after enabling the encryption are automatically encrypted.
- Existing VMs must be deallocated and reallocated in order to be encrypted.
Supported VM sizes
The complete list of supported VM sizes can be pulled programmatically. To learn how to retrieve them programmatically, refer to the Finding supported VM sizes section. Upgrading the VM size results in validation to check if the new VM size supports the EncryptionAtHost feature.
Prerequisites
You must enable the feature for your subscription before you use the EncryptionAtHost property for your VM/VMSS. Use the following steps to enable the feature for your subscription:
Execute the following command to register the feature for your subscription
Register-AzProviderFeature -FeatureName "EncryptionAtHost" -ProviderNamespace "Microsoft.Compute"
Check that the registration state is Registered (takes a few minutes) using the following command before trying out the feature.
Get-AzProviderFeature -FeatureName "EncryptionAtHost" -ProviderNamespace "Microsoft.Compute"
Create an Azure Key Vault and DiskEncryptionSet
Note
This section only applies to configurations with customer-managed keys. If you're using platform-managed keys, you can skip to the Example scripts section.
Once the feature is enabled, you need to set up an Azure Key Vault and a DiskEncryptionSet, if you haven't already.
Make sure that you have installed latest Azure PowerShell version, and you are signed in to an Azure account in with Connect-AzAccount
Create an instance of Azure Key Vault and encryption key.
When creating the Key Vault instance, you must enable purge protection. Purge protection ensures that a deleted key cannot be permanently deleted until the retention period lapses. These settings protect you from losing data due to accidental deletion. These settings are mandatory when using a Key Vault for encrypting managed disks.
$ResourceGroupName="yourResourceGroupName" $LocationName="westcentralus" $keyVaultName="yourKeyVaultName" $keyName="yourKeyName" $keyDestination="Software" $diskEncryptionSetName="yourDiskEncryptionSetName" $keyVault = New-AzKeyVault -Name $keyVaultName ` -ResourceGroupName $ResourceGroupName ` -Location $LocationName ` -EnablePurgeProtection $key = Add-AzKeyVaultKey -VaultName $keyVaultName ` -Name $keyName ` -Destination $keyDestination
Create an instance of a DiskEncryptionSet. You can set RotationToLatestKeyVersionEnabled equal to $true to enable automatic rotation of the key. When you enable automatic rotation, the system will automatically update all managed disks, snapshots, and images referencing the disk encryption set to use the new version of the key within one hour.
$desConfig=New-AzDiskEncryptionSetConfig -Location $LocationName ` -SourceVaultId $keyVault.ResourceId ` -KeyUrl $key.Key.Kid ` -IdentityType SystemAssigned ` -RotationToLatestKeyVersionEnabled $false $des=New-AzDiskEncryptionSet -Name $diskEncryptionSetName ` -ResourceGroupName $ResourceGroupName ` -InputObject $desConfig
Grant the DiskEncryptionSet resource access to the key vault.
Note
It may take few minutes for Azure to create the identity of your DiskEncryptionSet in your Microsoft Entra ID. If you get an error like "Cannot find the Active Directory object" when running the following command, wait a few minutes and try again.
Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName -ObjectId $des.Identity.PrincipalId -PermissionsToKeys wrapkey,unwrapkey,get
Use a key vault in a different subscription
Alternatively, you can manage your Azure Key Vaults centrally from a single subscription, and use the keys stored in the Key Vault to encrypt managed disks and snapshots in other subscriptions in your organization. This allows your security team to enforce and easily manage a robust security policy to a single subscription.
Important
For this configuration, both your Key Vault and your disk encryption set must be in the same region and be using the same tenant.
The following script is an example of how you would configure a disk encryption set to use a key from a Key Vault in a different subscription, but same region:
$sourceSubscriptionId="<sourceSubID>"
$sourceKeyVaultName="<sourceKVName>"
$sourceKeyName="<sourceKeyName>"
$targetSubscriptionId="<targetSubID>"
$targetResourceGroupName="<targetRGName>"
$targetDiskEncryptionSetName="<targetDiskEncSetName>"
$location="<targetRegion>"
Set-AzContext -Subscription $sourceSubscriptionId
$key = Get-AzKeyVaultKey -VaultName $sourceKeyVaultName -Name $sourceKeyName
Set-AzContext -Subscription $targetSubscriptionId
$desConfig=New-AzDiskEncryptionSetConfig -Location $location `
-KeyUrl $key.Key.Kid `
-IdentityType SystemAssigned `
-RotationToLatestKeyVersionEnabled $false
$des=New-AzDiskEncryptionSet -Name $targetDiskEncryptionSetName `
-ResourceGroupName $targetResourceGroupName `
-InputObject $desConfig
Enable encryption at host for disks attached to VM and Virtual Machine Scale Sets
You can enable encryption at host by setting a new property EncryptionAtHost under securityProfile of VMs or Virtual Machine Scale Sets using the API version 2020-06-01 and above.
"securityProfile": { "encryptionAtHost": "true" }
Example scripts
Create a VM with encryption at host enabled with customer-managed keys.
Create a VM with managed disks using the resource URI of the DiskEncryptionSet created earlier to encrypt cache of OS and data disks with customer-managed keys. The temp disks are encrypted with platform-managed keys.
$VMLocalAdminUser = "yourVMLocalAdminUserName"
$VMLocalAdminSecurePassword = ConvertTo-SecureString <password> -AsPlainText -Force
$LocationName = "yourRegion"
$ResourceGroupName = "yourResourceGroupName"
$ComputerName = "yourComputerName"
$VMName = "yourVMName"
$VMSize = "yourVMSize"
$diskEncryptionSetName="yourdiskEncryptionSetName"
$NetworkName = "yourNetworkName"
$NICName = "yourNICName"
$SubnetName = "yourSubnetName"
$SubnetAddressPrefix = "10.0.0.0/24"
$VnetAddressPrefix = "10.0.0.0/16"
$SingleSubnet = New-AzVirtualNetworkSubnetConfig -Name $SubnetName -AddressPrefix $SubnetAddressPrefix
$Vnet = New-AzVirtualNetwork -Name $NetworkName -ResourceGroupName $ResourceGroupName -Location $LocationName -AddressPrefix $VnetAddressPrefix -Subnet $SingleSubnet
$NIC = New-AzNetworkInterface -Name $NICName -ResourceGroupName $ResourceGroupName -Location $LocationName -SubnetId $Vnet.Subnets[0].Id
$Credential = New-Object System.Management.Automation.PSCredential ($VMLocalAdminUser, $VMLocalAdminSecurePassword);
# Enable encryption at host by specifying EncryptionAtHost parameter
$VirtualMachine = New-AzVMConfig -VMName $VMName -VMSize $VMSize -EncryptionAtHost
$VirtualMachine = Set-AzVMOperatingSystem -VM $VirtualMachine -Windows -ComputerName $ComputerName -Credential $Credential -ProvisionVMAgent -EnableAutoUpdate
$VirtualMachine = Add-AzVMNetworkInterface -VM $VirtualMachine -Id $NIC.Id
$VirtualMachine = Set-AzVMSourceImage -VM $VirtualMachine -PublisherName 'MicrosoftWindowsServer' -Offer 'WindowsServer' -Skus '2012-R2-Datacenter' -Version latest
$diskEncryptionSet=Get-AzDiskEncryptionSet -ResourceGroupName $ResourceGroupName -Name $diskEncryptionSetName
# Enable encryption with a customer managed key for OS disk by setting DiskEncryptionSetId property
$VirtualMachine = Set-AzVMOSDisk -VM $VirtualMachine -Name $($VMName +"_OSDisk") -DiskEncryptionSetId $diskEncryptionSet.Id -CreateOption FromImage
# Add a data disk encrypted with a customer managed key by setting DiskEncryptionSetId property
$VirtualMachine = Add-AzVMDataDisk -VM $VirtualMachine -Name $($VMName +"DataDisk1") -DiskSizeInGB 128 -StorageAccountType Premium_LRS -CreateOption Empty -Lun 0 -DiskEncryptionSetId $diskEncryptionSet.Id
New-AzVM -ResourceGroupName $ResourceGroupName -Location $LocationName -VM $VirtualMachine -Verbose
Create a VM with encryption at host enabled with platform-managed keys.
Create a VM with encryption at host enabled to encrypt cache of OS/data disks and temp disks with platform-managed keys.
$VMLocalAdminUser = "yourVMLocalAdminUserName"
$VMLocalAdminSecurePassword = ConvertTo-SecureString <password> -AsPlainText -Force
$LocationName = "yourRegion"
$ResourceGroupName = "yourResourceGroupName"
$ComputerName = "yourComputerName"
$VMName = "yourVMName"
$VMSize = "yourVMSize"
$NetworkName = "yourNetworkName"
$NICName = "yourNICName"
$SubnetName = "yourSubnetName"
$SubnetAddressPrefix = "10.0.0.0/24"
$VnetAddressPrefix = "10.0.0.0/16"
$SingleSubnet = New-AzVirtualNetworkSubnetConfig -Name $SubnetName -AddressPrefix $SubnetAddressPrefix
$Vnet = New-AzVirtualNetwork -Name $NetworkName -ResourceGroupName $ResourceGroupName -Location $LocationName -AddressPrefix $VnetAddressPrefix -Subnet $SingleSubnet
$NIC = New-AzNetworkInterface -Name $NICName -ResourceGroupName $ResourceGroupName -Location $LocationName -SubnetId $Vnet.Subnets[0].Id
$Credential = New-Object System.Management.Automation.PSCredential ($VMLocalAdminUser, $VMLocalAdminSecurePassword);
# Enable encryption at host by specifying EncryptionAtHost parameter
$VirtualMachine = New-AzVMConfig -VMName $VMName -VMSize $VMSize -EncryptionAtHost
$VirtualMachine = Set-AzVMOperatingSystem -VM $VirtualMachine -Windows -ComputerName $ComputerName -Credential $Credential -ProvisionVMAgent -EnableAutoUpdate
$VirtualMachine = Add-AzVMNetworkInterface -VM $VirtualMachine -Id $NIC.Id
$VirtualMachine = Set-AzVMSourceImage -VM $VirtualMachine -PublisherName 'MicrosoftWindowsServer' -Offer 'WindowsServer' -Skus '2012-R2-Datacenter' -Version latest
$VirtualMachine = Set-AzVMOSDisk -VM $VirtualMachine -Name $($VMName +"_OSDisk") -CreateOption FromImage
$VirtualMachine = Add-AzVMDataDisk -VM $VirtualMachine -Name $($VMName +"DataDisk1") -DiskSizeInGB 128 -StorageAccountType Premium_LRS -CreateOption Empty -Lun 0
New-AzVM -ResourceGroupName $ResourceGroupName -Location $LocationName -VM $VirtualMachine
Update a VM to enable encryption at host.
$ResourceGroupName = "yourResourceGroupName"
$VMName = "yourVMName"
$VM = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $VMName
Stop-AzVM -ResourceGroupName $ResourceGroupName -Name $VMName -Force
Update-AzVM -VM $VM -ResourceGroupName $ResourceGroupName -EncryptionAtHost $true
Check the status of encryption at host for a VM
$ResourceGroupName = "yourResourceGroupName"
$VMName = "yourVMName"
$VM = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $VMName
$VM.SecurityProfile.EncryptionAtHost
Disable encryption at host
You must deallocate your VM before you can disable encryption at host.
$ResourceGroupName = "yourResourceGroupName"
$VMName = "yourVMName"
$VM = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $VMName
Stop-AzVM -ResourceGroupName $ResourceGroupName -Name $VMName -Force
Update-AzVM -VM $VM -ResourceGroupName $ResourceGroupName -EncryptionAtHost $false
Create a Virtual Machine Scale Set with encryption at host enabled with customer-managed keys.
Important
Starting November 2023, VM scale sets created using PowerShell and Azure CLI will default to Flexible Orchestration Mode if no orchestration mode is specified. For more information about this change and what actions you should take, go to Breaking Change for VMSS PowerShell/CLI Customers - Microsoft Community Hub
Create a Virtual Machine Scale Set with managed disks using the resource URI of the DiskEncryptionSet created earlier to encrypt cache of OS and data disks with customer-managed keys. The temp disks are encrypted with platform-managed keys.
$VMLocalAdminUser = "yourLocalAdminUser"
$VMLocalAdminSecurePassword = ConvertTo-SecureString Password@123 -AsPlainText -Force
$LocationName = "westcentralus"
$ResourceGroupName = "yourResourceGroupName"
$ComputerNamePrefix = "yourComputerNamePrefix"
$VMScaleSetName = "yourVMSSName"
$VMSize = "Standard_DS3_v2"
$diskEncryptionSetName="yourDiskEncryptionSetName"
$NetworkName = "yourVNETName"
$SubnetName = "yourSubnetName"
$SubnetAddressPrefix = "10.0.0.0/24"
$VnetAddressPrefix = "10.0.0.0/16"
$SingleSubnet = New-AzVirtualNetworkSubnetConfig -Name $SubnetName -AddressPrefix $SubnetAddressPrefix
$Vnet = New-AzVirtualNetwork -Name $NetworkName -ResourceGroupName $ResourceGroupName -Location $LocationName -AddressPrefix $VnetAddressPrefix -Subnet $SingleSubnet
$ipConfig = New-AzVmssIpConfig -Name "myIPConfig" -SubnetId $Vnet.Subnets[0].Id
# Enable encryption at host by specifying EncryptionAtHost parameter
$VMSS = New-AzVmssConfig -Location $LocationName -SkuCapacity 2 -SkuName $VMSize -OrchestrationMode "Flexible" -EncryptionAtHost
$VMSS = Add-AzVmssNetworkInterfaceConfiguration -Name "myVMSSNetworkConfig" -VirtualMachineScaleSet $VMSS -Primary $true -IpConfiguration $ipConfig
$diskEncryptionSet=Get-AzDiskEncryptionSet -ResourceGroupName $ResourceGroupName -Name $diskEncryptionSetName
# Enable encryption with a customer managed key for the OS disk by setting DiskEncryptionSetId property
$VMSS = Set-AzVmssStorageProfile $VMSS -OsDiskCreateOption "FromImage" -DiskEncryptionSetId $diskEncryptionSet.Id -ImageReferenceOffer 'WindowsServer' -ImageReferenceSku '2012-R2-Datacenter' -ImageReferenceVersion latest -ImageReferencePublisher 'MicrosoftWindowsServer'
$VMSS = Set-AzVmssOsProfile $VMSS -ComputerNamePrefix $ComputerNamePrefix -AdminUsername $VMLocalAdminUser -AdminPassword $VMLocalAdminSecurePassword
# Add a data disk encrypted with a customer managed key by setting DiskEncryptionSetId property
$VMSS = Add-AzVmssDataDisk -VirtualMachineScaleSet $VMSS -CreateOption Empty -Lun 1 -DiskSizeGB 128 -StorageAccountType Premium_LRS -DiskEncryptionSetId $diskEncryptionSet.Id
Create a Virtual Machine Scale Set with encryption at host enabled with platform-managed keys.
Important
Starting November 2023, VM scale sets created using PowerShell and Azure CLI will default to Flexible Orchestration Mode if no orchestration mode is specified. For more information about this change and what actions you should take, go to Breaking Change for VMSS PowerShell/CLI Customers - Microsoft Community Hub
Create a Virtual Machine Scale Set with encryption at host enabled to encrypt cache of OS/data disks and temp disks with platform-managed keys.
$VMLocalAdminUser = "yourLocalAdminUser"
$VMLocalAdminSecurePassword = ConvertTo-SecureString Password@123 -AsPlainText -Force
$LocationName = "westcentralus"
$ResourceGroupName = "yourResourceGroupName"
$ComputerNamePrefix = "yourComputerNamePrefix"
$VMScaleSetName = "yourVMSSName"
$VMSize = "Standard_DS3_v2"
$NetworkName = "yourVNETName"
$SubnetName = "yourSubnetName"
$SubnetAddressPrefix = "10.0.0.0/24"
$VnetAddressPrefix = "10.0.0.0/16"
$SingleSubnet = New-AzVirtualNetworkSubnetConfig -Name $SubnetName -AddressPrefix $SubnetAddressPrefix
$Vnet = New-AzVirtualNetwork -Name $NetworkName -ResourceGroupName $ResourceGroupName -Location $LocationName -AddressPrefix $VnetAddressPrefix -Subnet $SingleSubnet
$ipConfig = New-AzVmssIpConfig -Name "myIPConfig" -SubnetId $Vnet.Subnets[0].Id
# Enable encryption at host by specifying EncryptionAtHost parameter
$VMSS = New-AzVmssConfig -Location $LocationName -SkuCapacity 2 -SkuName $VMSize -OrchestrationMode "Flexible" -EncryptionAtHost
$VMSS = Add-AzVmssNetworkInterfaceConfiguration -Name "myVMSSNetworkConfig" -VirtualMachineScaleSet $VMSS -Primary $true -IpConfiguration $ipConfig
$VMSS = Set-AzVmssStorageProfile $VMSS -OsDiskCreateOption "FromImage" -ImageReferenceOffer 'WindowsServer' -ImageReferenceSku '2012-R2-Datacenter' -ImageReferenceVersion latest -ImageReferencePublisher 'MicrosoftWindowsServer'
$VMSS = Set-AzVmssOsProfile $VMSS -ComputerNamePrefix $ComputerNamePrefix -AdminUsername $VMLocalAdminUser -AdminPassword $VMLocalAdminSecurePassword
$VMSS = Add-AzVmssDataDisk -VirtualMachineScaleSet $VMSS -CreateOption Empty -Lun 1 -DiskSizeGB 128 -StorageAccountType Premium_LRS
$Credential = New-Object System.Management.Automation.PSCredential ($VMLocalAdminUser, $VMLocalAdminSecurePassword);
New-AzVmss -VirtualMachineScaleSet $VMSS -ResourceGroupName $ResourceGroupName -VMScaleSetName $VMScaleSetName
Update a Virtual Machine Scale Set to enable encryption at host.
$ResourceGroupName = "yourResourceGroupName"
$VMScaleSetName = "yourVMSSName"
$VMSS = Get-AzVmss -ResourceGroupName $ResourceGroupName -Name $VMScaleSetName
Update-AzVmss -VirtualMachineScaleSet $VMSS -Name $VMScaleSetName -ResourceGroupName $ResourceGroupName -EncryptionAtHost $true
Check the status of encryption at host for a Virtual Machine Scale Set
$ResourceGroupName = "yourResourceGroupName"
$VMScaleSetName = "yourVMSSName"
$VMSS = Get-AzVmss -ResourceGroupName $ResourceGroupName -Name $VMScaleSetName
$VMSS.VirtualMachineProfile.SecurityProfile.EncryptionAtHost
Update a Virtual Machine Scale Set to disable encryption at host.
You can disable encryption at host on your Virtual Machine Scale Set but, this will only affect VMs created after you disable encryption at host. For existing VMs, you must deallocate the VM, disable encryption at host on that individual VM, then reallocate the VM.
$ResourceGroupName = "yourResourceGroupName"
$VMScaleSetName = "yourVMSSName"
$VMSS = Get-AzVmss -ResourceGroupName $ResourceGroupName -Name $VMScaleSetName
Update-AzVmss -VirtualMachineScaleSet $VMSS -Name $VMScaleSetName -ResourceGroupName $ResourceGroupName -EncryptionAtHost $false
Finding supported VM sizes
Legacy VM Sizes aren't supported. You can find the list of supported VM sizes by either:
Calling the Resource Skus API and checking that the EncryptionAtHostSupported
capability is set to True.
{
"resourceType": "virtualMachines",
"name": "Standard_DS1_v2",
"tier": "Standard",
"size": "DS1_v2",
"family": "standardDSv2Family",
"locations": [
"CentralUSEUAP"
],
"capabilities": [
{
"name": "EncryptionAtHostSupported",
"value": "True"
}
]
}
Or, calling the Get-AzComputeResourceSku PowerShell cmdlet.
$vmSizes=Get-AzComputeResourceSku | where{$_.ResourceType -eq 'virtualMachines' -and $_.Locations.Contains('CentralUSEUAP')}
foreach($vmSize in $vmSizes)
{
foreach($capability in $vmSize.capabilities)
{
if($capability.Name -eq 'EncryptionAtHostSupported' -and $capability.Value -eq 'true')
{
$vmSize
}
}
}
Next steps
Now that you've created and configured these resources, you can use them to secure your managed disks. The following link contains example scripts, each with a respective scenario, that you can use to secure your managed disks.