BurpSuite.psm1

using namespace System.IO
using namespace System.Collections
using namespace System.Collections.Generic
using namespace System.Management.Automation

[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13

function _getPowerShellVersion {
    param (
    )

    return $PSVersionTable.PSVersion
}

function _testIsPowerShellCore {
    param (
    )

    if ((_getPowerShellVersion).Major -ge 6) {
        return $true
    }

    return $false
}

if (-not (_testIsPowerShellCore)) {
    [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
}

function _registerAccelerators {
    param (
    )

    [ReflectionCache]::TypeAccelerators::Add(
        'BurpSuiteRequest',
        [Request])
}
_registerAccelerators

$ExecutionContext.SessionState.Module.OnRemove = {
    _uregisterAccelerators
}

class Exception : System.Exception {
    Exception(
        [string]$Message
    ) : base($Message) {
    }
}

class Query {
    [string] $Name
    [string] $AliasName
    [Dictionary[string, object]] $Arguments = [Dictionary[string, object]]::new()
    [List[object]] $Fields = [List[object]]::new()

    hidden [QueryStringBuilder] $QueryStringBuilder = [QueryStringBuilder]::new()

    Query([String] $newName) {
        $this.Name = $newName
    }

    [void] SetAlias([string] $alias) {
        $this.AliasName = $alias
    }

    [string] Build() {
        $this.QueryStringBuilder.Clear()
        return $this.QueryStringBuilder.Build($this)
    }

    [void] AddArgument([string] $key, [object] $value) {
        $this.Arguments.Add($key, $value)
    }

    [void] AddField([object] $field) {
        $this.Fields.Add($field)
    }

    [void] AddFields([object[]] $fields) {
        foreach ($field in $fields) { $this.Fields.Add($field) }
    }

    [string] ToString() { return $this.Build() }
}

class QueryStringBuilder {
    hidden [System.Text.StringBuilder] $QueryString = [System.Text.StringBuilder]::new()

    QueryStringBuilder() {
    }

    [void] Clear() {
        $this.QueryString.Clear()
    }

    hidden [string] FormatQueryParam([object] $value) {
        switch ($value) {
            { $_ -is [string] } { return "'" + $value + "'" }
            { $_ -is [byte] } { return $value.ToString() }
            { $_ -is [sbyte] } { return $value.ToString() }
            { $_ -is [int16] } { return $value.ToString() }
            { $_ -is [uint16] } { return $value.ToString() }
            { $_ -is [int] } { return $value.ToString() }
            { $_ -is [uint64] } { return $value.ToString() }
            { $_ -is [int64] } { return $value.ToString() }
            { $_ -is [float] } { return $value.ToString([CultureInfo]::CreateSpecificCulture("en-us")) }
            { $_ -is [double] } { return $value.ToString([CultureInfo]::CreateSpecificCulture("en-us")) }
            { $_ -is [decimal] } { return $value.ToString([CultureInfo]::CreateSpecificCulture("en-us")) }
            { $_ -is [bool] } { return @{$true = "true"; $false = "false" }[$value] }
            { $_ -is [enum] } { return $value.ToString() }
            { $_ -is [KeyValuePair[string, object]] } { return "$($value.Key):$($this.FormatQueryParam($value.Value))" }
            { $_ -is [IDictionary[string, object]] } { return "{$(@($value.GetEnumerator() | ForEach-Object { $this.FormatQueryParam($_) }) -join ", ")}" }
            { $_ -is [IEnumerable] } {
                $items = [System.Collections.Generic.List[string]]::new()
                foreach ($item in $_.GetEnumerator()) {
                    $items.Add($this.FormatQueryParam($item))
                }
                return "[$($items -join ",")]"
            }
            default {
                throw ([InvalidDataException]::new("Unsupported query parameter, type found: " + $value.GetType()))
            }
        }
        throw ([InvalidDataException]::new("Unsupported query parameter, type found: " + $value.GetType()))
    }

    hidden [void] AddParams([Query] $query) {
        foreach ($param in $query.Arguments.GetEnumerator()) {
            $this.QueryString.Append("$($param.Key):$($this.FormatQueryParam($param.Value)),")
        }

        if ($query.Arguments.Count -gt 0) { $this.QueryString.Length-- }
    }

    hidden [void] AddFields([Query] $query) {
        foreach ($item in $query.Fields.GetEnumerator()) {
            switch ($item) {
                { $_ -is [string] } { $this.QueryString.Append("$item ") }
                { $_ -is [Query] } { $this.QueryString.Append("$($item.Build()) ") }
                default {
                    throw ([ArgumentException]::new("Invalid field type specified, must be 'string' or 'Query'"))
                }
            }
        }
        if ($query.Fields.Count -gt 0) { $this.QueryString.Length-- }
    }

    [string] Build([Query] $query) {
        if (![string]::IsNullOrEmpty($query.AliasName)) { $this.QueryString.Append("$($query.AliasName):") }

        $this.QueryString.Append($query.Name)

        if ($query.Arguments.Count -gt 0) {
            $this.QueryString.Append("(")
            $this.AddParams($query)
            $this.QueryString.Append(")")
        }

        if ($query.Fields.Count -gt 0) {
            $this.QueryString.Append(" { ")
            $this.AddFields($query)
            $this.QueryString.Append(" }")
        } else { $this.AddFields($query) }

        return $this.QueryString.ToString()
    }
}

class ReflectionCache {
    static [type] $TypeAccelerators = [ref].Assembly.GetType('System.Management.Automation.TypeAccelerators')
}

class Request {
    [string] $Query = [string]::Empty
    [string] $OperationName = [string]::Empty
    [hashtable] $Variables = @{}

    Request() {
    }

    Request([string] $query) {
        $this.Query = $Query
    }

    Request([string] $query, [string] $operationName) {
        $this.Query = $Query
        $this.OperationName = $operationName
    }

    Request([string] $query, [hashtable] $variables) {
        $this.Query = $Query
        $this.Variables = $Variables
    }

    Request([string] $query, [string] $operationName, [hashtable] $variables) {
        $this.Query = $Query
        $this.OperationName = $operationName
        $this.Variables = $Variables
    }
}

class Session {
    static [string] $APIKey
    static [string] $APIUrl

    static [void] Create([string] $APIKey, [string] $APIUrl) {
        [Session]::APIKey = $APIKey
        [Session]::APIUrl = $APIUrl
    }

    static [void] Dispose() {
        [Session]::APIKey = $null
        [Session]::APIUrl = $null
    }
}

function _createSession {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $APIUrl,

        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $APIKey
    )

    [Session]::Create($APIKey, $APIUrl)
}

function _callAPI {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true)]
        [ValidateNotNull()]
        [object]
        $Request
    )

    _assertAPIKey
    _assertAPIUrl

    $params = @{ }

    $params['uri'] = [Session]::APIUrl
    $params['method'] = 'Post'

    $params['headers'] = @{ }

    $params['headers']['authorization'] = [Session]::APIKey
    $params['headers']['content-type'] = 'application/json'
    $params['headers']['accept'] = 'application/json'

    $convertToJsonArgs = @{}
    if (_testIsPowerShellCore) { $convertToJsonArgs['Compress'] = $true }

    $body = _preProcessRequest -Request $Request | ConvertTo-Json @convertToJsonArgs -Depth 5

    $params['body'] = $body
    Write-Verbose $body

    if (_testIsPowerShellCore) { $params.Add('SkipCertificateCheck', $true) }

    $response = Invoke-RestMethod @params
    if ((_testObjectProperty -InputObject $response -PropertyName 'errors')) {
        $exceptions = @()
        foreach ($e in $response.errors) { $exceptions += [Exception]::New($e.message) }
        $aggregate = [AggregateException]::new("One or more errors occurred while querying BurpSuite.", $exceptions)
        throw $aggregate
    } else {
        Write-Verbose $($response | ConvertTo-Json)
        $response
    }
}

