VMware vSphere generally leaks keys when objects are deleted or decrypted. The reason for doing so, I believe, is because VMware supposes that you might have a backup copy of the object and may need the key in the future to restore that object. For example, consider the case of a VM that is removed from inventory but remains on disk. VMware cannot know whether you will permanently delete this VM or add it back to inventory. Therefore VMware allows the key to remain in your key provider.
Over time this results in the growth of unused keys in your key provider. In order to clean up unused keys, you first need to inventory the keys that are in use by active objects. The following PowerCLI script uses the VMware.VMEncryption and VMware.VsanEncryption modules in VMware’s PowerCLI community repository. It will inventory all keys in use by your hosts (for core dumps), in use by vSAN clusters (for vSAN disk encryption), and in use by VMs and disks (for vSphere encryption).
$keydata = @()
# Collect host keys
foreach($myhost in Get-VMHost) {
if($myhost.CryptoSafe) {
$hostdata = [PSCustomObject]@{
type = "host"
name = $myhost.Name
keyprovider = $myhost.KMSserver
keyid = $myhost.ExtensionData.Runtime.CryptoKeyId.KeyId
}
$keydata += $hostdata
}
}
# collect vSAN keys
foreach($mycluster in Get-Cluster) {
$vsanClusterConfig = Get-VsanView -Id "VsanVcClusterConfigSystem-vsan-cluster-config-system"
$vsanEncryption = $vsanClusterConfig.VsanClusterGetConfig($mycluster.ExtensionData.MoRef).DataEncryptionConfig
if($mycluster.vSanEnabled -and $vsanEncryption.EncryptionEnabled) {
$clusterdata = [PSCustomObject]@{
type = "cluster"
name = $mycluster.Name
keyprovider = $vsanEncryption.kmsProviderId.Id
keyid = $vsanEncryption.kekId
}
$keydata += $clusterdata
}
}
# collect VM and disk keys
foreach($myvm in Get-VM) {
if($myvm.encrypted) {
$vmdata = [PSCustomObject]@{
type = "vm"
name = $myvm.Name
keyprovider = $myvm.KMSserver
keyid = $myvm.EncryptionKeyId.KeyId
}
$keydata += $vmdata
}
foreach($mydisk in Get-HardDisk -vm $myvm) {
if($mydisk.encrypted) {
$diskdata = [PSCustomObject]@{
type = "harddisk"
name = $myvm.Name + " | " + $mydisk.Name
keyprovider = $mydisk.EncryptionKeyId.ProviderId.Id
keyid = $mydisk.EncryptionKeyId.KeyId
}
$keydata += $diskdata
}
}
}
$keydata | Export-CSV -Path keys.csv -NoTypeInformation
There are some important caveats to note:
- This script is over-zealous; it may report that a key is in use multiple times (e.g., host encryption keys shared by multiple hosts, or VM encryption keys shared by the disks of a VM).
- Your vCenter may be connected to multiple key key providers. Before deleting any keys, take care that you identify which keys are in use for each key provider.
- You may have multiple vCenters connected to the same key provider. Before deleting any keys, take care to collect inventory across all vCenters and any other clients connected to each key provider.
- As noted above, you may have VM backups or other resources that are still dependent on an encryption key, even after that resource has been deleted. Before deleting any keys, take care to ensure you have identified which keys may still be in use for your backups.
- This script does not address the case of environments using VMware vSphere Trust Authority (vTA).
- Importantly, this script does not address the case of “first-class disks,” or what VMware Cloud Director calls “named disks.”