mercoledì 15 gennaio 2025

[NSX] Export Segment list into Excel

Issue


Starting from a post I wrote some time ago; about creating Session Cookies on Powershell for authentication in NSX, [NSX] - API Authentication Using a Session Cookie on PowerShell.
I had to create a script to export the complete list of segments configured in NSX, with their Subnets/Gateways, Tier-1s, Tier-0s, IDs, Transport Zones.
Below few line of code to do that. The code is provided without warranty, use at your own risk.

Solution


The script looks like this:

###################################################################
# list_nsx_segments.ps1
#
# LM v. 0.8
#
# This script uses the "ImportExcel" library 
# https://www.powershellgallery.com/packages/ImportExcel/7.8.10
# If not present install: Install-Module ImportExcel
# 
# Input parameters: NSX_MANGER_FQDN
#		    NSX_Username
#		    NSX_Password
#

param(
    [string] $nsx_manager = '<NSX_MANAGER_FQDN>'
)

#Used to handle/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 $($nsx_uri + "/api/session/create") -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
$nsx_user = 'admin'
$nsx_pass = 'VMware1!VMware1!'


#Create the cookie session 
createSession


$response_t0s = $null
$response_t1s = $null
$response_seg = $null
$response_tz = $null

#Query the Tier-0s
$response_t0s = Invoke-webrequest -WebSession $session -uri $($nsx_uri + "/policy/api/v1/infra/tier-0s") -Method 'GET' -Headers $headers -usebasicparsing -Erroraction Stop
if ($response_t0s.statuscode -eq '200') {
    #echo $response_t0s.Content #print Json format
    $keyValue_t0s= ConvertFrom-Json $response_t0s.Content | Select-Object -expand "results"
    $sheet_t0s = $keyValue_t0s | select @{Name='T0 Name';Expression={$_.display_name}}, 
                                        @{Name='ID';Expression={$_.id}}
} else {
    Write-Host
    Write-Host
    write-Host -ForegroundColor red " !!! Somenthing went wrong !!! "
    exit 9
}
#RAW data check
#$sheet_t0s | Sort-Object -Property "T0 Name" | Out-Gridview

#Query the Tier-1s
$response_t1s = Invoke-webrequest -WebSession $session -uri $($nsx_uri + "/policy/api/v1/infra/tier-1s") -Method 'GET' -Headers $headers -usebasicparsing -Erroraction Stop
if ($response_t1s.statuscode -eq '200') {
    #echo $response_t1s.Content #print Json format
    $keyValue_t1s= ConvertFrom-Json $response_t1s.Content | Select-Object -expand "results"
    $sheet_t1s = $keyValue_t1s | select @{Name='T1 Name';Expression={$_.display_name}}, 
                                        @{Name='ID';Expression={$_.id}}

}
#RAW data check
#$sheet_t1s | Sort-Object -Property "T1 Name" | Out-Gridview

#Query the Segments
$response_seg = Invoke-webrequest -WebSession $session -uri $($nsx_uri + "/policy/api/v1/infra/segments") -Method 'GET' -Headers $headers -usebasicparsing -Erroraction Stop
if ($response_seg.statuscode -eq '200') {
    # echo $response_seg.Content #print Json format
    $keyValue_seg= ConvertFrom-Json $response_seg.Content | Select-Object -expand "results"
    $sheet_seg = $keyValue_seg | select @{Name='Segment';Expression={$_.display_name}}, 
                                        @{Name='Connected-GW';Expression={$_.connectivity_path}},
                                        @{Name='Transport Zone';Expression={$_.transport_zone_path}},
                                        @{Name='Gateway'; Expression={$_.subnets.gateway_address}}, 
                                        @{Name='Type'; Expression={$_.type}}, 
                                        @{Name='Ports_Interfaces';Expression={0}},
                                        @{Name='Admin State'; Expression={$_.admin_state}},
                                        @{Name='Seg_ID'; Expression={$_.id}}
                                  
}
# RAW data check
#$sheet_seg | Sort-Object -Property Segment | Out-Gridview

#Query the Transport zones
$response_tz = Invoke-webrequest -WebSession $session -uri $($nsx_uri + "/api/v1/transport-zones") -Method 'GET' -Headers $headers -usebasicparsing -Erroraction Stop
if ($response_tz.statuscode -eq '200') {
    #echo $response_tz.Content
    $keyValue_tz= ConvertFrom-Json $response_tz.Content | Select-Object -expand "results"
    $sheet_tz = $keyValue_tz | select @{Name='TZ Name';Expression={$_.display_name}}, 
                                       @{Name='Type';Expression={$_.transport_type}},
                                       @{Name='ID';Expression={$_.id}}
                                        
}
#RAW data
#$sheet_tz |  Sort-Object -Property "TZ Name" | Out-Gridview

###########
#Replace RAW data with the right Name into Segments.
foreach($seg in $sheet_seg) {
    # Replace Tier-0s with Name (instead of raw data)
    if ($seg."Connected-GW" -ne $null) {
        $t0= $keyValue_t0s | Where-Object { $_.path -eq $($seg."Connected-GW") } | select display_name
        if ( $t0.display_name -ne $null) {
            $seg."Connected-GW" = $t0.display_name
        } 
    }  
    # Replace Tier-1s with Name (instead of raw data)
    if ($seg."Connected-GW" -ne $null) {
        $t1= $keyValue_t1s | Where-Object { $_.path -eq $($seg."Connected-GW") } | select display_name
        if ( $t1.display_name -ne $null) {
            $seg."Connected-GW" = $t1.display_name
        } 
    }  
    # Replace Transport Zone with Name (instead of raw data)
    if ($seg."Transport Zone" -ne $null) {
        $tz_id = $seg."Transport Zone".split("/")[7]
        $tz= $keyValue_tz | Where-Object { $_.id -eq $($tz_id) } | select display_name
        $seg."Transport Zone" = $tz.display_name
    }
    #Start-Sleep -Milliseconds 40
    #write-host $seg.Seg_ID
    $response_ports = Invoke-webrequest -WebSession $session -uri $($nsx_uri + "/policy/api/v1/infra/segments/$($seg.Seg_ID)/ports") -Method 'GET' -Headers $headers -usebasicparsing -Erroraction Stop
    if ($response_ports.statuscode -eq '200') {
        #echo $response_ports.Content       
        $seg."Ports_Interfaces" = (ConvertFrom-Json $response_ports.Content |  select "result_count").result_count                   
    }
}

#$sheet_seg | Sort-Object -Property Segment | Out-GridView
$sheet_seg | Sort-Object -Property Segment | Export-Excel

write-host 
Write-Host -foreground Green "Script correctly executed on NSX:"$nsx_manager

    
... and the result looks like the follow:

I hope it will be useful.

That's it.