Tools/Invoke-VcfCheckValidateCredentials.ps1
|
# Copyright (c) 2026 Broadcom. All Rights Reserved. # Broadcom Confidential. The term "Broadcom" refers to Broadcom Inc. # and/or its subsidiaries. # # ============================================================================= # # SOFTWARE LICENSE AGREEMENT # # Copyright (c) CA, Inc. All rights reserved. # # You are hereby granted a non-exclusive, worldwide, royalty-free license # under CA, Inc.'s copyrights to use, copy, modify, and distribute this # software in source code or binary form for use in connection with CA, Inc. # products. # # This copyright notice shall be included in all copies or substantial # portions of the software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. # # ============================================================================= <# .SYNOPSIS Command-line entry point for validating SDDC Manager and appliance root credentials. .DESCRIPTION Connects to SDDC Manager to validate provided API credentials and discover deployed workload domains. Reads SDDC Manager and root passwords directly from process environment variables (`VCFCHECK_SDDC_PASSWORD` and `VCFCHECK_ROOT_PASSWORD`). When `VCFCHECK_ROOT_PASSWORD` is supplied, additionally verifies SDDC Manager appliance root credentials via `Test-VcfCheckSddcManagerRootCredential` by executing guest operations commands against the SDDC Manager VM. When `VCFCHECK_ARIAOPS_CREDENTIALS_JSON` is supplied (a JSON array of `{Name, Fqdn, Username, Password}`), additionally verifies reachability and authentication for each standalone Aria Operations endpoint declared on the environment via `Connect-VcfCheckAriaOpsEndpoint`. Outputs a structured JSON payload to stdout detailing validation status, execution phases, and discovered domains: - `success`: Boolean indicating overall credential validation success. - `error`: Error message string if validation failed at the top level. - `phases`: Array of validation phase results (Network Reachability, SDDC Manager Authentication, Aria Suite Lifecycle Manager Connectivity, Aria Operations Network Reachability/Authentication per endpoint, ESX Host Connectivity, VMware Tools Status, SDDC Manager Root Authentication). - `domains`: Array of discovered VCF domain names and domain types. Writes audit log entries using `Write-LogMessage` throughout the validation process. .PARAMETER SddcManagerFqdn Fully qualified domain name of the SDDC Manager appliance. .PARAMETER SddcManagerUser Username for SDDC Manager authentication. .PARAMETER ConnectivityTimeoutSeconds Maximum duration in seconds to wait for TCP reachability checks. Defaults to 30 seconds. .NOTES Acts as the entry point contract for credential validation execution. .EXAMPLE pwsh -NoProfile -NonInteractive -File Invoke-VcfCheckValidateCredentials.ps1 -SddcManagerFqdn sddc.example.com -SddcManagerUser administrator@vsphere.local #> [CmdletBinding()] Param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$SddcManagerFqdn, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$SddcManagerUser, [Parameter(Mandatory = $false)] [Int]$ConnectivityTimeoutSeconds = 30 ) if ($null -ne $PSStyle) { $PSStyle.OutputRendering = 'PlainText' } $envModulePsd1 = ([String]$env:VCFCHECK_MODULE_PSD1).Trim() if (-not [String]::IsNullOrWhiteSpace($envModulePsd1) -and (Test-Path -LiteralPath $envModulePsd1 -PathType Leaf)) { $modulePath = $envModulePsd1 } else { $modulePath = Join-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -ChildPath 'VcfCheck.psd1' } try { Import-Module -Name $modulePath -Force -ErrorAction Stop } catch { @{ success = $false; error = "Could not load the VcfCheck module from `"$modulePath`": $($_.Exception.Message)" } | ConvertTo-Json -Compress exit 1 } try { Initialize-VcfCheckLogging | Out-Null } catch { # Logging initialization is best-effort when base directory environment variables are unconfigured. } $sddcPasswordPlainText = $env:VCFCHECK_SDDC_PASSWORD if ([String]::IsNullOrEmpty($sddcPasswordPlainText)) { Write-LogMessage -Type ERROR -Message 'Credential check aborted: VCFCHECK_SDDC_PASSWORD environment variable was not set.' @{ success = $false; error = 'VCFCHECK_SDDC_PASSWORD environment variable was not set.' } | ConvertTo-Json -Compress exit 1 } $sddcPassword = $null $rootPassword = $null $Context = $null $phases = @() $domains = @() try { $sddcPassword = ConvertTo-SecureString -String $sddcPasswordPlainText -AsPlainText -Force $Context = New-VcfCheckContext $Context.AllowInsecureTls = Resolve-VcfCheckAllowInsecureTls Write-LogMessage -Type INFO -Message "Checking credentials for SDDC Manager `"$SddcManagerFqdn`" as `"$SddcManagerUser`"." try { Connect-VcfCheckSddcManager -Context $Context -Fqdn $SddcManagerFqdn -User $SddcManagerUser -Password $sddcPassword ` -IgnoreInvalidCertificate:$Context.AllowInsecureTls -ConnectivityTimeoutSeconds $ConnectivityTimeoutSeconds Write-LogMessage -Type INFO -Message "Authentication successful: SDDC Manager `"$SddcManagerFqdn`"." $phases += @{ name = 'Network Reachability'; status = 'pass'; error = $null } $phases += @{ name = 'SDDC Manager Authentication'; status = 'pass'; error = $null } # Populate VCF domain inventory for UI selection filters. try { $domains = @((Invoke-VcfGetDomains -ErrorAction Stop).Elements | ForEach-Object { @{ name = [String]$_.Name; type = [String]$_.Type } }) } catch { Write-LogMessage -Type WARNING -Message "Could not retrieve VCF domains for `"$SddcManagerFqdn`": $($_.Exception.Message)" } # Verify Aria Suite Lifecycle Manager TCP connectivity if registered with SDDC Manager. try { $vrslcmConnection = Get-VcfCheckVrslcmConnection -Context $Context } catch { Write-LogMessage -Type WARNING -Message "Could not resolve Aria Suite Lifecycle Manager connection details: $($_.Exception.Message)" $vrslcmConnection = $null } if ($vrslcmConnection) { Write-LogMessage -Type INFO -Message "Checking TCP reachability to Aria Suite Lifecycle Manager `"$($vrslcmConnection.Fqdn)`" on port 443..." if (Test-VcfCheckTcpConnectivity -ComputerName $vrslcmConnection.Fqdn -Port 443 -TimeoutSeconds $ConnectivityTimeoutSeconds) { Write-LogMessage -Type INFO -Message "Aria Suite Lifecycle Manager `"$($vrslcmConnection.Fqdn)`" is reachable on TCP port 443." $phases += @{ name = 'Aria Suite Lifecycle Manager Connectivity'; status = 'pass'; error = $null } } else { Write-LogMessage -Type WARNING -Message "Aria Suite Lifecycle Manager `"$($vrslcmConnection.Fqdn)`" is not reachable on port 443." $phases += @{ name = 'Aria Suite Lifecycle Manager Connectivity' status = 'fail' error = "Aria Suite Lifecycle Manager (`"$($vrslcmConnection.Fqdn)`") is not reachable on port 443. Check VPN/network connectivity, firewall rules, and DNS resolution. Aria Suite checks will fail or time out until this is resolved." } } } # Validate reachability and authentication for each standalone Aria Operations endpoint # (Environment.Integrations) that the browser supplied a session-only password for. $ariaOpsCredentialsJson = $env:VCFCHECK_ARIAOPS_CREDENTIALS_JSON if (-not [String]::IsNullOrEmpty($ariaOpsCredentialsJson)) { try { $ariaOpsCredentialEntries = @(ConvertFrom-Json -InputObject $ariaOpsCredentialsJson -ErrorAction Stop) } catch { Write-LogMessage -Type WARNING -Message "Could not parse VCFCHECK_ARIAOPS_CREDENTIALS_JSON: $($_.Exception.Message)" $ariaOpsCredentialEntries = @() } foreach ($ariaOpsEntry in $ariaOpsCredentialEntries) { $ariaOpsLabel = $ariaOpsEntry.Fqdn $ariaOpsSecurePassword = ConvertTo-SecureString -String $ariaOpsEntry.Password -AsPlainText -Force $ariaOpsCredential = [PSCredential]::new($ariaOpsEntry.Username, $ariaOpsSecurePassword) Write-LogMessage -Type INFO -Message "Checking credentials for Aria Operations `"$($ariaOpsEntry.Fqdn)`" as `"$($ariaOpsEntry.Username)`"." try { Connect-VcfCheckAriaOpsEndpoint -Context $Context -Fqdn $ariaOpsEntry.Fqdn -Credential $ariaOpsCredential -ConnectivityTimeoutSeconds $ConnectivityTimeoutSeconds | Out-Null Write-LogMessage -Type INFO -Message "Authentication successful: Aria Operations `"$($ariaOpsEntry.Fqdn)`"." $phases += @{ name = "Aria Operations Network Reachability ($ariaOpsLabel)"; status = 'pass'; error = $null } $phases += @{ name = "Aria Operations Authentication ($ariaOpsLabel)"; status = 'pass'; error = $null } } catch { $ariaOpsErrorMsg = $_.Exception.Message Write-LogMessage -Type WARNING -Message "Authentication failed: Aria Operations `"$($ariaOpsEntry.Fqdn)`" - $ariaOpsErrorMsg" if ($ariaOpsErrorMsg -match 'Could not reach.*on port \d+') { $phases += @{ name = "Aria Operations Network Reachability ($ariaOpsLabel)"; status = 'fail'; error = "Aria Operations (`"$($ariaOpsEntry.Fqdn)`") is not reachable on port 443. Check VPN/network connectivity, firewall rules, and DNS resolution." } } else { $phases += @{ name = "Aria Operations Network Reachability ($ariaOpsLabel)"; status = 'pass'; error = $null } $phases += @{ name = "Aria Operations Authentication ($ariaOpsLabel)"; status = 'fail'; error = "Invalid username or password for Aria Operations (`"$($ariaOpsEntry.Fqdn)`"). Verify the credential entered for this endpoint." } } } } Remove-Variable -Name ariaOpsCredentialsJson, ariaOpsCredentialEntries, ariaOpsSecurePassword, ariaOpsCredential -ErrorAction SilentlyContinue } } catch { $errorMsg = $_.Exception.Message Write-LogMessage -Type ERROR -Message "Authentication failed: SDDC Manager `"$SddcManagerFqdn`" - $errorMsg" if ($errorMsg -match 'Could not reach.*on port \d+') { $phases += @{ name = 'Network Reachability'; status = 'fail'; error = 'SDDC Manager is not reachable on port 443. Check VPN/network connectivity, firewall rules, and DNS resolution.' } } elseif ($errorMsg -match '(?i)UNAUTHORIZED|not authorized|invalid credentials|incorrect.*password|authentication failed|401') { $phases += @{ name = 'Network Reachability'; status = 'pass'; error = $null } $phases += @{ name = 'SDDC Manager Authentication'; status = 'fail'; error = 'Invalid username or password. Verify your SDDC Manager credentials.' } } else { $phases += @{ name = 'Network Reachability'; status = 'pass'; error = $null } $phases += @{ name = 'SDDC Manager Authentication'; status = 'fail'; error = 'Check your network connectivity and SDDC Manager credentials.' } } @{ success = $false error = $null phases = $phases } | ConvertTo-Json -Compress exit 1 } $rootPasswordPlainText = $env:VCFCHECK_ROOT_PASSWORD if (-not [String]::IsNullOrEmpty($rootPasswordPlainText)) { $rootPassword = ConvertTo-SecureString -String $rootPasswordPlainText -AsPlainText -Force $rootCredential = [PSCredential]::new('root', $rootPassword) Write-LogMessage -Type INFO -Message "Starting SDDC Manager root credential validation for `"$SddcManagerFqdn`"." Write-LogMessage -Type INFO -Message "Resolving management domain vCenter and connecting..." try { $vcenterFqdn = Get-VcfCheckManagementVCenterFqdn -Context $Context Connect-VcfCheckVCenter -Context $Context -Fqdn $vcenterFqdn Write-LogMessage -Type DEBUG -Message "Connected to management vCenter `"$vcenterFqdn`"." } catch { Write-LogMessage -Type ERROR -Message "Failed to resolve/connect to management vCenter: $($_.Exception.Message)" $phases += @{ name = 'VMware Tools Status'; status = 'fail'; error = 'Could not connect to the management vCenter. Verify SDDC Manager connection and management domain configuration.' } @{ success = $false error = $null phases = $phases domains = $domains } | ConvertTo-Json -Compress exit 1 } $vmName = ($SddcManagerFqdn -split '\.')[0] $esxHostCheck = Test-VcfCheckEsxHostConnectivity -Context $Context -VcenterFqdn $vcenterFqdn -VmName $vmName -TimeoutSeconds $ConnectivityTimeoutSeconds # Evaluate ESX host reachability if host object resolution succeeded. if ($esxHostCheck.Hostname) { if (-not $esxHostCheck.Success) { Write-LogMessage -Type WARNING -Message "ESX host connectivity check failed: $($esxHostCheck.Error)" $phases += @{ name = 'ESX Host Connectivity'; status = 'fail'; error = $esxHostCheck.Error } $phases += @{ name = 'VMware Tools Status'; status = 'fail'; error = 'Could not verify ESX host connectivity. Resolve ESX host issues before retrying.' } @{ success = $false error = $null phases = $phases domains = $domains } | ConvertTo-Json -Compress exit 1 } Write-LogMessage -Type INFO -Message "ESX host `"$($esxHostCheck.Hostname)`" is reachable on required ports." $phases += @{ name = 'ESX Host Connectivity'; status = 'pass'; error = $null } } $rootCheck = Test-VcfCheckSddcManagerRootCredential -Context $Context -RootCredential $rootCredential Write-LogMessage -Type INFO -Message "Root credential validation completed. Success=$($rootCheck.Success)" if ($rootCheck.Success) { Write-LogMessage -Type INFO -Message "Root credential verified: SDDC Manager `"$SddcManagerFqdn`"." $phases += @{ name = 'VMware Tools Status'; status = 'pass'; error = $null } $phases += @{ name = 'SDDC Manager Root Authentication'; status = 'pass'; error = $null } } else { Write-LogMessage -Type WARNING -Message "Root credential check failed: SDDC Manager `"$SddcManagerFqdn`" - $($rootCheck.ErrorMessage)" if ($rootCheck.ErrorMessage -match 'The SSL connection could not be established') { $phases += @{ name = 'VMware Tools Status'; status = 'fail'; error = 'SSL connection to vCenter failed. Check your Set-PowerCLIConfiguration InvalidCertificateAction setting.' } } elseif ($rootCheck.ErrorMessage -match 'Failed to authenticate with the guest operating system') { $phases += @{ name = 'VMware Tools Status'; status = 'pass'; error = $null } $phases += @{ name = 'SDDC Manager Root Authentication'; status = 'fail'; error = 'Invalid root password. Verify the SDDC Manager appliance root password.' } } elseif ($rootCheck.ErrorMessage -match 'VMware Tools is not running' -or $rootCheck.ErrorCategory -eq 'ToolsNotRunning') { $phases += @{ name = 'VMware Tools Status'; status = 'fail'; error = 'VMware Tools is not running on the SDDC Manager appliance.' } } else { $phases += @{ name = 'VMware Tools Status'; status = 'fail'; error = $rootCheck.ErrorMessage } } @{ success = $false error = $null phases = $phases domains = $domains } | ConvertTo-Json -Compress exit 1 } } @{ success = $true error = $null phases = $phases domains = $domains } | ConvertTo-Json -Compress exit 0 } catch { Write-LogMessage -Type ERROR -Message "Credential validation failed: $($_.Exception.Message)" if ($phases.Count -eq 0) { $phases = @( @{ name = 'Network Reachability'; status = 'fail'; error = 'Unexpected error during network check.' } ) } @{ success = $false error = $null phases = $phases } | ConvertTo-Json -Compress exit 1 } finally { $sddcPasswordPlainText = $null $rootPasswordPlainText = $null $env:VCFCHECK_ARIAOPS_CREDENTIALS_JSON = $null if ($Context) { Disconnect-VcfCheckAll -Context $Context } Remove-Variable -Name sddcPasswordPlainText, rootPasswordPlainText, sddcPassword, rootPassword -ErrorAction SilentlyContinue [System.GC]::Collect() [System.GC]::WaitForPendingFinalizers() } |