virtuallywired / Install-vCenterSSL

13 stars 9 forks source link

System exception #2

Open kevsfastz opened 2 years ago

kevsfastz commented 2 years ago

Hello, I am trying to run your .ps1 against my environment and I am encountering the below error. Any thoughts on the best way to troubleshoot this? I am running vSphere 6.7.0.44000

image

Thanks

virtuallywired commented 2 years ago

Hi there, I haven't tested this on 6.7 and from the error I can't tell exactly what the problem is. The certificate files should be on your machine, so if you like why don't you test doing it manually using my latest post https://virtuallywired.io/2021/11/29/replace-default-vcenter-certificate-with-a-free-lets-encrypt-ssl/

I updated this to support the Root CA X1. Let me know how you go, happy to help troubleshoot.

kevsfastz commented 2 years ago

Thanks for the quick reply, I will try this manually and report back. Also what version are you testing with?

virtuallywired commented 2 years ago

I wrote this script using vSphere 7, I assumed 6.7 should have worked too. I just checked the error, seems like it failed on invoke-webrequest line 201. let me send you some code to test that on 6.7

virtuallywired commented 2 years ago

Hi There, try this and send me the result.


function Show-Failure {
    $global:helpme = $body
    $global:helpmoref = $moref
    $global:result = $_.Exception.Response.GetResponseStream()
    $global:reader = New-Object System.IO.StreamReader($global:result)
    $global:responseBody = $global:reader.ReadToEnd();
    Write-Host -BackgroundColor:Black -ForegroundColor:Red "Status: A system exception was caught."
    Write-Host -BackgroundColor:Black -ForegroundColor:Red $global:responsebody
    Write-Host -BackgroundColor:Black -ForegroundColor:Red "The request body has been saved to `$global:helpme"
    break
}
# --- Edit Variables Below ---

$vCenterURL = "vc.YourDomain.io"
$Credential = Get-Credential

# --- Do Not Edit Below This Point ---

# --- This section ignores invalid SSL for the WebRequest for Powershell 5.1 or Lower.
if (-not ([System.Management.Automation.PSTypeName]'ServerCertificateValidationCallback').Type) {
    $certCallback = @"
    using System;
    using System.Net;
    using System.Net.Security;
    using System.Security.Cryptography.X509Certificates;
    public class ServerCertificateValidationCallback
    {
        public static void Ignore()
        {
            if(ServicePointManager.ServerCertificateValidationCallback ==null)
            {
                ServicePointManager.ServerCertificateValidationCallback += 
                    delegate
                    (
                        Object obj, 
                        X509Certificate certificate, 
                        X509Chain chain, 
                        SslPolicyErrors errors
                    )
                    {
                        return true;
                    };
            }
        }
    }
"@
    Add-Type $certCallback
}
[ServerCertificateValidationCallback]::Ignore() 

# --- Get Some Credentials and Determine Authorisation Methods
$auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Credential.UserName + ':' + $Credential.GetNetworkCredential().Password))
$head = @{
    'Authorization' = "Basic $auth"
}

# --- Setting up Inital Params
$Params = @{

    Method  = "POST"
    Headers = $head
    Uri     = "https://$vCenterURL/rest/com/vmware/cis/session"
}

# --- Support for PowerShell Core certificate checking
if ($IsCoreCLR) {
    $Params.Add("SkipCertificateCheck", $true)
}

# --- Invoke WebRequest to get Session Token

try {
    $RestApi = Invoke-WebRequest @Params
    $token = (ConvertFrom-Json $RestApi.Content).value
    $session = @{'vmware-api-session-id' = $token }
    Write-Host "Session Token Created Successfully" -ForegroundColor Green
    Write-Host "Session Name: $($session.Keys)" -ForegroundColor Yellow
    Write-Host "Session Value: $($session.Values)" -ForegroundColor Yellow
}

catch {
    Write-Error "Unable to get Session Token, Terminating Script"
    Show-Failure
}

Write-Host "-- Getting vCenter Certificate --" -ForegroundColor Cyan

$Params = @{
    Method  = "GET"
    Headers = $session
    Uri     = "https://$vCenterURL/api/vcenter/certificate-management/vcenter/tls"
}

Invoke-WebRequest @Params
kevsfastz commented 2 years ago

Sorry for the delay, please see the results below:

image

virtuallywired commented 2 years ago

Ok, I will spin up a 6.7 vCenter and see what the problem could be. Did you happen to try updating the SSL manually via the UI?

kevsfastz commented 2 years ago

In the past, I always had to maintain the certificates via certificate-manager in the console, because the UI never loads in my environment for some reason, maybe the issues are related:

image

I was able to find the certificates your script created, however, when I tried to apply them via certificate-manager the vpxd service refused to start and had to roll back.

kevsfastz commented 2 years ago

I just tested in a different browser and it worked, I'll test it here from the UI as you suggested in a few.

virtuallywired commented 2 years ago

Ok great. Thanks

