Managing vSphere certificates is a feature that many customers have been asking for on our feature request site. And when all the necessary APIs for it were added in vSphere 7 we were finally able to add it to PowerCLI 12.4.
This doesn’t mean however that all the cmdlets require vSphere 7. Some of them are supported in 6.7 or even 6.5. For example, you can check what are the trusted certificates on vSphere 6.7, but to add a certificate or certificate chain to the trusted certificate store you need vSphere 7. Also, you can check or change the machine certificate of an ESXi host for all supported ESXi versions, but to do that for vCenter Server you need vSphere 7.
So, let’s take a look at what cmdlets are available for certificate management. Here is the list:
- Add-VITrustedCertificate
- Get-VIMachineCertificate
- Get-VITrustedCertificate
- New-VIMachineCertificateSigningRequest
- Remove-VITrustedCertificate
- Set-VIMachineCertificate
Managing the Trusted Certificate Store
Let’s start with trusted certificate store management. We can use Get-VITrustedCertificate to check the details of the trusted root certificates on our vCenter Server and/or the connected ESXi hosts, such as issuer, expiration date, serial number, etc. Here is an example of how we can check the certificate stores of our servers for expired certificates.
1 2 |
#Check the trusted certificate store of the vCenter and all connected ESXi servers for expired certificates Get-VITrustedCertificate | Where-Object { $_.NotValidAfter -lt (Get-Date) } |
If we want, for example, to add the certificate or certificate chain of the certificate authority that we use to the trusted certificate store we can use Add-VITrustedCertificate. Here is a sample script for this.
1 2 3 4 5 |
#Read the certificate or certificate chain from a .pem file $trustedCertChain = Get-Content "C:\Users\jdoe\Downloads\ca-chain.cert.pem" -Raw #Add it to the trusted certificate stores of the vCenter and the ESXi servers Add-VITrustedCertificate -PemCertificateOrChain $trustedCertChain |
We also have the Remove-VITrustedCertificate cmdlet to remove trusted certificates that we no longer need. However, this is a command that you should be very careful with. Make sure that you don’t remove a certificate that is in use, or is a part of a trust chain that is in use. It’s not accidental that this operation is not available at all in the UI. Here is an example how to use Remove-VITrustedCertificate to remove the expired certificates from the trusted certificate store of the vCenter Server:
1 2 3 |
Get-VITrustedCertificate -VCenterOnly | ` Where-Object { $_.NotValidAfter -lt (Get-Date) } | ` Remove-VITrustedCertificate |
Managing the Machine SSL Certificate of vCenter Server
Now let’s move on to managing the Machine SSL certificate of a vCenter Server. If we have a lot of people accessing the vSphere client and we want it to present a certificate that is accepted by default by various browsers, we have to replace it with a certificate generated by a trusted certificate authority. First, let’s check the details of the current machine certificate:
1 |
Get-VIMachineCertificate -VCenterOnly |
Next, we have to create a certificate signing request (CSR) for the vCenter Server to give to our trusted certificate authority. We can use New-VIMachineCertificateSigningRequest as in the following example.
1 2 3 4 5 6 7 8 9 10 11 |
$csrParams = @{ Country="US" Email="jdoe@vmware.com" Locality="San Francisco" Organization="My Company" OrganizationUnit="PowerCLI" StateOrProvince="California" } $csr = New-VIMachineCertificateSigningRequest @csrParams $csr.CertificateRequestPEM | Out-File "C:\Users\jdoe\Downloads\vc.csr.pem" -Force |
Then, when we receive our certificate file from the certificate authority, we can change the VC machine certificate by using Set-VIMachineCertificate like this.
1 2 |
$vcCert = Get-Content "C:\Users\jdoe\Downloads\vc.cert.jdoe.pem" -Raw Set-VIMachineCertificate -PemCertificate $vcCert |
Note: Before we try to set the Machine SSL certificate we have to make sure that the root certificate of our CA is added to the vCenter Server trusted root store. Also keep in mind that changing the certificate will cause the vCenter to reboot.
Managing Machine SSL Certificates of ESXi Servers
If we want to go to full custom mode and manage all the certificates on our own, we’ll have to change the certificates of the ESXi hosts as well. The workflow for changing the ESXi machine certificate is a bit more complex. First, we have to change the ESXi host certificate management mode setting on the vCenter to ‘custom’ and reboot the vCenter for the change to take effect.
1 2 3 4 5 |
$vCenterConnection = Connect-VIServer vc1.example.com ` -User 'My User' ` -Password 'My Password' $certModeSetting = Get-AdvancedSetting "vpxd.certmgmt.mode" -Entity $vCenterConnection Set-AdvancedSetting $certModeSetting -Value "custom" |
Then, we must to generate the CSR for the ESXi server. This step is similar to the one for the vCenter Server with the only difference that for the ESXi server it’s important to specify the CommonName parameter. The CommonName must be either the ESXi host’s FQDN or IP address. And it must match the identifier that we use to add the host to the vCenter Server system.
1 2 3 4 5 6 7 8 9 10 |
$esxRequest = New-VIMachineCertificateSigningRequest ` -VMHost $vmhost ` -Country "US" ` -Locality "San Francisco" ` -Organization "My Company" ` -OrganizationUnit "PowerCLI" ` -StateOrProvince "California" ` -CommonName <ESXi host's FQDN> or <ESXi host's IP address> $esxRequest.CertificateRequestPEM | Out-File "C:\Users\jdoe\Downloads\esx.csr.pem" -Force |
Then, when we get the certificate from the certificate authority we have to follow the steps below to set it to the ESXi server.
-
-
- Put the host in maintenance mode and remove it from vCenter
123$vmhost = Get-VMHost 'MyESXiHost' `Set-VMHost -VMHost $vmhost -State MaintenanceRemove-VMHost $vmhost - Connect directly to the ESXi host, set the new machine certificate and restart the host for the changes to take effect
123456789101112$esxConnection = Connect-VIServer $vmhost.Name `-User 'My User' `-Password 'My Password' `-Force$esxCertificatePem = Get-Content "C:\Users\jdoe\downloads\myesxcert.pem" -Raw$targetEsxHost = Get-VMHost $vmhost.NameSet-VIMachineCertificate -PemCertificate $esxCertificatePem -VMHost $targetEsxHost | Out-NullRestart-VMHost $targetEsxHostDisconnect-VIServer $esxConnection
Note: Just like with the vCenter, before we try to set the machine certificate, we need to make sure that the root certificate of our CA is added to the trusted root stores of the ESXi server and all other servers that will communicate with it – vCenter Server and ESXi.
- Re-add the ESXi server to the vCenter.
12345678910$vCenterConnection = Connect-VIServer vc1.example.com `-User 'My User' `-Password 'My Password'$vmhost = Add-VMHost -Name <ESXi host's FQDN> or <ESXi host's IP address> `-Location (Get-Datacenter "My Datacenter")`-User "My User" `-Password "My Password"$vmhost = Set-VMHost -VMHost $vmhost -State Connected
- Put the host in maintenance mode and remove it from vCenter
-
Summary
With the new certificate management cmdlets it’s now much easier to automate vSphere certificate management with PowerCLI. There are some specifics in the process (especially for the ESXi hosts), so I hope this blog post will be useful in getting the entire process right. For step-by-step guidance on vSphere certificate management, visit the PowerCLI User’s Guide. Let us know in the comments if you want to see more technical blog posts like this and feel free to propose new topics.
Don’t miss the blog post for PowerCLI 12.5 here: PowerCLI 12.5 – What’s new?
Thankfully, Certificate Management via Powershell finally introduced a REST API for managing certificate in easy way. Hopefully it’ll help me build my vsphere easily kepala bergetar.com
Thankfully vCenter Certificate Management via Powershell finally introduced a REST API for managing certificates with easy to manage interface kepala bergetar.com
thanks for sharing
When I try to import the CRT I get back from my CA – the host throws an error
Write-PowerCLIError : Exception calling “InstallServerCertificate” with “1” argument(s): “Cannot change the host configuration. Low-level system error. See logs for
details.”
The host.d shows “error hostd – Failed to get private key: error:0906D06C:PEM routines:PEM_read_bio:no start line”
If the certificate was created using CSR from the vCenter the private key should be on the server and you shouldn’t get such errors. If this is not the case you should import both the certificate and the private key on the server.
We are required to generate a custom CSR for our internal CA, and it generates a certificate that includes the private key. When I try to import the certificate and key using the following line I get the error below.
PS C:\Users\user123> Set-VIMachineCertificate -PemKey $esxPrivateKey -PemCertificate $esxCert -VMHost $esxHostObject | Out-Null
Set-VIMachineCertificate: Parameter set cannot be resolved using the specified named parameters. One or more parameters issued cannot be used together or an insufficient number of parameters were provided.
Our internal CA requires a custom CSR and it generates a certificate that includes the private key. When I try to import the certificate and private key to the ESXi host using the powercli below I get the error listed.
PS C:\Users\kreifer1adm> Set-VIMachineCertificate -PemKey $esxPrivateKey -PemCertificate $esxCert -VMHost $esxHostObject | Out-Null
Set-VIMachineCertificate: Parameter set cannot be resolved using the specified named parameters. One or more parameters issued cannot be used together or an insufficient number of parameters were provided.
The reason for this error is that -PemKey is only supported when you set the vCenter certificate and not the ESXi certificate. And this is because the underlying API does not support it.
Thank you for responding.
Is there any way to import a certificate and private key to an ESXi host using the new cmdlets in PowerCLI? We were using Invoke-WebRequest -method PUT to replace them, but ever since upgrading to ESXi 7 we get “401 Unauthorized” Was this due to a security change in ESXi 7?
$keyresult = Invoke-WebRequest -method PUT -uri https://$name/host/ssl_key -infile $certFolder\$name\rui.key -credential $credential
$crtresult = Invoke-WebRequest -method PUT -uri https://$name/host/ssl_cert -infile $certFolder\$name\rui.crt -credential $credential
“Invoke-WebRequest: Response status code does not indicate success: 401 (Unauthorized).”
Colleagues from the vCenter team said that there is no change in this code in ESXi 7 and it should still work. They said that unauthorized might be a result of a locked account, but to investigate it further they will need the appropriate logs. Please file an SR and GSS will help you investigate the issue.
The workflow that is recommended however is not to push the key to the host, but to:
1. Generate Certificate Signing Request (CSR)
2. Take this CSR and bring it to a Certificate Authority for certificate generation
3. Push the newly generated certificate to the host
This workflow is considered more secure because the private key does not leave the host.
Thanks!
If the declaration was made utilizing CSR from the Center, the confidential key should be on the server and you shouldn’t get such blunders. If this isn’t the case, you ought to import both the testament and the secret key on the server.
I will bookmark your site for future use.