PSx360Recover.psm1

using namespace System.Collections.Generic
using namespace System.Management.Automation
#Region '.\Private\ConvertTo-UnixEpoch.ps1' -1

function ConvertTo-UnixEpoch {
<#
.SYNOPSIS
    Converts a PowerShell DateTime object to a Unix Epoch timestamp.
 
.DESCRIPTION
    This cmdlet takes a PowerShell DateTime object and returns a Unix Epoch timestamp representing the same date/time. It supports input as a DateTime object, a string, or an integer.
 
.PARAMETER DateTime
    The PowerShell DateTime object, string, or integer to convert. This parameter is mandatory.
 
.EXAMPLE
    PS> ConvertTo-UnixEpoch -DateTime (Get-Date)
 
    Converts the current date and time to a Unix Epoch timestamp.
 
.EXAMPLE
    PS> ConvertTo-UnixEpoch -DateTime "2023-01-01T00:00:00"
 
    Converts the specified date and time string to a Unix Epoch timestamp.
 
.EXAMPLE
    PS> ConvertTo-UnixEpoch -DateTime 1672531200
 
    Converts the specified Unix Epoch timestamp to a Unix Epoch timestamp (returns the same value).
 
.INPUTS
    System.Object. The DateTime parameter can be a DateTime object, string, or integer.
 
.OUTPUTS
    System.Int. The Unix Epoch timestamp.
 
#>

    [CmdletBinding()]
    [OutputType([Int])]
    param (
        # The PowerShell DateTime object to convert.
        [Parameter(
            Mandatory = $True
        )]
        [Object]$DateTime
    )
    if ($DateTime -is [String]) {
        $DateTime = [DateTime]::Parse($DateTime)
    } elseif ($DateTime -is [Int]) {
                                (Get-Date 01.01.1970).AddSeconds($unixTimeStamp)
    } elseif ($DateTime -is [DateTime]) {
        $DateTime = $DateTime
    } else {
        Write-Error 'The DateTime parameter must be a DateTime object, a string, or an integer.'
        Exit 1
    }
    $UniversalDateTime = $DateTime.ToUniversalTime()
    $UnixEpochTimestamp = Get-Date -Date $UniversalDateTime -UFormat %s
    Write-Verbose "Converted $DateTime to Unix Epoch timestamp $UnixEpochTimestamp"
    return $UnixEpochTimestamp
}
#EndRegion '.\Private\ConvertTo-UnixEpoch.ps1' 58
#Region '.\Private\Get-x360RecoverSecrets.ps1' -1

function Get-x360RecoverSecrets {
<#
.SYNOPSIS
    Retrieves x360Recover connection information from a secret vault.
 
.DESCRIPTION
    This cmdlet retrieves x360Recover connection information, including the URL, instance name, and API key, from a specified secret vault. It uses the SecretManagement module to access the secrets and sets up script-scoped variables for the connection and authentication information.
 
.PARAMETER VaultName
    The name of the secret vault to use for retrieving the secrets. This parameter is mandatory.
 
.PARAMETER SecretPrefix
    The prefix to use for the secret names. Default is 'x360Recover'.
 
.EXAMPLE
    PS> Get-x360RecoverSecrets -VaultName "MyVault"
 
    Retrieves x360Recover connection information from the "MyVault" secret vault using the default secret prefix.
 
.EXAMPLE
    PS> Get-x360RecoverSecrets -VaultName "MyVault" -SecretPrefix "CustomPrefix"
 
    Retrieves x360Recover connection information from the "MyVault" secret vault using the custom secret prefix "CustomPrefix".
 
.INPUTS
    None. You cannot pipe objects to this cmdlet.
 
.OUTPUTS
    System.Void. This cmdlet does not produce any output.
 
#>

    [CmdletBinding()]
    [OutputType([System.Void])]
    param(
        # The vault name to use for retrieving the secrets.
        [String]$VaultName,
        # The prefix to use for the secret names.
        [String]$SecretPrefix = 'x360Recover'
    )
    $Secrets = @{
        ConnectionInfo = @{
            'URL' = ('{0}URL' -f $SecretPrefix)
            'Instance' = ('{0}Instance' -f $SecretPrefix)
            'ApiKey' = ('{0}ApiKey' -f $SecretPrefix)
            'UseSecretManagement' = ('{0}UseSecretManagement' -f $SecretPrefix)
            'WriteToSecretVault' = ('{0}WriteToSecretVault' -f $SecretPrefix)
            'ReadFromSecretVault' = ('{0}ReadFromSecretVault' -f $SecretPrefix)
            'VaultName' = ('{0}VaultName' -f $SecretPrefix)
        }
    }
    # Setup the the script scoped variables for the connection and authentication information.
    if ($null -eq $Script:x360RConnectionInformation) { $Script:x360RConnectionInformation = @{} }
    # Retrieve the connection information from the secret vault.
    foreach ($ConnectionSecret in $Secrets.ConnectionInfo.GetEnumerator()) {
        Write-Verbose ('Processing secret {0} for vault retrieval.' -f $ConnectionSecret.Key)
        $SecretName = $ConnectionSecret.Key
        $VaultSecretName = $ConnectionSecret.Value
        $SecretValue = Get-Secret -Name $VaultSecretName -Vault $VaultName -AsPlainText -ErrorAction SilentlyContinue
        if ($null -eq $SecretValue) {
            Write-Verbose ('Secret {0} is null. Skipping.' -f $SecretName)
            continue
        }
        Write-Verbose ('Secret {0} retrieved from secret vault {1}.' -f $SecretName, $VaultName)
        $Script:x360RConnectionInformation.$SecretName = $SecretValue
    }
    # if we values for UseSecretManagement, WriteToSecretVault, and ReadFromSecretVault, convert them to booleans.
    if ($null -ne $Script:x360RConnectionInformation.UseSecretManagement) {
        $Script:x360RConnectionInformation.UseSecretManagement = [Boolean]::Parse($Script:x360RConnectionInformation.UseSecretManagement)
    }
    if ($null -ne $Script:x360RConnectionInformation.WriteToSecretVault) {
        $Script:x360RConnectionInformation.WriteToSecretVault = [Boolean]::Parse($Script:x360RConnectionInformation.WriteToSecretVault)
    }
    if ($null -ne $Script:x360RConnectionInformation.ReadFromSecretVault) {
        $Script:x360RConnectionInformation.ReadFromSecretVault = [Boolean]::Parse($Script:x360RConnectionInformation.ReadFromSecretVault)
    }
    # Verify we have the required connection information.
    if ([String]::IsNullOrEmpty($Script:x360RConnectionInformation.URL)) {
        Write-Error 'x360Recover URL is not set.'
        exit 1
    }
    if ([String]::IsNullOrEmpty($Script:x360RConnectionInformation.Instance)) {
        Write-Error 'x360Recover instance is not set.'
        exit 1
    }
    if ([String]::IsNullOrEmpty($Script:x360RConnectionInformation.APIKey)) {
        Write-Error 'x360Recover API key is not set.'
        exit 1
    }

    $Script:x360RConnectionInformation.UseSecretManagement = $true
    $Script:x360RConnectionInformation.WriteToSecretVault = $true
    $Script:x360RConnectionInformation.VaultName = $VaultName
    $Script:x360RConnectionInformation.ReadFromSecretVault = $true
}
#EndRegion '.\Private\Get-x360RecoverSecrets.ps1' 95
#Region '.\Private\New-x360RecoverError.ps1' -1

