PowerCLI

 View Only

 How to update VCSA 8 using PowerCLi?

Sham81's profile image
Sham81 posted May 30, 2025 11:08 AM

Hello,

I am trying to write a script that I will be able to run and check for updates for VCSA then if any are found, stage them and remediate.

I've read somewhere that you have to use API calls in version 8 to do it.

I can connect to VCSA API through Power Shell as I have a script that checks health of the VCSA.

I tried to look for a proper commands but despite I can see pending updates in the web interface, script is not returning anything.

I am in on the stage of actually try to check if there are any updates available and then display them.

This is done for test VCSA so I haven't used encrypted credentials, etc. - it is a test version so all those security improvements I can apply after I manage to make it work.

Here is what I am using so far:

$vCenterServer = "xxx"
#$vcsaUser = "xxx"
#$vcsaPass = "xxx"
##########################################################################################
#                          FUNCTIONS                                                     #
##########################################################################################
#Function to convert the given credentials to Base64 encode
function Set-Credentials {
    param (
       [Parameter(Mandatory=$true)][string]$username,
       [Parameter(Mandatory=$true)][string]$password
    )
    
    $pair = "${username}:${password}"
    $bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
    $base64 = [System.Convert]::ToBase64String($bytes)
 
    $basicAuthValue = "Basic $base64"
    return $basicAuthValue
}
#Function to request session id
function Create-Session {
Ignore-Certificate
$responsesessionid = Invoke-vCenterTokenRequest -Uri $RestApiUrl/com/vmware/cis/session -method "POST"
    return $responsesessionid
}
#Function to create session id
function Invoke-vCenterTokenRequest {
    param (
        [string]$uri=$REST_URL,
        [string]$method,
        [string]$body=$null
    )
    
    $headers = @{
        'authorization' =  $creds;
        'content-type' =  'application/json';
        'Accept' = 'application/json';
        
    }
    $response = Invoke-RestMethod -uri $uri -Headers $headers -Method $method -Body $body 
    
    return $response
}
#Function to ignore vCenter certificate
function Ignore-Certificate {
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()
}
#Function to terminate the session 
function Terminate-Session {
    param (
       [Parameter(Mandatory=$true)][string]$AuthTokenValue
    )
    
       $headers = @{
            'Accept' = 'application/json';
            'vmware-api-session-id'= $AuthTokenValue;
       }
            
       $method = "DELETE"
            
       $respond = Invoke-RestMethod -Method $method  -Headers $headers -uri $RestApiUrl/com/vmware/cis/session
       $terminateSession = $respond.value | Select-Object -Property @{N='ESXi Host Name';E={$_.name}},@{N='Connection State';E={$_.connection_state} } ,@{N='Power State';E={$_.power_state} }
   
       return $terminateSession
}
######################################################################################################################################################################################################
######################################################################
#                            MAIN                                    #
######################################################################
            
            #######################################
            #      Connect to VCSA API            #
            #######################################
            $Credentials = IMPORT-CLIXML "C:\Scripts\VMware\VCSA_API_Test1.xml"
$User = $Credentials.UserName
            $Pass = $Credentials.GetNetworkCredential().Password
    
    
            Write-Host "Getting name of the vCenter Server..." -ForegroundColor Yellow
            $vCenterFQDN = $vCenterServer
    
            Ignore-Certificate
            $response = try { 
                        Invoke-WebRequest $vCenterFQDN
                        $RestApiUrl ='https://'+$vCenterFQDN+'/rest/'
                    } catch { 
                        $_.Exception.Response; 
                        Write-Host "FQDN is not correct or vCenter IP is not reachable. Please check and try again." -ForegroundColor Red 
                    }
   
    
            Write-Host "Getting credentials to authenticate against vSphere REST API...."   $RestApiUrl -ForegroundColor Yellow
            $username = $User
            $password = $Pass
            $password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))
            $creds = Set-Credentials -username $username -password $password
            $correctToken = 1
            try{
                    $AuthenticationToken = Create-Session
                    if ($AuthenticationToken.Value)
                    {
                        Write-Host "Authentication Token acquired successfully" -ForegroundColor Green
                        Start-Sleep -Seconds 2
                        $correctToken = 0
                        $FuncAuthToken = $AuthenticationToken.Value
                    }
        
               }
            catch
                {
                    Write-Host "Wrong Username or Password" -ForegroundColor Red
                    Start-Sleep -Seconds 2
                }
                #######################################################################################
        
# 1. Trigger Online Update Check
Write-Host "`n[INFO] Triggering online update check..."
$onlineCheckUri = "https://$vCenterServer:5480/rest/appliance/update/pending?action=check"
$checkResponse = Invoke-VCSAApi -Uri $onlineCheckUri -Method 'POST' -Headers $headers
if ($checkResponse) {
    Write-Host "[INFO] Online update check initiated successfully."
} else {
    Write-Host "[ERROR] Failed to trigger online update check."
    Disconnect-VIServer -Confirm:$false
    Exit
}
# 2. Wait for the Update Scan to Complete
Write-Host "[INFO] Waiting for update scan to complete..."
Start-Sleep -Seconds 20
# 3. Retrieve Available Online Updates
Write-Host "`n[INFO] Retrieving available online updates..."
$updatesUri = "https://$vCenterServer:5480/rest/appliance/update/pending"
$updatesResponse = Invoke-VCSAApi -Uri $updatesUri -Method 'GET' -Headers $headers
if ($updatesResponse -and $updatesResponse.value.Count -gt 0) {
    Write-Host "[INFO] Available Online Updates:"
    $updatesResponse.value | ForEach-Object {
        Write-Host "  - Version: $($_.version)"
        Write-Host "  - Description: $($_.description)"
        Write-Host "  - Release Date: $($_.release_date)"
    }
} else {
    Write-Host "[INFO] No online updates found."
    Disconnect-VIServer -Confirm:$false
    Exit
}
      
                              
        $quit = Terminate-Session -AuthTokenValue $FuncAuthToken | ft                         
        Write-Host "vSphere REST API session terminated successfully" -ForegroundColor Green
This returns absolutely nothing regarding update check.
Has anyone been successful in creating such a script?
Thank you for help,
Sham
James Dougherty's profile image
James Dougherty

I've been working on a report for the vCSA but I'm going about it a different way.  Here is the section for grabbing updates with the way I'm going about it.  Hopefully this helps with some ideas for your method.  Note, this will error if an update is not found so I am still working on this.

Connect-CisServer -Server $vCenter -Credential $root -ErrorAction Stop -ErrorVariable CisConnect
Write-Host "Checking VCSA Updates"
$SourceType = "LOCAL_AND_ONLINE" #"LAST_CHECK"
$vcsaUpdates = Get-CisService -Name 'com.vmware.appliance.update.pending' -Server $Global:DefaultCisServer
$results = $vcsaUpdates.list($SourceType)
$UpdateReport = @()

ForEach ($result in $results) {
    $UpdateReport += [pscustomobject] @{
    "vCenter"         = $vCenter;
    "Name"            = $result.name;
    "Version"         = $result.version.value;
    "Update Type"     = $result.update_type;
    "Severity"        = $result.severity;
    "Priority"        = $result.priority;
    "SizeGB"          = [math]::Round(([int]$result.size / 1024), 2);
    "Reboot Required" = $result.reboot_required;
    "Description"     = $result.description.default_message
    }
}
Sham81's profile image
Sham81

Thank you James Dougherty!

That put me on the right track - I can trigger update from the script but it only discovers updates when you actually trigger a check in the web interface first.

I am trying to find a way now on how to trigger this check from the script.