kevsfastz commented 2 years ago

I was able to replace the machine certs successfully however I received an error on vsphere-webclient. image

Logs didn't provide much useful information: image

virtuallywired commented 2 years ago

Ok. Let me test this with 6.7 and I'll let you know how it goes.

virtuallywired commented 2 years ago

Hi, I spun up 6.7 vCenter and changed some code. Can you test this below?


function Show-Failure {
    $global:helpme = $body
    $global:helpmoref = $moref
    $global:result = $_.Exception.Response.GetResponseStream()
    $global:reader = New-Object System.IO.StreamReader($global:result)
    $global:responseBody = $global:reader.ReadToEnd();
    Write-Host -BackgroundColor:Black -ForegroundColor:Red "Status: A system exception was caught."
    Write-Host -BackgroundColor:Black -ForegroundColor:Red $global:responsebody
    Write-Host -BackgroundColor:Black -ForegroundColor:Red "The request body has been saved to `$global:helpme"
    break
}
# --- Edit Variables Below ---

$vCenterURL = "vc.yourdomain.io"
$Credential = Get-Credential

# --- Do Not Edit Below This Point ---

# --- This section ignores invalid SSL for the WebRequest for Powershell 5.1 or Lower.
if (-not ([System.Management.Automation.PSTypeName]'ServerCertificateValidationCallback').Type) {
    $certCallback = @"
    using System;
    using System.Net;
    using System.Net.Security;
    using System.Security.Cryptography.X509Certificates;
    public class ServerCertificateValidationCallback
    {
        public static void Ignore()
        {
            if(ServicePointManager.ServerCertificateValidationCallback ==null)
            {
                ServicePointManager.ServerCertificateValidationCallback += 
                    delegate
                    (
                        Object obj, 
                        X509Certificate certificate, 
                        X509Chain chain, 
                        SslPolicyErrors errors
                    )
                    {
                        return true;
                    };
            }
        }
    }
"@
    Add-Type $certCallback
}
[ServerCertificateValidationCallback]::Ignore() 

# --- Get Some Credentials and Determine Authorisation Methods
$auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Credential.UserName + ':' + $Credential.GetNetworkCredential().Password))
$head = @{
    'Authorization' = "Basic $auth"
}

# --- Setting up Inital Params
$Params = @{

    Method  = "POST"
    Headers = $head
    Uri     = "https://$vCenterURL/rest/com/vmware/cis/session"
}

# --- Support for PowerShell Core certificate checking
if ($IsCoreCLR) {
    $Params.Add("SkipCertificateCheck", $true)
}

# --- Invoke WebRequest to get Session Token

try {
    $RestApi = Invoke-WebRequest @Params
    $token = (ConvertFrom-Json $RestApi.Content).value
    $session = @{'vmware-api-session-id' = $token }
    Write-Host "Session Token Created Successfully" -ForegroundColor Green
    Write-Host "Session Name: $($session.Keys)" -ForegroundColor Yellow
    Write-Host "Session Value: $($session.Values)" -ForegroundColor Yellow
}

catch {
    Write-Error "Unable to get Session Token, Terminating Script"
    Show-Failure
}

# --- Support for PowerShell Core certificate checking

Write-Host "-- Getting vCenter Certificate --" -ForegroundColor Cyan

$Params = @{
    Method      = "GET"
    Headers     = $session
    Uri         = "https://$vCenterURL/rest/vcenter/certificate-management/vcenter/tls"

}

if ($IsCoreCLR) {
    $Params.Add("SkipCertificateCheck", $true)
}

Invoke-WebRequest @Params
virtuallywired commented 2 years ago

Ok I've just checked, unfortunately the script won't work with vCenter 6.7 the json payload is formatted differently between versions. I can see how much effort is involved is trying to adapt it and let you know.

kevsfastz commented 2 years ago

I appreciate all your effort so far, but I think it would make more sense to upgrade my environment to 7.0 rather than having you invest your time in 6.7!

virtuallywired commented 2 years ago

Ok that is a good option. I was going to suggest it but, I understand people have valid reasons to stick with a particular version. What I can say is that 7 has some significant improvements, if you have the option of upgrading I would highly recommend it. Good luck and Let me know how you go.

kevsfastz commented 2 years ago

Finally got around to upgrading to 7.0 and can confirm your solution works as expected. Thanks again!

virtuallywired commented 2 years ago

Hey thank you for the feedback

kevsfastz commented 2 years ago

I have just upgraded to v7.0 U3 and it looks like VMware changed the authentication method for your script, which is preventing it from grabbing a token successfully.

These are the API calls you have currently: https://developer.vmware.com/apis/vsphere-automation/v7.0U2-deprecated/cis/rest/com/vmware/cis/session/post/

And these are the updated calls for U3: https://developer.vmware.com/apis/vsphere-automation/latest/cis/api/session/post/#authentication

I attempted to update the URL in your script, but I believe there are some additional changes that need to be made that are above my head. I am happy to test for you if needed.