Within a VMware Cloud Foundation instance, SDDC Manager is used to manage the lifecycle of passwords (or credentials). While we provide the ability to rotate (either scheduled or manually) currently there is no easy way to check when a particular password is due to expire, which can lead to appliance root passwords expiring, which will cause all sorts of issues. The ability to monitor expiry is something that is being worked on, but as a stop gap I put together the script below which leverages PowerVCF and also a currently undocumented API for validating credentials.
The script has a function called Get-VCFPasswordExpiry that accepts the following parameters
- -fqdn (FQDN of the SDDC Manager)
- -username (SDDC Manager Username – Must have the ADMIN role)
- -password (SDDC Manager password)
- -resourceType (Optional parameter to specify a resourceType. If not passed, all resources will be checked. If passed (e.g. VCENTER) then only that resourceType will be checked. Supported resource types are
PowerVCF is a requirement. If you dont already have it run the following
Install-Module -Name PowerVCF
The code takes a while to run as it needs to do the following to check password expiry
- Connect to SDDC Manager to retrieve an API token
- Retrieve a list of all credentials
- Using the resourceID of each credential
- Perform a credential validation
- Wait for the validation to complete
- Parse the results for the expiry details
- Add all the results to an array and present in a table (Kudos to Ken Gould for assistance with the presentation of this piece!)
In this example script I am returning all non SERVICE user accounts regardless of expiry (SERVICE account passwords are system managed). You could get more granular by adding something like this to only display accounts with passwords due to expire in less than 14 days
if ($validationTaskResponse.validationChecks.passwordDetails.numberOfDaysToExpiry -lt 14) {
Write-Output "Password for username $($validationTaskResponse.validationChecks.username) expires in $($validationTaskResponse.validationChecks.passwordDetails.numberOfDaysToExpiry) days"
}
Here is the script content. As always feedback is welcome. Also posted in Github here if anyone wants to fork and improve https://github.com/LifeOfBrianOC/Get-VCFPasswordExpiry
# Script to check the password expiry of VMware Cloud Foundation Credentials
# Written by Brian O'Connell - VMware
#User Variables
$sddcManagerFQDN = "sfo-vcf01.sfo.rainpole.io"
$sddcManagerAdminUser = "administrator@vsphere.local"
$sddcManagerAdminPassword = "VMw@re1!"
# Requires PowerVCF Module
#Requires -Module PowerVCF
Function Get-VCFPasswordExpiry
{
Param (
[Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$fqdn,
[Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$username,
[Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$password,
[Parameter (Mandatory = $false)] [ValidateSet("VCENTER", "PSC", "ESXI", "BACKUP", "NSXT_MANAGER", "NSXT_EDGE", "VRSLCM", "WSA", "VROPS", "VRLI", "VRA", "VXRAIL_MANAGER")] [ValidateNotNullOrEmpty()] [String]$resourceType
)
# Request an SDDC manager Token
Request-VCFToken -fqdn $fqdn -username $username -password $password
# Build the required headers
$credentialheaders = @{"Content-Type" = "application/json"}
$credentialheaders.Add("Authorization", "Bearer $accessToken")
# Get all credential objects that are not type SERVICE
if (!$PsBoundParameters.ContainsKey("resourceType")) {
$credentials = Get-VCFCredential | where-object {$_.accountType -ne "SERVICE"}
}
else {
$credentials = Get-VCFCredential -resourceType $resourceType | where-object {$_.accountType -ne "SERVICE"}
}
$validationArray = @()
Foreach ($credential in $credentials) {
$resourceType = $credential.resource.resourceType
$resourceID = $credential.resource.resourceId
$username = $credential.username
$credentialType = $credential.credentialType
$body = '[
{
"resourceType": "'+$resourceType+'",
"resourceId": "'+$resourceID+'",
"credentials": [
{
"username": "'+$username+'",
"credentialType": "'+$credentialType+'"
}
]
}
]'
$uri = "https://$sddcManagerFQDN/v1/credentials/validations"
# Submit a credential validation request
$response = Invoke-RestMethod -Method POST -URI $uri -headers $credentialheaders -body $body
$validationTaskId = $response.id
Do {
# Keep checking until executionStatus is not IN_PROGRESS
$validationTaskuri = "https://$sddcManagerFQDN/v1/credentials/validations/$validationTaskId"
$validationTaskResponse = Invoke-RestMethod -Method GET -URI $validationTaskuri -headers $credentialheaders
}
While ($validationTaskResponse.executionStatus -eq "IN_PROGRESS")
# Build the output
$validationObject = New-Object -TypeName psobject
$validationObject | Add-Member -notepropertyname 'Resource Name' -notepropertyvalue $validationTaskResponse.validationChecks.resourceName
$validationObject | Add-Member -notepropertyname 'Username' -notepropertyvalue $validationTaskResponse.validationChecks.username
$validationObject | Add-Member -notepropertyname 'Number Of Days To Expiry' -notepropertyvalue $validationTaskResponse.validationChecks.passwordDetails.numberOfDaysToExpiry
Write-Output "Checking Password Expiry for username $($validationTaskResponse.validationChecks.username) from resource $($validationTaskResponse.validationChecks.resourceName)"
# Add each credential result to the array
$validationArray += $validationObject
#break
}
# Print the array
$validationArray
}
# Run the function
Get-VCFPasswordExpiry -fqdn $sddcManagerFQDN -username $sddcManagerAdminUser -password $sddcManagerAdminPassword
# Run the function with resourceType VCENTER
# Get-VCFPasswordExpiry -fqdn $sddcManagerFQDN -username $sddcManagerAdminUser -password $sddcManagerAdminPassword -resourceType VCENTER
Here is a screenshot of the result

This is very cool. Would have saved me a lot of time a few month ago. Great to see all the root accounts on there.
Cheers Cliff. Yeah we’ve all been burned by expiring passwords!
nice tool! Thanks.
Added VXRAIL_MANAGER to ValidateSet of $ressourceType to support VCF on VxRail 🙂
Thanks for the feedback. Glad you found it useful. I’ve updated the post & github code with your suggestion
Looks like this script doesn’t work anymore. I just tried it with Powershell 7.1 and the PowerVCF module is 2.1.7 , Is there an updated script or logic to get this script working? –Fellow vExpert (Pradeep Adapa)
What version of VCF are you testing with?
I haven’t tested again 4.4. APIs may have changed.
Looks like this code doesn’t work anymore. i just tried it with PowerShell 7.1 and PowerVCF Module 2.1.7 on my VCF 3.10.2.2 SDDC Manager and it didn’t work. Interestingly there was no error after executing the script as well. It just went to the next line in Powershell after executing the script. Let me know if there is an updated version or if this can be resolved. — Pradeep Adapa (Fellow vExpert)
This is for VCF 4.x only.
Ahh, got it, my VCF Version is 3.10.x/3.11 , Is there a script for 3.10.x?