NsxtRest.psm1
function Connect-NsxtRestServer { <# .SYNOPSIS Connect to a NSXT Rest Server .DESCRIPTION Connect to a NSXT Rest Server and generate a connection object with Servername, Token etc .PARAMETER Server NSXT Rest Server to connect to .PARAMETER Port Optionally specify the server port. Default is 443 .PARAMETER Username Username to connect with .PARAMETER Password Password to connect with .PARAMETER Credential Credential object to connect with .PARAMETER IgnoreCertRequirements Ignore requirements to use fully signed certificates .PARAMETER SslProtocol Alternative Ssl protocol to use from the default Windows PowerShell: Ssl3, Tls, Tls11, Tls12 PowerShell Core: Tls, Tls11, Tls12 .INPUTS System.String System.SecureString Management.Automation.PSCredential Switch .OUTPUTS System.Management.Automation.PSObject. .EXAMPLE Connect-NsxtRestServer -Server nsxt.domain.local -Credential (Get-Credential) .EXAMPLE $SecurePassword = ConvertTo-SecureString “P@ssword” -AsPlainText -Force Connect-NsxtRestServer -Server nsxt.domain.local -Username admin -Password $SecurePassword -IgnoreCertRequirements .EXAMPLE Connect-NsxtRestServer -Server nsxt.domain.local -Port 443 -Credential (Get-Credential) #> [CmdletBinding(DefaultParametersetName="Username")][OutputType('System.Management.Automation.PSObject')] Param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [String]$Server, [Parameter(Mandatory=$false)] [ValidateNotNullOrEmpty()] [Int]$Port = 443, [Parameter(Mandatory=$true,ParameterSetName="Username")] [ValidateNotNullOrEmpty()] [String]$Username, [Parameter(Mandatory=$true,ParameterSetName="Username")] [ValidateNotNullOrEmpty()] [SecureString]$Password, [Parameter(Mandatory=$true,ParameterSetName="Credential")] [ValidateNotNullOrEmpty()] [Management.Automation.PSCredential]$Credential, [Parameter(Mandatory=$false)] [Switch]$IgnoreCertRequirements, [parameter(Mandatory=$false)] [ValidateSet('Ssl3', 'Tls', 'Tls11', 'Tls12')] [String]$SslProtocol ) # --- Test Connectivity to NSXT Rest Server on the given port try { # --- Test Connection to the NSXT Rest Server Write-Verbose -Message "Testing connectivity to $($Server):$($Port)" $TCPClient = New-Object Net.Sockets.TcpClient $TCPClient.Connect($Server, $Port) $TCPClient.Close() } catch [Exception] { throw "Could not connect to server $($Server) on port $($Port)" } # --- Handle untrusted certificates if necessary $SignedCertificates = $true if ($PSBoundParameters.ContainsKey("IgnoreCertRequirements")){ if (!$IsCoreCLR) { if ( -not ("TrustAllCertsPolicy" -as [type])) { 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; } } "@ } [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy } $SignedCertificates = $false } # --- Security Protocol $SslProtocolResult = 'Default' if ($PSBoundParameters.ContainsKey("SslProtocol") ){ if (!$IsCoreCLR) { $CurrentProtocols = ([System.Net.ServicePointManager]::SecurityProtocol).toString() -split ', ' if (!($SslProtocol -in $CurrentProtocols)){ [System.Net.ServicePointManager]::SecurityProtocol += [System.Net.SecurityProtocolType]::$($SslProtocol) } } $SslProtocolResult = $SslProtocol } elseif (!$IsCoreCLR) { # --- Set the default Security Protocol for Windows PS to be TLS 1.2 $CurrentProtocols = ([System.Net.ServicePointManager]::SecurityProtocol).toString() -split ', ' if (!($SslProtocol -in $CurrentProtocols)){ [System.Net.ServicePointManager]::SecurityProtocol += [System.Net.SecurityProtocolType]::Tls12 } $SslProtocolResult = 'Tls12' } # --- Convert Secure Credentials if ($PSBoundParameters.ContainsKey("Credential")){ $Username = $Credential.UserName $ConnectionPassword = $Credential.GetNetworkCredential().Password } if ($PSBoundParameters.ContainsKey("Password")){ $ConnectionPassword = (New-Object System.Management.Automation.PSCredential("username", $Password)).GetNetworkCredential().Password } try { # --- Set Encoded Password $Auth = $Username + ':' + $ConnectionPassword $Encoded = [System.Text.Encoding]::UTF8.GetBytes($Auth) $EncodedPassword = [System.Convert]::ToBase64String($Encoded) # --- Create Output Object $Global:NsxtRestConnection = [pscustomobject]@{ Server = "https://$($Server):$($Port)" Username = $Username EncodedPassword = $EncodedPassword Version = $Null APIVersion = $Null SignedCertificates = $SignedCertificates SslProtocol = $SslProtocolResult } # --- Update NsxtRestConnection with version information $VersionInfo = "2.4" $Global:NsxtRestConnection.Version = $VersionInfo.Version $Global:NsxtRestConnection.APIVersion = $VersionInfo.APIVersion # --- Test the credentials provided Write-Verbose -Message "Testing credentials" $URI = "/api/v1/licenses" Invoke-NsxtRestMethod -Method Get -URI $URI -ErrorAction Stop | Out-Null Write-Output $Global:NsxtRestConnection } catch [Exception]{ Remove-Variable -Name NsxtRestConnection -Scope Global -Force -ErrorAction SilentlyContinue $PSCmdlet.ThrowTerminatingError($PSitem) } } function Disconnect-NsxtRestServer { <# .SYNOPSIS Disconnect from a NSXT Rest server .DESCRIPTION Disconnect from a NSXT Rest server by removing the global NsxtRestConnection variable from PowerShell .EXAMPLE Disconnect-NsxtRestServer .EXAMPLE Disconnect-NsxtRestServer -Confirm:$false #> [CmdletBinding(SupportsShouldProcess,ConfirmImpact="High")] Param () # --- Test for existing connection to NsxtRestConnection if (-not $Global:NsxtRestConnection){ throw "NSXT Rest Connection variable does not exist. Please run Connect-NsxtRestServer first to create it" } if ($PSCmdlet.ShouldProcess($Global:NsxtRestConnection.Server)){ try { # --- Remove custom Security Protocol if it has been specified if ($Global:NsxtRestConnection.SslProtocol -ne 'Default'){ if (!$IsCoreCLR) { [System.Net.ServicePointManager]::SecurityProtocol -= [System.Net.SecurityProtocolType]::$($Global:NsxtRestConnection.SslProtocol) } } } catch [Exception]{ $PSCmdlet.ThrowTerminatingError($PSitem) } finally { # --- Remove the global PowerShell variable Write-Verbose -Message "Removing NsxtRestConnection Global Variable" Remove-Variable -Name NsxtRestConnection -Scope Global -Force -ErrorAction SilentlyContinue } } } function Invoke-NsxtRestMethod { <# .SYNOPSIS Wrapper for Invoke-RestMethod with NSXT Rest specifics .DESCRIPTION Wrapper for Invoke-RestMethod with NSXT Rest specifics .PARAMETER Method REST Method: GET, POST, PUT or DELETE .PARAMETER URI API URI, e.g. /api/v1/licenses .PARAMETER Body REST Body in JSON format .PARAMETER Webrequest Use Invoke-WebRequest instead of Invoke-RestMethod .PARAMETER Headers Optionally supply custom headers .PARAMETER OutFile Saves the response body in the specified output file .INPUTS System.String System.Collections.IDictionary Switch .OUTPUTS System.Management.Automation.PSObject .EXAMPLE Invoke-NsxtRestMethod -Method GET -URI '/api/v1/licenses' .EXAMPLE $URI = "/api/v1/licenses/" $JSON = @" {"parameters": [ { "value": {"string":{ "value": "Apple"}}, "type": "string", "name": "a", "scope": "local" }, { "value": {"number":{ "value": 20}}, "type": "number", "name": "b", "scope": "local" } ] } "@ $InvokeRequest = Invoke-NsxtRestMethod -Method POST -URI $URI -Body $Body -WebRequest #> [CmdletBinding()][OutputType('System.Management.Automation.PSObject')] Param ( [parameter(Mandatory=$true)] [ValidateSet("GET","POST","PUT","DELETE","PATCH")] [String]$Method, [parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [String]$URI, [parameter(Mandatory=$false)] [ValidateNotNullOrEmpty()] $Body, [parameter(Mandatory=$false)] [Switch]$WebRequest, [parameter(Mandatory=$false)] [ValidateNotNullOrEmpty()] [System.Collections.IDictionary]$Headers, [parameter(Mandatory=$false)] [ValidateNotNullOrEmpty()] [String]$OutFile ) # --- Test for existing connection to NSXT Rest if (-not $Global:NsxtRestConnection){ throw "NSXT Rest Connection variable does not exist. Please run Connect-NsxtRestServer first to create it" } # --- Create Invoke-RestMethod Parameters $FullURI = "$($Global:NsxtRestConnection.Server)$($URI)" # --- Add default headers if not passed if (!$PSBoundParameters.ContainsKey("Headers")){ $Headers = @{ "Accept"="application/json"; "Content-Type" = "application/json"; "Authorization" = "Basic $($Global:NsxtRestConnection.EncodedPassword)"; } } # --- Set up default parmaeters $Params = @{ Method = $Method Headers = $Headers Uri = $FullURI } if ($PSBoundParameters.ContainsKey("Body")) { $Params.Add("Body", $Body) # --- Log the payload being sent to the server Write-Debug -Message $Body } elseif ($PSBoundParameters.ContainsKey("OutFile")) { $Params.Add("OutFile", $OutFile) } # --- Support for PowerShell Core certificate checking if (!($Global:NsxtRestConnection.SignedCertificates) -and ($IsCoreCLR)) { $Params.Add("SkipCertificateCheck", $true) } try { # --- Use either Invoke-WebRequest or Invoke-RestMethod if ($PSBoundParameters.ContainsKey("WebRequest")) { Invoke-WebRequest @Params } else { Invoke-RestMethod @Params } } catch [Exception] { $PSCmdlet.ThrowTerminatingError($PSitem) } finally { if (!$IsCoreCLR) { # Workaround for bug in Invoke-RestMethod. Thanks to the PowerNSX guys for pointing this one out # https://bitbucket.org/nbradford/powernsx/src $ServicePoint = [System.Net.ServicePointManager]::FindServicePoint($FullURI) $ServicePoint.CloseConnectionGroup("") | Out-Null } } } |