diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 index 95b678f..aa83854 100644 --- a/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 +++ b/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 @@ -12,7 +12,7 @@ # RootModule = '' # Version number of this module. -ModuleVersion = '1.1' +ModuleVersion = '1.2' # ID used to uniquely identify this module GUID = 'f9592e48-6cd3-494e-891b-ee10ee9f7018' diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 index 7752274..df37e98 100644 --- a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 +++ b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 @@ -1,5 +1,5 @@ # Script Module : VMware.VMEncryption -# Version : 1.1 +# Version : 1.2 # Copyright © 2016 VMware, Inc. All Rights Reserved. @@ -1844,6 +1844,304 @@ Function Set-VMCryptoUnlock { } } +Function Add-Vtpm { + <# + .SYNOPSIS + This cmdlet adds a Virtual TPM to the specified VM. + + .DESCRIPTION + This cmdlet adds a Virtual TPM to the specified VM. + + .PARAMETER VM + Specifies the VM you want to add Virtual TPM to. + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>Add-Vtpm $vm1 + + Encrypts $vm1's VM home and adds Virtual TPM + + .NOTES + If VM home is already encrypted, the cmdlet will add a Virtual TPM to the VM. + If VM home is not encrypted, VM home will be encrypted and Virtual TPM will be added. + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + Process { + $deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $deviceChange.operation = "add" + $deviceChange.device = new-object VMware.Vim.VirtualTPM + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $VMCfgSpec.DeviceChange = $deviceChange + + return $VM.ExtensionData.ReconfigVM_task($VMCfgSpec) + } +} + +Function Remove-Vtpm { + <# + .SYNOPSIS + This cmdlet removes a Virtual TPM from the specified VM. + + .DESCRIPTION + This cmdlet removes a Virtual TPM from the specified VM. + + .PARAMETER VM + Specifies the VM you want to remove Virtual TPM from. + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>Remove-Vtpm $vm1 + + .EXAMPLE + C:\PS>Get-VM -Name win2016 |Remove-Vtpm + + Remove Virtual TPM from VM named win2016 + + .NOTES + Removing VirtualTPM will render all encrypted data on this VM unrecoverable. + VM home encryption state will be returned to the original state before Virtual TPM is added + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding(SupportsShouldProcess=$true, ConfirmImpact = "High")] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + Process { + $message = "Removing Virtual TPM will render all encrypted data on this VM unrecoverable" + if ($PSCmdlet.ShouldProcess($message, $message + "`n Do you want to proceed", "WARNING")) { + $deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $deviceChange.operation = "remove" + $deviceChange.device = $vtpm + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $VMCfgSpec.DeviceChange = $deviceChange + return $VM.ExtensionData.ReconfigVM_task($VMCfgSpec) + } + } +} + +Function Get-VtpmCsr { + <# + .SYNOPSIS + This cmdlet gets certficate signing requests(CSR) from Virtual TPM. + + .DESCRIPTION + This cmdlet gets certficate signing requests(CSR) from Virtual TPM. + The CSR is a ComObject X509enrollment.CX509CertificateRequestPkcs10 + + .PARAMETER VM + Specifies the VM you want to get the CSRs Virtual TPM from. + + .PARAMETER KeyType [RSA | ECC] + Specify that only get CSR with public key RSA algorithm. + If none is specified, both CSR will get returned + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>Get-VtpmCsr $vm1 -KeyType RSA + + .NOTES + Both RSA and ECC CSRs objects will be returned. If ECC or RSA is specified, + only the corresponding object will be returned + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, + + [Parameter(Mandatory=$False)] + [String]$KeyType + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + + process { + # Get vTPM from VM + $vtpm = $VM.ExtensionData.Config.Hardware.Device |Where {$_ -is [VMware.Vim.VirtualTPM]} + + # Check if vTPM is already present + if (!$vtpm) { + Write-Error "$VM does not contains a Virtual TPM" + return + } + + $CSRs = @() + foreach ($csrArray in $vtpm.EndorsementKeyCertificateSigningRequest) { + $csrString = [System.Convert]::ToBase64String($csrArray) + $csr = New-Object -ComObject X509enrollment.CX509CertificateRequestPkcs10 + + #decode a base64 string into a CSR object + $csr.InitializeDecode($csrString,6) + if ($keyType) { + if ($csr.PublicKey.Algorithm.FriendlyName -eq $KeyType){ + return $csr + } + } else { + $CSRs += $csr + } + } + return $CSRs + } +} + +Function Set-VtpmCert{ + <# + .SYNOPSIS + This cmdlet replaces certificates of Virtual TPM in the specified VM. + + .DESCRIPTION + This cmdlet replaces certificates to Virtual TPM in the specified VM. + + .PARAMETER VM + Specifies the VM with Virtual TPM where you want to replace the certificates to. + + .PARAMETER Cert + Specifies the certificate object (System.Security.Cryptography.X509Certificates.X509Certificate) + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>Set-VtpmCert $vm1 $certObj + + .EXAMPLE + C:\PS>Get-VM -Name win2016 | Set-VtpmCert $certObj + + Replace the appropriate certificate specified + + .NOTES + Only RSA or ECC certs will be overwritten + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine]$VM, + + [Parameter(Mandatory=$True)] + [System.Security.Cryptography.X509Certificates.X509Certificate] $Cert + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + + process { + # Get vTPM from VM + $vtpm = $VM.ExtensionData.Config.Hardware.Device |Where {$_ -is [VMware.Vim.VirtualTPM]} + + #check if vTPM is already present + if (!$vtpm) { + Write-Error "$VM does not contains a Virtual TPM" + return + } + + $certOid = New-Object System.Security.Cryptography.Oid($Cert.GetKeyAlgorithm()) + + # Check which certificate to overwrite + $certLocation = GetKeyIndex $vtpm.EndorsementKeyCertificate $certOid.FriendlyName + if ($certLocation -eq -1) { + Write-Error "No Certificate with Matching Algorithm $($certOid.FriendlyName) found" + return + } + + $vtpm.EndorsementKeyCertificate[$certLocation] = $cert.GetRawCertData() + $deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $deviceChange.Operation = "edit" + $deviceChange.Device = $vtpm + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $VMCfgSpec.DeviceChange = $deviceChange + + return $VM.ExtensionData.ReconfigVM_task($VMCfgSpec) + } +} + +Function Get-VtpmCert{ + <# + .SYNOPSIS + This cmdlet gets certificates of Virtual TPM in the specified VM. + + .DESCRIPTION + This cmdlet gets certificates of Virtual TPM in the specified VM. + + .PARAMETER VM + Specifies the VM with Virtual TPM where you want to get the certificate from + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>$certs = Get-VtpmCert $vm1 + + .NOTES + An array of certificate object (System.Security.Cryptography.X509Certificates.X509Certificate) + will be returned + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding()] + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM + ) + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + Process { + # Get vTPM from VM + $vtpm = $VM.ExtensionData.Config.Hardware.Device |Where {$_ -is [VMware.Vim.VirtualTPM]} + + # check if vTPM is already present + if (!$vtpm) { + Write-Error "$VM does not contain a Virtual TPM" + return + } + + $certs = @() + $vtpm.EndorsementKeyCertificate|foreach { + $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate + $cert.Import($_) + $certs += $cert + } + return $certs + } +} + Function ConfirmIsVCenter{ <# .SYNOPSIS @@ -2038,4 +2336,49 @@ Function GetCryptoManager { } } +Function GetKeyIndex{ + <# + .SYNOPSIS + This cmdlet returns the index to the key with a matching algorithm as the KeyType parameter + + .DESCRIPTION + This cmdlet returns the index to the key with a matching algorithm as the KeyType parameter + + .PARAMETER Certs + Specifies the list of certificats. Expected format is byte[][] + + .PARAMETER KeyType + Specifies the keytype to search for + + .EXAMPLE + C:\PS>$keyIndex = GetKeyIndex $Certs RSA + C:\PS>$keyIndex = GetKeyIndex $Certs ECC + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True)] + [byte[][]] $Certs, + + [Parameter(Mandatory=$True)] + [String] $KeyType + ) + process { + for ($i=0;$i -lt $Certs.Length; $i++) { + $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate + $cert.Import($Certs.Get($i)) + $certType = New-Object System.Security.Cryptography.Oid($cert.GetKeyAlgorithm()) + if ( $certType.FriendlyName -eq $keyType) { + return $i + } + } + return -1 + } +} + Export-ModuleMember *-*