#using namespace System.Collections.Generic
#using namespace System.Management.Automation
function New-x360RecoverError {
<#
.SYNOPSIS
    Generates a detailed error message for x360Recover API errors.
 
.DESCRIPTION
    This cmdlet processes an ErrorRecord object and generates a detailed error message for x360Recover API errors. It handles various error scenarios, including HTTP request exceptions and JSON error details, and constructs a comprehensive error message.
 
.PARAMETER ErrorRecord
    The ErrorRecord object containing the error details. This parameter is mandatory.
 
.PARAMETER HasResponse
    Indicates whether the error includes an HTTP response. This parameter is optional.
 
.EXAMPLE
    PS> try {
    >> # Some code that triggers an error
    >> } catch {
    >> $errorRecord = $_
    >> New-x360RecoverError -ErrorRecord $errorRecord -HasResponse
    >> }
 
    Processes the caught error and generates a detailed error message for the x360Recover API error.
 
.INPUTS
    None. You cannot pipe objects to this function.
 
.OUTPUTS
    None. This function throws a terminating error with the processed error details..
 
#>

    [CmdletBinding()]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Private function - no need to support.')]
    param (
        [Parameter(Mandatory = $true)]
        [errorrecord]$ErrorRecord,
        [Parameter()]
        [switch]$HasResponse
    )

    if (($Error.Exception -is [System.Net.Http.HttpRequestException]) -or ($Error.Exception -is [System.Net.WebException])) {
        Write-Verbose 'Generating x360Recover error output.'
        $ExceptionMessage = [Hashset[String]]::New()
        $APIResultMatchString = '*The x360Recover API said*'
        $HTTPResponseMatchString = '*The API returned the following HTTP*'
        if ($ErrorRecord.ErrorDetails) {
            Write-Verbose 'ErrorDetails contained in error record.'
            $ErrorDetailsIsJson = Test-Json -Json $ErrorRecord.ErrorDetails -ErrorAction SilentlyContinue
            if ($ErrorDetailsIsJson) {
                Write-Verbose 'ErrorDetails is JSON.'
                $ErrorDetails = $ErrorRecord.ErrorDetails | ConvertFrom-Json
                Write-Verbose "Raw error details: $($ErrorDetails | Out-String)"
                if ($null -ne $ErrorDetails) {
                    if (($null -ne $ErrorDetails.resultCode) -and ($null -ne $ErrorDetails.errorMessage)) {
                        Write-Verbose 'ErrorDetails contains resultCode and errorMessage.'
                        $ExceptionMessage.Add("The x360Recover API said $($ErrorDetails.resultCode): $($ErrorDetails.errorMessage).") | Out-Null
                    } elseif ($null -ne $ErrorDetails.resultCode) {
                        Write-Verbose 'ErrorDetails contains resultCode.'
                        $ExceptionMessage.Add("The x360Recover API said $($ErrorDetails.resultCode).") | Out-Null
                    } elseif ($null -ne $ErrorDetails.error) {
                        Write-Verbose 'ErrorDetails contains error.'
                        $ExceptionMessage.Add("The x360Recover API said $($ErrorDetails.error).") | Out-Null
                    } elseif ($null -ne $ErrorDetails) {
                        Write-Verbose 'ErrorDetails is not null.'
                        $ExceptionMessage.Add("The x360Recover API said $($ErrorRecord.ErrorDetails).") | Out-Null
                    } else {
                        Write-Verbose 'ErrorDetails is null.'
                        $ExceptionMessage.Add('The x360Recover API returned an error.') | Out-Null
                    }
                }
            } elseif ($ErrorRecord.ErrorDetails -like $APIResultMatchString -and $ErrorRecord.ErrorDetails -like $HTTPResponseMatchString) {
                $Errors = $ErrorRecord.ErrorDetails -Split "`r`n"
                if ($Errors -is [array]) {
                    ForEach-Object -InputObject $Errors {
                        $ExceptionMessage.Add($_) | Out-Null
                    }
                } elseif ($Errors -is [string]) {
                    $ExceptionMessage.Add($_)
                }
            }
        } else {
            $ExceptionMessage.Add('The x360Recover API returned an error but did not provide a result code or error message.') | Out-Null
        }
        if (($ErrorRecord.Exception.Response -and $HasResponse) -or $ExceptionMessage -notlike $HTTPResponseMatchString) {
            $Response = $ErrorRecord.Exception.Response
            Write-Verbose "Raw HTTP response: $($Response | Out-String)"
            if ($Response.StatusCode.value__ -and $Response.ReasonPhrase) {
                $ExceptionMessage.Add("The API returned the following HTTP error response: $($Response.StatusCode.value__) $($Response.ReasonPhrase)") | Out-Null
            } else {
                $ExceptionMessage.Add('The API returned an HTTP error response but did not provide a status code or reason phrase.')
            }
        } else {
            $ExceptionMessage.Add('The API did not provide a response code or status.') | Out-Null
        }
        $Exception = [System.Exception]::New(
            $ExceptionMessage,
            $ErrorRecord.Exception
        )
        $x360RecoverError = [ErrorRecord]::New(
            $ErrorRecord,
            $Exception
        )
        $UniqueExceptions = $ExceptionMessage | Get-Unique
        $x360RecoverError.ErrorDetails = [String]::Join("`r`n", $UniqueExceptions)
    } else {
        Write-Verbose 'Not generating x360Recover error output.'
        Write-Verbose "Raw error record: $($ErrorRecord | Out-String)"
        $x360RecoverError = $ErrorRecord
    }
    $PSCmdlet.throwTerminatingError($x360RecoverError)
}
#EndRegion '.\Private\New-x360RecoverError.ps1' 114
#Region '.\Private\New-x360RecoverGETRequest.ps1' -1

