sessionapi.psm1
# Helpers function Connect-Sps { [CmdletBinding()] Param( [Parameter(Mandatory=$true,Position=0)] [string]$SessionMaster, [Parameter(Mandatory=$true,Position=1)] [string]$SessionUsername, [Parameter(Mandatory=$true,Position=2)] [SecureString]$SessionPassword, [Parameter(Mandatory=$false)] [switch]$Insecure ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } Import-Module -Name "$PSScriptRoot\sslhandling.psm1" -Scope Local Edit-SslVersionSupport if ($Insecure) { Disable-SslVerification if ($global:PSDefaultParameterValues) { $PSDefaultParameterValues = $global:PSDefaultParameterValues.Clone() } } $local:PasswordPlainText = [System.Net.NetworkCredential]::new("", $SessionPassword).Password try { $local:BasicAuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $SessionUsername, $local:PasswordPlainText))) Remove-Variable -Scope local PasswordPlainText Invoke-RestMethod -Uri "https://$SessionMaster/api/authentication" -SessionVariable HttpSession ` -Headers @{ Authorization = ("Basic {0}" -f $local:BasicAuthInfo) } | Write-Verbose } catch { Import-Module -Name "$PSScriptRoot\sg-utilities.psm1" -Scope Local Out-SafeguardExceptionIfPossible $_ } finally { Remove-Variable -Scope local BasicAuthInfo } $HttpSession } function New-SpsUrl { [CmdletBinding()] Param( [Parameter(Mandatory=$true,Position=0)] [string]$RelativeUrl, [Parameter(Mandatory=$false)] [object]$Parameters ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } $local:Url = "https://$($SafeguardSpsSession.Appliance)/api/$RelativeUrl" if ($Parameters -and $Parameters.Length -gt 0) { $local:Url += "?" $Parameters.Keys | ForEach-Object { $local:Url += ($_ + "=" + [uri]::EscapeDataString($Parameters.Item($_)) + "&") } $local:Url = $local:Url -replace ".$" } $local:Url } function Invoke-SpsWithBody { [CmdletBinding()] Param( [Parameter(Mandatory=$true,Position=0)] [string]$Method, [Parameter(Mandatory=$true,Position=1)] [string]$RelativeUrl, [Parameter(Mandatory=$true,Position=2)] [object]$Headers, [Parameter(Mandatory=$false)] [object]$Body, [Parameter(Mandatory=$false)] [object]$JsonBody, [Parameter(Mandatory=$false)] [object]$Parameters ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } $local:BodyInternal = $JsonBody if ($Body) { $local:BodyInternal = (ConvertTo-Json -Depth 100 -InputObject $Body) } $local:Url = (New-SpsUrl $RelativeUrl -Parameters $Parameters) Write-Verbose "Url=$($local:Url)" Write-Verbose "Parameters=$(ConvertTo-Json -InputObject $Parameters)" Write-Verbose "---Request Body---" Write-Verbose "$($local:BodyInternal)" Invoke-RestMethod -WebSession $SafeguardSpsSession.Session -Method $Method -Headers $Headers -Uri $local:Url ` -Body ([System.Text.Encoding]::UTF8.GetBytes($local:BodyInternal)) ` } function Invoke-SpsWithoutBody { [CmdletBinding()] Param( [Parameter(Mandatory=$true,Position=0)] [string]$Method, [Parameter(Mandatory=$true,Position=1)] [string]$RelativeUrl, [Parameter(Mandatory=$true,Position=2)] [object]$Headers, [Parameter(Mandatory=$false)] [object]$Parameters ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } $local:Url = (New-SpsUrl $RelativeUrl -Parameters $Parameters) Write-Verbose "Url=$($local:Url)" Write-Verbose "Parameters=$(ConvertTo-Json -InputObject $Parameters)" Invoke-RestMethod -WebSession $SafeguardSpsSession.Session -Method $Method -Headers $Headers -Uri $local:Url } function Invoke-SpsInternal { [CmdletBinding()] Param( [Parameter(Mandatory=$true,Position=0)] [string]$Method, [Parameter(Mandatory=$true,Position=1)] [string]$RelativeUrl, [Parameter(Mandatory=$true,Position=2)] [object]$Headers, [Parameter(Mandatory=$false)] [object]$Body, [Parameter(Mandatory=$false)] [string]$JsonBody, [Parameter(Mandatory=$false)] [HashTable]$Parameters ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } try { switch ($Method.ToLower()) { {$_ -in "get","delete"} { Invoke-SpsWithoutBody $Method $RelativeUrl $Headers -Parameters $Parameters break } {$_ -in "put","post"} { Invoke-SpsWithBody $Method $RelativeUrl $Headers ` -Body $Body -JsonBody $JsonBody -Parameters $Parameters break } } } catch { Import-Module -Name "$PSScriptRoot\sg-utilities.psm1" -Scope Local Out-SafeguardExceptionIfPossible $_ } } <# .SYNOPSIS Log into a Safeguard SPS appliance in this Powershell session for the purposes of using the SPS Web API. .DESCRIPTION This utility can help you securely create a login session with a Safeguard SPS appliance and save it as a global variable. The password may be passed in as a SecureString. By default, this script will securely prompt for the password. .PARAMETER Appliance IP address or hostname of a Safeguard SPS appliance. .PARAMETER Insecure Ignore verification of Safeguard SPS appliance SSL certificate--will be ignored for entire session. .PARAMETER Username The username to authenticate as. .PARAMETER Password SecureString containing the password. .INPUTS None. .OUTPUTS None (with session variable filled out for calling Sps Web API). .EXAMPLE Connect-SafeguardSps 10.5.32.54 admin -Insecure Login Successful. .EXAMPLE Connect-SafeguardSps sps1.mycompany.corp admin Login Successful. #> function Connect-SafeguardSps { [CmdletBinding()] Param( [Parameter(Mandatory=$true,Position=0)] [string]$Appliance, [Parameter(Mandatory=$true,Position=1)] [string]$Username, [Parameter(Mandatory=$false)] [SecureString]$Password, [Parameter(Mandatory=$false)] [switch]$Insecure ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } if (-not $Password) { $Password = (Read-Host "Password" -AsSecureString) } $local:HttpSession = (Connect-Sps -SessionMaster $Appliance -SessionUsername $Username -SessionPassword $Password -Insecure:$Insecure) Set-Variable -Name "SafeguardSpsSession" -Scope Global -Value @{ "Appliance" = $Appliance; "Insecure" = $Insecure; "Session" = $local:HttpSession } Write-Host "Login Successful." } <# .SYNOPSIS Log out of a Safeguard SPS appliance when finished using the SPS Web API. .DESCRIPTION This utility will remove the session variable that was created by the Connect-SafeguardSps cmdlet. .INPUTS None. .OUTPUTS None. .EXAMPLE Disconnect-SafeguardSps Log out Successful. #> function Disconnect-SafeguardSps { [CmdletBinding()] Param( ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } if (-not $SafeguardSpsSession) { Write-Host "Not logged in." } else { Write-Host "Session variable removed." Set-Variable -Name "SafeguardSpsSession" -Scope Global -Value $null } } <# .SYNOPSIS Call a method in the Safeguard SPS Web API. .DESCRIPTION This utility is useful for calling the Safeguard SPS Web API for testing or scripting purposes. It provides a couple benefits over using curl.exe or Invoke-RestMethod by generating or reusing a secure session and composing the Url, headers, parameters, and body for the request. This script is meant to be used with the Connect-SafeguardSps cmdlet which will generate and store a variable in the session so that it doesn't need to be passed to each call to the API. Call Disconnect-SafeguardSps when finished. Safeguard SPS Web API is implemented as HATEOAS. To get started crawling through the API, call Show-SafeguardSpsEndpoint. Then, you can follow to the different API areas, such as configuration or health-status. .PARAMETER Appliance IP address or hostname of a Safeguard appliance. .PARAMETER Method HTTP method verb you would like to use: GET, PUT, POST, DELETE. .PARAMETER RelativeUrl Relative portion of the Url you would like to call starting after /api. .PARAMETER Accept Specify the Accept header (default: application/json), Use text/csv to request CSV output. .PARAMETER ContentType Specify the Content-type header (default: application/json). .PARAMETER Body A hash table containing an object to PUT or POST to the Url. .PARAMETER JsonBody A pre-formatted JSON string to PUT or Post to the URl. If -Body is also specified, this is ignored. It can sometimes be difficult to get arrays of objects to behave properly with hashtables in Powershell. .PARAMETER Parameters A hash table containing the HTTP query parameters to add to the Url. .PARAMETER JsonOutput A switch to return data as pretty JSON string. .PARAMETER BodyOutput A switch to just return the body as a PowerShell object. .INPUTS None. .OUTPUTS JSON response from Safeguard Web API. .EXAMPLE Invoke-SafeguardSpsMethod GET starling/join .EXAMPLE Invoke-SafeguardSpsMethod GET / -JsonOutput .EXAMPLE Open-SafeguardSpsTransaction $body = (Invoke-SafeguardSpsMethod GET configuration/management/email -BodyOutput) $body.admin_address = "admin@mycompany.corp" Invoke-SafeguardSpsMethod PUT configuration/management/email -Body $body Close-SafeguardSpsTransaction #> function Invoke-SafeguardSpsMethod { [CmdletBinding()] Param( [Parameter(Mandatory=$true,Position=0)] [string]$Method, [Parameter(Mandatory=$true,Position=1)] [string]$RelativeUrl, [Parameter(Mandatory=$false)] [string]$Accept = "application/json", [Parameter(Mandatory=$false)] [string]$ContentType = "application/json", [Parameter(Mandatory=$false)] [object]$Body, [Parameter(Mandatory=$false)] [string]$JsonBody, [Parameter(Mandatory=$false)] [HashTable]$Parameters, [Parameter(Mandatory=$false)] [HashTable]$ExtraHeaders, [Parameter(Mandatory=$false)] [switch]$JsonOutput, [Parameter(Mandatory=$false)] [switch]$BodyOutput ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } if (-not $SafeguardSpsSession) { throw "This cmdlet requires that you log in with the Connect-SafeguardSps cmdlet" } $local:Insecure = $SafeguardSpsSession.Insecure Write-Verbose "Insecure=$($local:Insecure)" Import-Module -Name "$PSScriptRoot\sslhandling.psm1" -Scope Local Edit-SslVersionSupport if ($local:Insecure) { Disable-SslVerification if ($global:PSDefaultParameterValues) { $PSDefaultParameterValues = $global:PSDefaultParameterValues.Clone() } } $local:Headers = @{ "Accept" = $Accept; "Content-type" = $ContentType; } foreach ($key in $ExtraHeaders.Keys) { $local:Headers[$key] = $ExtraHeaders[$key] } Write-Verbose "---Request---" Write-Verbose "Headers=$(ConvertTo-Json -InputObject $local:Headers)" try { if ($JsonOutput) { (Invoke-SpsInternal $Method $RelativeUrl $local:Headers ` -Body $Body -JsonBody $JsonBody -Parameters $Parameters) | ConvertTo-Json -Depth 100 } elseif ($BodyOutput) { $local:Response = (Invoke-SpsInternal $Method $RelativeUrl $local:Headers -Body $Body -JsonBody $JsonBody -Parameters $Parameters) if ($local:Response.body) { $local:Response.body } else { Write-Verbose "No body returned in response" } } else { Invoke-SpsInternal $Method $RelativeUrl $local:Headers -Body $Body -JsonBody $JsonBody -Parameters $Parameters } } finally { if ($local:Insecure) { Enable-SslVerification if ($global:PSDefaultParameterValues) { $PSDefaultParameterValues = $global:PSDefaultParameterValues.Clone() } } } } <# .SYNOPSIS Open a transaction for making changes via the Safeguard SPS Web API. .DESCRIPTION This cmdlet is used to create a transaction necessary to make changes via the Safeguard SPS API. Recent versions of SPS will open a transaction automatically, but this cmdlet may be used to open a transaction explicitly. In order to permanently save changes made via the Safeguard SPS API, you must also call Close-SafeguardSpsTransaction or its alias Save-SafeguardSpsTransaction. Clear-SafeguardSpsTransaction can be used to cancel changes. .INPUTS None. .OUTPUTS JSON response from Safeguard Web API. .EXAMPLE Open-SafeguardSpsTransaction $body = (Invoke-SafeguardSpsMethod GET configuration/management/email -BodyOutput) $body.admin_address = "admin@mycompany.corp" Invoke-SafeguardSpsMethod PUT configuration/management/email -Body $body Close-SafeguardSpsTransaction #> function Open-SafeguardSpsTransaction { [CmdletBinding()] Param( ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } Invoke-SafeguardSpsMethod POST transaction } <# .SYNOPSIS Close a transaction and save changes made via the Safeguard SPS Web API. .DESCRIPTION This cmdlet is used to end a transaction and permanently save the changes made via the Safeguard SPS API. This cmdlet is meant to be used with Open-SafeguardSpsTransaction. Save-SafeguardSpsTransaction is an alias for this cmdlet. Clear-SafeguardSpsTransaction can be used to cancel changes. To see the status of a transaction, use Get-SafeguardSpsTransaction. To see only the changes that are about to be made via a transaction, use Show-SafeguardSpsTransactionChange. .INPUTS None. .OUTPUTS JSON response from Safeguard Web API. .EXAMPLE Open-SafeguardSpsTransaction $body = (Invoke-SafeguardSpsMethod GET configuration/management/email -BodyOutput) $body.admin_address = "admin@mycompany.corp" Invoke-SafeguardSpsMethod PUT configuration/management/email -Body $body Close-SafeguardSpsTransaction #> function Close-SafeguardSpsTransaction { [CmdletBinding()] Param( ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } Invoke-SafeguardSpsMethod PUT transaction -Body @{ status = "commit" } } New-Alias -Name Save-SafeguardSpsTransaction -Value Close-SafeguardSpsTransaction <# .SYNOPSIS Get the status of a transaction using the Safeguard SPS Web API. .DESCRIPTION This cmdlet will report the status of an SPS transaction. The status 'closed' means no transaction is pending. The status 'open' means the transaction is pending. Close-SafeguardSpsTransaction can be used to permanently save changes. Clear-SafeguardSpsTransaction can be used to cancel changes. The remaining seconds is the time before the transaction will cancel automatically and the login session will be terminated. .INPUTS None. .OUTPUTS JSON response from Safeguard Web API. .EXAMPLE Open-SafeguardSpsTransaction $body = (Invoke-SafeguardSpsMethod GET configuration/management/email -BodyOutput) $body.admin_address = "admin@mycompany.corp" Invoke-SafeguardSpsMethod PUT configuration/management/email -Body $body Get-SafeguardSpsTransaction Clear-SafeguardSpsTransaction #> function Get-SafeguardSpsTransaction { [CmdletBinding()] Param( ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } $local:response = (Invoke-SafeguardSpsMethod GET transaction) $local:TransactionInfo = [ordered]@{ Status = $local:response.body.status; CommitMessage = $local:response.body.commit_message; RemainingSeconds = $local:response.meta.remaining_seconds; Changes = @() } if ($local:response.meta.changes) { $local:Changes = (Invoke-SafeguardSpsMethod GET transaction/changes).changes if ($local:Changes) { $local:TransactionInfo.Changes = $local:Changes } } New-Object PSObject -Property $local:TransactionInfo } <# .SYNOPSIS Show the pending changes in a transaction using the Safeguard SPS Web API. .DESCRIPTION Transactions are required to make changes via the Safeguard SPS Web API. The transaction must be closed or saved before changes become permanent. This cmdlet will show what values will be permanently changed if the transaction is closed. .INPUTS None. .OUTPUTS JSON response from Safeguard Web API. .EXAMPLE Open-SafeguardSpsTransaction $body = (Invoke-SafeguardSpsMethod GET configuration/management/email -BodyOutput) $body.admin_address = "admin@mycompany.corp" Invoke-SafeguardSpsMethod PUT configuration/management/email -Body $body Show-SafeguardSpsTransactionChange #> function Show-SafeguardSpsTransactionChange { [CmdletBinding()] Param( ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } (Get-SafeguardSpsTransaction).Changes | ConvertTo-Json -Depth 100 } <# .SYNOPSIS Cancel a transaction using the Safeguard SPS Web API. .DESCRIPTION Transactions are required to make changes via the Safeguard SPS Web API. The transaction must be closed or saved before changes become permanent. This cmdlet may be used to cancel pending changes. .INPUTS None. .OUTPUTS JSON response from Safeguard Web API. .EXAMPLE Open-SafeguardSpsTransaction $body = (Invoke-SafeguardSpsMethod GET configuration/management/email -BodyOutput) $body.admin_address = "admin@mycompany.corp" Invoke-SafeguardSpsMethod PUT configuration/management/email -Body $body Get-SafeguardSpsTransaction Clear-SafeguardSpsTransaction #> function Clear-SafeguardSpsTransaction { [CmdletBinding()] Param( ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } Invoke-SafeguardSpsMethod DELETE transaction } <# .SYNOPSIS Call a method in the Safeguard SPS Web API. .DESCRIPTION Safeguard SPS Web API is implemented as HATEOAS. This cmdlet is helpful for crawling through the API. You can explore the different API areas, such as configuration or health-status. .PARAMETER RelativeUrl Relative portion of the Url you would like to call starting after /api. .EXAMPLE Show-SafeguardSpsEndpoint configuration .EXAMPLE Show-SafeguardSpsEndpoint configuration/ssh/connections #> function Show-SafeguardSpsEndpoint { [CmdletBinding()] Param( [Parameter(Mandatory=$false,Position=0)] [string]$RelativeUrl ) if (-not $PSBoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" } if (-not $PSBoundParameters.ContainsKey("Verbose")) { $VerbosePreference = $PSCmdlet.GetVariableValue("VerbosePreference") } if (-not $RelativeUrl) { $RelativeUrl = "/" } $local:Response = (Invoke-SafeguardSpsMethod GET $RelativeUrl) if ($local:Response.items) { $local:Response.items | Select-Object key,meta } else { $local:Response.meta.href } } |