function _removeSession {
    [CmdletBinding()]
    Param (
    )

    [Session]::Dispose()
}

function _assertAPIKey {
    param (
    )

    if (-not [Session]::APIKey) {
        $e = [Exception]::New('You must call Connect-BurpSuite before calling any other function in this module.')
        throw $e
    }
}

function _assertAPIUrl {
    param (
    )

    if (-not [Session]::APIUrl) {
        $e = [Exception]::New('You must call Connect-BurpSuite before calling any other function in this module.')
        throw $e
    }
}

function _uregisterAccelerators {
    param (
    )

    [ReflectionCache]::TypeAccelerators::Remove(
        'BurpSuiteRequest')
}

function _preProcessRequest {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true)]
        [ValidateNotNull()]
        [Alias('Request')]
        [object]
        $InputObject
    )

    $properties = @{}
    $InputObject | Get-Member -MemberType Properties | ForEach-Object {
        $propertyName = $_.Name
        $propertyValue = $InputObject.$propertyName
        switch ($propertyValue) {
            { $_ -is [IEnumerable] -or $_ -is [IDictionary] } {
                if ($propertyValue.Count -gt 0) {
                    $properties[$propertyName.ToLowerInvariant()] = $propertyValue
                }
            }
            default {
                if ($null -ne $propertyValue) {
                    $properties[$propertyName.ToLowerInvariant()] = $propertyValue
                }
            }
        }
    }
    [PSCustomObject]$properties
}

function _buildMutation {
    param([string]$queryName, [string]$inputType, [string]$name, [string]$returnType, [switch]$returnTypeField)

    $query = [Query]::New($queryName)

    $query.AddArgument('$input', $inputType)

    switch ($returnType) {
        ScanConfiguration { $fieldName = 'scan_configuration' }
        ScheduleItem { $fieldName = 'schedule_item' }
        Scan { $fieldName = 'scan' }
        Agent { $fieldName = 'agent' }
        Id { $fieldName = 'Id' }
        Folder { $fieldName = 'folder' }
        Site { $fieldName = 'site' }
        ApplicationLogin { $fieldName = 'application_login' }
        EmailRecipient { $fieldName = 'email_recipient' }
        Scope { $fieldName = 'scope' }
        default {}
    }

    if ($returnTypeField.IsPresent) {
        $subQuery = _buildField -name $name -objectType $returnType
        $subQuery.AddArgument('input', '$input')
    } else {
        $subQuery = [Query]::new($name)
        $subQuery.AddArgument('input', '$input')
        $subQuery.AddField((_buildField -name $fieldName -objectType $returnType))
    }

    $query.AddField($subQuery)

    return ('mutation {0}' -f $query)
}

function _buildField {
    param([string]$name, [string]$objectType)

    $query = [Query]::New($name)

    $fields = @()

    switch ($objectType) {
        Id { $fields = 'id' }
        Agent { $fields = 'id', 'name' }
        AgentError { $fields = 'code', 'error' }
        ApplicationLogin { $fields = 'id', 'label', 'username' }
        AuditItem { $fields = 'id', 'host', 'path', 'error_types', (_buildField -name 'issue_counts' -objectType 'IssueCounts'), 'number_of_requests', 'number_of_errors', 'number_of_insertion_points', (_buildField -name 'issue_types' -objectType 'IssueType') }
        CountsByConfidence { $fields = 'total', 'firm', 'tentative', 'certain' }
        DataSegment { $fields = 'data_html' }
        DescriptiveEvidence { $fields = 'title', 'description_html' }
        EmailRecipient { $fields = 'id', 'email' }
        Folder { $fields = 'id', 'name', 'parent_id' }
        HighlightSegment { $fields = 'highlight_html' }
        HttpInteraction { $fields = 'title', 'description_html', 'request', 'response' }
        Issue { $fields = 'confidence', 'serial_number', 'severity', 'novelty' }
        IssueCounts { $fields = 'total', (_buildField -name 'high' -objectType 'CountsByConfidence'), (_buildField -name 'medium' -objectType 'CountsByConfidence'), (_buildField -name 'low' -objectType 'CountsByConfidence'), (_buildField -name 'info' -objectType 'CountsByConfidence') }
        IssueType { $fields = 'type_index', 'confidence', 'severity', 'number_of_children', 'first_child_serial_number', 'novelty' }
        JiraTicket { $fields = 'id', 'external_key', 'issue_type', 'summary', 'project', 'status', 'priority' }
        Request { $fields = 'request_index', 'request_count', 'request_segments' }
        Response { $fields = 'response_index', 'response_count', 'response_segments' }
        Scan { $fields = 'id' }
        ScanConfiguration { $fields = 'id' }
        ScanCountsByStatus { $fields = 'scheduled', 'queued', 'running', 'succeeded', 'cancelled', 'failed' }
        ScanDelta { $fields = 'new_issue_count', 'repeated_issue_count', 'regressed_issue_count', 'resolved_issue_count' }
        ScanProgressMetrics { $fields = 'crawl_request_count', 'unique_location_count', 'audit_request_count', 'crawl_and_audit_progress_percentage' }
        Schedule { $fields = 'initial_run_time', 'rrule' }
        ScheduleItem { $fields = 'id' }
        Scope { $fields = 'included_urls', 'excluded_urls' }
        Site { $fields = 'id', 'name', 'parent_id', (_buildField -name 'scope' -objectType 'Scope'), (_buildField -name 'scan_configurations' -objectType 'ScanConfiguration'), (_buildField -name 'application_logins' -objectType 'ApplicationLogin'), 'ephemeral', (_buildField -name 'email_recipients' -objectType 'EmailRecipient') }
        SiteTree { $fields = (_buildField -name 'folders' -objectType 'Folder'), (_buildField -name 'sites' -objectType 'Site') }
        SnipSegment { $fields = 'snip_length' }
        Ticket { $fields = (_buildField -name 'jira_ticket' -objectType 'JiraTicket'), 'link_url', 'link_id' }
        User { $fields = 'username' }
        QueryType { $fields = 'name' }
        MutationType { $fields = 'name' }
        FalsePositive { $fields = 'successful' }
    }

    $query.AddFields($fields)

    return $query
}


