lunedì 2 dicembre 2024

[NSX] - API Authentication Using a Session Cookie on PowerShell

Issue


Recently I had to create a PowerShell script that grab some information from NSX via Rest API calls. To do so, I had to create a few lines of code to authenticate on the NSX.
To reduce the number of times that I have to enter username and password and/or they transit over the network, I used NSX session-based authentication method to generate a JSESSIONID cookie when using the API as described here.
The method describe how to create a new session cookie and how to use thex-xsrf-token for subsequent requests for cURL on linux environment. Below here I wrote few lines of code to use the same method in powershell environment.
Let's see below how does it works for powershell ....

Solution


The script must run on an Windows machine, so I decided to make a powershell script. Information regarding api call, can be found at the following link https://developer.vmware.com/apis
I thought was useful share with everyone how to do it, let's see the script:
#
# Create a Session Token 
#
# LM v. 0.2
#
# This script is an example on how to create a session token on NSX and reuse for subsequent requests.
# 


#Script accept in input the FQDN of the NSX Manager to connect on, or leave it blank to use the default "nsx-mgr.vcf.sddc.lab"
param(
    [string] $nsx_manager = 'nsx-mgr.vcf.sddc.lab'
)

#Used to manage/skip certificates
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
    public bool CheckValidationResult(
        ServicePoint srvPoint, X509Certificate certificate,
        WebRequest request, int certificateProblem) {
        return true;
    }
}
"@
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy


function createSession {
    $script:session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
    $script:headers = @{}
    $script:nsx_uri = "https://" + $nsx_manager
    $uri = $nsx_uri + "/api/session/create"
    $private:body = "j_username=$($nsx_user)&j_password=$($nsx_pass)" 
    try {
        $response = invoke-webrequest -contentType "application/x-www-form-urlencoded" -WebSession $session -uri $uri -Method 'POST' -Body $body -usebasicparsing -Erroraction Stop
        $xsrftoken = $response.headers["X-XSRF-TOKEN"]
 
        #$response
        $script:loginSuccess = $true
        $script:headers.Add("X-XSRF-TOKEN", $xsrftoken)
        $script:headers.Add("Accept", "application/json")
        $script:headers.Add('Content-Type','"application/x-www-form-urlencoded')
    }
    catch {
        Write-Host "Failed" -ForegroundColor Red
        Write-Host "$($_.Exception)" -ForegroundColor Red
        write-host "Error Details:" $_.ErrorDetails.Message -ForegroundColor Magenta
        $script:loginSuccess = $false
    }
}

#If you want insert Credential on fly uncomment the three lines below here and comment the hardcoded credentials 
#$MyCredential = Get-Credential -Message "Insert $nsx_manager "
#$nsx_user = $MyCredential.UserName
#$nsx_pass = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($MyCredential.Password))

#Harcoded credentials; uncomment if you don't want to insert them with Get-Credential function or comment otherwise
$nsx_user = 'admin'
$nsx_pass = 'VMware123!VMware123!'

#Create the cookie session 
createSession


#how looks like subsequent example requests
#List of segments
$response_q1 = Invoke-webrequest -WebSession $session -uri $($nsx_uri + "/policy/api/v1/infra/segments") -Method 'GET' -Headers $headers -usebasicparsing -Erroraction Stop

#List of tier-1s
$response_q2 = invoke-webrequest -WebSession $session -uri $($nsx_uri + "/policy/api/v1/infra/tier-1s") -Method 'GET' -Headers $headers -usebasicparsing -Erroraction Stop

write-host " ----- Segments ----- " -ForegroundColor Green
write-host $response_q1.Content
write-host 
write-host 
write-host " ----- Tier-1s ----- " -ForegroundColor Green
#write-host $response_q2.Content

# END #

That's it.