public/Invoke-RSQuery.ps1
function Invoke-RSQuery { <# .SYNOPSIS Invokes a synchronous RedSeal query .OUTPUTS One or more query result pairs .PARAMETER SourceSubnet Source subnet for detailed queries .PARAMETER DestinationSUbnet Destination subnet for detailed queries .PARAMETER DestinationIPs Destination IPs .PARAMETER SourceIPs Source IPs .PARAMETER QueryType Either Access, Threat, Impact, or Path query type. Defaults to access. .PARAMETER XML Switch flag (T/F) to indicate returning raw XML is desired instead of parsed objects #> [cmdletbinding(DefaultParameterSetName='DetailedQuery')] Param( [Parameter(ParameterSetName='DetailedQuery', Mandatory = $false, ValueFromPipeline = $true, Position = 0)] [String] $SourceSubnet = "4028aa8f2f63ce90012f63d85f6600de", [Parameter(ParameterSetName='DetailedQuery', Mandatory = $false, valueFromPipeline = $true, Position = 1)] [String] $DestinationSubnet = $null, [Parameter(ParameterSetName = 'DetailedQuery', Mandatory = $false)] [String] $SourceIPs, [Parameter(ParameterSetName = 'DetailedQuery', Mandatory = $false)] [String] $DestinationIPs, [Parameter(ParameterSetName = 'TargetObject', Mandatory = $false, valueFromPipeline = $true, Position = 1)] [PSCustomObject[]] $SourceTarget, [Parameter(ParameterSetName = 'TargetObject', Mandatory = $false, valueFromPipeline = $true, Position = 2)] [PSCustomObject[]] $DestinationTarget, [Parameter(Mandatory = $false)] [ValidateSet('Access', 'Threat', 'Path', 'Impact')] [String] $QueryType = "Access", [Parameter(Mandatory = $false)] [Switch] $XML, [Parameter(Mandatory = $false)] [Int] $TimeoutSec = 60*6 ) begin { $uriPath = switch ($QueryType.ToLower()) { "Access" {"access"} "Threat" {"threats"} "Impact" {"impact"} "Path" {"path"} default {"access"} } } process { $accessXml = New-Object XML $e = $accessxml.CreateElement("Query") $accessXml.AppendChild($e) | Out-Null $e = $accessxml.CreateElement("Name") $e.innertext = "RS PoSH Query" $accessXml.SelectSingleNode("/Query").AppendChild($e) | Out-Null switch ($PSCmdlet.ParameterSetName) { 'DetailedQuery' { $accessXml.Query.Sources.Targets.target.type="Subnet" #if ($PSBoundParameters.ContainsKey("SourceSubnet")) { $accessXml.Query.Sources.Targets.target.id = $SourceSubnet #} else { #$accessXml.Query.Sources.Targets.target.id = "" #} if ($PSBoundParameters.ContainsKey("SourceIPs")) { $accessXml.Query.Sources.IPs = $SourceIPs } else { $accessXml.Query.Sources.IPs = "" } $accessXml.Query.Sources.Restrict = "NONE" $accessXml.Query.Destinations.Targets.target.type="AllSubnets" if ($PSBoundParameters.ContainsKey("Destinationubnet")) { $accessXml.Query.Destinations.Targets.target.id = $DestinationSubnet } else { $accessXml.Query.Destinations.Targets.target.id = "" } if ($PSBoundParameters.ContainsKey("DestinationIPs")) { $accessXml.Query.Destinations.IPs = $DestinationIPs } else { $accessXml.Query.Destinations.IPs = "" } $accessXml.Query.Destinations.Restrict = "NONE" } 'TargetObject' { $e = $accessXml.CreateElement("Protocol") $e.InnerText = $DestinationTarget.Protocols $accessXml.SelectSingleNode("/Query").AppendChild($e) | Out-Null #Create source targets XML stanzas $e = $accessXml.CreateElement("Sources") $accessXml.SelectSingleNode("/Query").AppendChild($e) | Out-Null $e = $accessXml.CreateElement("Targets") $accessXml.SelectSingleNode("/Query/Sources").AppendChild($e) | Out-Null foreach ($s in $SourceTarget) { $e = $accessXml.CreateElement("Target") $accessXml.Query.SelectSingleNode("/Query/Sources/Targets[last()]").AppendChild($e) | Out-Null $e = $accessXml.CreateElement("Type") $e.InnerText = $s.Type $accessXml.SelectSingleNode("/Query/Sources/Targets/Target[last()]").AppendChild($e) | Out-Null $e = $accessXml.CreateElement("ID") $e.InnerText = $s.id $accessXml.SelectSingleNode("/Query/Sources/Targets/Target[last()]").AppendChild($e) | Out-Null } #set source clause specific options $e = $accessXml.CreateElement("IPs") $e.InnerText = $sourceTarget.IPs | Sort | Unique $accessXml.SelectSingleNode("/Query/Sources").AppendChild($e) | Out-Null $e = $accessXml.CreateElement("Restrict") $e.InnerText = "NONE" $accessXml.SelectSingleNode("/Query/Sources").AppendChild($e) | Out-Null #Create Destination targets $e = $accessXml.CreateElement("Destinations") $accessXml.SelectSingleNode("/Query").AppendChild($e) | Out-Null $e = $accessXml.CreateElement("Targets") $accessXml.SelectSingleNode("/Query/Destinations").AppendChild($e) | Out-Null foreach ($d in $destinationTarget) { $e = $accessXml.CreateElement("Target") $accessXml.SelectSingleNode("/Query/Destinations/Targets[last()]").AppendChild($e) | Out-Null $e = $accessXml.CreateElement("ID") $e.InnerText = $d.id $accessXml.SelectSingleNode("/Query/Destinations/Targets/Target[last()]").AppendChild($e) | Out-Null $e = $accessXml.CreateElement("Type") $e.InnerText = $d.Type $accessXml.SelectSingleNode("/Query/Destinations/Targets/Target[last()]").AppendChild($e) | Out-Null } #set destination clause specific options $e = $accessXml.CreateElement("Ports") $e.InnerText = $DestinationTarget.Ports $accessXml.SelectSingleNode("/Query/Destinations").AppendChild($e) | Out-Null $e = $accessXml.CreateElement("IPs") $e.InnerText = $DestinationTarget.IPs $accessXml.SelectSingleNode("/Query/Destinations").AppendChild($e) | Out-Null $e = $accessXml.CreateElement("Restrict") $e.InnerText = "NONE" $accessXml.SelectSingleNode("/Query/Destinations").AppendChild($e) | Out-Null } } #set the body of the HTTP put $respBody = $($accessXml.InnerXML.ToString().Replace("><",">`r`n<")) Write-Verbose "Query put body is: $respBody" $uri = "https://$script:server/data/$uripath" Write-Verbose "URI is $uri" #finally, try to execute the query try { #$resultXml = Invoke-RestMethod -uri $uri -Credential $script:Credentials -Method Put -Body $respBody -TimeoutSec $timeoutSec -DisableKeepAlive $resultXml = Send-RSRequest -uri $uri -Method Put -Body $respBody -TimeoutSec $timeoutSec } catch { throw $_.Exception.Message } Write-Debug $resultXml.innerxml.tostring() if ($XML) { $resultXml } else { switch ($QueryType) { "Access" { Read-RSAccessResult -RawXML $resultXml } "Threat" { Read-RSThreatResult -RawXML $resultXml } "Path" { Read-RSPathResult -RawXML $resultXml } "Impact" { Read-RSImpactResult -RawXML $resultXml } } } } } |