function _buildQuery {
    param([string]$name, [string]$alias = "", [string]$objectType, [string[]]$fields, [hashtable]$arguments)

    $query = [Query]::New($name)

    if (-not ([string]::IsNullOrEmpty($alias))) { $query.SetAlias($alias) }

    switch ($objectType) {
        Agent {
            $fields | Where-Object { $_ -ne 'error' } | ForEach-Object { $query.AddField($_) }
            if ($fields -contains 'error') { $query.AddField((_buildField -name 'error' -objectType 'AgentError')) }
        }

        Scan {
            $subFields = 'schedule_item', 'agent', 'scan_metrics', 'scan_configurations', 'scan_delta', 'issue_types', 'issue_counts', 'audit_items', 'audit_item', 'scope', 'site_application_logins', 'schedule_item_application_logins', 'issues'
            $fields | Where-Object { $_ -notin $subFields } | ForEach-Object { $query.AddField($_) }

            if ($fields -contains 'schedule_item') { $query.AddField((_buildField -name 'schedule_item' -objectType 'ScheduleItem')) }
            if ($fields -contains 'agent') { $query.AddField((_buildField -name 'agent' -objectType 'Agent')) }
            if ($fields -contains 'scan_metrics') { $query.AddField((_buildField -name 'scan_metrics' -objectType 'ScanProgressMetrics')) }
            if ($fields -contains 'generated_by') { $query.AddField((_buildField -name 'generated_by' -objectType 'GeneratedBy')) }
            if ($fields -contains 'scan_configurations') { $query.AddField((_buildField -name 'scan_configurations' -objectType 'ScanConfiguration')) }
            if ($fields -contains 'scan_delta') { $query.AddField((_buildField -name 'scan_delta' -objectType 'ScanDelta')) }
            if ($fields -contains 'issue_types') { $query.AddField((_buildField -name 'issue_types' -objectType 'IssueType')) }
            if ($fields -contains 'issue_counts') { $query.AddField((_buildField -name 'issue_counts' -objectType 'IssueCounts')) }
            if ($fields -contains 'audit_item') { $query.AddField((_buildField -name 'audit_item' -objectType 'AuditItem')) }
            if ($fields -contains 'scope') { $query.AddField((_buildField -name 'scope' -objectType 'Scope')) }
            if ($fields -contains 'audit_items') { $query.AddField((_buildField -name 'audit_items' -objectType 'AuditItem')) }
            if ($fields -contains 'site_application_logins') { $query.AddField((_buildField -name 'site_application_logins' -objectType 'ApplicationLogin')) }
            if ($fields -contains 'schedule_item_application_logins') { $query.AddField((_buildField -name 'schedule_item_application_logins' -objectType 'ApplicationLogin')) }
            if ($fields -contains 'issues') { $query.AddField((_buildField -name 'issues' -objectType 'Issue')) }
        }

        Issue {
            $fields | Where-Object { $_ -ne 'tickets' } | ForEach-Object { $query.AddField($_) }
            if ($fields -contains 'tickets') { $query.AddField((_buildField -name 'tickets' -objectType 'Ticket')) }
        }

        ScanConfiguration {
            $fields | Where-Object { $_ -ne 'last_modified_by' } | ForEach-Object { $query.AddField($_) }
            if ($fields -contains 'last_modified_by') { $query.AddField((_buildField -name 'last_modified_by' -objectType 'User')) }
        }

        ScanReport {
            $query.AddField('report_html')
        }

        ScheduleItem {
            $subFields = 'site', 'schedule', 'scan_configurations'
            $fields | Where-Object { $_ -notin $subFields } | ForEach-Object { $query.AddField($_) }
            if ($fields -contains 'site') { $query.AddField((_buildField -name 'site' -objectType 'Site')) }
            if ($fields -contains 'schedule') { $query.AddField((_buildField -name 'schedule' -objectType 'Schedule')) }
            if ($fields -contains 'scan_configurations') { $query.AddField((_buildField -name 'scan_configurations' -objectType 'ScanConfiguration')) }
        }

        SiteTree {
            if ($fields -contains 'folders') { $query.AddField((_buildField -name 'folders' -objectType 'Folder')) }
            if ($fields -contains 'sites') { $query.AddField((_buildField -name 'sites' -objectType 'Site')) }
        }

        UnauthorizedAgent {
            $fields | ForEach-Object { $query.AddField($_) }
        }

        Schema {
            $query.AddField((_buildField -name 'queryType' -objectType 'QueryType'))
            $query.AddField((_buildField -name 'mutationType' -objectType 'MutationType'))
        }

        default {}
    }

    if ($null -ne $arguments) { foreach ($k in ($arguments.Keys | Sort-Object)) { $query.AddArgument($k, $arguments[$k]) } }

    return ('query {{ {0} }}' -f $query)
}
function _testObjectProperty {
    param(
        [object] $InputObject,
        [string] $PropertyName
    )

    return ((@($InputObject.PSObject.Properties.Match($PropertyName)).Count -gt 0) -and ($null -ne $InputObject.$PropertyName))
}

