CitrixSdwanFunctions.psm1
<#
.SYNOPSIS This module file contains SD-WAN functions. .DESCRIPTION Version 2. .NOTES Copyright (c) Citrix Systems, Inc. All rights reserved. #> <#Tested against Powershell Version 5.1.14393.2312 - run $PSVersionTable.PSVersion to identify on your system #> #Define default URL protocol to https, which can be changed by calling Set-Protocol function $Script:SDWURLProtocol = "https" #Workaround for SelfSigned Cert and force TLS 1.2 #without this snippet of code, there is a certicate trust relationship error which prevents successful connection to the SDWAN 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 [System.Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 function Set-SDWMgmtProtocol { <# .SYNOPSIS Set $Script:SDWURLProtocol, this will be used for all subsequent invocation of NITRO APIs .DESCRIPTION Set $Script:SDWURLProtocol .PARAMETER Protocol Protocol, acceptable values are "http" and "https" .EXAMPLE Set-SDWMgmtProtocol -Protocol https .NOTES Copyright (c) Citrix Systems, Inc. All rights reserved. #> [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [ValidateSet("http","https")] [string]$Protocol ) Write-Verbose "$($MyInvocation.MyCommand): Enter" $Script:SDWURLProtocol = $Protocol Write-Verbose "$($MyInvocation.MyCommand): Exit" } function Get-SDWMgmtProtocol { <# .SYNOPSIS Get the value of $Script:SDWURLProtocol .DESCRIPTION Set $Script:SDWURLProtocol .EXAMPLE $protocol = Get-Protocol .NOTES Copyright (c) Citrix Systems, Inc. All rights reserved. #> [CmdletBinding()] param() return $Script:SDWURLProtocol } function Connect-SDWAppliance { <# .SYNOPSIS Connect to SD-WAN device (physical or virtual appliance) .DESCRIPTION A custom web request session object will be returned. .PARAMETER SDWAddress Management IP address .PARAMETER SDWName DNS name or FQDN .PARAMETER SDWUserName UserName to access the SD-WAN device .PARAMETER SDWPassword Password to access the SD-WAN device .PARAMETER Timeout Timeout in seconds to for the token of the connection to the SD-WAN device. ### is the default admin configured value. .EXAMPLE $Session = Connect-SDWAppliance -SDWAddress 192.168.100.1 .EXAMPLE $Session = Connect-SDWAppliance - SDWName sdwan.mydomain.com .OUTPUTS CustomPSObject .NOTES Copyright (c) Citrix Systems, Inc. All rights reserved. #> [CmdletBinding()] param ( [Parameter(Mandatory=$true,ParameterSetName='Address')] [string]$SDWAddress, [Parameter(Mandatory=$true,ParameterSetName='Name')] [string]$SDWName, [Parameter(Mandatory=$false)] [string]$SDWUserName="admin", [Parameter(Mandatory=$false)] [string]$SDWPassword="password", [Parameter(Mandatory=$false)] [int]$Timeout=900 ) Write-Verbose "$($MyInvocation.MyCommand): Enter" if ($PSCmdlet.ParameterSetName -eq 'Address') { Write-Verbose "Validating IP Address" $IPAddressObj = New-Object -TypeName System.Net.IPAddress -ArgumentList 0 if (-not [System.Net.IPAddress]::TryParse($SDWAddress,[ref]$IPAddressObj)) { throw "'$SDWAddress' is an invalid IP address" } $sdwEndpoint = $SDWAddress } elseif ($PSCmdlet.ParameterSetName -eq 'Name') { $sdwEndpoint = $SDWName } $login = @{"login" = @{"username"=$SDWUserName;"password"=$SDWPassword;"timeout"=$Timeout}} $loginJson = ConvertTo-Json $login try { Write-Verbose "Calling Invoke-RestMethod for login" $response = Invoke-RestMethod -Uri "$($Script:SDWURLProtocol)://$sdwEndpoint/sdwan/nitro/v1/config/login" -Body $loginJson -Method POST -SessionVariable saveSession -ContentType application/json if ($response.severity -eq "ERROR") { throw "Error. See response: `n$($response | fl * | Out-String)" } else { Write-Verbose "Response:`n$(ConvertTo-Json $response | Out-String)" } } catch [Exception] { throw $_ } $sdwSession = New-Object -TypeName PSObject $sdwSession | Add-Member -NotePropertyName Endpoint -NotePropertyValue $sdwEndpoint -TypeName String $sdwSession | Add-Member -NotePropertyName WebSession -NotePropertyValue $saveSession -TypeName Microsoft.PowerShell.Commands.WebRequestSession Write-Verbose "$($MyInvocation.MyCommand): Exit" return $sdwSession } function Disconnect-SDWAppliance { <# .SYNOPSIS Disconnect SDWAN Appliance session .DESCRIPTION Disconnect SDWAN Appliance session .PARAMETER SDWSession An existing custom SDWAN Web Request Session object returned by Connect-SDWAppliance .EXAMPLE Disconnect-SDWAppliance -SDWSession $Session .NOTES Copyright (c) Citrix Systems, Inc. All rights reserved. #> [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [PSObject]$SDWSession ) Write-Verbose "$($MyInvocation.MyCommand): Enter" try { Write-Verbose "Calling Invoke-RestMethod for logout" $response = Invoke-RestMethod -Uri "$($Script:SDWURLProtocol)://$($SDWSession.Endpoint)/sdwan/nitro/v1/config/login" -Method DELETE -ContentType application/json -WebSession $SDWSession.WebSession } catch [Exception] { throw $_ } Write-Verbose "$($MyInvocation.MyCommand): Exit" } function Invoke-SDWNitroRestApi { <# .SYNOPSIS Invoke SDWAN NITRO REST API .DESCRIPTION Invoke SDWAN NITRO REST API .PARAMETER SDWSession An existing custom SDWAN Web Request Session object returned by Connect-SDWAppliance .PARAMETER OperationMethod Specifies the method used for the web request (e.g. POST, PUT, GET, ADD, MODIFY, DELETE) .PARAMETER ResourceType Type of the SDWAN appliance resource (e.g. config, monitor, config_editor, diag, download, mobile_broadband) .PARAMETER ResourceName Name of the SDWAN appliance resource, optional (e.g. mangement_ip, config_packages, remote_licnese, interface_groups, etc) .PARAMETER Action Name of the action to perform on the SDWAN appliance resource (e.g. compile, enable_remote_server, export_to_cm) .PARAMETER Payload Payload of the web request, in hashtable format .PARAMETER GetWarning Switch parameter, when turned on, warning message will be sent in 'message' field and 'WARNING' value is set in severity field of the response in case there is a warning. Turned off by default .PARAMETER OnErrorAction Use this parameter to set the onerror status for nitro request. Applicable only for bulk requests. Acceptable values: "EXIT", "CONTINUE", "ROLLBACK", default to "EXIT" .EXAMPLE #Invoke NITRO REST API to manaually set the management IP address. @{gateway="172.30.200.1";netmask="255.255.255.0";ip_address="172.30.200.150"} Invoke-SDWNitroRestApi -SDWSession $mySDWSession -OperationMethod PUT -ResourceType config -ResourceName management_ip -Payload $ReqPayload .OUTPUTS Only when the OperationMethod is GET: PSCustomObject that represents the JSON response content. This object can be manipulated using the ConvertTo-Json Cmdlet. .NOTES Copyright (c) Citrix Systems, Inc. All rights reserved. #> [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [PSObject]$SDWSession, [Parameter(Mandatory=$true)] [ValidateSet("DELETE","GET","POST","PUT")] [string]$OperationMethod, [Parameter(Mandatory=$true)] [string]$ResourceType, [Parameter(Mandatory=$true)] [string]$ResourceName, [Parameter(Mandatory=$false)] [string]$SubResource, [Parameter(Mandatory=$false)] [string]$Action, [Parameter(Mandatory=$false)] [ValidateScript({$OperationMethod -in @("GET", "DELETE")})] [hashtable]$Arguments=@{}, [Parameter(Mandatory=$false)] [ValidateScript({$OperationMethod -notin @("GET", "DELETE")})] [hashtable]$Payload=@{}, [Parameter(Mandatory=$false)] [switch]$GetWarning=$false, [Parameter(Mandatory=$false)] [ValidateSet("EXIT", "CONTINUE", "ROLLBACK")] [string]$OnErrorAction="EXIT" ) Write-Verbose "$($MyInvocation.MyCommand): Enter" #To do:test for healthy session, exit and return user instruction Write-Verbose "Building URI" $uri = "$($Script:SDWURLProtocol)://$($SDWSession.Endpoint)/sdwan/nitro/v1/$ResourceType/$ResourceName" if (-not [string]::IsNullOrEmpty($SubResource)) { $uri += "/$SubResource" } if ($OperationMethod -notin @("GET", "DELETE", "PUT")) { if (-not [string]::IsNullOrEmpty($Action)) { $uri += "?action=$Action" } } else { if ($Arguments.Count -gt 0) { $uri += "?args=" $argsList = @() foreach ($arg in $Arguments.GetEnumerator()) { $argsList += "$($arg.Name):$([System.Uri]::EscapeDataString($arg.Value))" } $uri += $argsList -join ',' } #To do: Add filter, view, and pagesize } Write-Verbose "URI: $uri" if ($OperationMethod -notin @("GET", "DELETE")) { Write-Verbose "Building Payload" #$warning = if ($GetWarning) { "YES" } else { "NO" } $hashtablePayload = @{} #$hashtablePayload."params" = @{"warning"=$warning;"onerror"=$OnErrorAction;<#"action"=$Action#>} $hashtablePayload.$ResourceName = $Payload $jsonPayload = ConvertTo-Json $hashtablePayload -Depth 100 Write-Verbose "JSON Payload:`n$jsonPayload" } try { Write-Verbose "Calling Invoke-RestMethod" $restParams = @{ Uri = $uri ContentType = "application/json" Method = $OperationMethod WebSession = $SDWSession.WebSession ErrorVariable = "restError" } if ($OperationMethod -notin @("GET", "DELETE")) { $restParams.Add("Body",$jsonPayload) } if ($ResourceName -eq "get_package_file"){ Invoke-RestMethod @restParams > activate_package.zip return "package_downloaded" } $response = Invoke-RestMethod @restParams if ($response) { if ($response.severity -eq "ERROR") { throw "Error. See response: `n$($response | fl * | Out-String)" #to do: writeout .status and .message to help root cuase 404 errors } else { Write-Verbose "Response:`n$(ConvertTo-Json $response | Out-String)" } } } catch [Exception] { if ($ResourceType -eq "reboot" -and $restError[0].Message -eq "The underlying connection was closed: The connection was closed unexpectedly.") { Write-Verbose "Connection closed due to reboot" } else { throw $_ } } Write-Verbose "$($MyInvocation.MyCommand): Exit" if (($OperationMethod -eq "GET") -or ($Action -eq "compile")) { return $response } } |