function New-x360RecoverGETRequest {
<#
.SYNOPSIS
    Sends a GET request to the specified x360Recover API resource.
 
.DESCRIPTION
    This cmdlet sends a GET request to the specified x360Recover API resource. It constructs the request URI using the provided resource and query string parameters, and returns the response. Optionally, it can return the raw response.
 
.PARAMETER Resource
    The resource to send the request to. This parameter is mandatory.
 
.PARAMETER QSCollection
    A hashtable used to build the query string. This parameter is optional.
 
.PARAMETER Raw
    If specified, returns the raw response. This parameter is optional.
 
.EXAMPLE
    PS> $qs = @{ param1 = "value1"; param2 = "value2" }
    PS> New-x360RecoverGETRequest -Resource "device" -QSCollection $qs
 
    Sends a GET request to the "device" resource with the specified query string parameters.
 
.EXAMPLE
    PS> New-x360RecoverGETRequest -Resource "client" -Raw
 
    Sends a GET request to the "client" resource and returns the raw response.
 
.INPUTS
    System.String. The resource can be piped to this cmdlet.
    System.Collections.Hashtable. The query string parameters can be piped to this cmdlet.
 
.OUTPUTS
    System.Object. The response from the x360Recover API.
 
#>

    [CmdletBinding()]
    [OutputType([Object])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Private function - no need to support.')]
    param (
        # The resource to send the request to.
        [Parameter( Mandatory = $True )]
        [String]$Resource,
        # A hashtable used to build the query string.
        [HashTable]$QSCollection,
        # return the raw response.
        [Switch]$Raw
    )
    if ($null -eq $Script:x360RConnectionInformation) {
        throw "Missing x360Recover connection information, please run 'Connect-x360Recover' first."
    }
    try {
        if ($QSCollection) {
            Write-Verbose "Query string in New-x360RecoverGETRequest contains: $($QSCollection | Out-String)"
            $QueryStringCollection = [System.Web.HTTPUtility]::ParseQueryString([String]::Empty)
            Write-Verbose 'Building [HttpQSCollection] for New-x360RecoverGETRequest'
            foreach ($Key in $QSCollection.Keys) {
                $QueryStringCollection.Add($Key, $QSCollection.$Key)
            }
        } else {
            Write-Verbose 'Query string collection not present...'
        }
        Write-Verbose "URI is $($Script:x360RConnectionInformation.URL)"
        $RequestUri = [System.UriBuilder]"$($Script:x360RConnectionInformation.URL)"
        if ($RequestUri.Path) {
            $RequestUri.Path = Join-Path $RequestUri.Path $Resource
        } else {
            $RequestUri.Path = $Resource
        }

        if ($QueryStringCollection) {
            $RequestUri.Query = $QueryStringCollection.toString()
        } else {
            Write-Verbose 'No query string collection present.'
        }
        $WebRequestParams = @{
            Method = 'GET'
            Uri = $RequestUri.ToString()
        }
        if ($Raw) {
            $WebRequestParams.Add('Raw', $Raw)
        } else {
            Write-Verbose 'Raw switch not present.'
        }
        if ($WebRequestParams) {
            Write-Verbose "WebRequestParams contains: $($WebRequestParams | Out-String)"
        } else {
            Write-Verbose 'WebRequestParams is empty.'
        }
        try {
            $Result = Invoke-x360RecoverRequest @WebRequestParams
            if ($Result) {
                Write-Verbose "x360Recover request returned:: $($Result | Out-String)"
                $Properties = ($Result | Get-Member -MemberType 'NoteProperty')
                if ($Properties.name -contains 'results') {
                    Write-Verbose "returning 'results' property.'"
                    Write-Verbose "Result type is $($Result.results.GetType())"
                    return $Result.results
                } elseif ($Properties.name -contains 'result') {
                    Write-Verbose "returning 'result' property."
                    Write-Verbose "Result type is $($Result.result.GetType())"
                    return $Result.result
                } else {
                    Write-Verbose 'returning raw.'
                    Write-Verbose "Result type is $($Result.GetType())"
                    return $Result
                }
            } else {
                Write-Verbose 'x360Recover request returned nothing.'
            }
        } catch {
            $ExceptionType = if ($IsCoreCLR) {
                [Microsoft.PowerShell.Commands.HttpResponseException]
            } else {
                [System.Net.WebException]
            }
            if ($_.Exception -is $ExceptionType) {
                throw
            } else {
                New-x360RecoverError -ErrorRecord $_
            }
        }
    } catch {
        $ExceptionType = if ($IsCoreCLR) {
            [Microsoft.PowerShell.Commands.HttpResponseException]
        } else {
            [System.Net.WebException]
        }
        if ($_.Exception -is $ExceptionType) {
            throw
        } else {
            New-x360RecoverError -ErrorRecord $_
            -ErrorRecord $_
        }
    }
}
#EndRegion '.\Private\New-x360RecoverGETRequest.ps1' 137
#Region '.\Private\New-x360RecoverPOSTRequest.ps1' -1

function New-x360RecoverPOSTRequest {
    <#
.SYNOPSIS
    Sends a POST request to the specified x360Recover API resource.
 
.DESCRIPTION
    This cmdlet sends a POST request to the specified x360Recover API resource. It constructs the request URI using the provided resource and query string parameters, and includes the specified body in the request. The cmdlet returns the response from the API.
 
.PARAMETER Resource
    The resource to send the request to. This parameter is mandatory.
 
.PARAMETER QSCollection
    A hashtable used to build the query string. This parameter is optional.
 
.PARAMETER Body
    A hashtable or object used to build the body of the request. This parameter is optional.
 
.EXAMPLE
    PS> $qs = @{ param1 = "value1"; param2 = "value2" }
    PS> $body = @{ key1 = "value1"; key2 = "value2" }
    PS> New-x360RecoverPOSTRequest -Resource "devices" -QSCollection $qs -Body $body
 
    Sends a POST request to the "devices" resource with the specified query string parameters and body.
 
.EXAMPLE
    PS> $body = @{ key1 = "value1"; key2 = "value2" }
    PS> New-x360RecoverPOSTRequest -Resource "devices/12345" -Body $body
 
    Sends a POST request to the "devices/12345" resource with the specified body.
 
.INPUTS
    System.String. The resource can be piped to this cmdlet.
    System.Collections.Hashtable. The query string parameters and body can be piped to this cmdlet.
 
.OUTPUTS
    System.Object. The response from the x360Recover API.
 
#>

    [CmdletBinding()]
    [OutputType([Object])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Private function - no need to support.')]
    param (
        # The resource to send the request to.
        [Parameter(Mandatory = $True)]
        [String]$Resource,
        # A hashtable used to build the query string.
        [Hashtable]$QSCollection,
        # A hashtable used to build the body of the request.
        [Object]$Body
    )
    if ($null -eq $Script:x360RConnectionInformation) {
        throw "Missing x360Recover connection information, please run 'Connect-x360Recover' first."
    }
    try {
        if ($QSCollection) {
            Write-Verbose "Query string in New-x360RecoverPOSTRequest contains: $($QSCollection | Out-String)"
            $QueryStringCollection = [System.Web.HTTPUtility]::ParseQueryString([String]::Empty)
            Write-Verbose 'Building [HttpQSCollection] for New-x360RecoverPOSTRequest'
            foreach ($Key in $QSCollection.Keys) {
                $QueryStringCollection.Add($Key, $QSCollection.$Key)
            }
        } else {
            Write-Verbose 'Query string collection not present...'
        }
        Write-Verbose "URI is $($Script:x360RConnectionInformation.URL)"
        $RequestUri = [System.UriBuilder]"$($Script:x360RConnectionInformation.URL)"
        Write-Verbose "Path is $($Resource)"
        $RequestUri.Path = $Resource
        if ($QueryStringCollection) {
            Write-Verbose "Query string is $($QueryStringCollection.toString())"
            $RequestUri.Query = $QueryStringCollection.toString()
        } else {
            Write-Verbose 'Query string not present...'
        }
        $WebRequestParams = @{
            Method = 'POST'
            Uri = $RequestUri.ToString()
        }
        if ($Body) {
            Write-Verbose 'Building [HttpBody] for New-x360RecoverPOSTRequest'
            $WebRequestParams.Body = (ConvertTo-Json -InputObject $Body -Depth 100)
            Write-Verbose "Raw body is $($WebRequestParams.Body)"
        } else {
            Write-Verbose 'No body provided for New-x360RecoverPOSTRequest'
        }
        Write-Verbose "Building new x360RecoverRequest with params: $($WebRequestParams | Out-String)"
        try {
            $Result = Invoke-x360RecoverRequest @WebRequestParams
            Write-Verbose "x360Recover request returned $($Result | Out-String)"
            if ($Result['results']) {
                return $Result.results
            } elseif ($Result['result']) {
                return $Result.result
            } else {
                return $Result
            }
        } catch {
            $ExceptionType = if ($IsCoreCLR) {
                [Microsoft.PowerShell.Commands.HttpResponseException]
            } else {
                [System.Net.WebException]
            }
            if ($_.Exception -is $ExceptionType) {
                throw
            } else {
                New-x360RecoverError -ErrorRecord $_
            }
        }
    } catch {
        $ExceptionType = if ($IsCoreCLR) {
            [Microsoft.PowerShell.Commands.HttpResponseException]
        } else {
            [System.Net.WebException]
        }
        if ($_.Exception -is $ExceptionType) {
            throw
        } else {
            New-x360RecoverError -ErrorRecord $_
            -ErrorRecord $_
        }
    }
}
#EndRegion '.\Private\New-x360RecoverPOSTRequest.ps1' 123
#Region '.\Private\New-x360RecoverQuery.ps1' -1

function New-x360RecoverQuery {
<#
.SYNOPSIS
    Builds a query string or hash table for x360Recover API requests.
 
.DESCRIPTION
    This cmdlet constructs a query string or hash table from the provided command name and parameters. It supports options to format arrays as comma-separated values and to return the result as a string.
 
.PARAMETER CommandName
    The name of the command for which the query is being built. This parameter is mandatory.
 
.PARAMETER Parameters
    A hash table of parameters to include in the query. This parameter is mandatory.
 
.PARAMETER CommaSeparatedArrays
    If specified, arrays will be formatted as comma-separated values in the query string. This parameter is optional.
 
.PARAMETER AsString
    If specified, the query will be returned as a string. Otherwise, it will be returned as a hash table. This parameter is optional.
 
.EXAMPLE
    PS> $params = @{ param1 = "value1"; param2 = "value2" }
    PS> New-x360RecoverQuery -CommandName "Get-x360RecoverDevice" -Parameters $params
 
    Builds a query string or hash table for the "Get-x360RecoverDevice" command using the specified parameters.
 
.EXAMPLE
    PS> $params = @{ param1 = "value1"; param2 = @("value2", "value3") }
    PS> New-x360RecoverQuery -CommandName "Get-x360RecoverDevice" -Parameters $params -CommaSeparatedArrays -AsString
 
    Builds a query string for the "Get-x360RecoverDevice" command using the specified parameters, formatting arrays as comma-separated values, and returns the result as a string.
 
.INPUTS
    System.String. The command name can be piped to this cmdlet.
    System.Collections.Hashtable. The parameters can be piped to this cmdlet.
 
.OUTPUTS
    System.String or System.Collections.Hashtable. The constructed query string or hash table.
 
#>

    [CmdletBinding()]
    [OutputType([String], [HashTable])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Private function - no need to support.')]
    param (
        [Parameter(Mandatory = $True)]
        [String]$CommandName,
        [Parameter(Mandatory = $True)]
        [HashTable]$Parameters,
        [Switch]$CommaSeparatedArrays,
        [Switch]$AsString
    )
    Write-Verbose "Building parameters for $($CommandName). Use '-Debug' with '-Verbose' to see parameter values as they are built."
    $QSCollection = [HashTable]@{}
    Write-Verbose "$($Parameters.Values | Out-String)"
    foreach ($Parameter in $Parameters.Values) {
        # Skip system parameters.
        if (([System.Management.Automation.Cmdlet]::CommonParameters).Contains($Parameter.Name)) {
            Write-Verbose "Excluding system parameter $($Parameter.Name)."
            Continue
        }
        # Skip optional system parameters.
        if (([System.Management.Automation.Cmdlet]::OptionalCommonParameters).Contains($Parameter.Name)) {
            Write-Verbose "Excluding optional system parameter $($Parameter.Name)."
            Continue
        }
        $ParameterVariable = Get-Variable -Name $Parameter.Name -ErrorAction SilentlyContinue
        Write-Verbose "Parameter variable: $($ParameterVariable | Out-String)"
        if (($Parameter.ParameterType.Name -eq 'String') -or ($Parameter.ParameterType.Name -eq 'String[]')) {
            Write-Verbose "Found String or String Array param $($ParameterVariable.Name) with value $($ParameterVariable.Value)."
            if ([String]::IsNullOrEmpty($ParameterVariable.Value)) {
                Write-Verbose "Skipping unset param $($ParameterVariable.Name)"
                Continue
            } else {
                if ($Parameter.Aliases) {
                    # Use the first alias as the query.
                    $Query = ([String]$Parameter.Aliases[0])
                } else {
                    # If no aliases then use the name.
                    $Query = ([String]$ParameterVariable.Name)
                }
                $Value = $ParameterVariable.Value
                if (($Value -is [Array]) -and ($CommaSeparatedArrays)) {
                    Write-Verbose 'Building comma separated array string.'
                    $QueryValue = $Value -join ','
                    $QSCollection.Add($Query, $QueryValue)
                    Write-Verbose "Adding parameter $($Query) with value $($QueryValue)"
                } elseif (($Value -is [Array]) -and (-not $CommaSeparatedArrays)) {
                    foreach ($ArrayValue in $Value) {
                        $QSCollection.Add($Query, $ArrayValue)
                        Write-Verbose "Adding parameter $($Query) with value(s) $($ArrayValue)"
                    }
                } else {
                    $QSCollection.Add($Query, $Value)
                    Write-Verbose "Adding parameter $($Query) with value $($Value)"
                }
            }
        }
        if ($Parameter.ParameterType.Name -eq 'SwitchParameter') {
            Write-Verbose "Found Switch param $($ParameterVariable.Name) with value $($ParameterVariable.Value)."
            if ($ParameterVariable.Value -eq $False) {
                Write-Verbose "Skipping unset param $($ParameterVariable.Name)"
                Continue
            } else {
                if ($Parameter.Aliases) {
                    # Use the first alias as the query string name.
                    $Query = ([String]$Parameter.Aliases[0])
                } else {
                    # If no aliases then use the name.
                    $Query = ([String]$ParameterVariable.Name)
                }
                $Value = ([String]$ParameterVariable.Value).ToLower()
                $QSCollection.Add($Query, $Value)
                Write-Verbose "Adding parameter $($Query) with value $($Value)"
            }
        }
        if ($Parameter.ParameterType.Name -eq 'Boolean') {
            Write-Verbose "Found Boolean param $($ParameterVariable.Name) with value $($ParameterVariable.Value)."
            if ($Parameter.Aliases) {
                # Use the first alias as the query string name.
                $Query = ([String]$Parameter.Aliases[0])
            } else {
                # If no aliases then use the name.
                $Query = ([String]$ParameterVariable.Name)
            }
            $Value = ([String]$ParameterVariable.Value).ToLower()
            $QSCollection.Add($Query, $Value)
            Write-Verbose "Adding parameter $($Query) with value $($Value)"
        }
        if (($Parameter.ParameterType.Name -eq 'Int32') -or ($Parameter.ParameterType.Name -eq 'Int64') -or ($Parameter.ParameterType.Name -eq 'Int32[]') -or ($Parameter.ParameterType.Name -eq 'Int64[]')) {
            Write-Verbose "Found Int or Int Array param $($ParameterVariable.Name) with value $($ParameterVariable.Value)."
            if (($ParameterVariable.Value -eq 0) -or ($null -eq $ParameterVariable.Value)) {
                Write-Verbose "Skipping unset param $($ParameterVariable.Name)"
                Continue
            } else {
                if ($Parameter.Aliases) {
                    # Use the first alias as the query string name.
                    $Query = ([String]$Parameter.Aliases[0])
                } else {
                    # If no aliases then use the name.
                    $Query = ([String]$ParameterVariable.Name)
                }
                $Value = $ParameterVariable.Value
                if (($Value -is [Array]) -and ($CommaSeparatedArrays)) {
                    Write-Verbose 'Building comma separated array string.'
                    $QueryValue = $Value -join ','
                    $QSCollection.Add($Query, $QueryValue)
                    Write-Verbose "Adding parameter $($Query) with value $($QueryValue)"
                } elseif (($Value -is [Array]) -and (-not $CommaSeparatedArrays)) {
                    foreach ($ArrayValue in $Value) {
                        $QSCollection.Add($Query, $ArrayValue)
                        Write-Verbose "Adding parameter $($Query) with value $($ArrayValue)"
                    }
                } else {
                    $QSCollection.Add($Query, $Value)
                    Write-Verbose "Adding parameter $($Query) with value $($Value)"
                }
            }
        }
        if (($Parameter.ParameterType.Name -eq 'DateTime') -or ($Parameter.ParameterType.Name -eq 'DateTime[]')) {
            Write-Verbose "Found DateTime or DateTime Array param $($ParameterVariable.Name) with value $($ParameterVariable.Value)."
            if ($null -eq $ParameterVariable.Value) {
                Write-Verbose "Skipping unset param $($ParameterVariable.Name)"
                Continue
            } else {
                if ($Parameter.Aliases) {
                    # Use the first alias as the query.
                    $Query = ([String]$Parameter.Aliases[0])
                } else {
                    # If no aliases then use the name.
                    $Query = ([String]$ParameterVariable.Name)
                }
                $Value = $ParameterVariable.Value
                if (($Value -is [Array]) -and ($CommaSeparatedArrays)) {
                    Write-Verbose 'Building comma separated array string.'
                    $QueryValue = $Value -join ','
                    $QSCollection.Add($Query, $QueryValue.ToUnixEpoch())
                    Write-Verbose "Adding parameter $($Query) with value $($QueryValue)"
                } elseif (($Value -is [Array]) -and (-not $CommaSeparatedArrays)) {
                    foreach ($ArrayValue in $Value) {
                        $QSCollection.Add($Query, $ArrayValue)
                        Write-Verbose "Adding parameter $($Query) with value $($ArrayValue)"
                    }
                } else {
                    $QSCollection.Add($Query, $Value)
                    Write-Verbose "Adding parameter $($Query) with value $($Value)"
                }
            }
        }
    }
    Write-Verbose "Query collection contains $($QSCollection | Out-String)"
    if ($AsString) {
        $QSBuilder.Query = $QSCollection.ToString()
        $Query = $QSBuilder.Query.ToString()
        return $Query
    } else {
        return $QSCollection
    }
}
#EndRegion '.\Private\New-x360RecoverQuery.ps1' 199
#Region '.\Private\Set-x360RecoverSecrets.ps1' -1

function Set-x360RecoverSecrets {
<#
.SYNOPSIS
    Sets the x360Recover connection information in a secret vault.
 
.DESCRIPTION
    This cmdlet sets the x360Recover connection information, including the URL, instance name, and API key, in a specified secret vault. It supports reading from and writing to the secret vault using the SecretManagement module.
 
.PARAMETER URL
    The URL of the x360Recover API instance.
 
.PARAMETER Instance
    The x360Recover instance name.
 
.PARAMETER ApiKey
    The client secret of the application.
 
.PARAMETER UseSecretManagement
    Use the Key Vault to store the connection information. This parameter is mandatory.
 
.PARAMETER VaultName
    The name of the secret vault to use.
 
.PARAMETER WriteToSecretVault
    Whether to write updated connection information to the secret vault.
 
.PARAMETER ReadFromSecretVault
    Whether to read the connection information from the secret vault.
 
.PARAMETER SecretPrefix
    The prefix to use for the secret names. Default is 'x360Recover'.
 
.EXAMPLE
    PS> Set-x360RecoverSecrets -URL "https://axapi.axcient.com/x360recover" -Instance "prod" -ApiKey "your-api-key" -UseSecretManagement -VaultName "MyVault" -WriteToSecretVault
 
    Sets the x360Recover connection information in the "MyVault" secret vault.
 
.INPUTS
    None. You cannot pipe objects to this cmdlet.
 
.OUTPUTS
    System.Void. This cmdlet does not produce any output.
 
#>

    [CmdletBinding()]
    [OutputType([System.Void])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Private function - no need to support.')]
    # Suppress the PSSA warning about using ConvertTo-SecureString with -AsPlainText. There's no viable alternative.
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'No viable alternative.')]
    # Suppress the PSSA warning about invoking empty members which is caused by our use of dynamic member names. This is a false positive.
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidInvokingEmptyMembers', '', Justification = 'False positive.')]
    param(
        # The URL of the x360Recover API instance.
        [URI]$URL,
        # The x360Recover instance name.
        [String]$Instance,
        # The client secret of the application.
        [String]$ApiKey,
        # Use the Key Vault to store the connection information.
        [Parameter(Mandatory)]
        [Switch]$UseSecretManagement,
        # The name of the secret vault to use.
        [String]$VaultName,
        # Whether to write updated connection information to the secret vault.
        [Switch]$WriteToSecretVault,
        # Whether to read the connection information from the secret vault.
        [Switch]$ReadFromSecretVault,
        # The prefix to use for the secret names.
        [String]$SecretPrefix = 'x360Recover'
    )
    # Check if the secret vault exists.
    $SecretVault = Get-SecretVault -Name $VaultName -ErrorAction SilentlyContinue
    if ($null -eq $SecretVault) {
        Write-Error ('Secret vault {0} does not exist.' -f $VaultName)
        exit 1
    }
    # Make sure we've been told to write to the secret vault.
    if ($false -eq $WriteToKeyVault) {
        Write-Error 'WriteToKeyVault must be specified.'
        exit 1
    }
    # Write the connection information to the secret vault.
    $Secrets = [Hashtable]@{}
    if ($null -ne $Script:x360RConnectionInformation.URL) {
        $Secrets.('{0}URL' -f $SecretPrefix) = $Script:x360RConnectionInformation.URL
    }
    if ($null -ne $Script:x360RConnectionInformation.Instance) {
        $Secrets.('{0}Instance' -f $SecretPrefix) = $Script:x360RConnectionInformation.Instance
    }
    if ($null -ne $Script:x360RConnectionInformation.ApiKey) {
        $Secrets.('{0}ApiKey' -f $SecretPrefix) = $Script:x360RConnectionInformation.ApiKey
    }
    if ($null -ne $Script:x360RConnectionInformation.UseSecretManagement) {
        $Secrets.('{0}UseSecretManagement' -f $SecretPrefix) = $Script:x360RConnectionInformation.UseSecretManagement.ToString()
    }
    if ($null -ne $Script:x360RConnectionInformation.WriteToSecretVault) {
        $Secrets.('{0}WriteToSecretVault' -f $SecretPrefix) = $Script:x360RConnectionInformation.WriteToSecretVault.ToString()
    }
    if ($null -ne $Script:x360RConnectionInformation.ReadFromSecretVault) {
        $Secrets.('{0}ReadFromSecretVault' -f $SecretPrefix) = $Script:x360RConnectionInformation.ReadFromSecretVault.ToString()
    }
    if ($null -ne $Script:x360RConnectionInformation.VaultName) {
        $Secrets.('{0}VaultName' -f $SecretPrefix) = $Script:x360RConnectionInformation.VaultName
    }
    foreach ($Secret in $Secrets.GetEnumerator()) {
        Write-Verbose ('Processing secret {0} for vault storage.' -f $Secret.Key)
        Write-Debug ('Secret {0} has type {1}.' -f $Secret.Key, $Secret.Value.GetType().Name)
        Write-Debug ('Secret {0} has value {1}.' -f $Secret.Key, $Secret.Value.ToString())
        $SecretName = $Secret.Key
        $SecretValue = $Secret.Value
        if ([String]::IsNullOrEmpty($SecretValue) -or ($null -eq $SecretValue)) {
            Write-Verbose ('Secret {0} is null. Skipping.' -f $SecretName)
            continue
        }
        Set-Secret -Vault $VaultName -Name $SecretName -Secret $SecretValue -ErrorAction Stop
        Write-Verbose ('Secret {0} written to secret vault {1}.' -f $SecretName, $VaultName)
    }
}
#EndRegion '.\Private\Set-x360RecoverSecrets.ps1' 119
#Region '.\Public\Appliance\Get-x360RecoverAppliance.ps1' -1

function Get-x360RecoverAppliance {
<#
.SYNOPSIS
    Retrieves appliance information from x360Recover.
 
.DESCRIPTION
    This cmdlet retrieves appliance information from the x360Recover system. It can retrieve information for a specific appliance by ID or for multiple appliances based on various filters such as service ID and whether to include device information.
 
.PARAMETER applianceId
    The ID of the appliance to retrieve information for. This parameter is used in the 'Single' parameter set and can be piped.
 
.PARAMETER serviceId
    The service ID to filter appliances. This parameter is optional.
 
.PARAMETER includeDevices
    If specified, includes short appliance information in the response. This parameter can be used in both 'Single' and 'Multi' parameter sets.
 
.EXAMPLE
    PS> Get-x360RecoverAppliance -applianceId 12345
 
    Retrieves information for the appliance with ID 12345.
 
.EXAMPLE
    PS> Get-x360RecoverAppliance -serviceId "ABCD" -includeDevices $true
 
    Retrieves information for appliances with service ID "ABCD" and includes short appliance information in the response.
 
.INPUTS
    System.Int64. The appliance ID can be piped to this cmdlet.
 
.OUTPUTS
    System.Object. The appliance information retrieved from x360Recover.
 
#>

    [CmdletBinding(DefaultParameterSetName = 'Multi')]
    [OutputType([Object])]
    [MetadataAttribute(
        '/appliance',
        'get',
        '/appliance/{appliance_id}',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The ID of the appliance to return
        [Parameter(Mandatory, ParameterSetName = 'Single', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('appliance_id','id')]
        [int64]$applianceId,
        # Unique serial number of the service(4 symbols)
        [ValidateLength(4,4)]
        [Parameter(ParameterSetName = 'Multi', Position = 1)]
        [Alias('service_id')]
        [string]$serviceId,
        # Include short appliance information to response or not
        [Parameter(ParameterSetName = 'Single', Position = 2)]
        [Parameter(ParameterSetName = 'Multi', Position = 2)]
        [Alias('include_devices')]
        [nullable[bool]]$includeDevices
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        write-verbose $MyInvocation
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-x360RecoverQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($applianceId) {
                Write-Verbose ('Getting appliance with id {0}.' -f $applianceId)
                $Resource = ('appliance/{0}' -f $applianceId)
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                }
            } else {
                Write-Verbose 'Retreiving all appliances'
                $Resource = 'appliance'
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                }
            }
            try {
                $gResults = New-x360RecoverGETRequest @RequestParams
                return $gResults
            } catch {
                if (-not $gResults) {
                    if ($applianceId) {
                        throw ('Appliance with id {0} not found.' -f $applianceId)
                    } else {
                        throw 'No appliances found.'
                    }
                }
            }
        } catch {
            New-x360RecoverError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Appliance\Get-x360RecoverAppliance.ps1' 100
#Region '.\Public\Appliance\Get-x360RecoverApplianceByClient.ps1' -1

function Get-x360RecoverApplianceByClient {
<#
.SYNOPSIS
    Retrieves appliance information for a specified client from x360Recover.
 
.DESCRIPTION
    This cmdlet retrieves appliance information for a specified client from the x360Recover system. It can filter appliances based on the client ID and optionally include detailed information.
 
.PARAMETER clientId
    The ID of the client to retrieve appliance information for. This parameter is mandatory and can be piped.
 
.PARAMETER includeDetails
    If specified, includes detailed information for each appliance. This parameter is optional.
 
.EXAMPLE
    PS> Get-x360RecoverApplianceByClient -clientId 12345
 
    Retrieves appliance information for the client with ID 12345.
 
.EXAMPLE
    PS> Get-x360RecoverApplianceByClient -clientId 12345 -includeDetails $true
 
    Retrieves detailed appliance information for the client with ID 12345.
 
.INPUTS
    System.Int64. The client ID can be piped to this cmdlet.
 
.OUTPUTS
    System.Object. The appliance information retrieved from x360Recover.
 
#>

    [CmdletBinding()]
    [OutputType([Object])]
    [MetadataAttribute(
        '/client/{client_id}/appliance',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The ID of the appliance to return
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('client_id','id')]
        [int64]$clientId,
        # Include short appliance information to response or not
        [Parameter(Position = 1)]
        [Alias('include_devices')]
        [nullable[bool]]$includeDevices
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        write-verbose $MyInvocation
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-x360RecoverQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($clientId) {
                Write-Verbose ('Getting appliance with client id {0}.' -f $clientId)
                $Resource = ('client/{0}/appliance' -f $clientId)
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                }
            }
            try {
                $gResults = New-x360RecoverGETRequest @RequestParams
                return $gResults
            } catch {
                if (-not $gResults) {
                    if ($applianceId) {
                        throw ('Appliance with client id {0} not found.' -f $client)
                    } else {
                        throw 'No appliances found.'
                    }
                }
            }
        } catch {
            New-x360RecoverError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Appliance\Get-x360RecoverApplianceByClient.ps1' 82
#Region '.\Public\Client\Get-x360RecoverClient.ps1' -1

function Get-x360RecoverClient {
<#
.SYNOPSIS
    Retrieves client information from x360Recover.
 
.DESCRIPTION
    This cmdlet retrieves client information from the x360Recover system. It can retrieve information for a specific client by ID or for multiple clients. Optionally, it can include short appliance information in the response.
 
.PARAMETER clientId
    The ID of the client to retrieve information for. This parameter is used in the 'Single' parameter set and can be piped.
 
.PARAMETER includeAppliances
    If specified, includes short appliance information in the response. This parameter can be used in both 'Single' and 'Multi' parameter sets.
 
.EXAMPLE
    PS> Get-x360RecoverClient -clientId 12345
 
    Retrieves information for the client with ID 12345.
 
.EXAMPLE
    PS> Get-x360RecoverClient -includeAppliances $true
 
    Retrieves information for all clients and includes short appliance information in the response.
 
.INPUTS
    System.Int64. The client ID can be piped to this cmdlet.
 
.OUTPUTS
    System.Object. The client information retrieved from x360Recover.
 
#>

    [CmdletBinding(DefaultParameterSetName = 'Multi')]
    [OutputType([Object])]
    [MetadataAttribute(
        '/client',
        'get',
        '/client/{client_id}',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        [Parameter(Mandatory, ParameterSetName = 'Single', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('client_id','id')]
        [int64]$clientId,
        # Include short appliance information to response or not
        [Parameter(ParameterSetName = 'Multi', Position = 1)]
        [Parameter(ParameterSetName = 'Single', Position = 1)]
        [Alias('include_appliances')]
        [nullable[bool]]$includeAppliances
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        write-verbose $MyInvocation
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-x360RecoverQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($clientId) {
                Write-Verbose ('Getting client with id {0}.' -f $clientId)
                $Resource = ('client/{0}' -f $clientId)
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                }
            } else {
                Write-Verbose 'Retreiving all clients'
                $Resource = 'client'
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                }
            }
            try {
                $gResults = New-x360RecoverGETRequest @RequestParams
                return $gResults
            } catch {
                if (-not $gResults) {
                    if ($clientId) {
                        throw ('Client with id {0} not found.' -f $clientId)
                    } else {
                        throw 'No clients found.'
                    }
                }
            }
        } catch {
            New-x360RecoverError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Client\Get-x360RecoverClient.ps1' 91
#Region '.\Public\Connect-x360Recover.ps1' -1


function Connect-x360Recover {
<#
.SYNOPSIS
    Connects to the x360Recover API instance.
 
.DESCRIPTION
    This function initializes the module, checks for the SecretManagement module, and retrieves secrets from a secret vault if specified. It also sets up the connection information for the x360Recover API instance.
 
.PARAMETER Api
    The API Key for authentication.
 
.PARAMETER Instance
    The Axcient API Instance to connect to. Choose from 'prod' or 'mock'.
 
.PARAMETER UseSecretManagement
    Switch to use the SecretManagement module to store and retrieve the API key.
 
.PARAMETER VaultName
    The name of the secret vault to use.
 
.PARAMETER WriteToSecretVault
    Switch to write the updated credentials to the secret vault.
 
.PARAMETER ReadFromSecretVault
    Switch to read the credentials from the secret vault.
 
.PARAMETER VaultEntryPrefix
    The prefix to add to the name of the secrets stored in the secret vault.
 
.EXAMPLE
    Connect-x360Recover -Api 'your-api-key' -Instance 'prod'
 
    Connects to the production instance of the x360Recover API using the provided API key.
 
.EXAMPLE
    Connect-x360Recover -UseSecretManagement -VaultName 'MyVault' -ReadFromSecretVault
 
    Connects to the x360Recover API using credentials stored in the 'MyVault' secret vault.
 
.INPUTS
    None. You cannot pipe objects to this function.
 
.OUTPUTS
    None. This function does not produce any output.
 
.NOTES
    Ensure that the SecretManagement module is installed and a secret vault is created if using the secret management features.
#>

    [CmdletBinding( DefaultParameterSetName = 'Default Auth' )]
    [MetadataAttribute('IGNORE')]
    [OutputType([System.Void])]
    param (
        # APi Key for authentication
        [Parameter(ParameterSetName = 'Default Auth')]
        [Parameter( ParameterSetName = 'Secret Vault Write' )]
        [string]$ApiKey,
        # The Axcient API Instance to connect to. Choose From 'prod' or 'mock'.
        [Parameter(ParameterSetName = 'Default Auth')]
        [Parameter( ParameterSetName = 'Secret Vault Write' )]
        [ValidateSet('prod', 'mock')]
        [string]$Instance,
        # Use the SecretManagement module to store and retrieve the API key.
        [Parameter(ParameterSetName = 'Default Auth')]
        [Parameter(ParameterSetName = 'Secret Vault Write')]
        [Parameter(ParameterSetName = 'Secret Vault Read')]
        [switch]$UseSecretManagement,
        # The name of the secret vault to use.
        [Parameter(ParameterSetName = 'Default Auth')]
        [Parameter( Mandatory, ParameterSetName = 'Secret Vault Write' )]
        [Parameter( Mandatory, ParameterSetName = 'Secret Vault Read' )]
        [String]$VaultName,
        # Write the updated credentials to the secret vault.
        [Parameter(ParameterSetName = 'Default Auth')]
        [Parameter(Mandatory,ParameterSetName = 'Secret Vault Write')]
        [Parameter(ParameterSetName = 'Secret Vault Read')]
        [switch]$WriteToSecretVault,
        # Read the credentials from the secret vault.
        [Parameter(ParameterSetName = 'Secret Vault Read')]
        [switch]$ReadFromSecretVault,
        # The prefix to add to the name of the secrets stored in the secret vault.
        [Parameter( ParameterSetName = 'Secret Vault Write' )]
        [Parameter( ParameterSetName = 'Secret Vault Read' )]
        [String]$VaultEntryPrefix = 'x360Recover'

    )

    begin {
        # Set the x360Recover instances.
        [hashtable]$Script:x360RInstances = @{
            'prod' = 'https://axapi.axcient.com/x360recover'
            'mock' = 'https://ax-pub-recover.wiremockapi.cloud'
        }
    }

    process {
        # Test for secret managment module
        if ($UseSecretManagement -or $Script:x360RConnectionInformation.UseSecretManagement) {
            if (-not (Get-Module -Name 'Microsoft.PowerShell.SecretManagement' -ListAvailable)) {
                Write-Error 'Secret management module not installed, please install the module and try again.'
                throw 'Secret management module not installed, please install the module and try again.'
            }
            if (-not (Get-SecretVault)) {
                Write-Error 'No secret vaults found, please create a secret vault and try again.'
                throw 'No secret vaults found, please create a secret vault and try again.'
            }
            if ($ReadFromSecretVault -or $Script:x360RConnectionInformation.ReadFromSecretVault) {
                Write-Verbose 'Reading authentication information from secret vault.'
                Get-x360RecoverSecrets -VaultName $VaultName
            }
        }
        # Get the x360 instance URL.
        if ($Instance) {
            Write-Verbose "Using instance $($Instance) with URL $($Script:x360RInstances[$Instance])"
            $URL = $Script:x360RInstances[$Instance]
        }
        else {
            Write-Verbose 'No instance specified, using default production instance.'
            $URL = $Script:x360RInstances['prod']
        }

        $ConnectionInformation = @{
            URL = $URL
            Instance = $Instance
            ApiKey = $ApiKey
            UseSecretManagement = $UseSecretManagement
            VaultName = $VaultName
            WriteToSecretVault = $WriteToSecretVault
            ReadFromSecretVault = $ReadFromSecretVault
            SecretPrefix = $VaultEntryPrefix
        }
        Set-Variable -Name 'x360RConnectionInformation' -Value $ConnectionInformation -Visibility Private -Scope Script -Force

        Write-Verbose "Connection information set to: $($Script:x360RConnectionInformation | Format-List | Out-String)"
        # If we're using secret management, store the authentication information we need.
        if ($Script:x360RConnectionInformation.UseSecretManagement -and $Script:x360RConnectionInformation.WriteToSecretVault) {
            $SecretManagementParams = @{
                URL = $Script:x360RConnectionInformation.URL
                Instance = $Script:x360RConnectionInformation.Instance
                ApiKey = $Script:x360RConnectionInformation.ApiKey
                UseSecretManagement = $Script:x360RConnectionInformation.UseSecretManagement
                VaultName = $Script:x360RConnectionInformation.VaultName
                WriteToSecretVault = $Script:x360RConnectionInformation.WriteToSecretVault
                ReadFromSecretVault = $Script:x360RConnectionInformation.ReadFromSecretVault
                SecretPrefix = $Script:x360RConnectionInformation.SecretPrefix
            }
            Write-Verbose 'Using secret management to store credentials.'
            Set-x360RecoverSecrets @SecretManagementParams
        }

    }

    end {

    }
}
#EndRegion '.\Public\Connect-x360Recover.ps1' 157
#Region '.\Public\Device\Get-x360RecoverDevice.ps1' -1

function Get-x360RecoverDevice {
<#
.SYNOPSIS
    Retrieves AutoVerify information for a specified device.
 
.DESCRIPTION
    This cmdlet retrieves AutoVerify information for a specified device from the x360Recover system. It sends a GET request to the x360Recover API and returns the AutoVerify details for the given device ID.
 
.PARAMETER deviceId
    The ID of the device to retrieve AutoVerify information for. This parameter is mandatory and can be piped.
 
.EXAMPLE
    PS> Get-x360RecoverDeviceAutoVerify -deviceId 12345
 
    Retrieves AutoVerify information for the device with ID 12345.
 
.INPUTS
    System.Int64. The device ID can be piped to this cmdlet.
 
.OUTPUTS
    System.Object. The AutoVerify information retrieved from x360Recover.
 
#>

    [CmdletBinding( DefaultParameterSetName = 'Multi' )]
    [OutputType([Object])]
    [MetadataAttribute(
        '/device',
        'get',
        '/device/{device_id}',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Return infomation about a single vault
        [Parameter(ParameterSetName = 'Single', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('device_id','id')]
        [Int64]$deviceId,
        # Records limit for pagination
        [Parameter(ParameterSetName = 'Multi', Position = 1)]
        [Int64]$limit,
        # Records offset for pagination
        [Parameter(ParameterSetName = 'Multi', Position = 2)]
        [Int64]$offset
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        write-verbose $MyInvocation
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-x360RecoverQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($deviceId) {
                Write-Verbose ('Getting device with id {0}.' -f $deviceId)
                $Resource = ('device/{0}' -f $deviceId)
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                }
            } else {
                Write-Verbose 'Retreiving all devices'
                $Resource = 'device'
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                }
            }
            try {
                $gResults = New-x360RecoverGETRequest @RequestParams
                return $gResults
            } catch {
                if (-not $gResults) {
                    if ($deviceId) {
                        throw ('Device with id {0} not found.' -f $deviceId)
                    } else {
                        throw 'No devices found.'
                    }
                }
            }
        } catch {
            New-x360RecoverError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Device\Get-x360RecoverDevice.ps1' 85
#Region '.\Public\Device\Get-x360RecoverDeviceAutoVerify.ps1' -1

function Get-x360RecoverDeviceAutoVerify {
<#
.SYNOPSIS
    Retrieves AutoVerify information for a specified device.
 
.DESCRIPTION
    This cmdlet retrieves AutoVerify information for a specified device from the x360Recover system. It sends a GET request to the x360Recover API and returns the AutoVerify details for the given device ID.
 
.PARAMETER deviceId
    The ID of the device to retrieve AutoVerify information for. This parameter is mandatory and can be piped.
 
.EXAMPLE
    PS> Get-x360RecoverDeviceAutoVerify -deviceId 12345
 
    Retrieves AutoVerify information for the device with ID 12345.
 
.INPUTS
    System.Int64. The device ID can be piped to this cmdlet.
 
.OUTPUTS
    System.Object. The AutoVerify information retrieved from x360Recover.
 
#>

    [CmdletBinding()]
    [OutputType([Object])]
    [MetadataAttribute(
        '/device/{device_id}/autoverify',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Returns information about AutoVerify for the given protected system by it's id.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('device_id','id')]
        [Int64]$deviceId
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        write-verbose $MyInvocation
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-x360RecoverQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($deviceId) {
                Write-Verbose ('Getting autoverify information for device with id {0}.' -f $deviceId)
                $Resource = ('device/{0}/autoverify' -f $deviceId)
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                }
            }
            try {
                $gResults = New-x360RecoverGETRequest @RequestParams
                return $gResults
            } catch {
                if (-not $gResults) {
                    if ($deviceId) {
                        throw ('Device with id {0} not found.' -f $deviceId)
                    } else {
                        throw 'No devices found.'
                    }
                }
            }
        } catch {
            New-x360RecoverError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Device\Get-x360RecoverDeviceAutoVerify.ps1' 70
#Region '.\Public\Device\Get-x360RecoverDeviceByClient.ps1' -1

function Get-x360RecoverDeviceByClient {
<#
.SYNOPSIS
    Retrieves device information for a specified client from x360Recover.
 
.DESCRIPTION
    This cmdlet retrieves device information for a specified client from the x360Recover system. It can filter devices based on the service ID and whether they are D2C (Direct-to-Cloud) devices.
 
.PARAMETER clientId
    The ID of the client to retrieve device information for. This parameter is mandatory and can be piped.
 
.PARAMETER serviceId
    The SID of the service (4 symbols). This parameter is optional.
 
.PARAMETER d2cOnly
    If specified, includes only D2C (Direct-to-Cloud) devices. This parameter is optional.
 
.EXAMPLE
    PS> Get-x360RecoverDeviceByClient -clientId 12345
 
    Retrieves device information for the client with ID 12345.
 
.EXAMPLE
    PS> Get-x360RecoverDeviceByClient -clientId 12345 -serviceId "ABCD"
 
    Retrieves device information for the client with ID 12345 and service ID "ABCD".
 
.EXAMPLE
    PS> Get-x360RecoverDeviceByClient -clientId 12345 -d2cOnly $true
 
    Retrieves only D2C devices for the client with ID 12345.
 
.INPUTS
    System.Int64. The client ID can be piped to this cmdlet.
 
.OUTPUTS
    System.Object. The device information retrieved from x360Recover.
 
#>

    [CmdletBinding()]
    [OutputType([Object])]
    [MetadataAttribute(
        '/client/{client_id}/device',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Return infomation about a single vault
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('client_id','id')]
        [Int64]$clientId,
        # the SID of the service (4 symbols)
        [ValidateLength(4,4)]
        [Parameter(Position = 1)]
        [Alias('service_id')]
        [string]$serviceId,
        # Include D2C devices only
        [Parameter(Position = 2)]
        [Alias('d2c_only')]
        [nullable[boolean]]$d2cOnly
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        write-verbose $MyInvocation
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-x360RecoverQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($clientId) {
                Write-Verbose ('Getting devices for client id {0}.' -f $clientId)
                $Resource = ('client/{0}/device' -f $clientId)
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                }
            }
            try {
                $gResults = New-x360RecoverGETRequest @RequestParams
                return $gResults
            } catch {
                if (-not $gResults) {
                    if ($clientId) {
                        throw ('Client with id {0} not found.' -f $clientId)
                    } else {
                        throw 'No devices found.'
                    }
                }
            }
        } catch {
            New-x360RecoverError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Device\Get-x360RecoverDeviceByClient.ps1' 95
#Region '.\Public\Device\Get-x360RecoverDeviceRestorePoint.ps1' -1

function Get-x360RecoverDeviceRestorePoint{
<#
.SYNOPSIS
    Retrieves restore point information for a specified device.
 
.DESCRIPTION
    This cmdlet retrieves restore point information for a specified device from the x360Recover system. It sends a GET request to the x360Recover API and returns the restore point details for the given device ID.
 
.PARAMETER deviceId
    The ID of the device to retrieve restore point information for. This parameter is mandatory and can be piped.
 
.EXAMPLE
    PS> Get-x360RecoverDeviceRestorePoint -deviceId 12345
 
    Retrieves restore point information for the device with ID 12345.
 
.INPUTS
    System.Int64. The device ID can be piped to this cmdlet.
 
.OUTPUTS
    System.Object. The restore point information retrieved from x360Recover.
 
#>

    [CmdletBinding()]
    [OutputType([Object])]
    [MetadataAttribute(
        '/device/{device_id}/restore_point',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Returns information about AutoVerify for the given protected system by it's id.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('device_id','id')]
        [Int64]$deviceId
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        write-verbose $MyInvocation
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-x360RecoverQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($deviceId) {
                Write-Verbose ('Getting restore point information for device with id {0}.' -f $deviceId)
                $Resource = ('device/{0}/restore_point' -f $deviceId)
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                }
            }
            try {
                $gResults = New-x360RecoverGETRequest @RequestParams
                return $gResults
            } catch {
                if (-not $gResults) {
                    if ($deviceId) {
                        throw ('Device with id {0} not found.' -f $deviceId)
                    } else {
                        throw 'No devices found.'
                    }
                }
            }
        } catch {
            New-x360RecoverError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Device\Get-x360RecoverDeviceRestorePoint.ps1' 70
#Region '.\Public\Invoke-x360RecoverRequest.ps1' -1


function Invoke-x360RecoverRequest {
<#
.SYNOPSIS
    Sends an HTTP request to the specified URI using the specified method.
 
.DESCRIPTION
    This cmdlet sends an HTTP request to the specified URI using the specified method. It supports GET, POST, PUT, PATCH, and DELETE methods. Optionally, it can include a request body and return the raw response.
 
.PARAMETER Method
    The HTTP method to use. Valid values are GET, POST, PUT, PATCH, and DELETE.
 
.PARAMETER Uri
    The URI to send the request to. Must be a valid HTTP or HTTPS URI.
 
.PARAMETER Body
    The body of the request. Must be a valid JSON string if provided.
 
.PARAMETER Raw
    If specified, returns the raw response without converting from JSON.
 
.EXAMPLE
    PS> Invoke-x360RecoverRequest -Method GET -Uri "https://axapi.axcient.com/x360recover/device"
 
    Sends a GET request to the x360 Device endpoint and returns JSON reponse.
 
.EXAMPLE
    PS> Invoke-x360RecoverRequest -Method POST -Uri "https://axapi.axcient.com/x360recover" -Body '{"key":"value"}'
 
    Sends a POST request with the specified body to the specified URI and returns the response.
 
.EXAMPLE
    PS> Invoke-x360RecoverRequest -Method GET -Uri "https://axapi.axcient.com/x360recover/organization" -Raw
 
    Sends a GET request to the x360Organization endpoint and returns the raw response.
 
.INPUTS
    None. You cannot pipe objects to this function.
 
.OUTPUTS
    System.Object. The response from the HTTP request, either as a raw string or a converted JSON object.
 
#>

    [Cmdletbinding()]
    [OutputType([Object])]
    [MetadataAttribute('IGNORE')]
    param (
        # HTTP method to use.
        [Parameter(Mandatory, Position = 0, ValueFromPipelineByPropertyName)]
        [ValidateSet('GET', 'POST', 'PUT', 'PATCH', 'DELETE')]
        [String]$Method,
        # The URI to send the request to.
        [Parameter(Mandatory, Position = 1, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ValidatePattern('^https?://')]
        [String]$Uri,
        # The body of the request.
        [Parameter(Position = 2)]
        [ValidateScript({ try { $null = $args[0] | ConvertFrom-Json; $true } catch { $false } })]
        [String]$Body,
        # Return the raw response - don't convert from JSON.
        [Switch]$Raw

    )
    begin {
        if ($null -eq $Script:x360RConnectionInformation) {
            throw "Missing x360Recover connection information, please run 'Connect-x360Recover' first."
        }

        $AuthHeaders = @{
            'x-api-key' = $Script:x360RConnectionInformation.APIKey
            'accept' = 'application/json'
        }
    }
    process {
        $WebRequestParams = @{
            Method = $Method
            Uri = $Uri
            Headers = $AuthHeaders
        }

        if ($Body) {
            Write-Verbose ('Body is {0}' -f ($Body | Out-String))
            $WebRequestParams.Add('Body', $Body)
        } else {
            Write-Verbose 'No body present.'
        }

        try {
            Write-Verbose ('Making a {0} request to {1}' -f $Method, $Uri)
            $Response = Invoke-WebRequest @WebRequestParams
            Write-Verbose ('Response status code: {0}' -f $Response.StatusCode)
            Write-Verbose ('Response headers: {0}' -f ($Response.Headers | Out-String))
            Write-Verbose ('Raw response: {0}' -f ($Response | Out-String))

            if ($Response.Content) {
                if ($Raw) {
                    Write-Verbose 'Raw switch present, returning raw response.'
                    return $Response.Content
                } else {
                    Write-Verbose 'Raw switch not present, converting response from JSON.'
                    return $Response.Content | ConvertFrom-Json
                }
            }
            else {
                Write-Verbose 'No response content.'
                if ($Response.StatusCode -and $WebRequestParams.Method -ne 'GET') {
                    Write-Verbose ('Request completed with status code {0}. No content in the response - returning Status Code.' -f $Response.StatusCode)
                    return $Response.StatusCode
                } else {
                    Write-Verbose 'Request completed with no results and/or no status code.'
                    return @{}
                }
            }
        } catch {
            Write-Verbose ('Caught an exception: {0}' -f $_)
            throw $_
        }
    }
}
#EndRegion '.\Public\Invoke-x360RecoverRequest.ps1' 120
#Region '.\Public\Job\Get-x360RecoverBackupJob.ps1' -1

function Get-x360RecoverBackupJob {
<#
.SYNOPSIS
    Retrieves backup job information for a specified client and device.
 
.DESCRIPTION
    This cmdlet retrieves backup job information for a specified client and device from the x360Recover system. It can retrieve information for a specific job by ID or for all jobs associated with a client and device.
 
.PARAMETER clientId
    The unique ID of the client. This parameter is mandatory and can be piped.
 
.PARAMETER deviceId
    The unique ID of the device. This parameter is mandatory and can be piped.
 
.PARAMETER jobId
    The unique ID of the job. This parameter is mandatory for the 'Single' parameter set and can be piped.
 
.EXAMPLE
    PS> Get-x360RecoverBackupJob -clientId 12345 -deviceId 67890
 
    Retrieves all backup jobs for the specified client and device.
 
.EXAMPLE
    PS> Get-x360RecoverBackupJob -clientId 12345 -deviceId 67890 -jobId 112233
 
    Retrieves the backup job with the specified job ID for the specified client and device.
 
.INPUTS
    System.Int64. The client ID, device ID, and job ID can be piped to this cmdlet.
 
.OUTPUTS
    System.Object. The backup job information retrieved from x360Recover.
 
#>

    [CmdletBinding( DefaultParameterSetName = 'Multi' )]
    [OutputType([Object])]
    [MetadataAttribute(
        '/client/{client_id}/device/{device_id}/job',
        'get',
        '/client/{client_id}/device/{device_id}/job/{job_id}',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The unique ID of the client
        [Parameter(Mandatory, ParameterSetName = 'Multi', Position = 0, ValueFromPipelineByPropertyName)]
        [Parameter(Mandatory, ParameterSetName = 'Single', Position = 0,  ValueFromPipelineByPropertyName)]
        [Alias('client_id')]
        [Int64]$clientId,
        # The unique ID of the device
        [Parameter(Mandatory, ParameterSetName = 'Multi', Position = 1, ValueFromPipelineByPropertyName)]
        [Parameter(Mandatory, ParameterSetName = 'Single', Position = 1, ValueFromPipelineByPropertyName)]
        [Alias('device_id','id')]
        [int64]$deviceId,
        # The unique ID of the job
        [Parameter(Mandatory, ParameterSetName = 'Single', Position = 2,ValueFromPipelineByPropertyName)]
        [Alias('job_id')]
        [int64]$jobId
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        write-verbose $MyInvocation
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-x360RecoverQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($clientId -and $deviceId) {
                if ($jobId) {
                    Write-Verbose ('Getting backup job with client id {0}, device id {1}, and job id {2}.' -f $clientId,$deviceId,$jobId)
                    $Resource = ('client/{0}/device/{1}/job/{2}' -f $clientId,$deviceId,$jobId)
                    $RequestParams = @{
                        Resource = $Resource
                        QSCollection = $QSCollection
                    }
                } else {
                Write-Verbose ('Getting backup jobs for client id {0} and device id {1}.' -f $clientId,$deviceId)
                $Resource = ('client/{0}/device/{1}/job' -f $clientId,$deviceId)
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                    }
                }
            }
            try {
                $gResults = New-x360RecoverGETRequest @RequestParams
                return $gResults
            } catch {
                if (-not $gResults) {
                    if ($clientId -and $deviceId) {
                        throw ('Job with client id {0} and device id {1} not found.' -f $clientId,$deviceId)
                    } else {
                        throw 'No jobs found.'
                    }
                }
            }
        } catch {
            New-x360RecoverError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Job\Get-x360RecoverBackupJob.ps1' 102
#Region '.\Public\Job\Get-x360RecoverBackupJobHistory.ps1' -1

function Get-x360RecoverBackupJobHistory {
<#
.SYNOPSIS
    Retrieves the backup job history for a specified client, device, and job.
 
.DESCRIPTION
    This cmdlet retrieves the backup job history for a specified client, device, and job from the x360Recover system. It supports pagination and filtering by start time.
 
.PARAMETER clientId
    The ID of the client to retrieve backup job history for. This parameter is mandatory.
 
.PARAMETER deviceId
    The ID of the device to retrieve backup job history for. This parameter is mandatory.
 
.PARAMETER jobId
    The ID of the job to retrieve backup job history for. This parameter is mandatory.
 
.PARAMETER limit
    The maximum number of records to return for pagination. This parameter is optional.
 
.PARAMETER offset
    The number of records to skip for pagination. This parameter is optional.
 
.PARAMETER jobsAfterUnixEpoch
    The minimum backup start time value as a Unix timestamp. This parameter is optional.
 
.PARAMETER jobsAfter
    The minimum backup start time value as a DateTime object. This parameter is optional.
 
.EXAMPLE
    PS> Get-x360RecoverBackupJobHistory -clientId 123 -deviceId 456 -jobId 789
 
    Retrieves the backup job history for the specified client, device, and job.
 
.EXAMPLE
    PS> Get-x360RecoverBackupJobHistory -clientId 123 -deviceId 456 -jobId 789 -limit 10 -offset 20
 
    Retrieves the backup job history for the specified client, device, and job with pagination.
 
.EXAMPLE
    PS> Get-x360RecoverBackupJobHistory -clientId 123 -deviceId 456 -jobId 789 -jobsAfter (Get-Date "2023-01-01")
 
    Retrieves the backup job history for the specified client, device, and job starting after January 1, 2023.
 
.INPUTS
    System.Int32. The client ID, device ID, and job ID can be piped to this cmdlet.
 
.OUTPUTS
    System.Object. The backup job history information retrieved from x360Recover.
 
#>

    [CmdletBinding()]
    [OutputType([Object])]
    [MetadataAttribute(
        '/client/{client_id}/device/{device_id}/job/{job_id}/history',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The unique ID of the client
        [Parameter(Mandatory, Position = 0, ValueFromPipelineByPropertyName)]
        [Alias('client_id')]
        [Int64]$clientId,
        # The unique ID of the device
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [Alias('device_id','id')]
        [int64]$deviceId,
        # The unique ID of the job
        [Parameter(Mandatory, Position = 2, ValueFromPipelineByPropertyName)]
        [Alias('job_id')]
        [int64]$jobId,
        # Records limit for pagination
        [Parameter(Position = 3)]
        [Int64]$limit,
        # Records offset for pagination
        [Parameter(Position = 4)]
        [Int64]$offset,
        # unix timestamp of minimum backup start time value
        [Parameter(Position = 5)]
        [Alias('starttime_begin','startTimeBegin')]
        [int64]$jobsAfterUnixEpoch,
        # unix timestamp of minimum backup start time value
        [Parameter(Position = 5)]
        [dateTime]$jobsAfter

    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        Write-verbose $MyInvocation
        $Parameters = (Get-Command -Name $CommandName).Parameters
        #if the datetime parameter is passed, convert it to unix epoch
        if ($jobStartTime) {
            [Int64]$jobsAfterUnixEpoch = ConvertTo-UnixEpoch -DateTime $jobsAfter
            $null = $Parameters.Remove('jobsAfter')
        }
        $QSCollection = New-x360RecoverQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($clientId -and $deviceId -and $jobId) {
                Write-Verbose ('Getting backup job history with client id {0}, device id {1}, and job id {2}.' -f $clientId,$deviceId,$jobId)
                $Resource = ('client/{0}/device/{1}/job/{2}/history' -f $clientId,$deviceId,$jobId)
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                }
            }
            try {
                $gResults = New-x360RecoverGETRequest @RequestParams
                return $gResults
            } catch {
                if (-not $gResults) {
                    if ($clientId -and $deviceId) {
                        throw ('History with client id {0}, device id {1}, and job id {2} not found.' -f $clientId,$deviceId,$jobId)
                    } else {
                        throw 'No job history found.'
                    }
                }
            }
        } catch {
            New-x360RecoverError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Job\Get-x360RecoverBackupJobHistory.ps1' 125
#Region '.\Public\Organization\Get-x360RecoverOrganization.ps1' -1

function Get-x360RecoverOrganization {
<#
.SYNOPSIS
    Retrieves organization information from x360Recover.
 
.DESCRIPTION
    This cmdlet retrieves organization information from x360Recover using a GET request. It fetches details about the organization configured in the x360Recover system.
 
.PARAMETER None
    This cmdlet does not take any parameters.
 
.EXAMPLE
    PS> Get-x360RecoverOrganization
 
    Retrieves information about the organization from x360Recover.
 
.INPUTS
    None. You cannot pipe objects to this cmdlet.
 
.OUTPUTS
    System.Object. The organization information retrieved from x360Recover.
 
#>

    [CmdletBinding()]
    [OutputType([Object])]
    [MetadataAttribute(
        '/organization',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param()
    begin {    }
    process {
        try {
            Write-Verbose 'Retreiving organization information'
            $Resource = 'organization'
            $RequestParams = @{
                Resource = $Resource
            }

            try {
                $gResults = New-x360RecoverGETRequest @RequestParams
                return $gResults
            } catch {
                if (-not $gResults) {
                    throw 'Organization not found.'
                }
            }
        } catch {
            New-x360RecoverError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Organization\Get-x360RecoverOrganization.ps1' 54
#Region '.\Public\Vault\Get-x360RecoverVault.ps1' -1

function Get-x360RecoverVault {
<#
.SYNOPSIS
    Retrieves information about x360Recover vaults.
 
.DESCRIPTION
    This cmdlet retrieves information about x360Recover vaults. It can retrieve information for a specific vault by ID or for multiple vaults based on various filters such as vault type, active status, URL presence, and limit. Optionally, it can include the device list for each vault.
 
.PARAMETER vaultId
    The ID of the vault to return. This parameter is used in the 'Single' parameter set and can be piped.
 
.PARAMETER vaultType
    Filter to return only private or only cloud vaults. This parameter is used in the 'Multi' parameter set.
 
.PARAMETER active
    Filter to return only vaults with active status. This parameter is used in the 'Multi' parameter set.
 
.PARAMETER withUrl
    Filter to return only vaults with a URL present. This parameter is used in the 'Multi' parameter set.
 
.PARAMETER limit
    The maximum number of vaults to return in the response. This parameter is used in the 'Multi' parameter set.
 
.PARAMETER includeDevices
    If specified, returns the device list for each vault. This parameter is used in the 'Multi' parameter set.
 
.EXAMPLE
    PS> Get-x360RecoverVault -vaultId 12345
 
    Retrieves information for the vault with ID 12345.
 
.EXAMPLE
    PS> Get-x360RecoverVault -vaultType 'Private' -active $true -limit 10
 
    Retrieves information for up to 10 active private vaults.
 
.EXAMPLE
    PS> Get-x360RecoverVault -withUrl $true -includeDevices $true
 
    Retrieves information for vaults with a URL present and includes the device list for each vault.
 
.INPUTS
    System.Int32. The vault ID can be piped to this cmdlet.
 
.OUTPUTS
    System.Object. The information about the specified vault(s).
 
#>

    [CmdletBinding( DefaultParameterSetName = 'Multi' )]
    [OutputType([Object])]
    [MetadataAttribute(
        '/vault',
        'get',
        '/vault/{vault_id}',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Return infomation about a single vault
        [Parameter(ParameterSetName = 'Single', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('vault_id','id')]
        [Int]$vaultId,
        #Filter only private or only cloud vaults
        [Parameter(ParameterSetName = 'Multi', Position = 1)]
        [ValidateSet('Private', 'Cloud')]
        [Alias('vault_type')]
        [string]$vaultType,
        # Filter only vaults with active status
        [Parameter(ParameterSetName = 'Multi', Position = 2)]
        [nullable[bool]]$active,
        # Filter by URL presence
        [Parameter(ParameterSetName = 'Multi', Position = 3)]
        [Alias('with_url')]
        [nullable[bool]]$withUrl,
        # Max amount of vaults in response
        [Parameter(ParameterSetName = 'Multi', Position = 4)]
        [Int64]$limit,
        # Return device list for each vault if True
        [Parameter(ParameterSetName = 'Multi', Position = 5)]
        [Alias('include_devices')]
        [nullable[bool]]$includeDevices
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        write-verbose $MyInvocation
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-x360RecoverQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($vaultId) {
                Write-Verbose ('Getting vault with id {0}.' -f $vaultId)
                $Resource = ('vault/{0}' -f $vaultId)
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                }
            } else {
                Write-Verbose 'Retreiving all vaults'
                $Resource = 'vault'
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                }
            }
            try {
                $gResults = New-x360RecoverGETRequest @RequestParams
                return $gResults
            } catch {
                if (-not $gResults) {
                    if ($vaultId) {
                        throw ('Vault with id {0} not found.' -f $vaultId)
                    } else {
                        throw 'No vaults found.'
                    }
                }
            }
        } catch {
            New-x360RecoverError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Vault\Get-x360RecoverVault.ps1' 123
#Region '.\Public\Vault\Get-x360RecoverVaultConnThreshold.ps1' -1

function Get-x360RecoverVaultConnThreshold {
    <#
.SYNOPSIS
    Retrieves the connectivity threshold information for a specified x360Recover vault.
 
.DESCRIPTION
    This cmdlet retrieves the connectivity threshold information for a specified x360Recover vault by its ID. It sends a GET request to the x360Recover API and returns the connectivity threshold details.
 
.PARAMETER vaultId
    The ID of the vault to retrieve connectivity threshold information for. This parameter is mandatory and can be piped.
 
.EXAMPLE
    PS> Get-x360RecoverVaultConnThreshold -vaultId 12345
 
    Retrieves the connectivity threshold information for the vault with ID 12345.
 
.INPUTS
    System.Int32. The vault ID can be piped to this cmdlet.
 
.OUTPUTS
    System.Object. The connectivity threshold information for the specified vault.
#>

    [CmdletBinding()]
    [OutputType([Object])]
    [MetadataAttribute(
        '/vault/{vault_id}/threshold/connectivity',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Return infomation about a single vault
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('vault_id','id')]
        [Int]$vaultId
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        write-verbose $MyInvocation
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-x360RecoverQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($vaultId) {
                Write-Verbose ('Getting connectivity threshold for vault with id {0}.' -f $vaultId)
                $Resource = ('vault/{0}/threshold/connectivity' -f $vaultId)
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                }
            }
            try {
                $gResults = New-x360RecoverGETRequest @RequestParams
                return $gResults
            } catch {
                if (-not $gResults) {
                    if ($vaultId) {
                        throw ('Vault with id {0} not found.' -f $vaultId)
                    } else {
                        throw 'No vaults found.'
                    }
                }
            }
        } catch {
            New-x360RecoverError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Vault\Get-x360RecoverVaultConnThreshold.ps1' 69
#Region '.\Public\Vault\Set-x360RecoverVaultConnThreshold.ps1' -1

function Set-x360RecoverVaultConnThreshold {
<#
.SYNOPSIS
    Sets the connectivity threshold for a specified vault in x360Recover.
 
.DESCRIPTION
    This cmdlet sets the connectivity threshold for a specified vault in the x360Recover system. It sends a POST request to the x360Recover API with the provided vault ID and threshold value.
 
.PARAMETER vaultId
    The ID of the vault to set the connectivity threshold for. This parameter is mandatory and can be piped.
 
.PARAMETER threshold
    The connectivity threshold value to set for the vault. This parameter is mandatory.
 
.EXAMPLE
    PS> Set-x360RecoverVaultConnThreshold -vaultId 12345 -threshold 10
 
    Sets the connectivity threshold to 10 for the vault with ID 12345.
 
.INPUTS
    System.Int64. The vault ID can be piped to this cmdlet.
    System.Int32. The threshold value can be piped to this cmdlet.
 
.OUTPUTS
    System.Object. The response from the x360Recover API.
#>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [MetadataAttribute(
        '/vault/{vault_id}/threshold/connectivity',
        'post'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Return infomation about a single vault
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('vault_id','id')]
        [Int64]$vaultId,
        # Return infomation about a single vault
        [Parameter(Mandatory, Position = 1, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Int]$threshold
    )
    process {
        try {
            Write-Verbose ('Setting connectivity thresholds for vaultid {0}.' -f $vaultId)
            $Resource = ('vault/{0}/threshold/connectivity' -f $vaultId)

            $Body = @{}
            $Body.threshold = $threshold

            $RequestParams = @{
                Resource = $Resource
                Body = $Body
            }
            if ($PSCmdlet.ShouldProcess(('Connectivity threshold for vaultid {0}' -f $vaultId), 'Set')) {
                $Result = New-x360RecoverPOSTRequest @RequestParams
                if ($Result -eq 200) {
                    Write-Information ('Connectivity threshold for vaultid {0} updated successfully.' -f $vaultId)
                }
            }
        } catch {
            New-x360RecoverError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Vault\Set-x360RecoverVaultConnThreshold.ps1' 66