function _getObjectProperty {
    param(
        [object] $InputObject,
        [string] $PropertyName
    )

    if ((_testObjectProperty -InputObject $InputObject -PropertyName $PropertyName)) {
        return $InputObject.$PropertyName
    }

    return $null
}
function Connect-BurpSuite {
    [CmdletBinding(SupportsShouldProcess = $true,
        ConfirmImpact = 'Low')]
    [Alias('Login-BurpSuite')]
    Param (
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Uri,

        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $APIKey,

        [Parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [switch]
        $PassThru
    )

    begin {
        $uriBuilder = New-Object -TypeName System.UriBuilder -ArgumentList $Uri
        $uriBuilder.Path = '/graphql/v1'

        $apiUrl = $uriBuilder.ToString()
    }

    process {
        $query = _buildQuery -name '__schema' -objectType 'Schema'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                _createSession -APIUrl $apiUrl -APIKey $APIKey
                $request = [Request]::new($query)
                $response = _callAPI -Request $Request
                if ($PassThru.IsPresent) {
                    $data = _getObjectProperty -InputObject $response -PropertyName 'data'
                    $data
                }
            } catch {
                _removeSession
                $e = [Exception]::new("Cannot access BurpSuite API using key $APIKey and Uri $Uri")
                throw $e
            }
        }
    }

    end {
    }
}
function Disable-BurpSuiteAgent {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Id
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'EnableAgent' -inputType 'EnableAgentInput!' -name 'enable_agent' -returnType 'Agent'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.id = $Id
                $variables.input.enabled = "false"

                $request = [Request]::new($query, 'EnableAgent', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Disconnect-BurpSuite {
    [CmdletBinding()]
    Param (
    )

    begin {
    }

    process {
        _removeSession
    }

    end {
    }
}
function Enable-BurpSuiteAgent {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Id
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'EnableAgent' -inputType 'EnableAgentInput!' -name 'enable_agent' -returnType 'Agent'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.id = $Id
                $variables.input.enabled = "true"

                $request = [Request]::new($query, 'EnableAgent', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Get-BurpSuiteAgent {
    [CmdletBinding(DefaultParameterSetName = 'List',
        SupportsShouldProcess = $true,
        ConfirmImpact = 'Low')]
    Param (
        [Parameter(Mandatory = $false)]
        [ValidateSet('id', 'machine_id', 'current_scan_count', 'ip', 'name', 'state', 'error', 'enabled', 'max_concurrent_scans')]
        [string[]]
        $Fields,

        [Parameter(Mandatory = $false,
            ParameterSetName = 'Specific')]
        [ValidateNotNullOrEmpty()]
        [string]
        $Id
    )

    begin {
        if (-not ($PSBoundParameters.ContainsKey('Fields'))) { $Fields = 'id', 'name', 'state', 'enabled' }
    }

    process {

        if ($PSCmdlet.ParameterSetName -eq 'List') {
            $query = _buildQuery -name 'agents' -objectType 'Agent' -fields $Fields -arguments @{}
        } else {
            $query = _buildQuery -name 'agent' -alias 'agents' -objectType 'Agent' -fields $Fields -arguments @{id = $Id }
        }

        $request = [Request]::new($query)

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $response = _callAPI -Request $request

                $data = _getObjectProperty -InputObject $response -PropertyName 'data'
                if ($null -ne $data) {
                    $data.agents
                }
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Get-BurpSuiteIssue {
    [CmdletBinding(SupportsShouldProcess = $true,
        ConfirmImpact = 'Low')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $ScanId,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $SerialNumber,

        [Parameter(Mandatory = $false)]
        [ValidateSet('confidence', 'display_confidence', 'serial_number', 'severity', 'description_html',
            'remediation_html', 'type_index', 'path', 'origin', 'novelty', 'evidence', 'tickets')]
        [string[]]
        $Fields
    )

    begin {
        if (-not ($PSBoundParameters.ContainsKey('Fields'))) { $Fields = 'confidence', 'serial_number', 'severity', 'novelty' }
    }

    process {
        $arguments = @{}
        $arguments.scan_id = $ScanId
        $arguments.serial_number = $SerialNumber
        $query = _buildQuery -name 'issue' -objectType 'Issue' -fields $Fields -arguments $arguments

        $request = [Request]::new($query)

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $response = _callAPI -Request $request
                $data = _getObjectProperty -InputObject $response -PropertyName 'data'
                if ($null -ne $data) {
                    $data.issue
                }
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Get-BurpSuiteScan {
    [CmdletBinding(DefaultParameterSetName = 'List',
        SupportsShouldProcess = $true,
        ConfirmImpact = 'Low')]
    Param (
        [Parameter(Mandatory = $true,
            ParameterSetName = 'Specific')]
        [ValidateNotNullOrEmpty()]
        [string]
        $Id,

        [Parameter(Mandatory = $false,
            ParameterSetName = 'List')]
        [ValidateNotNullOrEmpty()]
        [int]
        $Offset,

        [Parameter(Mandatory = $false,
            ParameterSetName = 'List')]
        [ValidateNotNullOrEmpty()]
        [int]
        $Limit,

        [Parameter(Mandatory = $false,
            ParameterSetName = 'List')]
        [ValidateSet('start', 'end', 'status', 'site', 'id')]
        [string]
        $SortColumn,

        [Parameter(Mandatory = $false,
            ParameterSetName = 'List')]
        [ValidateSet('asc', 'desc')]
        [string]
        $SortOrder,

        [Parameter(Mandatory = $false,
            ParameterSetName = 'List')]
        [ValidateSet('queued', 'running', 'succeeded', 'cancelled', 'failed')]
        [string[]]
        $ScanStatus,

        [Parameter(Mandatory = $false)]
        [ValidateSet('id', 'schedule_item', 'site_id', 'site_name', 'start_time', 'end_time', 'duration_in_seconds', 'status', 'agent', 'scan_metrics',
            'scan_failure_message', 'generated_by', 'scanner_version', 'scan_configurations', 'scan_delta', 'jira_ticket_count', 'issue_types', 'issue_counts',
            'audit_items', 'audit_item', 'scope', 'site_application_logins', 'schedule_item_application_logins', 'issues')]
        [string[]]
        $Fields
    )

    begin {
        if ($PSBoundParameters.ContainsKey('Fields')) {
            $unsupportedFields = @('site_name', 'agent', 'scan_configurations', 'jira_ticket_count', 'issue_types', 'audit_items', 'audit_item', 'scope', 'site_application_logins', 'schedule_item_application_logins', 'issues')
            $equalFields = Compare-Object -ReferenceObject $unsupportedFields -DifferenceObject $Fields -IncludeEqual -ExcludeDifferent -PassThru
            if ($null -ne $equalFields) {
                Write-Warning "Fetching fields ('$($unsupportedFields -join ", '")') is not yet supported."
            }
        } else {
            $Fields = 'id', 'status', 'issue_counts'
        }
    }

    process {
        $arguments = @{}
        if ($PSBoundParameters.ContainsKey('Id')) { $arguments.id = $Id }
        if ($PSBoundParameters.ContainsKey('Offset')) { $arguments.offset = $Offset }
        if ($PSBoundParameters.ContainsKey('Limit')) { $arguments.limit = $Limit }
        if ($PSBoundParameters.ContainsKey('SortColumn')) { $arguments.sort_column = $SortColumn }
        if ($PSBoundParameters.ContainsKey('SortOrder')) { $arguments.sort_order = $SortOrder }
        if ($PSBoundParameters.ContainsKey('ScanStatus')) { $arguments.scan_status = $ScanStatus }

        if ($PSCmdlet.ParameterSetName -eq 'List') {
            $query = _buildQuery -name 'scans' -objectType 'Scan' -fields $Fields -arguments $arguments
        } else {
            $query = _buildQuery -name 'scan' -alias 'scans' -objectType 'Scan' -fields $Fields -arguments $arguments
        }

        $request = [Request]::new($query)

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $response = _callAPI -Request $Request
                $data = _getObjectProperty -InputObject $response -PropertyName 'data'
                if ($null -ne $data) {
                    $data.scans
                }
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Get-BurpSuiteScanConfiguration {
    [CmdletBinding(SupportsShouldProcess = $true,
        ConfirmImpact = 'Low')]
    Param (
        [Parameter(Mandatory = $false)]
        [ValidateSet('id', 'name', 'scan_configuration_fragment_json', 'built_in', 'last_modified_time', 'last_modified_by')]
        [string[]]
        $Fields
    )

    begin {
        if (-not ($PSBoundParameters.ContainsKey('Fields'))) { $Fields = 'id', 'name' }
    }

    process {
        $query = _buildQuery -name 'scan_configurations' -objectType 'ScanConfiguration' -fields $Fields

        $request = [Request]::new($query)

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $response = _callAPI -Request $Request
                $data = _getObjectProperty -InputObject $response -PropertyName 'data'
                if ($null -ne $data) {
                    $data.scan_configurations
                }
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Get-BurpSuiteScanReport {
    [CmdletBinding(DefaultParameterSetName = 'Download',
        SupportsShouldProcess = $true,
        ConfirmImpact = 'Low')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [Alias('Id')]
        [string]
        $ScanId,

        [Parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [int]
        $TimezoneOffset,

        [Parameter(Mandatory = $false)]
        [ValidateSet('detailed', 'summary')]
        [string]
        $ReportType,

        [Parameter(Mandatory = $false)]
        [switch]
        $IncludeFalsePositives,

        [Parameter(Mandatory = $false)]
        [ValidateSet('info', 'low', 'medium', 'high')]
        [string[]]
        $Severities,

        [Parameter(Mandatory = $true,
            ParameterSetName = 'DownloadToDisk')]
        [ValidateScript( { Test-Path -Path $_ -PathType Leaf -IsValid })]
        [string]
        $OutFile
    )

    begin {
    }

    process {
        $arguments = @{}
        $arguments.scan_id = $ScanId
        if ($PSBoundParameters.ContainsKey('TimezoneOffset')) { $arguments.timezone_offset = $TimezoneOffset }
        if ($PSBoundParameters.ContainsKey('ReportType')) { $arguments.report_type = $ReportType }
        if ($PSBoundParameters.ContainsKey('IncludeFalsePositives')) { $arguments.include_false_positives = $IncludeFalsePositives.IsPresent }
        if ($PSBoundParameters.ContainsKey('Severities')) { $arguments.severities = ,@($Severities) }

        $query = _buildQuery -name 'scan_report' -objectType 'ScanReport' -arguments $arguments

        $request = [Request]::new($query)

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $response = _callAPI -Request $Request
                $data = _getObjectProperty -InputObject $response -PropertyName 'data'
                if ($null -ne $data) {
                    if ($PSCmdlet.ParameterSetName -eq 'Download') {
                        $data.scan_report
                    } else {
                        $outFileArgs = @{}
                        $outFileArgs.FilePath = $OutFile
                        $data.scan_report.report_html | Out-File @outFileArgs
                    }
                }
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Get-BurpSuiteScheduleItem {
    [CmdletBinding(DefaultParameterSetName = 'List',
        SupportsShouldProcess = $true,
        ConfirmImpact = 'Low')]
    Param (
        [Parameter(Mandatory = $true,
            ParameterSetName = 'Specific')]
        [ValidateNotNullOrEmpty()]
        [string]
        $Id,

        [Parameter(Mandatory = $false,
            ParameterSetName = 'List')]
        [ValidateNotNullOrEmpty()]
        [string]
        $SortBy,

        [Parameter(Mandatory = $false,
            ParameterSetName = 'List')]
        [ValidateNotNullOrEmpty()]
        [string]
        $SortOrder,

        [Parameter(Mandatory = $false)]
        [ValidateSet('id', 'site', 'schedule', 'scan_configurations', 'has_run_more_than_once', 'scheduled_run_time')]
        [string[]]
        $Fields
    )

    begin {
        if (-not ($PSBoundParameters.ContainsKey('Fields'))) { $Fields = 'id', 'schedule', 'scheduled_run_time' }
    }

    process {
        $arguments = @{}
        if ($PSBoundParameters.ContainsKey('Id')) { $arguments.id = $Id }
        if ($PSBoundParameters.ContainsKey('SortBy')) { $arguments.sort_by = $SortBy }
        if ($PSBoundParameters.ContainsKey('SortOrder')) { $arguments.sort_order = $SortOrder }

        if ($PSCmdlet.ParameterSetName -eq 'List') {
            $query = _buildQuery -name 'schedule_items' -objectType 'ScheduleItem' -fields $Fields -arguments $arguments
        } else {
            $query = _buildQuery -name 'schedule_item' -alias 'schedule_items' -objectType 'ScheduleItem' -fields $Fields -arguments $arguments
        }

        $request = [Request]::new($query)

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $response = _callAPI -Request $Request
                $data = _getObjectProperty -InputObject $response -PropertyName 'data'
                if ($null -ne $data) {
                    $data.schedule_items
                }
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Get-BurpSuiteSiteTree {
    [CmdletBinding(SupportsShouldProcess = $true,
        ConfirmImpact = 'Low')]
    Param (
        [Parameter(Mandatory = $false)]
        [ValidateSet('folders', 'sites')]
        [string[]]
        $Fields
    )

    begin {
        if (-not ($PSBoundParameters.ContainsKey('Fields'))) { $Fields = 'folders', 'sites' }
    }

    process {

        $query = _buildQuery -name 'site_tree' -objectType 'SiteTree' -fields $Fields

        $request = [Request]::new($query)

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $response = _callAPI -Request $Request
                $data = _getObjectProperty -InputObject $response -PropertyName 'data'
                if ($null -ne $data) {
                    $data.site_tree
                }
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Get-BurpSuiteUnauthorizedAgent {
    [CmdletBinding(SupportsShouldProcess = $true,
        ConfirmImpact = 'Low')]
    Param (
        [Parameter(Mandatory = $false)]
        [ValidateSet('machine_id', 'ip')]
        [string[]]
        $Fields
    )

    begin {
        if (-not ($PSBoundParameters.ContainsKey('Fields'))) { $Fields = 'ip' }
    }

    process {
        $query = _buildQuery -name 'unauthorized_agents' -objectType 'UnauthorizedAgent' -fields $Fields

        if ($PSCmdlet.ShouldProcess("BurpSuite", $Request.Query)) {
            try {
                $request = [Request]::new($query)
                $response = _callAPI -Request $Request
                $data = _getObjectProperty -InputObject $response -PropertyName 'data'
                if ($null -ne $data) {
                    $data.unauthorized_agents
                }
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Grant-BurpSuiteAgent {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [Alias('machine_id')]
        [string] $MachineId
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'AuthorizeAgent' -inputType 'AuthorizeAgentInput!' -name 'authorize_agent' -returnType 'Agent'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.machine_id = $MachineId

                $request = [Request]::new($query, 'AuthorizeAgent', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Invoke-BurpSuiteAPI {
    [CmdletBinding(DefaultParameterSetName = 'Default',
        SupportsShouldProcess = $true,
        ConfirmImpact = 'High')]
    Param (
        [Parameter(Mandatory = $true,
            ValueFromPipeline = $true,
            ParameterSetName = 'Default')]
        [ValidateNotNullOrEmpty()]
        [object]
        $Request,

        [Parameter(Mandatory = $true,
            ValueFromPipelineByPropertyName = $true,
            ParameterSetName = 'FreeForm')]
        [ValidateNotNullOrEmpty()]
        [string]
        $Query,

        [Parameter(Mandatory = $false,
            ValueFromPipelineByPropertyName = $true,
            ParameterSetName = 'FreeForm')]
        [ValidateNotNullOrEmpty()]
        [hashtable]
        $Variables
    )

    begin {
    }

    process {
        if ($PSCmdlet.ParameterSetName -eq 'FreeForm') {
            $Request = [Request]::new($Query)
            if ($PSBoundParameters.ContainsKey('Variables')) { $Request.Variables = $Variables }
        }

        if ($PSCmdlet.ShouldProcess("BurpSuite", $Request.Query)) {
            try {
                $response = _callAPI -Request $Request
                $response
            } catch {
                throw
            }
        }
    }

    end {
    }
}

function Move-BurpSuiteFolder {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $FolderId,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $ParentId
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'MoveFolder' -inputType 'MoveFolderInput!' -name 'move_folder' -returnType 'Folder'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.folder_id = $FolderId
                $variables.input.parent_id = $ParentId

                $request = [Request]::new($query, 'MoveFolder', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Move-BurpSuiteSite {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [Alias('id')]
        [string] $SiteId,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [Alias('parent_id')]
        [string] $ParentId
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'MoveSite' -inputType 'MoveSiteInput!' -name 'move_site' -returnType 'Site'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.site_id = $SiteId
                $variables.input.parent_id = $ParentId

                $request = [Request]::new($query, 'MoveSite', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function New-BurpSuiteFolder {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $ParentId,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Name
    )

    begin {
    }

    process {
        if (-not ($PSBoundParameters.ContainsKey('ParentId'))) { $ParentId = "0" }

        $query = _buildMutation -queryName 'CreateFolder' -inputType 'CreateFolderInput!' -name 'create_folder' -returnType 'Folder'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.name = $Name
                $variables.input.parent_id = $ParentId

                $request = [Request]::new($query, 'CreateFolder', $variables)

                $response = _callAPI -Request $request
                $response.data.create_folder.folder
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function New-BurpSuiteScanConfiguration {
    [CmdletBinding(SupportsShouldProcess = $true,
        ConfirmImpact = 'Low')]
    Param (
        [Parameter(Mandatory = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Name,

        [Parameter(Mandatory = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateScript( { Test-Path -Path $_ -PathType Leaf })]
        [string]
        $FilePath
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'CreateScanConfiguration' -inputType 'CreateScanConfigurationInput!' -name 'create_scan_configuration' -returnType 'ScanConfiguration'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.name = $Name
                $variables.input.scan_configuration_fragment_json = Get-Content -Raw -Path $FilePath | Out-String

                $request = [Request]::new($query, 'CreateScanConfiguration', $variables)

                $response = _callAPI -Request $Request
                $response.data.create_scan_configuration.scan_configuration
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function New-BurpSuiteScheduleItem {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $SiteId,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string[]] $ScanConfigurationIds,

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [psobject] $Schedule
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'CreateScheduleItem' -inputType 'CreateScheduleItemInput!' -name 'create_schedule_item' -returnType 'ScheduleItem'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.site_id = $SiteId
                $variables.input.scan_configuration_ids = $ScanConfigurationIds

                if ($PSBoundParameters.ContainsKey('Schedule')) {
                    $scheduleInput = @{}

                    $initialRunTime = _getObjectProperty -InputObject $Schedule -PropertyName 'InitialRunTime'
                    if ($null -ne $initialRunTime) { $scheduleInput.initial_run_time = $initialRunTime }

                    $recurrenceRule = _getObjectProperty -InputObject $Schedule -PropertyName 'RRule'
                    if ($null -ne $recurrenceRule) { $scheduleInput.rrule = $recurrenceRule }

                    $variables.input.schedule = $scheduleInput
                }

                $request = [Request]::new($query, 'CreateScheduleItem', $variables)

                $response = _callAPI -Request $request
                $response.data.create_schedule_item.schedule_item
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function New-BurpSuiteSite {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Name,

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $ParentId,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [psobject] $Scope,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string[]] $ScanConfigurationIds,

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [psobject[]] $EmailRecipients,

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [psobject[]] $ApplicationLogins
    )

    begin {
    }

    process {
        if (-not ($PSBoundParameters.ContainsKey('ParentId'))) { $ParentId = "0" }

        $query = _buildMutation -queryName 'CreateSite' -inputType 'CreateSiteInput!' -name 'create_site' -returnType 'Site'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.name = $Name
                $variables.input.parent_id = $ParentId

                if ($PSBoundParameters.ContainsKey('Scope')) {
                    $scopeInput = @{ included_urls = @(); excluded_urls = @() }

                    $includedUrls = _getObjectProperty -InputObject $Scope -PropertyName 'IncludedUrls'
                    if ($null -eq $includedUrls) { throw "Property 'IncludedUrls' is required when specifying scope object." }
                    $scopeInput.included_urls = @($includedUrls)

                    $excludedUrls = _getObjectProperty -InputObject $Scope -PropertyName 'ExcludedUrls'
                    if ($null -ne $excludedUrls) { $scopeInput.excluded_urls = @($excludedUrls) }

                    $variables.input.scope = $scopeInput
                }

                $variables.input.scan_configuration_ids = $ScanConfigurationIds

                if ($PSBoundParameters.ContainsKey('EmailRecipients')) {
                    $emailRecipientInput = @()

                    foreach ($emailRecipient in $EmailRecipients) {
                        $email = _getObjectProperty -InputObject $emailRecipient -PropertyName 'Email'
                        if ($null -eq $email) { throw "Property 'Email' is required when specifying email recipient objects." }
                        $emailRecipientInput += @{ email = $email }
                    }

                    $variables.input.email_recipients = $emailRecipientInput
                }

                if ($PSBoundParameters.ContainsKey('ApplicationLogins')) {
                    $applicationLoginInput = @()

                    foreach ($applicationLogin in $ApplicationLogins) {
                        $label = _getObjectProperty -InputObject $applicationLogin -PropertyName 'Label'
                        if ($null -eq $label) { throw "Property 'Label' is required when specifying application login objects." }

                        $credential = _getObjectProperty -InputObject $applicationLogin -PropertyName 'Credential'
                        if ($null -eq $credential) { throw "Property 'Credential' is required when specifying application login objects." }

                        $networkCredential = $credential.GetNetworkCredential()

                        $applicationLoginInput += @{ label = $label; username = $networkCredential.UserName; password = $networkCredential.Password }
                    }

                    $variables.input.application_logins = $applicationLoginInput
                }

                $request = [Request]::new($query, 'CreateSite', $variables)

                $response = _callAPI -Request $request
                $response.data.create_site.site
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function New-BurpSuiteSiteApplicationLogin {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $SiteId,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Label,

        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [ValidateNotNull()]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.CredentialAttribute()]
        $Credential
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'CreateSiteApplicationLogin' -inputType 'CreateSiteApplicationLoginInput!' -name 'create_site_application_login' -returnType 'ApplicationLogin'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $networkCredential = $Credential.GetNetworkCredential()

                $variables = @{ input = @{} }
                $variables.input.site_id = $SiteId
                $variables.input.application_login = @{}
                $variables.input.application_login.label = $Label
                $variables.input.application_login.username = $networkCredential.UserName
                $variables.input.application_login.password = $networkCredential.Password

                $request = [Request]::new($query, 'CreateSiteApplicationLogin', $variables)

                $response = _callAPI -Request $request
                $response.data.create_site_application_login.application_login
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function New-BurpSuiteSiteEmailRecipient {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $SiteId,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $EmailRecipient
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'CreateSiteEmailRecipient' -inputType 'CreateSiteEmailRecipientInput!' -name 'create_site_email_recipient' -returnType 'EmailRecipient'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.site_id = $SiteId
                $variables.input.email_recipient = @{email = $EmailRecipient }

                $request = [Request]::new($query, 'CreateSiteEmailRecipient', $variables)

                $response = _callAPI -Request $request
                $response.data.create_site_email_recipient.email_recipient
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Remove-BurpSuiteFolder {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Id
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'DeleteFolder' -inputType 'DeleteFolderInput!' -name 'delete_folder' -returnType 'Id' -returnTypeField

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.id = $Id

                $request = [Request]::new($query, 'DeleteFolder', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Remove-BurpSuiteScan {
    [CmdletBinding(SupportsShouldProcess = $true,
        ConfirmImpact = 'High')]
    Param (
        [Parameter(Mandatory = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Id
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'DeleteScan' -inputType 'DeleteScanInput!' -name 'delete_scan' -returnType 'Scan' -returnTypeField

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{id = $Id } }

                $request = [Request]::new($query, 'DeleteScan', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Remove-BurpSuiteScanConfiguration {
    [CmdletBinding(SupportsShouldProcess = $true,
        ConfirmImpact = 'High')]
    Param (
        [Parameter(Mandatory = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Id
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'DeleteScanConfiguration' -inputType 'DeleteScanConfigurationInput!' -name 'delete_scan_configuration' -returnType 'ScanConfiguration' -returnTypeField

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.id = $Id

                $request = [Request]::new($query, 'DeleteScanConfiguration', $variables)

                $null = _callAPI -Request $Request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Remove-BurpSuiteScheduleItem {
    [CmdletBinding(SupportsShouldProcess = $true,
        ConfirmImpact = 'High')]
    Param (
        [Parameter(Mandatory = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Id
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'DeleteScheduleItem' -inputType 'DeleteScheduleItemInput!' -name 'delete_schedule_item' -returnType 'ScheduleItem' -returnTypeField

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{input = @{} }
                $variables.input.id = $Id

                $request = [Request]::new($query, 'DeleteScheduleItem', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Remove-BurpSuiteSite {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Id
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'DeleteSite' -inputType 'DeleteSiteInput!' -name 'delete_site' -returnType 'Id' -returnTypeField

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.id = $Id

                $request = [Request]::new($query, 'DeleteSite', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Remove-BurpSuiteSiteApplicationLogin {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Id
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'DeleteSiteApplicationLogin' -inputType 'DeleteSiteApplicationLoginInput!' -name 'delete_site_application_login' -returnType 'Id' -returnTypeField

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.id = $Id

                $request = [Request]::new($query, 'DeleteSiteApplicationLogin', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Remove-BurpSuiteSiteEmailRecipient {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Id
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'DeleteSiteEmailRecipient' -inputType 'DeleteSiteEmailRecipientInput!' -name 'delete_site_email_recipient' -returnType 'Id' -returnTypeField

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.id = $Id

                $request = [Request]::new($query, 'DeleteSiteEmailRecipient', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Rename-BurpSuiteAgent {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Id,

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Name
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'RenameAgent' -inputType 'RenameAgentInput!' -name 'rename_agent' -returnType 'Agent'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.id = $Id
                $variables.input.name = $Name

                $request = [Request]::new($query, 'RenameAgent', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Rename-BurpSuiteFolder {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Id,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Name
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'RenameFolder' -inputType 'RenameFolderInput!' -name 'rename_folder' -returnType 'Folder'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.name = $Name
                $variables.input.id = $Id

                $request = [Request]::new($query, 'RenameFolder', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Rename-BurpSuiteSite {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Id,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Name
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'RenameSite' -inputType 'RenameSiteInput!' -name 'rename_site' -returnType 'Site'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.id = $Id
                $variables.input.name = $Name

                $request = [Request]::new($query, 'RenameSite', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Revoke-BurpSuiteAgent {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [Alias('Id')]
        [string] $MachineId
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'DeauthorizeAgent' -inputType 'DeauthorizeAgentInput!' -name 'deauthorize_agent' -returnType 'Id' -returnTypeField

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.machine_id = $MachineId

                $request = [Request]::new($query, 'DeauthorizeAgent', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Set-BurpSuiteAgentMaxConcurrentScan {
    [CmdletBinding(SupportsShouldProcess = $true,
        ConfirmImpact = 'Low')]
    Param (
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Id,

        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [int]
        $MaxConcurrentScans
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'UpdateAgentMaxConcurrentScans' -inputType 'UpdateAgentMaxConcurrentScansInput!' -name 'update_agent_max_concurrent_scans' -returnType 'Agent'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }

                $variables.input.id = $Id
                $variables.input.max_concurrent_scans = $MaxConcurrentScans

                $request = [Request]::new($query, 'UpdateAgentMaxConcurrentScans', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Stop-BurpSuiteScan {
    [CmdletBinding(SupportsShouldProcess = $true,
        ConfirmImpact = 'High')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Id
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'CancelScan' -inputType 'CancelScanInput!' -name 'cancel_scan' -returnType 'Scan' -returnTypeField

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{input = @{} }
                $variables.input.id = $Id

                $request = [Request]::new($query, 'CancelScan', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Update-BurpSuiteFalsePositive {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $ScanId,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $SerialNumber,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [switch] $IsFalsePositive,

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [ValidateSet('none', 'issue_type_only', 'issue_type_and_url')]
        [string] $PropagationMode
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'UpdateFalsePositive' -inputType 'UpdateFalsePositiveInput!' -name 'update_false_positive' -returnType 'FalsePositive' -returnTypeField

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }

                $variables.input.scan_id = $ScanId
                $variables.input.serial_number = $SerialNumber
                $variables.input.is_false_positive = "false"
                if ($PSBoundParameters.ContainsKey('IsFalsePositive')) {
                    if ($IsFalsePositive.IsPresent) { $variables.input.is_false_positive = "true" }
                }
                if ($PSBoundParameters.ContainsKey('PropagationMode')) { $variables.input.propagation_mode = $PropagationMode }

                $request = [Request]::new($query, 'UpdateFalsePositive', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Update-BurpSuiteScanConfiguration {
    [CmdletBinding(DefaultParameterSetName = 'UpdateName',
        SupportsShouldProcess = $true,
        ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Id,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'UpdateName')]
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'AllFields')]
        [ValidateNotNullOrEmpty()]
        [string]
        $Name,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'UpdateSettings')]
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'AllFields')]
        [ValidateScript( { Test-Path -Path $_ -PathType Leaf } )]
        [string]
        $FilePath
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'UpdateScanConfiguration' -inputType 'UpdateScanConfigurationInput!' -name 'update_scan_configuration' -returnType 'ScanConfiguration'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.id = $Id
                if ($PSBoundParameters.ContainsKey('Name')) { $variables.input.name = $Name }
                if ($PSBoundParameters.ContainsKey('FilePath')) { $variables.input.scan_configuration_fragment_json = Get-Content -Raw -Path $FilePath | Out-String }

                $request = [Request]::new($query, 'UpdateScanConfiguration', $variables)

                $null = _callAPI -Request $Request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Update-BurpSuiteScheduleItem {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Id,

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $SiteId,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string[]] $ScanConfigurationIds,

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [psobject] $Schedule
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'UpdateScheduleItem' -inputType 'UpdateScheduleItemInput!' -name 'update_schedule_item' -returnType 'ScheduleItem'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.id = $Id
                $variables.input.site_id = $SiteId
                $variables.input.scan_configuration_ids = $ScanConfigurationIds

                if ($PSBoundParameters.ContainsKey('SiteId')) { $variables.input.site_id = $SiteId }

                if ($PSBoundParameters.ContainsKey('Schedule')) {
                    $scheduleInput = @{}

                    $initialRunTime = _getObjectProperty -InputObject $Schedule -PropertyName 'InitialRunTime'
                    if ($null -ne $initialRunTime) {
                        $scheduleInput.initial_run_time = $initialRunTime
                        $scheduleInput.initial_run_time_is_set = "true"
                    }

                    $recurrenceRule = _getObjectProperty -InputObject $Schedule -PropertyName 'RRule'
                    if ($null -ne $recurrenceRule) {
                        $scheduleInput.rrule = $recurrenceRule
                        $scheduleInput.rrule_is_set = "true"
                    }

                    $variables.input.schedule = $scheduleInput
                }

                $request = [Request]::new($query, 'UpdateScheduleItem', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Update-BurpSuiteSiteApplicationLogin {
    [CmdletBinding(DefaultParameterSetName = 'Credential', SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Id,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Label')]
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'All')]
        [ValidateNotNullOrEmpty()]
        [string] $Label,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Credential')]
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'All')]
        [ValidateNotNull()]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.CredentialAttribute()]
        $Credential
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'UpdateSiteApplicationLogin' -inputType 'UpdateSiteApplicationLoginInput!' -name 'update_site_application_login' -returnType 'ApplicationLogin'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.id = $Id

                if ($PSBoundParameters.ContainsKey('Label')) {
                    $variables.input.label = $Label
                }

                if ($PSBoundParameters.ContainsKey('Credential')) {
                    $networkCredential = $Credential.GetNetworkCredential()
                    $variables.input.username = $networkCredential.UserName
                    $variables.input.password = $networkCredential.Password
                }

                $request = [Request]::new($query, 'UpdateSiteApplicationLogin', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Update-BurpSuiteSiteEmailRecipient {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Id,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Email
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'UpdateSiteEmailRecipient' -inputType 'UpdateSiteEmailRecipientInput!' -name 'update_site_email_recipient' -returnType 'EmailRecipient'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.id = $Id
                $variables.input.email = $Email

                $request = [Request]::new($query, 'UpdateSiteEmailRecipient', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Update-BurpSuiteSiteScanConfiguration {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Id,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string[]] $ScanConfigurationIds
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'UpdateSiteScanConfigurations' -inputType 'UpdateSiteScanConfigurationsInput!' -name 'update_site_scan_configurations' -returnType 'Site'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.id = $Id
                $variables.input.scan_configuration_ids = $ScanConfigurationIds

                $request = [Request]::new($query, 'UpdateSiteScanConfigurations', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}
function Update-BurpSuiteSiteScope {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $SiteId,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [string[]] $IncludedUrls,

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [AllowEmptyCollection()]
        [string[]] $ExcludedUrls
    )

    begin {
    }

    process {

        $query = _buildMutation -queryName 'UpdateSiteScope' -inputType 'UpdateSiteScopeInput!' -name 'update_site_scope' -returnType 'Scope'

        if ($PSCmdlet.ShouldProcess("BurpSuite", $query)) {
            try {
                $variables = @{ input = @{} }
                $variables.input.site_id = $SiteId

                $variables.input.included_urls = $IncludedUrls

                if ($PSBoundParameters.ContainsKey('ExcludedUrls')) { $variables.input.excluded_urls = $ExcludedUrls }
                else { $variables.input.excluded_urls = @() }

                $request = [Request]::new($query, 'UpdateSiteScope', $variables)

                $null = _callAPI -Request $request
            } catch {
                throw
            }
        }
    }

    end {
    }
}