NinjaOne.psm1

using namespace System.Management.Automation
using namespace System.Collections.Generic
#Region '.\Initialisation.ps1' 0
[int32]$Script:NRAPIDefaultPageSize = 2000
[Hashtable]$Script:NRAPIInstances = @{
    'eu' = 'https://eu.ninjarmm.com'
    'oc' = 'https://oc.ninjarmm.com'
    'us' = 'https://app.ninjarmm.com'
    'ca' = 'https://ca.ninjarmm.com'
    'us2' = 'https://us2.ninjarmm.com'
}
#EndRegion '.\Initialisation.ps1' 9
#Region '.\Classes\02-EntityType.Enum.Class.ps1' 0
enum EntityType {
    ORGANIZATION = 1
    DOCUMENT = 2
    LOCATION = 3
    NODE = 4
    ATTACHMENT = 5
    TECHNICIAN = 6
    CREDENTIAL = 7
    CHECKLIST = 8
    END_USER = 9
    CONTACT = 10
    KB_DOCUMENT = 11
}
#EndRegion '.\Classes\02-EntityType.Enum.Class.ps1' 14
#Region '.\Classes\02-FilterOperator.Enum.Class.ps1' 0
enum FilterOperator {
    present = 1
    not_present = 2
    is = 3
    is_not = 4
    contains = 5
    not_contains = 6
    contains_any = 7
    contains_none = 8
    greater_than = 9
    less_than = 10
    greater_or_equal_than = 11
    less_or_equal_than = 12
    between = 13
}
#EndRegion '.\Classes\02-FilterOperator.Enum.Class.ps1' 16
#Region '.\Classes\02-NinjaOneCustomField.Object.Class.ps1' 0
#using namespace System.Management.Automation
class NinjaOneCustomField {
    [String]$name
    [Object]$value
    [Bool]$isHTML

    NinjaOneCustomField([String]$name, [Object]$value) {
        $this.name = $name
        $this.value = $value
    }

    NinjaOneCustomField([String]$name, [Object]$value, [Bool]$isHTML) {
        $this.name = $name
        $this.value = @{ html = $value }
    }
}
#EndRegion '.\Classes\02-NinjaOneCustomField.Object.Class.ps1' 17
#Region '.\Classes\05-NinjaOneDocumentTemplateField.Object.Class.ps1' 0
#using namespace System.Management.Automation
class NinjaOneDocumentTemplateField {
    # The human readable label for the field.
    [String]$fieldLabel
    # The machine readable name for the field. This is an immutable value.
    [String]$fieldName
    # The description of the field.
    [String]$fieldDescription
    # The type of the field.
    [ValidateSet('DROPDOWN', 'MULTI_SELECT', 'CHECKBOX', 'TEXT', 'TEXT_MULTILINE', 'TEXT_ENCRYPTED', 'NUMERIC', 'DECIMAL', 'DATE', 'DATE_TIME', 'TIME', 'ATTACHMENT', 'NODE_DROPDOWN', 'NODE_MULTI_SELECT', 'CLIENT_DROPDOWN', 'CLIENT_MULTI_SELECT', 'CLIENT_LOCATION_DROPDOWN', 'CLIENT_LOCATION_MULTI_SELECT', 'CLIENT_DOCUMENT_DROPDOWN', 'CLIENT_DOCUMENT_MULTI_SELECT', 'EMAIL', 'PHONE', 'IP_ADDRESS', 'WYSIWYG', 'URL')]
    [String]$fieldType
    # The technician permissions for the field.
    [ValidateSet('NONE', 'EDITABLE', 'READ_ONLY')]
    [String]$fieldTechnicianPermission
    # The script permissions for the field.
    [ValidateSet('NONE', 'READ_ONLY', 'WRITE_ONLY', 'READ_WRITE')]
    [String]$fieldScriptPermission
    # The API permissions for the field.
    [ValidateSet('NONE', 'READ_ONLY', 'WRITE_ONLY', 'READ_WRITE')]
    [String]$fieldAPIPermission
    # The default value for the field.
    [String]$fieldDefaultValue
    # The field content for the field (a.k.a the field options).
    [Object[]]$fieldContent
    # When creating a UI element (e.g a title, separator or description box) this is the machine readable name of the UI element.
    [String]$uiElementName
    # When creating a UI element (e.g a title, separator or description box) this is the value of the UI element.
    [String]$uiElementValue
    # When creating a UI element (e.g a title, separator or description box) this is the type of the UI element.
    [ValidateSet('TITLE', 'SEPARATOR', 'DESCRIPTION')]
    [String]$uiElementType

    # Full object constructor.
    NinjaOneDocumentTemplateField(
        [String]$fieldLabel,
        [String]$fieldName,
        [String]$fieldDescription,
        [String]$fieldType,
        [String]$fieldTechnicianPermission,
        [String]$fieldScriptPermission,
        [String]$fieldAPIPermission,
        [String]$fieldDefaultValue,
        [Object[]]$fieldContent,
        [String]$uiElementName,
        [String]$uiElementValue,
        [String]$uiElementType
    ) {
        $this.fieldLabel = $fieldLabel
        $this.fieldName = $fieldName
        $this.fieldDescription = $fieldDescription
        $this.fieldType = $fieldType
        $this.fieldTechnicianPermission = $fieldTechnicianPermission
        $this.fieldScriptPermission = $fieldScriptPermission
        $this.fieldAPIPermission = $fieldAPIPermission
        $this.fieldDefaultValue = $fieldDefaultValue
        $this.fieldContent = $fieldContent
        $this.uiElementName = $uiElementName
        $this.uiElementValue = $uiElementValue
        $this.uiElementType = $uiElementType
    }
}
#EndRegion '.\Classes\05-NinjaOneDocumentTemplateField.Object.Class.ps1' 62
#Region '.\Classes\05-NinjaOneEntityRelation.Object.Class.ps1' 0
#using namespace System.Management.Automation
class NinjaOneEntityRelation {
    [EntityType]$relationEntityType
    [FilterOperator]$Operator
    [ValidateStringOrInt()][Object]$Value

    NinjaOneTicketBoardFilter([String]$Field, [String]$Operator, [Object]$Value) {
        if ($Operator -in @('present', 'not_present') -and ($null -ne $Value)) {
            throw [MetadataException]::new("Operator '$Operator' does not accept a value.")
        }
        if ($Operator -notin @('present', 'not_present') -and ($null -eq $Value)) {
            throw [MetadataException]::new("Operator '$Operator' requires a value.")
        }
        if ($Operator -in @('greater_than', 'less_than', 'greater_or_equal_than', 'less_or_equal_than') -and ($Value -isnot [Int])) {
            throw [MetadataException]::new("Operator '$Operator' requires a numeric value.")
        }
        if ($Operator -in @('contains_any', 'contains_none') -and ($Value -notlike '*,*')) {
            throw [MetadataException]::new("Operator '$Operator' requires a value in the format 'value1,value2,value3'.")
        }
        if ($Operator -eq 'between' -and ($Value -notlike '*:*')) {
            throw [MetadataException]::new("Operator '$Operator' requires a value in the format 'start:end'.")
        }
        if ($Operator -eq 'is' -and ($Value -notlike '*:is')) {
            throw [MetadataException]::new("Operator '$Operator' requires a value in the format 'property:is'.")
        }
        # ToDo: Get clarification on the in and not_in operators from NinjaOne. Support request #279234
        #if ($Operator -in @('in', 'not_in')) {
        # throw [MetadataException]::new("Operator '$Operator' requires a value in the format 'property:value'.")
        #}
        $this.Field = $Field
        $this.Operator = $Operator
        $this.Value = $Value
    }
}
#EndRegion '.\Classes\05-NinjaOneEntityRelation.Object.Class.ps1' 35
#Region '.\Classes\05-NinjaOneOrganisationDocument.Object.Class.ps1' 0
#using namespace System.Management.Automation
class NinjaOneOrganisationDocument {
    [Int]$documentId
    [String]$documentName
    [String]$documentDescription
    [NinjaOneCustomField[]]$fields
    [Int]$documentTemplateId
    [Int]$organisationId
    # New object contructors.
    ## Full object constructor.
    NinjaOneOrganisationDocument(
        [String]$documentName,
        [String]$documentDescription,
        [NinjaOneCustomField[]]$fields,
        [Int]$documentTemplateId,
        [Int]$organisationId
    ) {
        $this.documentName = $documentName
        $this.documentDescription = $documentDescription
        $this.fields = $fields
        $this.documentTemplateId = $documentTemplateId
        $this.organisationId = $organisationId
    }
    ## No template id constructor.
    NinjaOneOrganisationDocument(
        [String]$documentName,
        [String]$documentDescription,
        [NinjaOneCustomField[]]$fields,
        [Int]$organisationId
    ) {
        $this.documentName = $documentName
        $this.documentDescription = $documentDescription
        $this.fields = $fields
        $this.organisationId = $organisationId
    }
    ## No description constructor.
    NinjaOneOrganisationDocument(
        [String]$documentName,
        [NinjaOneCustomField[]]$fields,
        [Int]$documentTemplateId,
        [Int]$organisationId
    ) {
        $this.documentName = $documentName
        $this.fields = $fields
        $this.documentTemplateId = $documentTemplateId
        $this.organisationId = $organisationId
    }
    ## No template id or description constructor.
    NinjaOneOrganisationDocument(
        [String]$documentName,
        [NinjaOneCustomField[]]$fields,
        [Int]$organisationId
    ) {
        $this.documentName = $documentName
        $this.fields = $fields
        $this.organisationId = $organisationId
    }
    # Update object contructors.
    ## Full object constructor.
    NinjaOneOrganisationDocument(
        [Int]$documentId,
        [String]$documentName,
        [String]$documentDescription,
        [NinjaOneCustomField[]]$fields,
        [Int]$organisationId
    ) {
        $this.documentId = $documentId
        $this.documentName = $documentName
        $this.documentDescription = $documentDescription
        $this.fields = $fields
        $this.organisationId = $organisationId
    }
    ##
}
#EndRegion '.\Classes\05-NinjaOneOrganisationDocument.Object.Class.ps1' 75
#Region '.\Classes\05-NinjaOneTicketBoardFilter.Object.Class.ps1' 0
#using namespace System.Management.Automation
class NinjaOneTicketBoardFilter {
    [String]$Field
    [FilterOperator]$Operator
    [ValidateStringOrInt()][Object]$Value

    NinjaOneTicketBoardFilter([String]$Field, [String]$Operator, [Object]$Value) {
        if ($Operator -in @('present', 'not_present') -and ($null -ne $Value)) {
            throw [MetadataException]::new("Operator '$Operator' does not accept a value.")
        }
        if ($Operator -notin @('present', 'not_present') -and ($null -eq $Value)) {
            throw [MetadataException]::new("Operator '$Operator' requires a value.")
        }
        if ($Operator -in @('greater_than', 'less_than', 'greater_or_equal_than', 'less_or_equal_than') -and ($Value -isnot [Int])) {
            throw [MetadataException]::new("Operator '$Operator' requires a numeric value.")
        }
        if ($Operator -in @('contains_any', 'contains_none') -and ($Value -notlike '*,*')) {
            throw [MetadataException]::new("Operator '$Operator' requires a value in the format 'value1,value2,value3'.")
        }
        if ($Operator -eq 'between' -and ($Value -notlike '*:*')) {
            throw [MetadataException]::new("Operator '$Operator' requires a value in the format 'start:end'.")
        }
        if ($Operator -eq 'is' -and ($Value -notlike '*:is')) {
            throw [MetadataException]::new("Operator '$Operator' requires a value in the format 'property:is'.")
        }
        # ToDo: Get clarification on the in and not_in operators from NinjaOne. Support request #279234
        #if ($Operator -in @('in', 'not_in')) {
        # throw [MetadataException]::new("Operator '$Operator' requires a value in the format 'property:value'.")
        #}
        $this.Field = $Field
        $this.Operator = $Operator
        $this.Value = $Value
    }
}
#EndRegion '.\Classes\05-NinjaOneTicketBoardFilter.Object.Class.ps1' 35
#Region '.\Classes\05-NinjaOneTicketBoardSort.Object.Class.ps1' 0
class NinjaOneTicketBoardSort {
    [String]$Field
    [ValidateSet('asc', 'desc')][String]$Direction
}
#EndRegion '.\Classes\05-NinjaOneTicketBoardSort.Object.Class.ps1' 5
#Region '.\Private\ConvertTo-UnixEpoch.ps1' 0
function ConvertTo-UnixEpoch {
    <#
    .SYNOPSIS
        Converts a PowerShell DateTime object to a Unix Epoch timestamp.
    .DESCRIPTION
        Takes a PowerShell DateTime object and returns a Unix Epoch timestamp representing the same date/time.
    .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' 36
#Region '.\Private\Get-NinjaOneSecrets.ps1' 0
function Get-NinjaOneSecrets {
    <#
        .SYNOPSIS
            Retrieves NinjaOne connection and authentication using the SecretManagement module.
        .DESCRIPTION
            Handles the retrieval of NinjaOne connection and authentication information using the SecretManagement module. This function is intended to be used internally by the module and should not be called directly.
        .OUTPUTS
            [System.Void]
 
            Returns nothing.
    #>

    [CmdletBinding()]
    [OutputType([System.Void])]
    param(
        # The vault name to use for retrieving the secrets.
        [String]$VaultName
    )
    $Secrets = @{
        ConnectionInfo = @{
            'AuthMode' = 'NinjaOneAuthMode'
            'URL' = 'NinjaOneURL'
            'Instance' = 'NinjaOneInstance'
            'ClientId' = 'NinjaOneClientId'
            'ClientSecret' = 'NinjaOneClientSecret'
            'AuthScopes' = 'NinjaOneAuthScopes'
            'RedirectURI' = 'NinjaOneRedirectURI'
            'AuthListenerPort' = 'NinjaOneAuthListenerPort'
            'UseSecretManagement' = 'NinjaOneUseSecretManagement'
            'WriteToSecretVault' = 'NinjaOneWriteToSecretVault'
            'ReadFromSecretVault' = 'NinjaOneReadFromSecretVault'
            'VaultName' = 'NinjaOneVaultName'
        }
        AuthenticationInfo = @{
            'Type' = 'NinjaOneType'
            'Access' = 'NinjaOneAccess'
            'Expires' = 'NinjaOneExpires'
            'Refresh' = 'NinjaOneRefresh'
        }
    }
    # Setup the the script scoped variables for the connection and authentication information.
    if ($null -eq $Script:NRAPIConnectionInformation) { $Script:NRAPIConnectionInformation = @{} }
    if ($null -eq $Script:NRAPIAuthenticationInformation) { $Script:NRAPIAuthenticationInformation = @{} }
    # 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
        $SecretValue = Get-Secret -Name $SecretName -Vault $VaultName -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:NRAPIConnectionInformation.$SecretName = $SecretValue
    }
    # Retrieve the authentication information from the secret vault.
    foreach ($AuthenticationSecret in $Secrets.AuthenticationInfo.GetEnumerator()) {
        Write-Verbose ('Processing secret {0} for vault retrieval.' -f $AuthenticationSecret.Key)
        $SecretName = $AuthenticationSecret.Key
        $SecretValue = Get-Secret -Name $SecretName -Vault $VaultName -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:NRAPIAuthenticationInformation.$SecretName = $SecretValue
    }
    # If we have the port value, convert it to an integer.
    if ($null -ne $Script:NRAPIConnectionInformation.AuthListenerPort) {
        $Script:NRAPIConnectionInformation.AuthListenerPort = [Int32]::Parse($Script:NRAPIConnectionInformation.AuthListenerPort)
    }
    # if we values for UseSecretManagement, WriteToSecretVault, and ReadFromSecretVault, convert them to booleans.
    if ($null -ne $Script:NRAPIConnectionInformation.UseSecretManagement) {
        $Script:NRAPIConnectionInformation.UseSecretManagement = [Boolean]::Parse($Script:NRAPIConnectionInformation.UseSecretManagement)
    }
    if ($null -ne $Script:NRAPIConnectionInformation.WriteToSecretVault) {
        $Script:NRAPIConnectionInformation.WriteToSecretVault = [Boolean]::Parse($Script:NRAPIConnectionInformation.WriteToSecretVault)
    }
    if ($null -ne $Script:NRAPIConnectionInformation.ReadFromSecretVault) {
        $Script:NRAPIConnectionInformation.ReadFromSecretVault = [Boolean]::Parse($Script:NRAPIConnectionInformation.ReadFromSecretVault)
    }
    # If we have the expires value, convert it to a DateTime object.
    if ($null -ne $Script:NRAPIAuthenticationInformation.Expires) {
        $Script:NRAPIAuthenticationInformation.Expires = [DateTime]::Parse($Script:NRAPIAuthenticationInformation.Expires)
    }
    # Verify we have the required connection information.
    if ([String]::IsNullOrEmpty($Script:NRAPIConnectionInformation.AuthMode)) {
        Write-Error 'NinjaOne authentication mode is not set.'
        exit 1
    }
    if ([String]::IsNullOrEmpty($Script:NRAPIConnectionInformation.URL)) {
        Write-Error 'NinjaOne URL is not set.'
        exit 1
    }
    if ([String]::IsNullOrEmpty($Script:NRAPIConnectionInformation.Instance)) {
        Write-Error 'NinjaOne instance is not set.'
        exit 1
    }
    if ([String]::IsNullOrEmpty($Script:NRAPIConnectionInformation.ClientId)) {
        Write-Error 'NinjaOne client ID is not set.'
        exit 1
    }
    if ([String]::IsNullOrEmpty($Script:NRAPIConnectionInformation.ClientSecret)) {
        Write-Error 'NinjaOne client secret is not set.'
        exit 1
    }
    if ([String]::IsNullOrEmpty($Script:NRAPIConnectionInformation.AuthScopes)) {
        Write-Error 'NinjaOne authentication scopes are not set.'
        exit 1
    }
    if ($Script:NRAPIConnectionInformation.AuthMode -eq 'Authorization Code' -and [String]::IsNullOrEmpty($Script:NRAPIConnectionInformation.RedirectURI)) {
        Write-Error 'NinjaOne redirect URI is not set.'
        exit 1
    }
    if ($Script:NRAPIConnectionInformation.AuthMode -eq 'Authorization Code' -and [String]::IsNullOrEmpty($Script:NRAPIConnectionInformation.AuthListenerPort)) {
        Write-Error 'NinjaOne authentication listener port is not set.'
        exit 1
    }
    if ($Script:NRAPIConnectionInformation.AuthMode -eq 'Token Authentication' -and [String]::IsNullOrEmpty($Script:NRAPIAuthenticationInformation.Refresh)) {
        Write-Error 'NinjaOne refresh token is not set.'
        exit 1
    }
    $Script:NRAPIConnectionInformation.UseSecretManagement = $true
    $Script:NRAPIConnectionInformation.WriteToSecretVault = $true
    $Script:NRAPIConnectionInformation.VaultName = $VaultName
    $Script:NRAPIConnectionInformation.ReadFromSecretVault = $true
}
#EndRegion '.\Private\Get-NinjaOneSecrets.ps1' 127
#Region '.\Private\Get-TokenExpiry.ps1' 0
function Get-TokenExpiry {
    <#
    .SYNOPSIS
        Calculates and returns the expiry date/time of an access token.
    .DESCRIPTION
        Takes the expires in time for an auth token and returns a PowerShell date/time object containing the expiry date/time of the token.
    .OUTPUTS
        [System.DateTime]
 
        A powershell date/time object representing the token expiry.
    #>

    [CmdletBinding()]
    [OutputType([DateTime])]
    param (
        # Timestamp value for token expiry. e.g 3600
        [Parameter(
            Mandatory = $True
        )]
        [int64]$ExpiresIn
    )
    $Now = Get-Date
    $ExpiryDateTime = $Now.AddSeconds($ExpiresIn)
    Write-Verbose "Calcuated token expiry as $ExpiryDateTime"
    return $ExpiryDateTime
}
#EndRegion '.\Private\Get-TokenExpiry.ps1' 26
#Region '.\Private\Invoke-NinjaOnePreFlightCheck.ps1' 0
#using namespace System.Management.Automation
function Invoke-NinjaOnePreFlightCheck {
    <#
        .SYNOPSIS
            Conducts pre-flight checks for the NinjaOne API.
        .DESCRIPTION
            Conducts pre-flight checks ensuring that the NinjaOne API connection information is present and that the user is authenticated.
        .EXAMPLE
            PS> Invoke-NinjaOnePreFlightCheck
 
            Conducts pre-flight checks for the NinjaOne API.
        .EXAMPLE
            PS> Invoke-NinjaOnePreFlightCheck -SkipConnectionChecks
 
            Conducts pre-flight checks for the NinjaOne API, skipping the connection checks.
        .OUTPUTS
            [System.Void]
 
            Returns nothing if the checks pass. Otherwise, throws an error.
    #>

    [CmdletBinding()]
    param(
        # Skip the connection checks.
        [Parameter()]
        [Switch]$SkipConnectionChecks
    )
    if (-not $SkipConnectionChecks) {
        if ($null -eq $Script:NRAPIConnectionInformation) {
            $NoConnectionInformationException = [System.Exception]::New("Missing NinjaOne connection information, please run 'Connect-NinjaOne' first.")
            $ErrorRecord = [ErrorRecord]::New($NoConnectionInformationException, 'NoConnectionInformation', 'AuthenticationError', 'NinjaOnePreFlightCheck')
            
            $PSCmdlet.throwTerminatingError($ErrorRecord)
        }
        if (($null -eq $Script:HAPIAuthToken) -and ($null -eq $AllowAnonymous)) {
            $NoAuthTokenException = [System.Exception]::New("Missing Halo authentication token, please run 'Connect-HaloAPI' first.")
            $ErrorRecord = [ErrorRecord]::New($NoAuthTokenException, 'NoAuthToken', 'AuthenticationError', 'NinjaOnePreFlightCheck')

            $PSCmdlet.throwTerminatingError($ErrorRecord)
        }
    } else {
        Write-Verbose 'Skipping connection checks.'
    }
}
#EndRegion '.\Private\Invoke-NinjaOnePreFlightCheck.ps1' 44
#Region '.\Private\New-NinjaOneDELETERequest.ps1' 0
function New-NinjaOneDELETERequest {
    <#
        .SYNOPSIS
            Builds a request for the NinjaOne API.
        .DESCRIPTION
            Wrapper function to build web requests for the NinjaOne API.
        .EXAMPLE
            Cancel the maintenance for device with id 1.
 
            PS ~> New-NinjaOneDELETERequest -Resource "/v2/device/1/maintenance"
        .OUTPUTS
            Outputs an object containing the response from the web request.
    #>

    [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
    )
    if ($null -eq $Script:NRAPIConnectionInformation) {
        throw "Missing NinjaOne connection information, please run 'Connect-NinjaOne' first."
    }
    if ($null -eq $Script:NRAPIAuthenticationInformation) {
        throw "Missing NinjaOne authentication tokens, please run 'Connect-NinjaOne' first."
    }
    try {
        if ($QSCollection) {
            Write-Verbose "Query string in New-NinjaOneDELETERequest contains: $($QSCollection | Out-String)"
            $QueryStringCollection = [System.Web.HTTPUtility]::ParseQueryString([String]::Empty)
            Write-Verbose 'Building [HttpQSCollection] for New-NinjaOneDELETERequest'
            foreach ($Key in $QSCollection.Keys) {
                $QueryStringCollection.Add($Key, $QSCollection.$Key)
            }
        } else {
            Write-Verbose 'Query string collection not present...'
        }
        Write-Verbose "URI is $($Script:NRAPIConnectionInformation.URL)"
        $RequestUri = [System.UriBuilder]"$($Script:NRAPIConnectionInformation.URL)"
        Write-Verbose "Path is $($Resource)"
        $RequestUri.Path = $Resource
        $WebRequestParams = @{
            Method = 'DELETE'
            Uri = $RequestUri.ToString()
        }
        Write-Verbose "Building new NinjaOneRequest with params: $($WebRequestParams | Out-String)"
        try {
            $Result = Invoke-NinjaOneRequest @WebRequestParams
            Write-Verbose "NinjaOne 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-NinjaOneError -ErrorRecord $_
            }
        }
    } catch {
        $ExceptionType = if ($IsCoreCLR) {
            [Microsoft.PowerShell.Commands.HttpResponseException]
        } else {
            [System.Net.WebException]
        }
        if ($_.Exception -is $ExceptionType) {
            throw
        } else {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Private\New-NinjaOneDELETERequest.ps1' 83
#Region '.\Private\New-NinjaOneError.ps1' 0
#using namespace System.Collections.Generic
#using namespace System.Management.Automation
function New-NinjaOneError {
    [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 NinjaOne error output.'
        $ExceptionMessage = [Hashset[String]]::New()
        $APIResultMatchString = '*The NinjaOne 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 NinjaOne API said $($ErrorDetails.resultCode): $($ErrorDetails.errorMessage).") | Out-Null
                    } elseif ($null -ne $ErrorDetails.resultCode) {
                        Write-Verbose 'ErrorDetails contains resultCode.'
                        $ExceptionMessage.Add("The NinjaOne API said $($ErrorDetails.resultCode).") | Out-Null
                    } elseif ($null -ne $ErrorDetails.error) {
                        Write-Verbose 'ErrorDetails contains error.'
                        $ExceptionMessage.Add("The NinjaOne API said $($ErrorDetails.error).") | Out-Null
                    } elseif ($null -ne $ErrorDetails) {
                        Write-Verbose 'ErrorDetails is not null.'
                        $ExceptionMessage.Add("The NinjaOne API said $($ErrorRecord.ErrorDetails).") | Out-Null
                    } else {
                        Write-Verbose 'ErrorDetails is null.'
                        $ExceptionMessage.Add('The NinjaOne 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 NinjaOne 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
        )
        $NinjaOneError = [ErrorRecord]::New(
            $ErrorRecord,
            $Exception
        )
        $UniqueExceptions = $ExceptionMessage | Get-Unique
        $NinjaOneError.ErrorDetails = [String]::Join("`r`n", $UniqueExceptions)
    } else {
        Write-Verbose 'Not generating NinjaOne error output.'
        $NinjaOneError = $ErrorRecord
    }
    $PSCmdlet.throwTerminatingError($NinjaOneError)
}
#EndRegion '.\Private\New-NinjaOneError.ps1' 83
#Region '.\Private\New-NinjaOneGETRequest.ps1' 0
function New-NinjaOneGETRequest {
    <#
        .SYNOPSIS
            Builds a request for the NinjaOne API.
        .DESCRIPTION
            Wrapper function to build web requests for the NinjaOne API.
        .EXAMPLE
            Make a GET request to the organisations endpoint.
 
            PS C:\> New-NinjaOneGETRequest -Resource "/v2/organizations"
        .OUTPUTS
            Outputs an object containing the response from the web request.
    #>

    [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,
        # Don't drill down into the data property.
        [Switch]$NoDrill,
        # return the raw response.
        [Switch]$Raw
    )
    if ($null -eq $Script:NRAPIConnectionInformation) {
        throw "Missing NinjaOne connection information, please run 'Connect-NinjaOne' first."
    }
    if ($null -eq $Script:NRAPIAuthenticationInformation) {
        throw "Missing NinjaOne authentication tokens, please run 'Connect-NinjaOne' first."
    }
    try {
        if ($QSCollection) {
            Write-Verbose "Query string in New-NinjaOneGETRequest contains: $($QSCollection | Out-String)"
            $QueryStringCollection = [System.Web.HTTPUtility]::ParseQueryString([String]::Empty)
            Write-Verbose 'Building [HttpQSCollection] for New-NinjaOneGETRequest'
            foreach ($Key in $QSCollection.Keys) {
                $QueryStringCollection.Add($Key, $QSCollection.$Key)
            }
        } else {
            Write-Verbose 'Query string collection not present...'
        }
        Write-Verbose "URI is $($Script:NRAPIConnectionInformation.URL)"
        $RequestUri = [System.UriBuilder]"$($Script:NRAPIConnectionInformation.URL)"
        $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-NinjaOneRequest @WebRequestParams
            if ($Result) {
                Write-Verbose "NinjaOne 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 'NinjaOne request returned nothing.'
            }
        } catch {
            $ExceptionType = if ($IsCoreCLR) {
                [Microsoft.PowerShell.Commands.HttpResponseException]
            } else {
                [System.Net.WebException]
            }
            if ($_.Exception -is $ExceptionType) {
                throw
            } else {
                New-NinjaOneError -ErrorRecord $_
            }
        }
    } catch {
        $ExceptionType = if ($IsCoreCLR) {
            [Microsoft.PowerShell.Commands.HttpResponseException]
        } else {
            [System.Net.WebException]
        }
        if ($_.Exception -is $ExceptionType) {
            throw
        } else {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Private\New-NinjaOneGETRequest.ps1' 113
#Region '.\Private\New-NinjaOnePATCHRequest.ps1' 0
function New-NinjaOnePATCHRequest {
    <#
        .SYNOPSIS
            Builds a request for the NinjaOne API.
        .DESCRIPTION
            Wrapper function to build web requests for the NinjaOne API.
        .EXAMPLE
            Make a PATCH request to the custom fields endpoint for device 1.
 
            PS C:\> New-NinjaOnePATCHRequest -Resource "/v2/device/1/custom-fields" -Body @{"myCustomField" = "value"}
        .OUTPUTS
            Outputs an object containing the response from the web request.
    #>

    [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.
        [Parameter(Mandatory = $True)]
        [Object]$Body
    )
    if ($null -eq $Script:NRAPIConnectionInformation) {
        throw "Missing NinjaOne connection information, please run 'Connect-NinjaOne' first."
    }
    if ($null -eq $Script:NRAPIAuthenticationInformation) {
        throw "Missing NinjaOne authentication tokens, please run 'Connect-NinjaOne' first."
    }
    try {
        if ($QSCollection) {
            Write-Verbose "Query string in New-NinjaOnePATCHRequest contains: $($QSCollection | Out-String)"
            $QueryStringCollection = [System.Web.HTTPUtility]::ParseQueryString([String]::Empty)
            Write-Verbose 'Building [HttpQSCollection] for New-NinjaOnePATCHRequest'
            foreach ($Key in $QSCollection.Keys) {
                $QueryStringCollection.Add($Key, $QSCollection.$Key)
            }
        } else {
            Write-Verbose 'Query string collection not present...'
        }
        Write-Verbose "URI is $($Script:NRAPIConnectionInformation.URL)"
        $RequestUri = [System.UriBuilder]"$($Script:NRAPIConnectionInformation.URL)"
        Write-Verbose "Path is $($Resource)"
        $RequestUri.Path = $Resource
        if ($QueryStringCollection) {
            Write-Verbose "Query string is $($QueryStringCollection | Out-String)"
            $RequestUri.Query = $QueryStringCollection
        } else {
            Write-Verbose 'Query string not present...'
        }
        $WebRequestParams = @{
            Method = 'PATCH'
            Uri = $RequestUri.ToString()
            Body = (ConvertTo-Json -InputObject $Body -Depth 100)
        }
        Write-Verbose "Raw body is $($WebRequestParams.Body)"
        Write-Verbose "Building new NinjaOneRequest with params: $($WebRequestParams | Out-String)"
        try {
            $Result = Invoke-NinjaOneRequest @WebRequestParams
            Write-Verbose "NinjaOne 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-NinjaOneError -ErrorRecord $_
            }
        }
    } catch {
        $ExceptionType = if ($IsCoreCLR) {
            [Microsoft.PowerShell.Commands.HttpResponseException]
        } else {
            [System.Net.WebException]
        }
        if ($_.Exception -is $ExceptionType) {
            throw
        } else {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Private\New-NinjaOnePATCHRequest.ps1' 96
#Region '.\Private\New-NinjaOnePOSTRequest.ps1' 0
function New-NinjaOnePOSTRequest {
    <#
        .SYNOPSIS
            Builds a request for the NinjaOne API.
        .DESCRIPTION
            Wrapper function to build web requests for the NinjaOne API.
        .EXAMPLE
            Make a POST request to the organisations endpoint.
 
            PS C:\> New-NinjaOnePOSTRequest -Method "POST" -Resource "/v2/organizations"
        .OUTPUTS
            Outputs an object containing the response from the web request.
    #>

    [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:NRAPIConnectionInformation) {
        throw "Missing NinjaOne connection information, please run 'Connect-NinjaOne' first."
    }
    if ($null -eq $Script:NRAPIAuthenticationInformation) {
        throw "Missing NinjaOne authentication tokens, please run 'Connect-NinjaOne' first."
    }
    try {
        if ($QSCollection) {
            Write-Verbose "Query string in New-NinjaOnePOSTRequest contains: $($QSCollection | Out-String)"
            $QueryStringCollection = [System.Web.HTTPUtility]::ParseQueryString([String]::Empty)
            Write-Verbose 'Building [HttpQSCollection] for New-NinjaOnePOSTRequest'
            foreach ($Key in $QSCollection.Keys) {
                $QueryStringCollection.Add($Key, $QSCollection.$Key)
            }
        } else {
            Write-Verbose 'Query string collection not present...'
        }
        Write-Verbose "URI is $($Script:NRAPIConnectionInformation.URL)"
        $RequestUri = [System.UriBuilder]"$($Script:NRAPIConnectionInformation.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-NinjaOnePOSTRequest'
            $WebRequestParams.Body = (ConvertTo-Json -InputObject $Body -Depth 100)
            Write-Verbose "Raw body is $($WebRequestParams.Body)"
        } else {
            Write-Verbose 'No body provided for New-NinjaOnePOSTRequest'
        }
        Write-Verbose "Building new NinjaOneRequest with params: $($WebRequestParams | Out-String)"
        try {
            $Result = Invoke-NinjaOneRequest @WebRequestParams
            Write-Verbose "NinjaOne 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-NinjaOneError -ErrorRecord $_
            }
        }
    } catch {
        $ExceptionType = if ($IsCoreCLR) {
            [Microsoft.PowerShell.Commands.HttpResponseException]
        } else {
            [System.Net.WebException]
        }
        if ($_.Exception -is $ExceptionType) {
            throw
        } else {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Private\New-NinjaOnePOSTRequest.ps1' 100
#Region '.\Private\New-NinjaOnePUTRequest.ps1' 0
function New-NinjaOnePUTRequest {
    <#
        .SYNOPSIS
            Builds a request for the NinjaOne API.
        .DESCRIPTION
            Wrapper function to build web requests for the NinjaOne API.
        .EXAMPLE
            PS C:\> New-NinjaOnePUTRequest -Resource "/v2/organizations -Body @{"name"="MyOrg"}
        .OUTPUTS
            Outputs an object containing the response from the web request.
    #>

    [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.
        [Parameter(Mandatory = $True)]
        [Object]$Body,
        # Force body to an array.
        [Switch]$AsArray
    )
    if ($null -eq $Script:NRAPIConnectionInformation) {
        throw "Missing NinjaOne connection information, please run 'Connect-NinjaOne' first."
    }
    if ($null -eq $Script:NRAPIAuthenticationInformation) {
        throw "Missing NinjaOne authentication tokens, please run 'Connect-NinjaOne' first."
    }
    try {
        if ($QSCollection) {
            Write-Verbose "Query string in New-NinjaOnePUTRequest contains: $($QSCollection | Out-String)"
            $QueryStringCollection = [System.Web.HTTPUtility]::ParseQueryString([String]::Empty)
            Write-Verbose 'Building [HttpQSCollection] for New-NinjaOnePUTRequest'
            foreach ($Key in $QSCollection.Keys) {
                $QueryStringCollection.Add($Key, $QSCollection.$Key)
            }
        } else {
            Write-Verbose 'Query string collection not present...'
        }
        Write-Verbose "URI is $($Script:NRAPIConnectionInformation.URL)"
        $RequestUri = [System.UriBuilder]"$($Script:NRAPIConnectionInformation.URL)"
        Write-Verbose "Path is $($Resource)"
        $RequestUri.Path = $Resource
        if ($QueryStringCollection) {
            Write-Verbose "Query string is $($QueryStringCollection | Out-String)"
            $RequestUri.Query = $QueryStringCollection
        } else {
            Write-Verbose 'Query string not present...'
        }
        $WebRequestParams = @{
            Method = 'PUT'
            Uri = $RequestUri.ToString()
        }
        if ($Body) {
            Write-Verbose 'Building [HttpBody] for New-NinjaOnePUTRequest'
            if ($AsArray) {
                Write-Verbose 'Forcing body to array'
                $WebRequestParams.Body = (ConvertTo-Json -InputObject @($Body) -Depth 100)
            } else {
                Write-Verbose 'Not forcing body to array'
                $WebRequestParams.Body = (ConvertTo-Json -InputObject $Body -Depth 100)
            }
            Write-Verbose "Raw body is $($WebRequestParams.Body)"
        } else {
            Write-Verbose 'No body provided for New-NinjaOnePUTRequest'
        }
        Write-Verbose "Building new NinjaOneRequest with params: $($WebRequestParams | Out-String)"
        try {
            $Result = Invoke-NinjaOneRequest @WebRequestParams
            Write-Verbose "NinjaOne 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-NinjaOneError -ErrorRecord $_
            }
        }
    } catch {
        $ExceptionType = if ($IsCoreCLR) {
            [Microsoft.PowerShell.Commands.HttpResponseException]
        } else {
            [System.Net.WebException]
        }
        if ($_.Exception -is $ExceptionType) {
            throw
        } else {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Private\New-NinjaOnePUTRequest.ps1' 107
#Region '.\Private\New-NinjaOneQuery.ps1' 0
function New-NinjaOneQuery {
    [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 Boolearn 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-NinjaOneQuery.ps1' 165
#Region '.\Private\Set-NinjaOneSecrets.ps1' 0
function Set-NinjaOneSecrets {
    <#
        .SYNOPSIS
            Saves NinjaOne connection and authentication using the SecretManagement module.
        .DESCRIPTION
            Handles the saving of NinjaOne connection and authentication information using the SecretManagement module. This function is intended to be used internally by the module and should not be called directly.
        .OUTPUTS
            [System.Void]
 
            Returns nothing.
    #>

    [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.')]
    param(
        # The authentication mode to use.
        [String]$AuthMode,
        # The URL of the NinjaRMM instance.
        [URI]$URL,
        # The NinjaRMM instance name.
        [String]$Instance,
        # The client ID of the application.
        [String]$ClientId,
        # The client secret of the application.
        [String]$ClientSecret,
        # The port to listen on for the authentication callback.
        [Int]$AuthListenerPort,
        # The authentication scopes to request.
        [String]$AuthScopes,
        # The redirect URI to use for the authentication callback.
        [URI]$RedirectURI,
        # 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 type of the authentication token.
        [String]$Type,
        # The access token to use for authentication.
        [String]$Access,
        # The expiration time of the access token.
        [DateTime]$Expires,
        # The refresh token to use for authentication.
        [String]$Refresh
    )
    # 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:NRAPIConnectionInformation.AuthMode) {
        $Secrets.NinjaOneAuthMode = $Script:NRAPIConnectionInformation.AuthMode
    }
    if ($null -ne $Script:NRAPIConnectionInformation.URL) {
        $Secrets.NinjaOneURL = $Script:NRAPIConnectionInformation.URL
    }
    if ($null -ne $Script:NRAPIConnectionInformation.Instance) {
        $Secrets.NinjaOneInstance = $Script:NRAPIConnectionInformation.Instance
    }
    if ($null -ne $Script:NRAPIConnectionInformation.ClientId) {
        $Secrets.NinjaOneClientId = $Script:NRAPIConnectionInformation.ClientId
    }
    if ($null -ne $Script:NRAPIConnectionInformation.ClientSecret) {
        $Secrets.NinjaOneClientSecret = $Script:NRAPIConnectionInformation.ClientSecret
    }
    if ($null -ne $Script:NRAPIConnectionInformation.AuthScopes) {
        $Secrets.NinjaOneAuthScopes = $Script:NRAPIConnectionInformation.AuthScopes
    }
    if ($null -ne $Script:NRAPIConnectionInformation.RedirectURI) {
        $Secrets.NinjaOneRedirectURI = $Script:NRAPIConnectionInformation.RedirectURI.ToString()
    }
    if ($null -ne $Script:NRAPIConnectionInformation.AuthListenerPort) {
        $Secrets.NinjaOneAuthListenerPort = $Script:NRAPIConnectionInformation.AuthListenerPort.ToString()
    }
    if ($null -ne $Script:NRAPIAuthenticationInformation.Type) {
        $Secrets.NinjaOneType = $Script:NRAPIAuthenticationInformation.Type
    }
    if ($null -ne $Script:NRAPIAuthenticationInformation.Access) {
        $Secrets.NinjaOneAccess = $Script:NRAPIAuthenticationInformation.Access
    }
    if ($null -ne $Script:NRAPIAuthenticationInformation.Expires) {
        $Secrets.NinjaOneExpires = $Script:NRAPIAuthenticationInformation.Expires.ToString()
    }
    if ($null -ne $Script:NRAPIAuthenticationInformation.Refresh) {
        $Secrets.NinjaOneRefresh = $Script:NRAPIAuthenticationInformation.Refresh
    }
    if ($null -ne $Script:NRAPIConnectionInformation.UseSecretManagement) {
        $Secrets.NinjaOneUseSecretManagement = $Script:NRAPIConnectionInformation.UseSecretManagement.ToString()
    }
    if ($null -ne $Script:NRAPIConnectionInformation.WriteToSecretVault) {
        $Secrets.NinjaOneWriteToSecretVault = $Script:NRAPIConnectionInformation.WriteToSecretVault.ToString()
    }
    if ($null -ne $Script:NRAPIConnectionInformation.ReadFromSecretVault) {
        $Secrets.NinjaOneReadFromSecretVault = $Script:NRAPIConnectionInformation.ReadFromSecretVault.ToString()
    }
    if ($null -ne $Script:NRAPIConnectionInformation.VaultName) {
        $Secrets.NinjaOneVaultName = $Script:NRAPIConnectionInformation.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-NinjaOneSecrets.ps1' 127
#Region '.\Private\Start-OAuthHTTPListener.ps1' 0

function Start-OAuthHTTPListener {
    <#
        .SYNOPSIS
            Instantiates and starts a .NET HTTP listener to handle OAuth authorization code responses.
        .DESCRIPTION
            Utilises the `System.Net.HttpListener` class to create a simple HTTP listener on a user-defined port
        .EXAMPLE
            PS C:\> New-NinjaOnePATCHRequest -OpenURI 'http://localhost:9090'
        .OUTPUTS
            Outputs an object containing the response from the web request.
    #>

    [CmdletBinding()]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Private function - no need to support.')]
    param (
        [Parameter(Mandatory)]
        [System.UriBuilder]$OpenURI
    )
    Write-Verbose 'Opening browser to authenticate.'
    Write-Verbose "Authentication URL: $($OpenURI.ToString())"
    $HTTP = [System.Net.HttpListener]::new()
    $HTTP.Prefixes.Add("http://localhost:$Port/")
    $HTTP.Start()
    Start-Process $OpenURI.ToString()
    $Result = @{}
    while ($HTTP.IsListening) {
        $Context = $HTTP.GetContext()
        if ($Context.Request.QueryString -and $Context.Request.QueryString['Code']) {
            $Result.Code = $Context.Request.QueryString['Code']
            Write-Verbose "Authorisation code received: $($Result.Code)"
            if ($null -ne $Result.Code) {
                $Result.GotAuthorisationCode = $True
            }
            [string]$HTML = '<h1>NinjaOne PowerShell Module</h1><br /><p>An authorisation code has been received. The HTTP listener will stop in 5 seconds.</p><p>Please close this tab / window.</p>'
            $Response = [System.Text.Encoding]::UTF8.GetBytes($HTML)
            $Context.Response.ContentLength64 = $Response.Length
            $Context.Response.OutputStream.Write($Response, 0, $Response.Length)
            $Context.Response.OutputStream.Close()
            Start-Sleep -Seconds 5
            $HTTP.Stop()
        }
    }
    return $Result
}
#EndRegion '.\Private\Start-OAuthHTTPListener.ps1' 45
#Region '.\Private\Update-NinjaOneToken.ps1' 0
function Update-NinjaOneToken {
    [CmdletBinding()]
    [OutputType([Void])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Private function - no need to support.')]
    param()
    try {
        # Using our refresh token let's get a new auth token by re-running Connect-NinjaOne.
        if ($Script:NRAPIConnectionInformation.AuthMode -eq 'Client Credentials') {
            $ReauthParams = @{
                Instance = $Script:NRAPIConnectionInformation.Instance
                ClientId = $Script:NRAPIConnectionInformation.ClientId
                ClientSecret = $Script:NRAPIConnectionInformation.ClientSecret
                UseClientAuth = $True
                ShowTokens = $Script:NRAPIConnectionInformation.ShowTokens
                UseKeyVault = $Script:NRAPIConnectionInformation.UseKeyVault
                VaultName = $Script:NRAPIConnectionInformation.VaultName
                WriteToKeyVault = $Script:NRAPIConnectionInformation.WriteToKeyVault
            }
        } elseif ($null -ne $Script:NRAPIAuthenticationInformation.Refresh) {
            $ReauthParams = @{
                Instance = $Script:NRAPIConnectionInformation.Instance
                ClientId = $Script:NRAPIConnectionInformation.ClientId
                ClientSecret = $Script:NRAPIConnectionInformation.ClientSecret
                RefreshToken = $Script:NRAPIAuthenticationInformation.Refresh
                UseTokenAuth = $True
                ShowTokens = $Script:NRAPIConnectionInformation.ShowTokens
                UseKeyVault = $Script:NRAPIConnectionInformation.UseKeyVault
                VaultName = $Script:NRAPIConnectionInformation.VaultName
                WriteToKeyVault = $Script:NRAPIConnectionInformation.WriteToKeyVault
            }
        } else {
            throw 'Unable to refresh authentication token information. Not using client credentials and/or refresh token is missing.'
        }
        Connect-NinjaOne @ReauthParams
        Write-Verbose 'Refreshed authentication token information from NinjaOne.'
        Write-Verbose "Authentication information now set to: $($Script:NRAPIAuthenticationInformation | Out-String -Width 2048)"
    } catch {
        New-NinjaOneError $_
    }
}
#EndRegion '.\Private\Update-NinjaOneToken.ps1' 41
#Region '.\Public\Connect-NinjaOne.ps1' 0
function Connect-NinjaOne {
    <#
        .SYNOPSIS
            Creates a new connection to a NinjaOne instance.
        .DESCRIPTION
            Creates a new connection to a NinjaOne instance and stores this in a PowerShell Session.
        .FUNCTIONALITY
            NinjaOne
        .EXAMPLE
            PS> Connect-NinjaOne -Instance 'eu' -ClientId 'AAaaA1aaAaAA-aaAaaA11a1A-aA' -ClientSecret '00Z00zzZzzzZzZzZzZzZZZ0zZ0zzZ_0zzz0zZZzzZz0Z0ZZZzz0z0Z' -UseClientAuth
 
            This logs into NinjaOne using the client credentials flow.
        .EXAMPLE
            PS> Connect-NinjaOne -Instance 'eu' -ClientId 'AAaaA1aaAaAA-aaAaaA11a1A-aA' -ClientSecret '00Z00zzZzzzZzZzZzZzZZZ0zZ0zzZ_0zzz0zZZzzZz0Z0ZZZzz0z0Z' -Port 9090 -UseWebAuth
 
            This logs into NinjaOne using the authorization code flow.
        .EXAMPLE
            PS> Connect-NinjaOne -Instance 'eu' -ClientId 'AAaaA1aaAaAA-aaAaaA11a1A-aA' -ClientSecret '00Z00zzZzzzZzZzZzZzZZZ0zZ0zzZ_0zzz0zZZzzZz0Z0ZZZzz0z0Z' -RefreshToken 'a1a11a11-aa11-11a1-a111-a1a111aaa111.11AaaAaaa11aA-AA1aaaAAA111aAaaaaA1AAAA1_AAa' -UseTokenAuth
 
            This logs into NinjaOne using the refresh token flow.
        .EXAMPLE
            PS> Connect-NinjaOne -UseSecretManagement -VaultName 'NinjaOneVault' -WriteToSecretVault
        .OUTPUTS
            Sets two script-scoped variables to hold connection and authentication information.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Connect/ninjaone
    #>

    [CmdletBinding( DefaultParameterSetName = 'Authorisation Code' )]
    [OutputType([System.Void])]
    [Alias('cno')]
    [MetadataAttribute('IGNORE')]
    Param (
        # Use the "Authorisation Code" flow with your web browser.
        [Parameter( Mandatory, ParameterSetName = 'Authorisation Code')]
        [Parameter( ParameterSetName = 'Secret Vault Write' )]
        [Switch]$UseWebAuth,
        # Use the "Token Authentication" flow - useful if you already have a refresh token.
        [Parameter( Mandatory, ParameterSetName = 'Token Authentication' )]
        [Parameter( ParameterSetName = 'Secret Vault Write' )]
        [switch]$UseTokenAuth,
        # Use the "Client Credentials" flow - useful if you already have a client ID and secret.
        [Parameter( Mandatory, ParameterSetName = 'Client Credentials' )]
        [Parameter( ParameterSetName = 'Secret Vault Write' )]
        [switch]$UseClientAuth,
        # The NinjaOne instance to connect to. Choose from 'eu', 'oc' or 'us'.
        [Parameter( Mandatory, ParameterSetName = 'Authorisation Code' )]
        [Parameter( Mandatory, ParameterSetName = 'Token Authentication' )]
        [Parameter( Mandatory, ParameterSetName = 'Client Credentials' )]
        [Parameter( Mandatory, ParameterSetName = 'Secret Vault Write' )]
        [ValidateSet('eu', 'oc', 'us', 'ca', 'us2')]
        [string]$Instance,
        # The Client Id for the application configured in NinjaOne.
        [Parameter( Mandatory, ParameterSetName = 'Authorisation Code' )]
        [Parameter( Mandatory, ParameterSetName = 'Token Authentication' )]
        [Parameter( Mandatory, ParameterSetName = 'Client Credentials' )]
        [Parameter( Mandatory, ParameterSetName = 'Secret Vault Write' )]
        [String]$ClientId,
        # The Client Secret for the application configured in NinjaOne.
        [Parameter( Mandatory, ParameterSetName = 'Authorisation Code' )]
        [Parameter( Mandatory, ParameterSetName = 'Token Authentication' )]
        [Parameter( Mandatory, ParameterSetName = 'Client Credentials' )]
        [Parameter( Mandatory, ParameterSetName = 'Secret Vault Write' )]
        [String]$ClientSecret,
        # The API scopes to request, if this isn't passed the scope is assumed to be "all". Pass a string or array of strings. Limited by the scopes granted to the application in NinjaOne.
        [Parameter( ParameterSetName = 'Authorisation Code' )]
        [Parameter( ParameterSetName = 'Token Authentication' )]
        [Parameter( ParameterSetName = 'Client Credentials' )]
        [Parameter( ParameterSetName = 'Secret Vault Write' )]
        [ValidateSet('monitoring', 'management', 'control', 'offline_access')]
        [String[]]$Scopes,
        # The redirect URI to use. If not set defaults to 'http://localhost'. Should be a full URI e.g. https://redirect.example.uk:9090/auth
        [Parameter( ParameterSetName = 'Authorisation Code' )]
        [Parameter( ParameterSetName = 'Secret Vault Write' )]
        [URI]$RedirectURL,
        # The port to use for the redirect URI. Must match with the configuration set in NinjaOne. If not set defaults to '9090'.
        [Parameter( ParameterSetName = 'Authorisation Code' )]
        [Parameter( ParameterSetName = 'Secret Vault Write' )]
        [Int]$Port = 9090,
        # The refresh token to use for "Token Authentication" flow.
        [Parameter( ParameterSetName = 'Token Authentication' )]
        [Parameter( ParameterSetName = 'Secret Vault Write' )]
        [String]$RefreshToken,
        # Output the tokens - useful when using "Authorisation Code" flow - to use with "Token Authentication" flow.
        [Parameter( ParameterSetName = 'Authorisation Code' )]
        [Parameter( ParameterSetName = 'Token Authentication' )]
        [Parameter( ParameterSetName = 'Client Credentials' )]
        [Switch]$ShowTokens,
        # Use the secret management module to retrieve credentials and store tokens.
        [Parameter( ParameterSetName = 'Authorisation Code' )]
        [Parameter( ParameterSetName = 'Token Authentication' )]
        [Parameter( ParameterSetName = 'Client Credentials' )]
        [Parameter( Mandatory, ParameterSetName = 'Secret Vault Write' )]
        [Parameter( Mandatory, ParameterSetName = 'Secret Vault Read' )]
        [Switch]$UseSecretManagement,
        # The name of the secret vault to use.
        [Parameter( ParameterSetName = 'Authorisation Code' )]
        [Parameter( ParameterSetName = 'Token Authentication' )]
        [Parameter( ParameterSetName = 'Client Credentials' )]
        [Parameter( Mandatory, ParameterSetName = 'Secret Vault Write' )]
        [Parameter( Mandatory, ParameterSetName = 'Secret Vault Read' )]
        [String]$VaultName,
        # Write updated credentials to secret management vault.
        [Parameter( ParameterSetName = 'Authorisation Code' )]
        [Parameter( ParameterSetName = 'Token Authentication' )]
        [Parameter( ParameterSetName = 'Client Credentials' )]
        [Parameter( Mandatory, ParameterSetName = 'Secret Vault Write' )]
        [Parameter( ParameterSetName = 'Secret Vault Read')]
        [Switch]$WriteToSecretVault,
        # Read the authentication information from secret management vault.
        [Parameter( ParameterSetName = 'Secret Vault Read' )]
        [Switch]$ReadFromSecretVault
    )
    process {
        # Run the pre-flight check.
        Invoke-NinjaOnePreFlightCheck -SkipConnectionChecks
        # Test for secret management module.
        if ($UseSecretManagement -or $Script:NRAPIConnectionInformation.UseSecretManagement) {
            if (-not (Get-Module -Name 'Microsoft.PowerShell.SecretManagement' -ListAvailable)) {
                Write-Error 'Secret management module not installed, please install the module and try again.'
                exit 1
            }
            if (-not (Get-SecretVault)) {
                Write-Error 'No secret vaults found, please create a secret vault and try again.'
                exit 1
            }
            if ($ReadFromSecretVault -or $Script:NRAPIConnectionInformation.ReadFromSecretVault) {
                Write-Verbose 'Reading authentication information from secret vault.'
                Get-NinjaOneSecrets -VaultName $VaultName
            }
        }
        # Set the default scopes if they're not passed.
        if ($UseClientAuth -and $null -eq $Scopes) {
            $Scopes = @('monitoring', 'management', 'control')
        } elseif (($UseWebAuth -or $UseTokenAuth) -and $null -eq $Scopes) {
            $Scopes = @('monitoring', 'management', 'control', 'offline_access')
        }
        # Convert scopes to space separated string if it's an array.
        if ($Scopes -is [System.Array]) {
            Write-Verbose ('Scopes are an array, converting to space separated string.')
            $AuthScopes = $Scopes -Join ' '
        } else {
            Write-Verbose ('Scopes are a string, using as is.')
            $AuthScopes = $Scopes
        }
        # Get the NinjaOne instance URL.
        if ($Instance) {
            Write-Verbose "Using instance $($Instance) with URL $($Script:NRAPIInstances[$Instance])"
            $URL = $Script:NRAPIInstances[$Instance]
        }
        # Generate a GUID to serve as our state validator.
        $GUID = ([GUID]::NewGuid()).Guid
        # Build the redirect URI, if we need one.
        if ($RedirectURL) {
            $RedirectURI = [System.UriBuilder]$RedirectURL
        } else {
            $RedirectURI = New-Object System.UriBuilder -ArgumentList 'http', 'localhost', $Port
        }
        # Determine the authentication mode.
        if ($UseWebAuth -and $Scopes -notcontains 'offline_access') {
            $AuthMode = 'Authorisation Code'
        } elseif ($UseTokenAuth -or ($UseWebAuth -and $Scopes -contains 'offline_access')) {
            $AuthMode = 'Token Authentication'
        } elseif ($UseClientAuth) {
            $AuthMode = 'Client Credentials'
        }
        # Build a script-scoped variable to hold the connection information.
        if ($null -eq $Script:NRAPIConnectionInformation) {  
            $ConnectionInformation = @{
                AuthMode = $AuthMode
                URL = $URL
                Instance = $Instance
                ClientId = $ClientId
                ClientSecret = $ClientSecret
                AuthListenerPort = $Port
                AuthScopes = $AuthScopes
                RedirectURI = $RedirectURI
                UseSecretManagement = $UseSecretManagement
                VaultName = $VaultName
                WriteToSecretVault = $WriteToSecretVault
            }
            Set-Variable -Name 'NRAPIConnectionInformation' -Value $ConnectionInformation -Visibility Private -Scope Script -Force
        }
        Write-Verbose "Connection information set to: $($Script:NRAPIConnectionInformation | Format-List | Out-String)"
        if ($null -eq $Script:NRAPIAuthenticationInformation) {
            $AuthenticationInformation = [HashTable]@{}
            # Set a script-scoped variable to hold authentication information.
            Set-Variable -Name 'NRAPIAuthenticationInformation' -Value $AuthenticationInformation -Visibility Private -Scope Script -Force
        }
        if ($Script.NRAPIConnectionInformation.AuthMode -eq 'Token Authentication' -and $null -eq $UseTokenAuth) {
            $UseTokenAuth = $true
        }
        if ($Script.NRAPIConnectionInformation.AuthMode -eq 'Client Credentials' -and $null -eq $UseClientAuth) {
            $UseClientAuth = $true
        }
        if ($Script.NRAPIConnectionInformation.AuthMode -eq 'Authorisation Code' -and $null -eq $UseWebAuth) {
            $UseWebAuth = $true
        }
        if ($UseWebAuth) {
            # NinjaOne authorisation request query params.
            $AuthRequestParams = @{
                response_type = 'code'
                client_id = $Script:NRAPIConnectionInformation.ClientId
                client_secret = $Script:NRAPIConnectionInformation.ClientSecret
                redirect_uri = $Script:NRAPIConnectionInformation.RedirectURI.ToString()
                state = $GUID
            }
            if ($Script:NRAPIConnectionInformation.AuthScopes) {
                $AuthRequestParams.scope = $Script:NRAPIConnectionInformation.AuthScopes
            }
            # Build the authentication URI.
            # Start with the query string.
            $AuthRequestQuery = [System.Web.HttpUtility]::ParseQueryString([String]::Empty)
            $AuthRequestParams.GetEnumerator() | ForEach-Object {
                $AuthRequestQuery.Add($_.Key, $_.Value)
            }
            # Now the authentication URI
            $AuthRequestURI = [System.UriBuilder]$URL
            $AuthRequestURI.Path = 'oauth/authorize'
            $AuthRequestURI.Query = $AuthRequestQuery.ToString()
            Write-Verbose "Authentication request query string is $($AuthRequestQuery.ToString())"
            try {
                $OAuthListenerParams = @{
                    OpenURI = $AuthRequestURI
                }
                if ($VerbosePreference = 'Continue') {
                    $OAuthListenerParams.Verbose = $true
                }
                if ($DebugPreference = 'Continue') {
                    $OAuthListenerParams.Debug = $true
                }
                $OAuthListenerResponse = Start-OAuthHTTPListener @OAuthListenerParams
                $Script:NRAPIAuthenticationInformation.Code = $OAuthListenerResponse.Code
            } catch {
                New-NinjaOneError -ErrorRecord $_
            }
        }
        if (($UseTokenAuth) -or ($OAuthListenerResponse.GotAuthorisationCode) -or ($UseClientAuth)) {
            Write-Verbose 'Getting authentication token.'
            try {
                if ($OAuthListenerResponse.GotAuthorisationCode) {
                    Write-Verbose 'Using token authentication.'
                    $TokenRequestBody = @{
                        grant_type = 'authorization_code'
                        client_id = $Script:NRAPIConnectionInformation.ClientId
                        client_secret = $Script:NRAPIConnectionInformation.ClientSecret
                        code = $Script:NRAPIAuthenticationInformation.Code
                        redirect_uri = $Script:NRAPIConnectionInformation.RedirectURI.toString()
                        scope = $Script:NRAPIConnectionInformation.AuthScopes
                    }
                } elseif ($UseTokenAuth) {
                    Write-Verbose 'Using refresh token.'
                    $TokenRequestBody = @{
                        grant_type = 'refresh_token'
                        client_id = $Script:NRAPIConnectionInformation.ClientId
                        client_secret = $Script:NRAPIConnectionInformation.ClientSecret
                        refresh_token = $RefreshToken
                        scope = $Script:NRAPIConnectionInformation.AuthScopes
                    }
                } elseif ($UseClientAuth) {
                    Write-Verbose 'Using client authentication.'
                    $TokenRequestBody = @{
                        grant_type = 'client_credentials'
                        client_id = $Script:NRAPIConnectionInformation.ClientId
                        client_secret = $Script:NRAPIConnectionInformation.ClientSecret
                        redirect_uri = $Script:NRAPIConnectionInformation.RedirectURI.toString()
                        scope = $Script:NRAPIConnectionInformation.AuthScopes
                    }
                }
                Write-Verbose "Token request body is $($TokenRequestBody | Format-List | Out-String)"
                # Using our authorisation code or refresh token let's get an auth token.
                $TokenRequestUri = [System.UriBuilder]$URL
                $TokenRequestUri.Path = 'oauth/token'
                Write-Verbose "Making token request to $($TokenRequestUri.ToString())"
                $TokenRequestParams = @{
                    Uri = $TokenRequestUri.ToString()
                    Method = 'POST'
                    Body = $TokenRequestBody
                    ContentType = 'application/x-www-form-urlencoded'
                }
                $TokenResult = Invoke-WebRequest @TokenRequestParams
                $TokenPayload = $TokenResult.Content | ConvertFrom-Json
                Write-Verbose "Token payload is $($TokenPayload | Format-List | Out-String)"
                # Update our script-scoped NRAPIAuthenticationInformation variable with the token.
                $Script:NRAPIAuthenticationInformation.Type = $TokenPayload.token_type
                $Script:NRAPIAuthenticationInformation.Access = $TokenPayload.access_token
                $Script:NRAPIAuthenticationInformation.Expires = Get-TokenExpiry -ExpiresIn $TokenPayload.expires_in
                $Script:NRAPIAuthenticationInformation.Refresh = $TokenPayload.refresh_token
                Write-Verbose 'Got authentication token information from NinjaOne.'
                Write-Verbose "Authentication information set to: $($Script:NRAPIAuthenticationInformation | Format-List | Out-String)"
                if ($ShowTokens) {
                    Write-Output '================ Auth Tokens ================'
                    Write-Output $($Script:NRAPIAuthenticationInformation | Format-Table -AutoSize)
                    Write-Output ' SAVE THESE IN A SECURE LOCATION '
                }
            } catch {
                throw
            }
        }
        # If we're using secret management, store the authentication information we need.
        if ($Script:NRAPIConnectionInformation.UseSecretManagement -and $Script:NRAPIConnectionInformation.WriteToSecretVault) {
            $SecretManagementParams = @{
                AuthMode = $Script:NRAPIConnectionInformation.AuthMode
                URL = $Script:NRAPIConnectionInformation.URL
                Instance = $Script:NRAPIConnectionInformation.Instance
                ClientId = $Script:NRAPIConnectionInformation.ClientId
                ClientSecret = $Script:NRAPIConnectionInformation.ClientSecret
                AuthListenerPort = $Script:NRAPIConnectionInformation.AuthListenerPort
                AuthScopes = $Script:NRAPIConnectionInformation.AuthScopes
                RedirectURI = $Script:NRAPIConnectionInformation.RedirectURI.ToString()
                UseSecretManagement = $Script:NRAPIConnectionInformation.UseSecretManagement
                VaultName = $Script:NRAPIConnectionInformation.VaultName
                WriteToSecretVault = $Script:NRAPIConnectionInformation.WriteToSecretVault
                ReadFromSecretVault = $Script:NRAPIConnectionInformation.ReadFromSecretVault
                Type = $Script:NRAPIAuthenticationInformation.Type
                Access = $Script:NRAPIAuthenticationInformation.Access
                Expires = $Script:NRAPIAuthenticationInformation.Expires
                Refresh = $Script:NRAPIAuthenticationInformation.Refresh
            }
            Write-Verbose 'Using secret management to store credentials.'
            Set-NinjaOneSecrets @SecretManagementParams
        }
    }
}
#EndRegion '.\Public\Connect-NinjaOne.ps1' 324
#Region '.\Public\Find\Find-NinjaOneDevices.ps1' 0
#using namespace System.Management.Automation

function Find-NinjaOneDevices {
    <#
        .SYNOPSIS
            Searches for devices from the NinjaOne API.
        .DESCRIPTION
            Retrieves devices from the NinjaOne v2 API matching a search string. Cannot be used with client credentials authentication at present.
        .FUNCTIONALITY
            Devices
        .EXAMPLE
            PS> Find-NinjaOneDevices -limit 10 -searchQuery 'ABCD'
 
            returns an object containing the query and matching devices. Raw data return
        .EXAMPLE
            PS> (Find-NinjaOneDevices -limit 10 -searchQuery 'ABCD').devices
 
            returns an array of device objects matching the query.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Find/devices
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('fnod', 'Find-NinjaOneDevice')]
    [MetadataAttribute(
        '/v2/devices/search',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Limit number of devices to return.
        [Int]$limit,
        # Search query
        [Parameter(Mandatory, Position = 0, ValueFromPipeline)]
        [Alias('q')]
        [String]$searchQuery
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
    }
    process {
        try {
            Write-Verbose ('Searching for upto {0} devices matching {1}.' -f $limit, $searchQuery)
            $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
            $Resource = 'v2/devices/search'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $DeviceSearchResults = New-NinjaOneGETRequest @RequestParams
            return $DeviceSearchResults
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Find\Find-NinjaOneDevices.ps1' 60
#Region '.\Public\Get\Backup\Get-NinjaOneBackupJobs.ps1' 0

function Get-NinjaOneBackupJobs {
    <#
        .SYNOPSIS
            Gets backup jobs from the NinjaOne API.
        .DESCRIPTION
            Retrieves backup jobs from the NinjaOne v2 API.
        .FUNCTIONALITY
            Backup Jobs
        .EXAMPLE
            PS> Get-NinjaOneBackupJobs
 
            Gets all backup jobs.
        .EXAMPLE
            PS> Get-NinjaOneBackupJobs -status 'RUNNING'
 
            Gets all backup jobs with a status of 'RUNNING'.
        .EXAMPLE
            PS> Get-NinjaOneBackupJobs -status 'RUNNING', 'COMPLETED'
 
            Gets all backup jobs with a status of 'RUNNING' or 'COMPLETED'.
        .EXAMPLE
            PS> Get-NinjaOneBackupJobs -statusFilter 'status = RUNNING'
 
            Gets all backup jobs with a status of 'RUNNING'.
        .EXAMPLE
            PS> Get-NinjaOneBackupJobs -statusFilter 'status in (RUNNING, COMPLETED)'
 
            Gets all backup jobs with a status of 'RUNNING' or 'COMPLETED'.
        .EXAMPLE
            PS> Get-NinjaOneBackupJobs -planType 'IMAGE'
 
            Gets all backup jobs with a plan type of 'IMAGE'.
        .EXAMPLE
            PS> Get-NinjaOneBackupJobs -planType 'IMAGE', 'FILE_FOLDER'
 
            Gets all backup jobs with a plan type of 'IMAGE' or 'FILE_FOLDER'.
        .EXAMPLE
            PS> Get-NinjaOneBackupJobs -planTypeFilter 'planType = IMAGE'
 
            Gets all backup jobs with a plan type of 'IMAGE'.
        .EXAMPLE
            PS> Get-NinjaOneBackupJobs -planTypeFilter 'planType in (IMAGE, FILE_FOLDER)'
 
            Gets all backup jobs with a plan type of 'IMAGE' or 'FILE_FOLDER'.
        .EXAMPLE
            PS> Get-NinjaOneBackupJobs -startTimeBetween (Get-Date).AddDays(-1), (Get-Date)
 
            Gets all backup jobs with a start time between 24 hours ago and now.
        .EXAMPLE
            PS> Get-NinjaOneBackupJobs -startTimeAfter (Get-Date).AddDays(-1)
 
            Gets all backup jobs with a start time after 24 hours ago.
        .EXAMPLE
            PS> Get-NinjaOneBackupJobs -startTimeFilter 'startTime between(2024-01-01T00:00:00.000Z,2024-01-02T00:00:00.000Z)'
 
            Gets all backup jobs with a start time between 2024-01-01T00:00:00.000Z and 2024-01-02T00:00:00.000Z.
        .EXAMPLE
            PS> Get-NinjaOneBackupJobs -startTimeFilter 'startTime after 2024-01-01T00:00:00.000Z'
 
            Gets all backup jobs with a start time after 2024-01-01T00:00:00.000Z.
        .EXAMPLE
            PS> Get-NinjaOneBackupJobs -deviceFilter all
 
            Gets all backup jobs for the all devices. Includes active and deleted devices.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/backupjobs
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnobj')]
    [MetadataAttribute(
        '/v2/backup/jobs',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Cursor name.
        [Parameter(Position = 0, ValueFromPipelineByPropertyName)]
        [String]$cursor,
        # Deleted device filter.
        [Parameter(Position = 1, ValueFromPipelineByPropertyName)]
        [Alias('ddf')]
        [String]$deletedDeviceFilter,
        # Device filter.
        [Parameter(Position = 2, ValueFromPipelineByPropertyName)]
        [Alias('df')]
        [String]$deviceFilter,
        # Which devices to include (defaults to 'active').
        [Parameter(Position = 3, ValueFromPipelineByPropertyName)]
        [ValidateSet('active', 'deleted', 'all')]
        [String]$include,
        # Number of results per page.
        [Parameter(Position = 4, ValueFromPipelineByPropertyName)]
        [Int]$pageSize,
        # Filter by plan type. See the supplemental documentation at https://docs.homotechsual.dev/modules/ninjaone/filters/ptf
        [Parameter(Position = 5, ValueFromPipelineByPropertyName)]
        [ValidateSet('IMAGE, FILE_FOLDER')]
        [String]$planType,
        # Raw plan type filter. See the supplemental documentation at https://docs.homotechsual.dev/modules/ninjaone/filters/ptf
        [Parameter(Position = 6, ValueFromPipelineByPropertyName)]
        [Alias('ptf')]
        [String]$planTypeFilter,
        # Filter by status. See the supplemental documentation at https://docs.homotechsual.dev/modules/ninjaone/filters/sf
        [Parameter(Position = 6, ValueFromPipelineByPropertyName)]
        [ValidateSet('PROCESSING', 'RUNNING', 'COMPLETED', 'CANCELED', 'FAILED')]
        [String]$status,
        # Raw status filter. See the supplemental documentation at https://docs.homotechsual.dev/modules/ninjaone/filters/sf
        [Parameter(Position = 7, ValueFromPipelineByPropertyName)]
        [Alias('sf')]
        [String]$statusFilter,
        # Start time between filter. See the supplemental documentation at https://docs.homotechsual.dev/modules/ninjaone/filters/stf
        [Parameter(Position = 8, ValueFromPipelineByPropertyName)]
        [ValidateCount(2, 2)]
        [DateTime[]]$startTimeBetween,
        # Start time after filter. See the supplemental documentation at https://docs.homotechsual.dev/modules/ninjaone/filters/stf
        [Parameter(Position = 9, ValueFromPipelineByPropertyName)]
        [DateTime]$startTimeAfter,
        # Raw start time filter. See the supplemental documentation at https://docs.homotechsual.dev/modules/ninjaone/filters/stf
        [Parameter(Position = 10, ValueFromPipelineByPropertyName)]
        [Alias('stf')]
        [String]$startTimeFilter
    )
    begin {
        # Preprocess the $status parameter to the format for the sf filter.
        if ($status.Count -eq 1) {
            $statusFilter = ('status = {0}' -f $status)
        } elseif ($status.Count -gt 1) {
            $statusFilter = ('status in ({0})' -f ($status -join ','))
        }
        # Preprocess the $planType parameter to the format for the ptf filter.
        if ($planType.Count -eq 1) {
            $planTypeFilter = ('planType = {0}' -f $planType)
        } elseif ($planType.Count -gt 1) {
            $planTypeFilter = ('planType in ({0})' -f ($planType -join ','))
        }
        # Preprocess the $startTimeBetween parameter to the format for the stf filter.
        if ($startTimeBetween) {
            $startTimeFilter = ('startTime between({0},{1})' -f $startTimeBetween[0].ToUniversalTime().ToString('o'), $startTimeBetween[1].ToUniversalTime().ToString('o'))
        }
        # Preprocess the $startTimeAfter parameter to the format for the stf filter.
        if ($startTimeAfter) {
            $startTimeFilter = ('startTime after {0}' -f $startTimeAfter.ToUniversalTime().ToString('o'))
        }
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        if ($status) {
            # Workaround to prevent the query string processor from adding a 'status=' parameter by removing it from the set parameters.
            $Parameters.Remove('status') | Out-Null
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = '/v2/backup/jobs'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $LocationBackupUsageResults = New-NinjaOneGETRequest @RequestParams
            return $LocationBackupUsageResults
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Backup\Get-NinjaOneBackupJobs.ps1' 169
#Region '.\Public\Get\Backup\Get-NinjaOneLocationBackupUsage.ps1' 0

function Get-NinjaOneLocationBackupUsage {
    <#
        .SYNOPSIS
            Gets backup usage for a location from the NinjaOne API.
        .DESCRIPTION
            Retrieves backup usage for a location from the NinjaOne v2 API. For all locations omit the `locationId` parameter for devices backup usage use `Get-NinjaOneBackupUsage`.
        .FUNCTIONALITY
            Location Backup Usage
        .EXAMPLE
            PS> Get-NinjaOneLocationBackupUsage -organisationId 1
 
            Gets backup usage for all locations in the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneLocationBackupUsage -organisationId 1 -locationId 1
 
            Gets backup usage for the location with id 1 in the organisation with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/locationbackupusage
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnolbu')]
    [MetadataAttribute(
        '/v2/organization/{id}/locations/backup/usage',
        'get',
        '/v2/organization/{id}/locations/{locationId}/backup/usage',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Organisation id to retrieve backup usage for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id', 'organizationId')]
        [Int]$organisationId,
        # Location id to retrieve backup usage for.
        [Parameter(Position = 1, ValueFromPipelineByPropertyName)]
        [Int]$locationId
    )
    process {
        try {
            Write-Verbose 'Getting organisation from NinjaOne API.'
            $Organisation = Get-NinjaOneOrganisations -organisationId $organisationId
            if ($Organisation) {
                Write-Verbose 'Getting location from NinjaOne API.'
                if ($locationId) {
                    $Location = Get-NinjaOneLocations -organisationId $organisationId | Where-Object -Property id -EQ -Value $locationId
                    if ($Location) {
                        Write-Verbose ('Getting backup usage for location {0} in organisation {1}.' -f $location.name, $organisation.name)
                        $Resource = ('v2/organization/{0}/locations/{1}/backup/usage' -f $organisationId, $locationId)
                    } else {
                        throw ('Location with id {0} not found in organisation {1}' -f $locationId, $Organisation.Name)
                    }
                } else {
                    $Locations = Get-NinjaOneLocations -organisationId $organisationId
                    if ($Organisation -and $Locations) {
                        Write-Verbose ('Getting backup usage for all locations in organisation {0}.' -f $organisation.name)
                        $Resource = ('v2/organization/{0}/locations/backup/usage' -f $organisationId)
                    } else {
                        throw ('Organisation {0} does not have any locations.' -f $Organisation.Name)
                    }
                }
            } else {
                throw ('Organisation with id {0} not found.' -f $organisationId)
            }
            $RequestParams = @{
                Resource = $Resource
            }
            $LocationBackupUsageResults = New-NinjaOneGETRequest @RequestParams
            return $LocationBackupUsageResults
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Backup\Get-NinjaOneLocationBackupUsage.ps1' 78
#Region '.\Public\Get\Devices\Get-NinjaOneDeviceCustomFields.ps1' 0

function Get-NinjaOneDeviceCustomFields {
    <#
        .SYNOPSIS
            Gets device custom fields from the NinjaOne API.
        .DESCRIPTION
            Retrieves device custom fields from the NinjaOne v2 API.
        .FUNCTIONALITY
            Device Custom Fields
        .EXAMPLE
            PS> Get-NinjaOneDeviceCustomFields
             
            Gets all device custom fields.
        .EXAMPLE
            PS> Get-NinjaOneDeviceCustomFields | Group-Object { $_.scope }
 
            Gets all device custom fields grouped by the scope property.
        .EXAMPLE
            PS> Get-NinjaOneDeviceCustomFields -deviceId 1
 
            Gets the device custom fields and values for the device with id 1
        .EXAMPLE
            PS> Get-NinjaOneDeviceCustomFields -deviceId 1 -withInheritance
 
            Gets the device custom fields and values for the device with id 1 and inherits values from parent location and/or organisation, if no value is set for the device you will get the value from the parent location and if no value is set for the parent location you will get the value from the parent organisation.
        .OUTPUTS
            A powershell object containing the response
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/contacts
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnodcf')]
    [MetadataAttribute(
        '/v2/device/{id}/custom-fields',
        'get',
        '/v2/device-custom-fields',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Device id to get custom field values for a specific device.
        [Parameter(Mandatory, ParameterSetName = 'Single', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # The scopes to get custom field definitions for.
        [Parameter(ParameterSetName = 'Multi', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ValidateSet('all', 'node', 'location', 'organisation')]
        [String[]]$scope = 'all'
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        $Parameters.Remove('deviceId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
        # If $scope has more than one value preprocess the value to a comma separated string.
        if ($scope.Count -gt 1) {
            $scope = $scope -join ','
        }
    }
    process {
        try {
            if ($deviceId) {
                Write-Verbose 'Getting device from NinjaOne API.'
                $Device = Get-NinjaOneDevices -deviceId $deviceId
                if ($Device) {
                    Write-Verbose ('Getting custom fields for device {0}.' -f $Device.SystemName)
                    $Resource = ('v2/device/{0}/custom-fields' -f $deviceId)
                } else {
                    throw ('Device with id {0} not found.' -f $deviceId)
                }
            } else {
                Write-Verbose 'Retrieving all device custom fields.'
                $Resource = 'v2/device-custom-fields'
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $DeviceCustomFieldResults = New-NinjaOneGETRequest @RequestParams
            return $DeviceCustomFieldResults
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Devices\Get-NinjaOneDeviceCustomFields.ps1' 88
#Region '.\Public\Get\Devices\Get-NinjaOneDeviceDisks.ps1' 0

function Get-NinjaOneDeviceDisks {
    <#
        .SYNOPSIS
            Gets device disks from the NinjaOne API.
        .DESCRIPTION
            Retrieves device disks from the NinjaOne v2 API.
        .FUNCTIONALITY
            Device Disks
        .EXAMPLE
            PS> Get-NinjaOneDeviceDisks -deviceId 1
 
            Gets the disks for the device with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/devicedisks
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnodd')]
    [MetadataAttribute(
        '/v2/device/{id}/disks',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Device id to get disk information for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        $Parameters.Remove('deviceId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            Write-Verbose 'Getting device from NinjaOne API.'
            $Device = Get-NinjaOneDevices -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Getting disks for device {0}.' -f $Device.SystemName)
                $Resource = ('v2/device/{0}/disks' -f $deviceId)
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $DeviceDiskResults = New-NinjaOneGETRequest @RequestParams
            return $DeviceDiskResults
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Devices\Get-NinjaOneDeviceDisks.ps1' 61
#Region '.\Public\Get\Devices\Get-NinjaOneDeviceLastLoggedOnUser.ps1' 0

function Get-NinjaOneDeviceLastLoggedOnUser {
    <#
        .SYNOPSIS
            Gets device last logged on user from the NinjaOne API.
        .DESCRIPTION
            Retrieves device last logged on user from the NinjaOne v2 API.
        .FUNCTIONALITY
            Device Last Logged On User
        .EXAMPLE
            PS> Get-NinjaOneDeviceLastLoggedOnUser -deviceId 1
 
            Gets the last logged on user for the device with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/devicelastloggedonuser
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnodllou')]
    [MetadataAttribute(
        '/v2/device/{id}/last-logged-on-user',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Device id to get the last logged on user for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        $Parameters.Remove('deviceId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            Write-Verbose 'Getting device from NinjaOne API.'
            $Device = Get-NinjaOneDevices -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Getting last logged on user for device {0}.' -f $Device.SystemName)
                $Resource = ('v2/device/{0}/last-logged-on-user' -f $deviceId)
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $DeviceLastLoggedOnUserResults = New-NinjaOneGETRequest @RequestParams
            return $DeviceLastLoggedOnUserResults
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Devices\Get-NinjaOneDeviceLastLoggedOnUser.ps1' 61
#Region '.\Public\Get\Devices\Get-NinjaOneDeviceNetworkInterfaces.ps1' 0

function Get-NinjaOneDeviceNetworkInterfaces {
    <#
        .SYNOPSIS
            Gets device network interfaces from the NinjaOne API.
        .DESCRIPTION
            Retrieves device network interfaces from the NinjaOne v2 API.
        .FUNCTIONALITY
            Device Network Interfaces
        .EXAMPLE
            PS> Get-NinjaOneDeviceNetworkInterfaces -deviceId 1
 
            Gets the network interfaces for the device with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/devicelastloggedonuser
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnodni')]
    [MetadataAttribute(
        '/v2/device/{id}/network-interfaces',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Device id to get the network interfaces for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        $Parameters.Remove('deviceId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            Write-Verbose 'Getting device from NinjaOne API.'
            $Device = Get-NinjaOneDevices -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Getting network interfaces for device {0}.' -f $Device.SystemName)
                $Resource = ('v2/device/{0}/network-interfaces' -f $deviceId)
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $DeviceNetworkInterfaceResults = New-NinjaOneGETRequest @RequestParams
            return $DeviceNetworkInterfaceResults
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Devices\Get-NinjaOneDeviceNetworkInterfaces.ps1' 61
#Region '.\Public\Get\Devices\Get-NinjaOneDeviceOSPatches.ps1' 0

function Get-NinjaOneDeviceOSPatches {
    <#
        .SYNOPSIS
            Gets device OS patches from the NinjaOne API.
        .DESCRIPTION
            Retrieves device OS patches from the NinjaOne v2 API. If you want patch information for multiple devices please check out the related 'queries' commandlet `Get-NinjaOneOSPatches`.
        .FUNCTIONALITY
            Device OS Patches
        .EXAMPLE
            PS> Get-NinjaOneDeviceOSPatches -deviceId 1
 
            Gets OS patch information for the device with id 1.
        .EXAMPLE
            PS> Get-NinjaOneDeviceOSPatches -deviceId 1 -status 'APPROVED' -type 'SECURITY_UPDATES' -severity 'CRITICAL'
 
            Gets OS patch information for the device with id 1 where the patch is an approved security update with critical severity.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/deviceospatches
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnodosp')]
    [MetadataAttribute(
        '/v2/device/{id}/os-patches',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Device id to get OS patch information for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # Filter returned patches by patch status.
        [Parameter(Position = 1)]
        [ValidateSet('MANUAL', 'APPROVED', 'FAILED', 'REJECTED')]
        [String[]]$status,
        # Filter returned patches by type.
        [Parameter(Position = 2)]
        [ValidateSet('UPDATE_ROLLUPS', 'SECURITY_UPDATES', 'DEFINITION_UPDATES', 'CRITICAL_UPDATES', 'REGULAR_UPDATES', 'FEATURE_PACKS', 'DRIVER_UPDATES')]
        [String[]]$type,
        # Filter returned patches by severity.
        [Parameter(Position = 3)]
        [ValidateSet('OPTIONAL', 'MODERATE', 'IMPORTANT', 'CRITICAL')]
        [String[]]$severity
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        $Parameters.Remove('deviceId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            Write-Verbose 'Getting device from NinjaOne API.'
            $Device = Get-NinjaOneDevices -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Getting OS patches for device {0}.' -f $Device.SystemName)
                $Resource = ('v2/device/{0}/os-patches' -f $deviceId)
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $DeviceOSPatchResults = New-NinjaOneGETRequest @RequestParams
            return $DeviceOSPatchResults
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Devices\Get-NinjaOneDeviceOSPatches.ps1' 77
#Region '.\Public\Get\Devices\Get-NinjaOneDeviceOSPatchInstalls.ps1' 0

function Get-NinjaOneDeviceOSPatchInstalls {
    <#
        .SYNOPSIS
            Gets device OS patch installs from the NinjaOne API.
        .DESCRIPTION
            Retrieves device OS patch installs from the NinjaOne v2 API. If you want patch install status for multiple devices please check out the related 'queries' commandlet `Get-NinjaOneOSPatchInstalls`.
        .FUNCTIONALITY
            Device OS Patch Installs
        .EXAMPLE
            PS> Get-NinjaOneDeviceOSPatchInstalls -deviceId 1
 
            Gets OS patch installs for the device with id 1.
        .EXAMPLE
            PS> Get-NinjaOneDeviceOSPatchInstalls -deviceId 1 -status 'FAILED' -installedAfter (Get-Date 2022/01/01)
 
            Gets OS patch installs for the device with id 1 where the patch failed to install after 2022-01-01.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/deviceospatchinstalls
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnodospi')]
    [MetadataAttribute(
        '/v2/device/{id}/os-patch-installs',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Device id to get OS patch install information for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # Filter patches by patch status.
        [Parameter(Position = 1)]
        [ValidateSet('FAILED', 'INSTALLED')]
        [String]$status,
        # Filter patches to those installed before this date. Expects DateTime or Int.
        [Parameter(Position = 2)]
        [DateTime]$installedBefore,
        # Filter patches to those installed after this date. Unix Epoch time.
        [Parameter(Position = 2)]
        [Int]$installedBeforeUnixEpoch,
        # Filter patches to those installed after this date. Expects DateTime or Int.
        [Parameter(Position = 3)]
        [DateTime]$installedAfter,
        # Filter patches to those installed after this date. Unix Epoch time.
        [Parameter(Position = 3)]
        [Int]$installedAfterUnixEpoch
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        Write-Verbose ('Parameters: {0}' -f ($Parameters | Out-String))
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        $Parameters.Remove('deviceId') | Out-Null
        # If the [DateTime] parameter $installedBefore is set convert the value to a Unix Epoch.
        if ($installedBefore) {
            [Int]$installedBefore = ConvertTo-UnixEpoch -DateTime $installedBefore
        }
        # If the Unix Epoch parameter $installedBeforeUnixEpoch is set assign the value to the $installedBefore variable and null $installedBeforeUnixEpoch.
        if ($installedBeforeUnixEpoch) {
            $Parameters.Remove('installedBeforeUnixEpoch') | Out-Null
            [Int]$installedBefore = $installedBeforeUnixEpoch
        }
        # If the [DateTime] parameter $installedAfter is set convert the value to a Unix Epoch.
        if ($installedAfter) {
            [Int]$installedAfter = ConvertTo-UnixEpoch -DateTime $installedAfter
        }
        # If the Unix Epoch parameter $installedAfterUnixEpoch is set assign the value to the $installedAfter variable and null $installedAfterUnixEpoch.
        if ($installedAfterUnixEpoch) {
            $Parameters.Remove('installedAfterUnixEpoch') | Out-Null
            [Int]$installedAfter = $installedAfterUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            
            Write-Verbose 'Getting device from NinjaOne API.'
            $Device = Get-NinjaOneDevices -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Getting OS patch installs for device {0}.' -f $Device.SystemName)
                $Resource = ('v2/device/{0}/os-patch-installs' -f $deviceId)
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                }
                $DeviceOSPatchInstallResults = New-NinjaOneGETRequest @RequestParams
                return $DeviceOSPatchInstallResults
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Devices\Get-NinjaOneDeviceOSPatchInstalls.ps1' 101
#Region '.\Public\Get\Devices\Get-NinjaOneDevicePolicyOverrides.ps1' 0

function Get-NinjaOneDevicePolicyOverrides {
    <#
        .SYNOPSIS
            Gets device policy overrides from the NinjaOne API.
        .DESCRIPTION
            Retrieves device policy override sections from the NinjaOne v2 API.
        .FUNCTIONALITY
            Device Policy Overrides
        .EXAMPLE
            PS> Get-NinjaOneDevicePolicyOverrides -deviceId 1
 
            Gets the policy override sections for the device with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/devicepolicyoverrides
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnodpo')]
    [MetadataAttribute(
        '/v2/device/{id}/policy/overrides',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Device id to get the policy overrides for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # Expand the overrides property.
        [Switch]$expandOverrides
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        $Parameters.Remove('deviceId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            Write-Verbose 'Getting device from NinjaOne API.'
            $Device = Get-NinjaOneDevices -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Getting policy overrides for device {0}.' -f $Device.SystemName)
                $Resource = ('v2/device/{0}/policy/overrides' -f $deviceId)
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $DeviceLastLoggedOnUserResults = New-NinjaOneGETRequest @RequestParams
            if ($expandOverrides) {
                return $DeviceLastLoggedOnUserResults | Select-Object -ExpandProperty Overrides
            } else {
                return $DeviceLastLoggedOnUserResults
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Devices\Get-NinjaOneDevicePolicyOverrides.ps1' 67
#Region '.\Public\Get\Devices\Get-NinjaOneDeviceProcessors.ps1' 0

function Get-NinjaOneDeviceProcessors {
    <#
        .SYNOPSIS
            Gets device processors from the NinjaOne API.
        .DESCRIPTION
            Retrieves device processors from the NinjaOne v2 API.
        .FUNCTIONALITY
            Device Processors
        .EXAMPLE
            PS> Get-NinjaOneDeviceProcessors -deviceId 1
             
            Gets the processors for the device with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/deviceprocessors
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnodp')]
    [MetadataAttribute(
        '/v2/device/{id}/processors',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Device id to get processor information for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        $Parameters.Remove('deviceId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            Write-Verbose 'Getting device from NinjaOne API.'
            $Device = Get-NinjaOneDevices -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Getting processors for device {0}.' -f $Device.SystemName)
                $Resource = ('v2/device/{0}/processors' -f $deviceId)
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $DeviceProcessorResults = New-NinjaOneGETRequest @RequestParams
            return $DeviceProcessorResults
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Devices\Get-NinjaOneDeviceProcessors.ps1' 61
#Region '.\Public\Get\Devices\Get-NinjaOneDevices.ps1' 0
#using namespace System.Management.Automation

function Get-NinjaOneDevices {
    <#
        .SYNOPSIS
            Gets devices from the NinjaOne API.
        .DESCRIPTION
            Retrieves devices from the NinjaOne v2 API.
        .FUNCTIONALITY
            Devices
        .EXAMPLE
            PS> Get-NinjaOneDevices
 
            Gets all devices.
        .EXAMPLE
            PS> Get-NinjaOneDevices -deviceId 1
 
            Gets the device with id 1.
        .EXAMPLE
            PS> Get-NinjaOneDevices -organisationId 1
 
            Gets all devices for the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneDevices -deviceFilter 'status eq APPROVED'
 
            Gets all approved devices.
        .EXAMPLE
            PS> Get-NinjaOneDevices -deviceFilter 'class in (WINDOWS_WORKSTATION,MAC,LINUX_WORKSTATION)'
 
            Gets all WINDOWS_WORKSTATION, MAC or LINUX_WORKSTATION devices.
        .EXAMPLE
            PS> Get-NinjaOneDevices -deviceFilter 'class eq WINDOWS_WORKSTATION AND online'
 
            Gets all online WINDOWS_WORKSTATION devices.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/devices
        .OUTPUTS
            A powershell object containing the response.
    #>

    [CmdletBinding(DefaultParameterSetName = 'Multi')]
    [OutputType([Object])]
    [Alias('gnod', 'Get-NinjaOneDevice')]
    [MetadataAttribute(
        '/v2/devices',
        'get',
        '/v2/device/{id}',
        'get',
        '/v2/organization/{id}/devices',
        'get',
        '/v2/devices-detailed',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Device id to retrieve
        [Parameter(Mandatory, ParameterSetName = 'Single', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # Filter devices.
        [Parameter(ParameterSetName = 'Multi', Position = 1)]
        [Alias('df')]
        [String]$deviceFilter,
        # Number of results per page.
        [Parameter(ParameterSetName = 'Multi', Position = 2)]
        [Int]$pageSize,
        # Start results from device id.
        [Parameter(ParameterSetName = 'Multi', Position = 3)]
        [Int]$after,
        # Include locations and policy mappings.
        [Parameter(ParameterSetName = 'Multi', Position = 4)]
        [Switch]$detailed,
        # Filter by organisation id.
        [Parameter(Mandatory, ParameterSetName = 'Organisation', Position = 5, ValueFromPipelineByPropertyName)]
        [Alias('organizationId')]
        [Int]$organisationId
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        if ($deviceId) {
            $Parameters.Remove('deviceId') | Out-Null
        }
        # Similarly we don't want a `detailed=` parameter since we're targetting a different resource.
        if ($detailed) {
            $Parameters.Remove('detailed') | Out-Null
        }
        # Similarly we don't want an `organisationid=` parameter since we're targetting a different resource.
        if ($organisationId) {
            $Parameters.Remove('organisationId') | Out-Null
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            
            if ($deviceId) {
                Write-Verbose ('Getting device with id {0}.' -f $deviceId)
                $Resource = ('v2/device/{0}' -f $deviceId)
            } elseif ($organisationId) {
                Write-Verbose 'Getting organisation from NinjaOne API.'
                $Organisation = Get-NinjaOneOrganisations -organisationId $organisationId
                if ($Organisation) {
                    Write-Verbose ('Getting devices for organisation with id {0}.' -f $organisationId)
                    $Resource = ('v2/organization/{0}/devices' -f $organisationId)
                } else {
                    throw ('Organisation with id {0} not found.' -f $organisationId)
                }
            } else {
                if ($Detailed) {
                    Write-Verbose 'Retrieving detailed information on all devices.'
                    $Resource = 'v2/devices-detailed'
                } else {
                    Write-Verbose 'Retrieving all devices.'
                    $Resource = 'v2/devices'
                }
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            try {
                $DeviceResults = New-NinjaOneGETRequest @RequestParams
                return $DeviceResults
            } catch {
                if (-not $DeviceResults) {
                    if ($deviceId) {
                        throw ('Device with id {0} not found.' -f $deviceId)
                    } else {
                        throw 'No devices found.'
                    }
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Devices\Get-NinjaOneDevices.ps1' 139
#Region '.\Public\Get\Devices\Get-NinjaOneDeviceSoftwarePatches.ps1' 0

function Get-NinjaOneDeviceSoftwarePatches {
    <#
        .SYNOPSIS
            Gets device Software patches from the NinjaOne API.
        .DESCRIPTION
            Retrieves device Software patches from the NinjaOne v2 API. If you want patch information for multiple devices please check out the related 'queries' commandlet `Get-NinjaOneSoftwarePatches`.
        .FUNCTIONALITY
            Device Software Patches
        .EXAMPLE
            PS> Get-NinjaOneDeviceSoftwarePatches -deviceId 1
 
            Gets all software patches for the device with id 1.
        .EXAMPLE
            PS> Get-NinjaOneDeviceSoftwarePatches -deviceId 1 -status 'APPROVED' -type 'PATCH' -impact 'CRITICAL'
 
            Gets all software patches for the device with id 1 where the patch is approved, has type patch and has critical impact/severity.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/devicesoftwarepatches
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnodsp')]
    [MetadataAttribute(
        '/v2/device/{id}/software-patches',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Device id to get software patch information for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # Filter patches by patch status.
        [Parameter(Position = 1)]
        [ValidateSet('MANUAL', 'APPROVED', 'FAILED', 'REJECTED')]
        [String]$status,
        # Filter patches by product identifier.
        [Parameter(Position = 2)]
        [string]$productIdentifier,
        # Filter patches by type.
        [Parameter(Position = 3)]
        [ValidateSet('PATCH', 'INSTALLER')]
        [String]$type,
        # Filter patches by impact.
        [Parameter(Position = 4)]
        [ValidateSet('OPTIONAL', 'RECOMMENDED', 'CRITICAL')]
        [String]$impact
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        $Parameters.Remove('deviceId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            
            Write-Verbose 'Getting device from NinjaOne API.'
            $Device = Get-NinjaOneDevices -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Getting software patches for device {0}.' -f $Device.SystemName)
                $Resource = ('v2/device/{0}/software-patches' -f $deviceId)
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $DeviceSoftwarePatchResults = New-NinjaOneGETRequest @RequestParams
            return $DeviceSoftwarePatchResults
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Devices\Get-NinjaOneDeviceSoftwarePatches.ps1' 81
#Region '.\Public\Get\Devices\Get-NinjaOneDeviceSoftwarePatchInstalls.ps1' 0

function Get-NinjaOneDeviceSoftwarePatchInstalls {
    <#
        .SYNOPSIS
            Gets device software patch installs from the NinjaOne API.
        .DESCRIPTION
            Retrieves device software patch installs from the NinjaOne v2 API. If you want patch install status for multiple devices please check out the related 'queries' commandlet `Get-NinjaOneSoftwarePatchInstalls`.
        .FUNCTIONALITY
            Device Software Patch Installs
        .EXAMPLE
            PS> Get-NinjaOneDeviceSoftwarePatchInstalls -deviceId 1
 
            Gets software patch installs for the device with id 1.
        .EXAMPLE
            PS> Get-NinjaOneDeviceSoftwarePatchInstalls -deviceId 1 -type 'PATCH' -impact 'RECOMMENDED' -status 'FAILED' -installedAfter (Get-Date 2022/01/01)
 
            Gets OS patch installs for the device with id 1 where the patch with type patch and impact / severity recommended failed to install after 2022-01-01.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/devicesoftwarepatchinstalls
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnodspi')]
    [MetadataAttribute(
        '/v2/device/{id}/software-patch-installs',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Device id to get software patch install information for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # Filter patches by type.
        [Parameter(Position = 1)]
        [ValidateSet('PATCH', 'INSTALLER')]
        [string]$type,
        # Filter patches by impact.
        [Parameter(Position = 2)]
        [ValidateSet('OPTIONAL', 'RECOMMENDED', 'CRITICAL')]
        [string]$impact,
        # Filter patches by patch status.
        [Parameter(Position = 3)]
        [ValidateSet('FAILED', 'INSTALLED')]
        [String]$status,
        # Filter patches by product identifier.
        [Parameter(Position = 4)]
        [String]$productIdentifier,
        # Filter patches to those installed before this date. PowerShell DateTime object.
        [Parameter(Position = 5)]
        [DateTime]$installedBefore,
        # Filter patches to those installed after this date. Unix Epoch time.
        [Parameter(Position = 5)]
        [Int]$installedBeforeUnixEpoch,
        # Filter patches to those installed after this date. PowerShell DateTime object.
        [Parameter(Position = 6)]
        [DateTime]$installedAfter,
        # Filter patches to those installed after this date. Unix Epoch time.
        [Parameter(Position = 6)]
        [Int]$installedAfterUnixEpoch
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        $Parameters.Remove('deviceId') | Out-Null
        # If the [DateTime] parameter $installedBefore is set convert the value to a Unix Epoch.
        if ($installedBefore) {
            [Int]$installedBefore = ConvertTo-UnixEpoch -DateTime $installedBefore
        }
        # If the Unix Epoch parameter $installedBeforeUnixEpoch is set assign the value to the $installedBefore variable and null $installedBeforeUnixEpoch.
        if ($installedBeforeUnixEpoch) {
            $Parameters.Remove('installedBeforeUnixEpoch') | Out-Null
            [Int]$installedBefore = $installedBeforeUnixEpoch
        }
        # If the [DateTime] parameter $installedAfter is set convert the value to a Unix Epoch.
        if ($installedAfter) {
            [Int]$installedAfter = ConvertTo-UnixEpoch -DateTime $installedAfter
        }
        # If the Unix Epoch parameter $installedAfterUnixEpoch is set assign the value to the $installedAfter variable and null $installedAfterUnixEpoch.
        if ($installedAfterUnixEpoch) {
            $Parameters.Remove('installedAfterUnixEpoch') | Out-Null
            [Int]$installedAfter = $installedAfterUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            
            Write-Verbose 'Getting device from NinjaOne API.'
            $Device = Get-NinjaOneDevices -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Getting software patch installs for device {0}.' -f $Device.SystemName)
                $Resource = ('v2/device/{0}/software-patch-installs' -f $deviceId)
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $DeviceSoftwarePatchInstallResults = New-NinjaOneGETRequest @RequestParams
            return $DeviceSoftwarePatchInstallResults
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Devices\Get-NinjaOneDeviceSoftwarePatchInstalls.ps1' 111
#Region '.\Public\Get\Devices\Get-NinjaOneDeviceVolumes.ps1' 0

function Get-NinjaOneDeviceVolumes {
    <#
        .SYNOPSIS
            Gets device volumes from the NinjaOne API.
        .DESCRIPTION
            Retrieves device volumes from the NinjaOne v2 API.
        .FUNCTIONALITY
            Device Volumes
        .EXAMPLE
            PS> Get-NinjaOneDeviceVolumes -deviceId 1
 
            Gets the volumes for the device with id 1.
        .EXAMPLE
            PS> Get-NinjaOneDeviceVolumes -deviceId 1 -include bl
 
            Gets the volumes for the device with id 1 and includes BitLocker status.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/devicevolumes
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnodv')]
    [MetadataAttribute(
        '/v2/device/{id}/volumes',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Device id to get volumes for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # Additional information to include currently known options are 'bl' for BitLocker status.
        [Parameter(Position = 1)]
        [String]$include
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        $Parameters.Remove('deviceId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            
            Write-Verbose 'Getting device from NinjaOne API.'
            $Device = Get-NinjaOneDevices -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Getting volumes for device {0}.' -f $Device.SystemName)
                $Resource = ('v2/device/{0}/volumes' -f $deviceId)
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $DeviceVolumeResults = New-NinjaOneGETRequest @RequestParams
            return $DeviceVolumeResults
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Devices\Get-NinjaOneDeviceVolumes.ps1' 69
#Region '.\Public\Get\Devices\Get-NinjaOneDeviceWindowsServices.ps1' 0

function Get-NinjaOneDeviceWindowsServices {
    <#
        .SYNOPSIS
            Gets device windows services from the NinjaOne API.
        .DESCRIPTION
            Retrieves device windows services from the NinjaOne v2 API.
        .FUNCTIONALITY
            Device Windows Services
        .EXAMPLE
            PS> Get-NinjaOneDeviceWindowsServices -deviceId 1
 
            Gets all windows services for the device with id 1.
        .EXAMPLE
            PS> Get-NinjaOneDeviceWindowsServices -deviceId 1 -name 'NinjaRMM Agent'
 
            Gets all windows services for the device with id 1 that match the name 'NinjaRMM Agent'.
        .EXAMPLE
            PS> Get-NinjaOneDeviceWindowsServices -deviceId 1 -state 'RUNNING'
 
            Gets all windows services for the device with id 1 that are in the 'RUNNING' state.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/devicewindowsservices
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnodws')]
    [MetadataAttribute(
        '/v2/device/{id}/windows-services',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Device id to get windows services for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # Filter by service name. Ninja interprets this case sensitively.
        [Parameter(Position = 1)]
        [String]$name,
        # Filter by service state.
        [Parameter(Position = 2)]
        [ValidateSet(
            'UNKNOWN',
            'STOPPED',
            'START_PENDING',
            'RUNNING',
            'STOP_PENDING',
            'PAUSE_PENDING',
            'PAUSED',
            'CONTINUE_PENDING'
        )]
        [String]$state
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        $Parameters.Remove('deviceId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            
            Write-Verbose 'Getting device from NinjaOne API.'
            $Device = Get-NinjaOneDevices -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Getting windows services for device {0}.' -f $Device.SystemName)
                $Resource = ('v2/device/{0}/windows-services' -f $deviceId)
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $DeviceWindowsServiceResults = New-NinjaOneGETRequest @RequestParams
            return $DeviceWindowsServiceResults
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Devices\Get-NinjaOneDeviceWindowsServices.ps1' 86
#Region '.\Public\Get\Entities\Get-NinjaOneActivities.ps1' 0

function Get-NinjaOneActivities {
    <#
        .SYNOPSIS
            Gets activities from the NinjaOne API.
        .DESCRIPTION
            Retrieves activities from the NinjaOne v2 API.
        .FUNCTIONALITY
            Activities
        .EXAMPLE
            PS> Get-NinjaOneActivities
 
            Gets all activities.
        .EXAMPLE
            PS> Get-NinjaOneActivities -deviceId 1
 
            Gets activities for the device with id 1.
        .EXAMPLE
            PS> Get-NinjaOneActivities -class SYSTEM
 
            Gets system activities.
        .EXAMPLE
            PS> Get-NinjaOneActivities -before ([DateTime]::Now.AddDays(-1))
 
            Gets activities from before yesterday.
        .EXAMPLE
            PS> Get-NinjaOneActivities -after ([DateTime]::Now.AddDays(-1))
 
            Gets activities from after yesterday.
        .EXAMPLE
            PS> Get-NinjaOneActivities -olderThan 1
 
            Gets activities older than activity id 1.
        .EXAMPLE
            PS> Get-NinjaOneActivities -newerThan 1
 
            Gets activities newer than activity id 1.
        .EXAMPLE
            PS> Get-NinjaOneActivities -type 'Action'
 
            Gets activities of type 'Action'.
        .EXAMPLE
            PS> Get-NinjaOneActivities -status 'COMPLETED'
 
            Gets activities with status 'COMPLETED'.
        .EXAMPLE
            PS> Get-NinjaOneActivities -seriesUid '23e4567-e89b-12d3-a456-426614174000'
 
            Gets activities for the alert series with uid '23e4567-e89b-12d3-a456-426614174000'.
        .EXAMPLE
            PS> Get-NinjaOneActivities -deviceFilter 'organization in (1,2,3)'
 
            Gets activities for devices in organisations 1, 2 and 3.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/activities
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnoac')]
    [MetadataAttribute(
        '/v2/device/{id}/activities',
        'get',
        '/v2/activities',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter by device id.
        [Parameter(Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # Activity class.
        [Parameter(Position = 1)]
        [ValidateSet('SYSTEM', 'DEVICE', 'USER', 'ALL')]
        [String]$class,
        # return activities from before this date. PowerShell DateTime object.
        [Parameter(Position = 2)]
        [DateTime]$before,
        # return activities from before this date. Unix Epoch time.
        [Parameter(Position = 2)]
        [Int]$beforeUnixEpoch,
        # return activities from after this date. PowerShell DateTime object.
        [Parameter(Position = 3)]
        [DateTime]$after,
        # return activities from after this date. Unix Epoch time.
        [Parameter(Position = 3)]
        [Int]$afterUnixEpoch,
        # return activities older than this activity id.
        [Parameter(Position = 4)]
        [Int]$olderThan,
        # return activities newer than this activity id.
        [Parameter(Position = 5)]
        [Int]$newerThan,
        # return activities of this type.
        [Parameter(Position = 6)]
        [String]$type,
        # return activities of this type.
        [Parameter(Position = 6)]
        [String]$activityType,
        # return activities with this status.
        [Parameter(Position = 7)]
        [String]$status,
        # return activities for this user.
        [Parameter(Position = 8)]
        [String]$user,
        # return activities for this alert series.
        [Parameter(Position = 9)]
        [String]$seriesUid,
        # return activities matching this device filter.
        [Parameter(Position = 10)]
        [Alias('df')]
        [String]$deviceFilter,
        # Number of results per page.
        [Parameter(Position = 11)]
        [Int]$pageSize,
        # Filter by language tag.
        [Parameter(Position = 12)]
        [Alias('lang')]
        [String]$languageTag,
        # Filter by timezone.
        [Parameter(Position = 13)]
        [Alias('tz')]
        [String]$timeZone,
        # return the activities object instead of the default return with `lastActivityId` and `activities` properties.
        [Switch]$expandActivities
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        if ($deviceId) {
            $Parameters.Remove('deviceId')
            if ($type) {
                $Parameters.Remove('type')
                [string]$activityType = $type
            }
        } else {
            if ($activityType) {
                $Parameters.Remove('activityType')
                [string]$type = $activityType
            }
        }
        # If the [DateTime] parameter $before is set convert the value to a Unix Epoch.
        if ($before) {
            [Int]$before = ConvertTo-UnixEpoch -DateTime $before
        }
        # If the Unix Epoch parameter $beforeUnixEpoch is set assign the value to the $before variable and null $beforeUnixEpoch.
        if ($beforeUnixEpoch) {
            $Parameters.Remove('beforeUnixEpoch') | Out-Null
            [Int]$before = $beforeUnixEpoch
        }
        # If the [DateTime] parameter $after is set convert the value to a Unix Epoch.
        if ($after) {
            [Int]$after = ConvertTo-UnixEpoch -DateTime $after
        }
        # If the Unix Epoch parameter $afterUnixEpoch is set assign the value to the $after variable and null $afterUnixEpoch.
        if ($afterUnixEpoch) {
            $Parameters.Remove('afterUnixEpoch') | Out-Null
            [Int]$after = $afterUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            
            if ($deviceId) {
                Write-Verbose 'Getting device from NinjaOne API.'
                $Device = Get-NinjaOneDevices -deviceId $deviceId
                if ($Device) {
                    Write-Verbose ('Getting activities for device {0}.' -f $Device.SystemName)
                    $Resource = ('v2/device/{0}/activities' -f $deviceId)
                } else {
                    throw ('Device with id {0} not found.' -f $deviceId)
                }
            } else {
                Write-Verbose 'Retrieving all device activities.'
                $Resource = 'v2/activities'
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $ActivityResults = New-NinjaOneGETRequest @RequestParams
            if ($ActivityResults) {
                if ($expandActivities) {
                    return $ActivityResults.activities
                } else {
                    return $ActivityResults
                }
            } else {
                if ($Device) {
                    throw ('No activities found for device {0}.' -f $Device.SystemName)
                } else {
                    throw 'No activities found.'
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Entities\Get-NinjaOneActivities.ps1' 204
#Region '.\Public\Get\Entities\Get-NinjaOneAlerts.ps1' 0
#using namespace System.Management.Automation

function Get-NinjaOneAlerts {
    <#
        .SYNOPSIS
            Gets alerts from the NinjaOne API.
        .DESCRIPTION
            Retrieves alerts from the NinjaOne v2 API.
        .FUNCTIONALITY
            Alerts
        .EXAMPLE
            PS> Get-NinjaOneAlerts
             
            Gets all alerts.
        .EXAMPLE
            PS> Get-NinjaOneAlerts -sourceType 'CONDITION_CUSTOM_FIELD'
 
            Gets all alerts with source type CONDITION_CUSTOM_FIELD.
        .EXAMPLE
            PS> Get-NinjaOneAlerts -deviceFilter 'status eq APPROVED'
 
            Gets alerts for all approved devices.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/alerts
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnoal')]
    [MetadataAttribute(
        '/v2/alerts',
        'get',
        '/v2/device/{id}/alerts',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter by device id.
        [Parameter(Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # Filter by source type.
        [Parameter(Position = 1)]
        [String]$sourceType,
        # Filter by device which triggered the alert.
        [Parameter(Position = 2)]
        [Alias('df')]
        [String]$deviceFilter,
        # Filter by language tag.
        [Parameter(Position = 3)]
        [Alias('lang')]
        [String]$languageTag,
        # Filter by timezone.
        [Parameter(Position = 4)]
        [Alias('tz')]
        [String]$timeZone
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        if ($deviceId) {
            $Parameters.Remove('deviceId') | Out-Null
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($deviceId) {
                Write-Verbose 'Getting device from NinjaOne API.'
                $Device = Get-NinjaOneDevices -deviceId $deviceId
                if ($Device) {
                    Write-Verbose ('Getting alerts for device {0}.' -f $Device.SystemName)
                    $Resource = ('v2/device/{0}/alerts' -f $deviceId)
                } else {
                    throw ('Device with id {0} not found.' -f $deviceId)
                }
            } else {
                Write-Verbose 'Retrieving all alerts.'
                $Resource = 'v2/alerts'
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            try {
                $AlertResults = New-NinjaOneGETRequest @RequestParams
                return $AlertResults
            } catch {
                if (-not $AlertResults) {
                    if ($Device) {
                        throw ('No alerts found for device {0}.' -f $Device.SystemName)
                    } else {
                        throw 'No alerts found.'
                    }
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Entities\Get-NinjaOneAlerts.ps1' 104
#Region '.\Public\Get\Entities\Get-NinjaOneAttachment.ps1' 0

function Get-NinjaOneAttachment {
    <#
        .SYNOPSIS
            Gets a help request form / systray help form attachment from the NinjaOne API.
        .DESCRIPTION
            Retrieves a help request form / systray help form attachment from the NinjaOne v2 API.
        .FUNCTIONALITY
            Attachment
        .OUTPUTS
            A powershell object containing the response.
        .EXAMPLE
            PS> Get-NinjaOneAttachment -attachmentId 'somethinggoesherebutidontknowwhatandneitherdoninja'
 
            Retrieves the attachment with id 'somethinggoesherebutidontknowwhatandneitherdoninja'.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/attachment
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnoat')]
    [MetadataAttribute(
        '/v2/attachment/{id}',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The attachment id to retrieve.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [String]$attachmentId
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'attachmentid=' parameter by removing it from the set parameters.
        $Parameters.Remove('attachmentId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            Write-Verbose 'Retrieving attachment.'
            $Resource = ('v2/attachment/{0}' -f $attachmentId)
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $AttachmentResults = New-NinjaOneGETRequest @RequestParams
            if ($AttachmentResults) {
                return $AttachmentResults   
            } else {
                throw ('Attachment with id {0} not found.' -f $attachmentId)
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Entities\Get-NinjaOneAttachment.ps1' 59
#Region '.\Public\Get\Entities\Get-NinjaOneDocumentTemplates.ps1' 0

function Get-NinjaOneDocumentTemplates {
    <#
        .SYNOPSIS
            Gets one or more document templates from the NinjaOne API.
        .DESCRIPTION
            Retrieves one or more document templates from the NinjaOne v2 API.
        .FUNCTIONALITY
            Document Template
        .OUTPUTS
            A powershell object containing the response.
        .EXAMPLE
            PS> Get-NinjaOneDocumentTemplate
 
            Retrieves all document templates with their fields.
        .EXAMPLE
            PS> Get-NinjaOneDocumentTemplate -documentTemplateId 1
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/documenttemplate
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnodt', 'Get-NinjaOneDocumentTemplate')]
    [MetadataAttribute(
        '/v2/document-templates',
        'get',
        '/v2/document-templates/{documentTemplateId}',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The document template id to retrieve.
        [Parameter(Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [String]$documentTemplateId
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'documenttemplateid=' parameter by removing it from the set parameters.
        $Parameters.Remove('documentTemplateId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($documentTemplateId) {
                Write-Verbose 'Getting document template from NinjaOne API.'
                $DocumentTemplate = Get-NinjaOneDocumentTemplates -documentTemplateId $documentTemplateId
                if ($DocumentTemplate) {
                    Write-Verbose ('Getting document template with id {0}.' -f $documentTemplateId)
                    $Resource = ('v2/document-templates/{0}' -f $documentTemplateId)
                }
            } else {
                Write-Verbose 'Retrieving all document templates.'
                $Resource = 'v2/document-templates'
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            try {
                $DocumentTemplateResults = New-NinjaOneGETRequest @RequestParams
                return $DocumentTemplateResults
            } catch {
                if (-not $DocumentTemplateResults) {
                    if ($documentTemplateId) {
                        throw ('Document template with id {0} not found.' -f $documentTemplateId)
                    } else {
                        throw 'No document templates found.'
                    }
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Entities\Get-NinjaOneDocumentTemplates.ps1' 78
#Region '.\Public\Get\Entities\Get-NinjaOneJobs.ps1' 0

function Get-NinjaOneJobs {
    <#
        .SYNOPSIS
            Gets jobs from the NinjaOne API.
        .DESCRIPTION
            Retrieves jobs from the NinjaOne v2 API.
        .FUNCTIONALITY
            Jobs
        .EXAMPLE
            PS> Get-NinjaOneJobs
 
            Gets all jobs.
        .EXAMPLE
            PS> Get-NinjaOneJobs -jobType SOFTWARE_PATCH_MANAGEMENT
 
            Gets software patch management jobs.
        .EXAMPLE
            PS> Get-NinjaOneJobs -deviceFilter 'organization in (1,2,3)'
 
            Gets jobs for devices in organisations 1, 2 and 3.
        .EXAMPLE
            PS> Get-NinjaOneJobs -deviceId 1
 
            Gets jobs for the device with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/jobs/
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnoj')]
    [MetadataAttribute(
        '/v2/jobs',
        'get',
        '/v2/device/{id}/jobs',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter by device id.
        [Parameter(Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # Filter by job type.
        [Parameter(Position = 1)]
        [String]$jobType,
        # Filter by device triggering the alert.
        [Parameter(Position = 2)]
        [Alias('df')]
        [String]$deviceFilter,
        # Filter by language tag.
        [Parameter(Position = 3)]
        [Alias('lang')]
        [String]$languageTag,
        # Filter by timezone.
        [Parameter(Position = 4)]
        [Alias('ts')]
        [String]$timeZone
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        if ($deviceId) {
            $Parameters.Remove('deviceId') | Out-Null
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($deviceId) {
                Write-Verbose 'Getting device from NinjaOne API.'
                $Device = Get-NinjaOneDevices -deviceId $deviceId
                if ($Device) {
                    Write-Verbose ('Getting jobs for device {0}.' -f $Device.SystemName)
                    $Resource = ('v2/device/{0}/jobs' -f $deviceId)
                }
            } else {
                Write-Verbose 'Retrieving all jobs.'
                $Resource = 'v2/jobs'
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
                NoDrill = $True
            }
            $JobResults = New-NinjaOneGETRequest @RequestParams
            if ($JobResults) {
                return $JobResults
            } else {
                if ($Device) {
                    throw ('No jobs found for device {0}.' -f $Device.SystemName)
                } else {
                    throw 'No jobs found.'
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Entities\Get-NinjaOneJobs.ps1' 104
#Region '.\Public\Get\Entities\Get-NinjaOnePolicies.ps1' 0

function Get-NinjaOnePolicies {
    <#
        .SYNOPSIS
            Gets policies from the NinjaOne API.
        .DESCRIPTION
            Retrieves policies from the NinjaOne v2 API.
        .FUNCTIONALITY
            Policies
        .EXAMPLE
            PS> Get-NinjaOnePolicies
 
            Gets all policies.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/policies
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnop')]
    [MetadataAttribute(
        '/v2/policies',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param()
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            Write-Verbose 'Retrieving all policies.'
            $Resource = 'v2/policies'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $PolicyResults = New-NinjaOneGETRequest @RequestParams
            if ($PolicyResults) {
                return $PolicyResults
            } else {
                throw 'No policies found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Entities\Get-NinjaOnePolicies.ps1' 52
#Region '.\Public\Get\Entities\Get-NinjaOneRoles.ps1' 0

function Get-NinjaOneRoles {
    <#
        .SYNOPSIS
            Gets device roles from the NinjaOne API.
        .DESCRIPTION
            Retrieves device roles from the NinjaOne v2 API.
        .FUNCTIONALITY
            Device Roles
        .EXAMPLE
            PS> Get-NinjaOneRoles
 
            Gets all device roles.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/deviceroles
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnor')]
    [MetadataAttribute(
        '/v2/roles',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param()
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            
            Write-Verbose 'Retrieving all roles.'
            $Resource = 'v2/roles'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $RoleResults = New-NinjaOneGETRequest @RequestParams
            if ($RoleResults) {
                return $RoleResults
            } else {
                throw 'No roles found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Entities\Get-NinjaOneRoles.ps1' 53
#Region '.\Public\Get\Entities\Get-NinjaOneSoftwareProducts.ps1' 0

function Get-NinjaOneSoftwareProducts {
    <#
        .SYNOPSIS
            Gets software products from the NinjaOne API.
        .DESCRIPTION
            Retrieves software products from the NinjaOne v2 API.
        .FUNCTIONALITY
            Software Products
        .EXAMPLE
            PS> Get-NinjaOneSoftwareProducts
             
            Gets all software products.
        .EXAMPLE
            PS> Get-NinjaOneSoftwareProducts -deviceId 1
 
            Gets all software products for the device with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/softwareproducts
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnosp')]
    [MetadataAttribute(
        '/v2/software-products',
        'get',
        '/v2/device/{id}/software',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The device id to get software products for.
        [Parameter(Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        $Parameters.Remove('deviceId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            
            if ($deviceId) {
                $Device = Get-NinjaOneDevices -deviceId $deviceId
                if ($Device) {
                    Write-Verbose ('Getting software products for device {0}.' -f $Device.SystemName)
                    $Resource = ('v2/device/{0}/software' -f $deviceId)
                } else {
                    throw ('Device with id {0} not found.' -f $deviceId)
                }
            } else {
                Write-Verbose 'Retrieving all software products.'
                $Resource = 'v2/software-products'
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $SoftwareProductResults = New-NinjaOneGETRequest @RequestParams
            if ($SoftwareProductResults) {
                return $SoftwareProductResults
            } else {
                if ($Device) {
                    throw ('No software products found for device {0}.' -f $Device.SystemName)
                } else {
                    throw 'No software products found.'
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Entities\Get-NinjaOneSoftwareProducts.ps1' 80
#Region '.\Public\Get\Entities\Get-NinjaOneTasks.ps1' 0

function Get-NinjaOneTasks {
    <#
        .SYNOPSIS
            Gets tasks from the NinjaOne API.
        .DESCRIPTION
            Retrieves tasks from the NinjaOne v2 API.
        .FUNCTIONALITY
            Scheduled Tasks
        .EXAMPLE
            PS> Get-NinjaOneTasks
             
            Gets all tasks.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/scheduledtasks
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnota')]
    [MetadataAttribute(
        '/v2/tasks',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param()
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            
            Write-Verbose 'Retrieving all tasks.'
            $Resource = 'v2/tasks'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $TaskResults = New-NinjaOneGETRequest @RequestParams
            if ($TaskResults) {
                return $TaskResults
            } else {
                throw 'No tasks found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Entities\Get-NinjaOneTasks.ps1' 53
#Region '.\Public\Get\Entities\Get-NinjaOneUsers.ps1' 0

function Get-NinjaOneUsers {
    <#
        .SYNOPSIS
            Gets users from the NinjaOne API.
        .DESCRIPTION
            Retrieves users from the NinjaOne v2 API.
        .FUNCTIONALITY
            Users
        .EXAMPLE
            PS> Get-NinjaOneUsers
             
            Gets all users.
        .EXAMPLE
            PS> Get-NinjaOneUsers -userType TECHNICIAN
             
            Gets all technicians (users with the TECHNICIAN user type).
        .EXAMPLE
            PS> Get-NinjaOneUsers -organisationId 1
             
            Gets all users for the organisation with id 1 (only works for users with the END_USER user type).
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/users
    #>

    [CmdletBinding(DefaultParameterSetName = 'Default')]
    [OutputType([Object])]
    [Alias('gnou')]
    [MetadataAttribute(
        '/v2/users',
        'get',
        '/v2/organization/{id}/end-users',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Get users for this organisation id.
        [Parameter(Mandatory, ParameterSetName = 'Organisation', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id', 'organizationId')]
        [Int]$organisationId,
        # Filter by user type. This can be one of "TECHNICIAN" or "END_USER".
        [Parameter(ParameterSetName = 'Default', Position = 1, ValueFromPipelineByPropertyName)]
        [Parameter(ParameterSetName = 'Organisation', Position = 1, ValueFromPipelineByPropertyName)]
        [ValidateSet(
            'TECHNICIAN',
            'END_USER'
        )]
        [String]$userType
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'organisationid=' parameter by removing it from the set parameters.
        if ($organisationId) {
            $Parameters.Remove('organisationId') | Out-Null
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($organisationId) {
                Write-Verbose 'Getting organisation from NinjaOne API.'
                $Organisation = Get-NinjaOneOrganisations -organisationId $organisationId
                if ($Organisation) {
                    Write-Verbose ('Getting users for organisation {0}.' -f $Organisation.Name)
                    $Resource = ('v2/organization/{0}/end-users' -f $organisationId)
                } 
            } else {
                Write-Verbose 'Retrieving all users.'
                $Resource = 'v2/users'
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $UserResults = New-NinjaOneGETRequest @RequestParams
            if ($UserResults) {
                return $UserResults
            } else {
                if ($Organisation) {
                    throw ('No users found for organisation {0}.' -f $Organisation.Name)
                } else {
                    throw 'No users found.'
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Entities\Get-NinjaOneUsers.ps1' 92
#Region '.\Public\Get\Groups\Get-NinjaOneGroupMembers.ps1' 0

function Get-NinjaOneGroupMembers {
    <#
        .SYNOPSIS
            Gets group members from the NinjaOne API.
        .DESCRIPTION
            Retrieves group members from the NinjaOne v2 API.
        .FUNCTIONALITY
            Group Members
        .EXAMPLE
            PS> Get-NinjaOneGroupMembers -groupId 1
             
            Gets all group members for group with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/groupmembers
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnogm')]
    [MetadataAttribute(
        '/v2/group/{id}/device-ids',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The group id to get members for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$groupId,
        # Refresh ?ToDo Query with Ninja
        [Parameter(Position = 1)]
        [string]$refresh
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'groupid=' parameter by removing it from the set parameters.
        $Parameters.Remove('groupId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            
            Write-Verbose 'Getting group from NinjaOne API.'
            $Groups = Get-NinjaOneGroups
            $Group = $Groups | Where-Object { $_.id -eq $groupId }
            if ($Group) {
                Write-Verbose ('Getting group members for group {0}.' -f $Group.Name)
                $Resource = ('v2/group/{0}/device-ids' -f $groupId)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $GroupMemberResults = New-NinjaOneGETRequest @RequestParams
            if ($GroupMemberResults) {
                return $GroupMemberResults
            } else {
                throw ('No group members found for group {0}.' -f $Group.Name)
            }
            return $GroupMemberResults
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Groups\Get-NinjaOneGroupMembers.ps1' 69
#Region '.\Public\Get\Groups\Get-NinjaOneGroups.ps1' 0

function Get-NinjaOneGroups {
    <#
        .SYNOPSIS
            Gets groups from the NinjaOne API.
        .DESCRIPTION
            Retrieves groups from the NinjaOne v2 API.
        .FUNCTIONALITY
            Groups
        .EXAMPLE
            PS> Get-NinjaOneGroups
             
            Gets all groups.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/groups
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnog')]
    [MetadataAttribute(
        '/v2/groups',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Group names should be returned in this language.
        [Parameter(Position = 0)]
        [Alias('lang')]
        [String]$languageTag
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            Write-Verbose 'Retrieving all groups.'
            $Resource = 'v2/groups'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $GroupResults = New-NinjaOneGETRequest @RequestParams
            if ($GroupResults) {
                return $GroupResults
            } else {
                throw 'No groups found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Groups\Get-NinjaOneGroups.ps1' 57
#Region '.\Public\Get\Management\Get-NinjaOneDeviceDashboardURL.ps1' 0

function Get-NinjaOneDeviceDashboardURL {
    <#
        .SYNOPSIS
            Gets device dashboard URL from the NinjaOne API.
        .DESCRIPTION
            Retrieves device dashboard URL from the NinjaOne v2 API.
        .FUNCTIONALITY
            Device Dashboard URL
        .EXAMPLE
            PS> Get-NinjaOneDeviceDashboardURL -deviceId 1
 
            Gets the device dashboard URL for the device with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/devicedashboardurl
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnoddurl')]
    [MetadataAttribute(
        '/v2/device/{id}/dashboard-url',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The device id to get the dashboard URL for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # return redirect response. This is largely useless as it will return a HTML redirect page source.
        [Parameter(Position = 1)]
        [Switch]$redirect
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        $Parameters.Remove('deviceId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            Write-Verbose 'Getting device from NinjaOne API.'
            $Device = Get-NinjaOneDevices -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Getting dashboard URL for device {0}.' -f $Device.SystemName)
                $Resource = ('v2/device/{0}/dashboard-url' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            if ($redirect) {
                $RequestParams.Add('Raw', $true)
            }
            $DeviceDashboardURLResults = New-NinjaOneGETRequest @RequestParams
            if ($DeviceDashboardURLResults) {
                return $DeviceDashboardURLResults
            } else {
                throw ('No dashboard URL found for device {0}.' -f $Device.SystemName)
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Management\Get-NinjaOneDeviceDashboardURL.ps1' 69
#Region '.\Public\Get\Management\Get-NinjaOneDeviceScriptingOptions.ps1' 0

function Get-NinjaOneDeviceScriptingOptions {
    <#
        .SYNOPSIS
            Gets device scripting options from the NinjaOne API.
        .DESCRIPTION
            Retrieves device scripting options from the NinjaOne v2 API.
        .FUNCTIONALITY
            Device Scripting Options
        .EXAMPLE
            PS> Get-NinjaOneDeviceScriptingOptions -deviceId 1
 
            Gets the device scripting options for the device with id 1.
        .EXAMPLE
            PS> Get-NinjaOneDeviceScriptingOptions -deviceId 1 -Scripts
 
            Gets the scripts for the device with id 1.
        .EXAMPLE
            PS> Get-NinjaOneDeviceScriptingOptions -deviceId 1 -Categories
 
            Gets the categories for the device with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/devicescriptingoptions
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnodso')]
    [MetadataAttribute(
        '/v2/device/{id}/scripting/options',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The device id to get the scripting options for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # Built in scripts / job names should be returned in the specified language.
        [Parameter(Position = 1)]
        [Alias('lang')]
        [String]$LanguageTag,
        # Return the categories list only.
        [Parameter(Position = 2)]
        [Switch]$Categories,
        # Return the scripts list only.
        [Parameter(Position = 3)]
        [Switch]$Scripts
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'deviceid=' parameter by removing it from the set parameters.
        $Parameters.Remove('deviceId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            Write-Verbose 'Getting device from NinjaOne API.'
            $Device = Get-NinjaOneDevices -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Getting scripting options for device {0}.' -f $Device.SystemName)
                $Resource = ('v2/device/{0}/scripting/options' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $DeviceScriptingOptionResults = New-NinjaOneGETRequest @RequestParams
            if ($DeviceScriptingOptionResults) {
                if ($Categories) {
                    return $DeviceScriptingOptionResults.Categories
                } elseif ($Scripts) {
                    return $DeviceScriptingOptionResults.Scripts
                } else {
                    return $DeviceScriptingOptionResults
                }
            } else {
                throw ('No scripting options found for device {0}.' -f $Device.SystemName)
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Management\Get-NinjaOneDeviceScriptingOptions.ps1' 87
#Region '.\Public\Get\Management\Get-NinjaOneInstaller.ps1' 0

function Get-NinjaOneInstaller {
    <#
        .SYNOPSIS
            Gets agent installer URL from the NinjaOne API.
        .DESCRIPTION
            Retrieves agent installer URL from the NinjaOne v2 API.
        .FUNCTIONALITY
            Installer
        .EXAMPLE
            PS> Get-NinjaOneInstaller -organisationId 1 -locationId 1 -installerType WINDOWS_MSI
 
            Gets the agent installer URL for the location with id 1 in the organisation with id 1 for the Windows MSI installer.
        .EXAMPLE
            PS> Get-NinjaOneInstaller -organisationId 1 -locationId 1 -installerType MAC_PKG
 
            Gets the agent installer URL for the location with id 1 in the organisation with id 1 for the Mac PKG installer.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/installer
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnoi')]
    [MetadataAttribute(
        '/v2/organization/{id}/location/{location_id}/installer/{installer_type}',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The organisation id to get the installer for.
        [Parameter(Mandatory, Position = 0, ValueFromPipelineByPropertyName)]
        [Alias('id', 'organizationId')]
        [Int]$organisationId,
        # The location id to get the installer for.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [Int]$locationId,
        # Installer type/platform.
        [Parameter(Mandatory, Position = 2, ValueFromPipelineByPropertyName)]
        [ValidateSet(
            'WINDOWS_MSI',
            'MAC_DMG',
            'MAC_PKG',
            'LINUX_DEB',
            'LINUX_RPM'
        )]
        [String]$installerType
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'organisationid=' parameter by removing it from the set parameters.
        $Parameters.Remove('organisationId') | Out-Null
        # Workaround to prevent the query string processor from adding a 'locationid=' parameter by removing it from the set parameters.
        $Parameters.Remove('locationId') | Out-Null
        # Workaround to prevent the query string processor from adding an 'installertype=' parameter by removing it from the set parameters.
        $Parameters.Remove('installerType') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            Write-Verbose 'Getting device from NinjaOne API.'
            $Organisation = Get-NinjaOneOrganisations -organisationId $organisationId
            $Location = Get-NinjaOneLocations -organisationId $organisationId | Where-Object { $_.id -eq $locationId }
            if ($Organisation -and $Location) {
                Write-Verbose ('Getting installer for organisation {0} - location {1} ({2}).' -f $Organisation.Name, $Location.Name, $installerType)
                $Resource = ('v2/organization/{0}/location/{1}/installer/{2}' -f $organisationId, $locationId, $installerType)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $AgentInstallerResults = New-NinjaOneGETRequest @RequestParams
            if ($AgentInstallerResults) {
                return $AgentInstallerResults
            } else {
                throw ('No agent installer found for organisation { 0 } - location { 1 } ({ 2 }).' -f $Organisation.Name, $Location.Name, $installerType)
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Management\Get-NinjaOneInstaller.ps1' 85
#Region '.\Public\Get\Organisation\Get-NinjaOneLocationCustomFields.ps1' 0
function Get-NinjaOneLocationCustomFields {
    <#
        .SYNOPSIS
            Gets location custom fields from the NinjaOne API.
        .DESCRIPTION
            Retrieves location custom fields from the NinjaOne v2 API.
        .FUNCTIONALITY
            Location Custom Fields
        .EXAMPLE
            Get-NinjaOneLocationCustomFields organisationId 1 -locationId 2
 
            Gets custom field details for the location with id 2 belonging to the organisation with id 1.
        .EXAMPLE
            Get-NinjaOneLocationCustomFields organisationId 1 -locationId 2 -withInheritance
 
            Gets custom field details for the location with id 2 belonging to the organisation with id 1 and inherits values from parent organisation, if no value is set for the location you will get the value from the parent organisation.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/locationcustomfields
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnolcf')]
    [MetadataAttribute(
        '/v2/organization/{id}/location/{locationId}/custom-fields',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter by organisation id.
        [Parameter(Mandatory, Position = 0, ValueFromPipelineByPropertyName)]
        [Alias('id', 'organizationId')]
        [Int]$organisationId,
        # Filter by location id.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [Int]$locationId,
        # Inherit custom field values from parent organisation.
        [Parameter(Position = 2, ValueFromPipelineByPropertyName)]
        [Boolean]$withInheritance
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'organisationid=' parameter by removing it from the set parameters.
        $Parameters.Remove('organisationId') | Out-Null
        # Workaround to prevent the query string processor from adding an 'locationid=' parameter by removing it from the set parameters.
        $Parameters.Remove('locationId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            Write-Verbose 'Getting organisation custom fields from NinjaOne API.'
            $Organisation = Get-NinjaOneOrganisations -organisationId $organisationId
            if ($Organisation) {
                $Location = Get-NinjaOneLocations -organisationId $organisationId | Where-Object -Property id -EQ -Value $locationId
                if ($Location) {
                    Write-Verbose ('Getting custom fields for organisation {0} - location {1}.' -f $Organisation.Name, $Location.Name)
                    $Resource = ('v2/organization/{0}/location/{1}/custom-fields' -f $organisationId, $locationId)
                } else {
                    throw ('Location with id {0} not found for organisation {1}.' -f $locationId, $Organisation.Name)
                }
            } else {
                throw ('Organisation with id {0} not found.' -f $organisationId)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $CustomFieldResults = New-NinjaOneGETRequest @RequestParams
            if ($CustomFieldResults) {
                return $CustomFieldResults
            } else {
                throw ('No custom fields found for organisation {0} - location {1}.' -f $Organisation.Name, $Location.Name)
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Organisation\Get-NinjaOneLocationCustomFields.ps1' 81
#Region '.\Public\Get\Organisation\Get-NinjaOneLocations.ps1' 0
function Get-NinjaOneLocations {
    <#
        .SYNOPSIS
            Gets locations from the NinjaOne API.
        .DESCRIPTION
            Retrieves locations from the NinjaOne v2 API.
        .FUNCTIONALITY
            Locations
        .EXAMPLE
            PS> Get-NinjaOneLocations
 
            Gets all locations.
        .EXAMPLE
            PS> Get-NinjaOneLocations -after 1
 
            Gets all locations after location id 1.
        .EXAMPLE
            PS> Get-NinjaOneLocations -organisationId 1
             
            Gets all locations for the organisation with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/locations
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnol')]
    [MetadataAttribute(
        '/v2/locations',
        'get',
        '/v2/organization/{id}/locations',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Number of results per page.
        [Parameter(Position = 0)]
        [Int]$pageSize,
        # Start results from location id.
        [Parameter(Position = 1)]
        [Int]$after,
        # Filter by organisation id.
        [Parameter(Position = 2, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id', 'organizationId')]
        [Int]$organisationId
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'organisationid=' parameter by removing it from the set parameters.
        if ($organisationId) {
            $Parameters.Remove('organisationId') | Out-Null
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($organisationId) {
                Write-Verbose 'Getting organisation from NinjaOne API.'
                $Organisation = Get-NinjaOneOrganisations -organisationId $organisationId
                if ($Organisation) {
                    Write-Verbose ('Getting locations for organisation {0}.' -f $Organisation.Name)
                    $Resource = ('v2/organization/{0}/locations' -f $organisationId)
                }
            } else {
                Write-Verbose 'Retrieving all locations.'
                $Resource = 'v2/locations'
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $LocationResults = New-NinjaOneGETRequest @RequestParams
            if ($LocationResults) {
                return $LocationResults
            } else {
                throw ('No locations found for organisation {0}.' -f $Organisation.Name)
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Organisation\Get-NinjaOneLocations.ps1' 85
#Region '.\Public\Get\Organisation\Get-NinjaOneOrganisationCustomFields.ps1' 0
function Get-NinjaOneOrganisationCustomFields {
    <#
        .SYNOPSIS
            Gets organisation custom fields from the NinjaOne API.
        .DESCRIPTION
            Retrieves organisation custom fields from the NinjaOne v2 API.
        .FUNCTIONALITY
            Organisation Custom Fields
        .EXAMPLE
            Get-NinjaOneOrganisationCustomFields -organisationId 1
 
            Gets custom field details for the organisation with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/organisationcustomfields
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnoocf', 'Get-NinjaOneOrganizationCustomFields')]
    [MetadataAttribute(
        '/v2/organization/{id}/custom-fields',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter by organisation id.
        [Parameter(Mandatory, Position = 0, ValueFromPipelineByPropertyName)]
        [Alias('id', 'organizationId')]
        [Int]$organisationId
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'organisationid=' parameter by removing it from the set parameters.
        if ($organisationId) {
            $Parameters.Remove('organisationId') | Out-Null
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            Write-Verbose 'Getting organisation custom fields from NinjaOne API.'
            $Organisation = Get-NinjaOneOrganisations -organisationId $organisationId
            if ($Organisation) {
                Write-Verbose ('Getting custom fields for organisation {0}.' -f $Organisation.Name)
                $Resource = ('v2/organization/{0}/custom-fields' -f $organisationId)
            } else {
                throw ('Organisation with id {0} not found.' -f $organisationId)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $CustomFieldResults = New-NinjaOneGETRequest @RequestParams
            if ($CustomFieldResults) {
                return $CustomFieldResults
            } else {
                throw ('No custom fields found for organisation {0}.' -f $Organisation.Name)
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Organisation\Get-NinjaOneOrganisationCustomFields.ps1' 66
#Region '.\Public\Get\Organisation\Get-NinjaOneOrganisationDocuments.ps1' 0
function Get-NinjaOneOrganisationDocuments {
    <#
        .SYNOPSIS
            Gets documents from the NinjaOne API.
        .DESCRIPTION
            Retrieves documents from the NinjaOne v2 API.
        .FUNCTIONALITY
            Documents
        .EXAMPLE
            Get-NinjaOneOrganisationDocuments -organisationId 1
 
            Gets documents for the organisation with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/documents
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnood', 'Get-NinjaOneOrganizationDocuments')]
    [MetadataAttribute(
        '/v2/organization/{organizationId}/documents',
        'get',
        '/v2/organization/documents',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter by organisation id.
        [Parameter(Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id', 'organizationId')]
        [Int]$organisationId,
        # Filter by document name.
        [Parameter(Position = 1, ValueFromPipelineByPropertyName)]
        [String]$documentName,
        # Group by template or organisation.
        [Parameter(Position = 2, ValueFromPipelineByPropertyName)]
        [ValidateSet('template', 'organization')]
        [String]$groupBy,
        # Filter by organisation ids. TODO: Describe the format.
        [Parameter(Position = 3, ValueFromPipelineByPropertyName)]
        [String]$organisationIds,
        # Filter by template ids. TODO: Describe the format.
        [Parameter(Position = 4, ValueFromPipelineByPropertyName)]
        [String]$templateIds,
        # Filter by template name.
        [Parameter(Position = 5, ValueFromPipelineByPropertyName)]
        [String]$templateName

    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'organisationid=' parameter by removing it from the set parameters.
        if ($organisationId) {
            $Parameters.Remove('organisationId') | Out-Null
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {  
            Write-Verbose 'Getting organisation documents from NinjaOne API.'
            $Organisation = Get-NinjaOneOrganisations -organisationId $organisationId
            if ($Organisation) {
                Write-Verbose ('Getting documents for organisation {0}.' -f $Organisation.Name)
                $Resource = ('v2/organization/{0}/documents' -f $organisationId)
            } else {
                throw ('Organisation with id {0} not found.' -f $organisationId)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $ActivityResults = New-NinjaOneGETRequest @RequestParams
            if ($ActivityResults) {
                return $ActivityResults
            } else {
                throw ('No documents found for organisation {0}.' -f $Organisation.Name)
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Organisation\Get-NinjaOneOrganisationDocuments.ps1' 85
#Region '.\Public\Get\Organisation\Get-NinjaOneOrganisations.ps1' 0
function Get-NinjaOneOrganisations {
    <#
        .SYNOPSIS
            Gets organisations from the NinjaOne API.
        .DESCRIPTION
            Retrieves organisations from the NinjaOne v2 API.
        .FUNCTIONALITY
            Organisations
        .EXAMPLE
            PS> Get-NinjaOneOrganisations
 
            Gets all organisations.
        .EXAMPLE
            PS> Get-NinjaOneOrganisations -organisationId 1
 
            Gets the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneOrganisations -pageSize 10 -after 1
 
            Gets 10 organisations starting from organisation id 1.
        .EXAMPLE
            PS> Get-NinjaOneOrganisations -detailed
 
            Gets all organisations with locations and policy mappings.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/organisations
    #>

    [CmdletBinding( DefaultParameterSetName = 'Multi' )]
    [OutputType([Object])]
    [Alias('gnoo', 'Get-NinjaOneOrganizations', 'Get-NinjaOneOrganisation', 'Get-NinjaOneOrganization')]
    [MetadataAttribute(
        '/v2/organizations',
        'get',
        '/v2/organization/{id}',
        'get',
        '/v2/organizations-detailed',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Organisation id
        [Parameter(ParameterSetName = 'Single', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id', 'organizationId')]
        [Int]$organisationId,
        # Number of results per page.
        [Parameter(ParameterSetName = 'Multi', Position = 1)]
        [Int]$pageSize,
        # Start results from organisation id.
        [Parameter(ParameterSetName = 'Multi', Position = 2)]
        [Int]$after,
        # Include locations and policy mappings.
        [Parameter(ParameterSetName = 'Multi', Position = 3)]
        [Switch]$detailed
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'organisationid=' parameter by removing it from the set parameters.
        if ($organisationId) {
            $Parameters.Remove('organisationId') | Out-Null
        }
        # Similarly we don't want a `detailed=true` parameter since we're targetting a different resource.
        if ($detailed) {
            $Parameters.Remove('detailed') | Out-Null
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($organisationId) {
                Write-Verbose ('Getting organisation with id {0}.' -f $organisationId)
                $Resource = ('v2/organization/{0}' -f $organisationId)
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                }
            } else {
                if ($detailed) {
                    Write-Verbose 'Retrieving detailed information on all organisations'
                    $Resource = 'v2/organizations-detailed'
                } else {
                    Write-Verbose 'Retrieving all organisations'
                    $Resource = 'v2/organizations'
                }
                $RequestParams = @{
                    Resource = $Resource
                    QSCollection = $QSCollection
                }
            }
            try {
                $OrganisationResults = New-NinjaOneGETRequest @RequestParams
                return $OrganisationResults
            } catch {
                if (-not $OrganisationResults) {
                    if ($organisationId) {
                        throw ('Organisation with id {0} not found.' -f $organisationId)
                    } else {
                        throw 'No organisations found.'
                    }
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Organisation\Get-NinjaOneOrganisations.ps1' 109
#Region '.\Public\Get\Queries\Get-NinjaOneAntiVirusStatus.ps1' 0
function Get-NinjaOneAntiVirusStatus {
    <#
        .SYNOPSIS
            Gets the antivirus status from the NinjaOne API.
        .DESCRIPTION
            Retrieves the antivirus status from the NinjaOne v2 API.
        .FUNCTIONALITY
            AntiVirus Status Query
        .EXAMPLE
            PS> Get-NinjaOneAntivirusStatus -deviceFilter 'org = 1'
 
            Gets the antivirus status for the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneAntivirusStatus -timeStamp 1619712000
 
            Gets the antivirus status at or after the timestamp 1619712000.
        .EXAMPLE
            PS> Get-NinjaOneAntivirusStatus -productState 'ON'
 
            Gets the antivirus status where the product state is ON.
        .EXAMPLE
            PS> Get-NinjaOneAntivirusStatus -productName 'Microsoft Defender Antivirus'
 
            Gets the antivirus status where the antivirus product name is Microsoft Defender Antivirus.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/antivirusstatusquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnoavs')]
    [MetadataAttribute(
        '/v2/queries/antivirus-status',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Monitoring timestamp filter.
        [Parameter(Position = 1)]
        [Alias('ts')]
        [DateTime]$timeStamp,
        # Monitoring timestamp filter in unix time.
        [Parameter(Position = 1)]
        [int]$timeStampUnixEpoch,
        # Filter by product state.
        [Parameter(Position = 2)]
        [String]$productState,
        # Filter by product name.
        [Parameter(Position = 3, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [string]$productName,
        # Cursor name.
        [Parameter(Position = 4)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 5)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # If the [DateTime] parameter $timeStamp is set convert the value to a Unix Epoch.
        if ($timeStamp) {
            [int]$timeStamp = ConvertTo-UnixEpoch -DateTime $timeStamp
        }
        # If the Unix Epoch parameter $timeStampUnixEpoch is set assign the value to the $timeStamp variable and null $timeStampUnixEpoch.
        if ($timeStampUnixEpoch) {
            $Parameters.Remove('timeStampUnixEpoch') | Out-Null
            [int]$timeStamp = $timeStampUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/antivirus-status'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $AntivirusStatus = New-NinjaOneGETRequest @RequestParams
            if ($AntivirusStatus) {
                return $AntivirusStatus
            } else {
                throw 'No antivirus status found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneAntiVirusStatus.ps1' 95
#Region '.\Public\Get\Queries\Get-NinjaOneAntiVirusThreats.ps1' 0
function Get-NinjaOneAntiVirusThreats {
    <#
        .SYNOPSIS
            Gets the antivirus threats from the NinjaOne API.
        .DESCRIPTION
            Retrieves the antivirus threats from the NinjaOne v2 API.
        .FUNCTIONALITY
            AntiVirus Threats Query
        .EXAMPLE
            PS> Get-NinjaOneAntivirusThreats
 
            Gets the antivirus threats.
        .EXAMPLE
            PS> Get-NinjaOneAntivirusThreats -deviceFilter 'org = 1'
 
            Gets the antivirus threats for the organisation with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/antivirusthreatsquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnoavt')]
    [MetadataAttribute(
        '/v2/queries/antivirus-threats',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Monitoring timestamp filter.
        [Parameter(Position = 1)]
        [Alias('ts')]
        [DateTime]$timeStamp,
        # Monitoring timestamp filter in unix time.
        [Parameter(Position = 1)]
        [int]$timeStampUnixEpoch,
        # Cursor name.
        [Parameter(Position = 2)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 3)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # If the [DateTime] parameter $timeStamp is set convert the value to a Unix Epoch.
        if ($timeStamp) {
            [int]$timeStamp = ConvertTo-UnixEpoch -DateTime $timeStamp
        }
        # If the Unix Epoch parameter $timeStampUnixEpoch is set assign the value to the $timeStamp variable and null $timeStampUnixEpoch.
        if ($timeStampUnixEpoch) {
            $parameters.Remove('timeStampUnixEpoch') | Out-Null
            [int]$timeStamp = $timeStampUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            
            $Resource = 'v2/queries/antivirus-threats'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $AntivirusThreats = New-NinjaOneGETRequest @RequestParams
            if ($AntivirusThreats) {
                return $AntivirusThreats
            } else {
                throw 'No antivirus threats found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneAntiVirusThreats.ps1' 82
#Region '.\Public\Get\Queries\Get-NinjaOneBackupUsage.ps1' 0
function Get-NinjaOneBackupUsage {
    <#
        .SYNOPSIS
            Gets the backup usage by device from the NinjaOne API.
        .DESCRIPTION
            Retrieves the backup usage by device from the NinjaOne v2 API.
        .FUNCTIONALITY
            Backup Usage Query
        .EXAMPLE
            PS> Get-NinjaOneBackupUsage
 
            Gets the backup usage by device.
        .EXAMPLE
            PS> Get-NinjaOneBackupUsage -includeDeleted
 
            Gets the backup usage by device including deleted devices.
        .EXAMPLE
            PS> Get-NinjaOneBackupUsage | Where-Object { ($_.references.backupUsage.cloudTotalSize -ne 0) -or ($_.references.backupUsage.localTotalSize -ne 0) }
 
            Gets the backup usage by device where the cloud or local total size is not 0.
        .EXAMPLE
            PS> Get-NinjaOneBackupUsage -includeDeleted | Where-Object { ($_.references.backupUsage.cloudTotalSize -ne 0) -and ($_.references.backupUsage.localTotalSize -ne 0) -and ($_.references.backupUsage.revisionsTotalSize -ne 0) }
 
            Gets the backup usage where the cloud, local and revisions total size is not 0 including deleted devices.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/backupusagequery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnobu')]
    [MetadataAttribute(
        '/v2/queries/backup/usage',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Cursor name.
        [Parameter(Position = 0)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 1)]
        [Int]$pageSize,
        # Include deleted devices.
        [Alias('includeDeletedDevices')]
        [Switch]$includeDeleted
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/backup/usage'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $BackupUsage = New-NinjaOneGETRequest @RequestParams
            if ($BackupUsage) {
                return $BackupUsage
            } else {
                throw 'No backup usage found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneBackupUsage.ps1' 72
#Region '.\Public\Get\Queries\Get-NinjaOneComputerSystems.ps1' 0
function Get-NinjaOneComputerSystems {
    <#
        .SYNOPSIS
            Gets the computer systems from the NinjaOne API.
        .DESCRIPTION
            Retrieves the computer systems from the NinjaOne v2 API.
        .FUNCTIONALITY
            Computer Systems Query
        .EXAMPLE
            PS> Get-NinjaOneComputerSystems
 
            Gets all computer systems.
        .EXAMPLE
            PS> Get-NinjaOneComputerSystems -deviceFilter 'org = 1'
 
            Gets the computer systems for the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneComputerSystems -timeStamp 1619712000
 
            Gets the computer systems with a monitoring timestamp at or after 1619712000.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/computersystemsquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnocs')]
    [MetadataAttribute(
        '/v2/queries/computer-systems',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Monitoring timestamp filter.
        [Parameter(Position = 1)]
        [Alias('ts')]
        [DateTime]$timeStamp,
        # Monitoring timestamp filter in unix time.
        [Parameter(Position = 1)]
        [int]$timeStampUnixEpoch,
        # Cursor name.
        [Parameter(Position = 2)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 3)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # If the [DateTime] parameter $timeStamp is set convert the value to a Unix Epoch.
        if ($timeStamp) {
            [int]$timeStamp = ConvertTo-UnixEpoch -DateTime $timeStamp
        }
        # If the Unix Epoch parameter $timeStampUnixEpoch is set assign the value to the $timeStamp variable and null $timeStampUnixEpoch.
        if ($timeStampUnixEpoch) {
            $Parameters.Remove('timeStampUnixEpoch') | Out-Null
            [int]$timeStamp = $timeStampUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/computer-systems'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $ComputerSystems = New-NinjaOneGETRequest @RequestParams
            if ($ComputerSystems) {
                return $ComputerSystems
            } else {
                throw 'No computer systems found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneComputerSystems.ps1' 85
#Region '.\Public\Get\Queries\Get-NinjaOneCustomFields.ps1' 0
function Get-NinjaOneCustomFields {
    <#
        .SYNOPSIS
            Gets the custom fields from the NinjaOne API.
        .DESCRIPTION
            Retrieves the custom fields from the NinjaOne v2 API.
        .FUNCTIONALITY
            Custom Fields Query
        .EXAMPLE
            PS> Get-NinjaOneCustomFields
 
            Gets all custom field values for all devices.
        .EXAMPLE
            PS> Get-NinjaOneCustomFields -deviceFilter 'org = 1'
 
            Gets all custom field values for all devices in the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneCustomFields -updatedAfter (Get-Date).AddDays(-1)
 
            Gets all custom field values for all devices updated in the last 24 hours.
        .EXAMPLE
            PS> Get-NinjaOneCustomFields -updatedAfterUnixEpoch 1619712000
 
            Gets all custom field values for all devices updated at or after 1619712000.
        .EXAMPLE
            PS> Get-NinjaOneCustomFields -fields 'hasBatteries', 'autopilotHwid'
 
            Gets the custom field values for the specified fields.
        .EXAMPLE
            PS> Get-NinjaOneCustomFields -detailed
 
            Gets the detailed version of the custom field values.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/customfieldsquery
    #>

    [CmdletBinding(DefaultParameterSetName = 'Default')]
    [OutputType([Object])]
    [Alias('gnocf')]
    [MetadataAttribute(
        '/v2/queries/custom-fields',
        'get',
        '/v2/queries/custom-fields-detailed',
        'get',
        '/v2/queries/scoped-custom-fields',
        'get',
        '/v2/queries/scoped-custom-fields-detailed',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(ParameterSetName = 'Default', Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Cursor name.
        [Parameter(ParameterSetName = 'Default', Position = 1)]
        [Parameter(ParameterSetName = 'Scoped', Position = 0)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(ParameterSetName = 'Default', Position = 2)]
        [Parameter(ParameterSetName = 'Scoped', Position = 1)]
        [Int]$pageSize,
        # Custom field scopes to filter by.
        [Parameter(ParameterSetName = 'Scoped', Position = 2, ValueFromPipeline)]
        [ValidateSet('NODE', 'ORGANIZATION', 'LOCATION', 'ALL')]
        [String[]]$scopes,
        # Custom fields updated after the specified date. PowerShell DateTime object.
        [Parameter(ParameterSetName = 'Default', Position = 3)]
        [Parameter(ParameterSetName = 'Scoped', Position = 3)]
        [DateTime]$updatedAfter,
        # Custom fields updated after the specified date. Unix Epoch time.
        [Parameter(ParameterSetName = 'Default', Position = 3)]
        [Parameter(ParameterSetName = 'Scoped', Position = 3)]
        [Int]$updatedAfterUnixEpoch,
        # Array of fields.
        [Parameter(ParameterSetName = 'Default', Position = 4)]
        [Parameter(ParameterSetName = 'Scoped', Position = 4)]
        [String[]]$fields,
        # Get the detailed custom fields report(s).
        [Parameter(ParameterSetName = 'Default')]
        [Parameter(ParameterSetName = 'Scoped')]
        [Switch]$detailed
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding a 'detailed=' parameter as we use this param to targed an alternative resource.
        if ($detailed) {
            $Parameters.Remove('detailed') | Out-Null
        }
        # If the [DateTime] parameter $updatedAfter is set convert the value to a Unix Epoch.
        if ($updatedAfter) {
            [Int]$updatedAfter = ConvertTo-UnixEpoch -DateTime $updatedAfter
        }
        # If the Unix Epoch parameter $updatedAfterUnixEpoch is set assign the value to the $updatedAfter variable and null $updatedAfterUnixEpoch.
        if ($updatedAfterUnixEpoch) {
            $Parameters.Remove('updatedAfterUnixEpoch') | Out-Null
            [Int]$updatedAfter = $updatedAfterUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters -CommaSeparatedArrays
    }
    process {
        try {
            if ($PSCmdlet.ParameterSetName -eq 'Default') {
                if ($detailed) {
                    $Resource = 'v2/queries/custom-fields-detailed'
                } else {
                    $Resource = 'v2/queries/custom-fields'
                }
            } elseif ($PSCmdlet.ParameterSetName -eq 'Scoped') {
                if ($detailed) {
                    $Resource = 'v2/queries/scoped-custom-fields-detailed'
                } else {
                    $Resource = 'v2/queries/scoped-custom-fields'
                }
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $CustomFields = New-NinjaOneGETRequest @RequestParams
            if ($CustomFields) {
                return $CustomFields
            } else {
                throw 'No custom fields found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneCustomFields.ps1' 134
#Region '.\Public\Get\Queries\Get-NinjaOneDeviceHealth.ps1' 0
function Get-NinjaOneDeviceHealth {
    <#
        .SYNOPSIS
            Gets the device health from the NinjaOne API.
        .DESCRIPTION
            Retrieves the device health from the NinjaOne v2 API.
        .FUNCTIONALITY
            Device Health Query
        .EXAMPLE
            PS> Get-NinjaOneDeviceHealth
 
            Gets the device health.
        .EXAMPLE
            PS> Get-NinjaOneDeviceHealth -deviceFilter 'org = 1'
 
            Gets the device health for the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneDeviceHealth -health 'UNHEALTHY'
 
            Gets the device health for devices with the health status 'UNHEALTHY'.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/devicehealthquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnodh')]
    [MetadataAttribute(
        '/v2/queries/device-health',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Filter by health status.
        [Parameter(Position = 1, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ValidateSet('UNHEALTHY', 'HEALTHY', 'UNKNOWN', 'NEEDS_ATTENTION')]
        [String]$health,
        # Cursor name.
        [Parameter(Position = 2)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 3)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/device-health'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $DeviceHealth = New-NinjaOneGETRequest @RequestParams
            if ($DeviceHealth) {
                return $DeviceHealth
            } else {
                throw 'No device health found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneDeviceHealth.ps1' 73
#Region '.\Public\Get\Queries\Get-NinjaOneDisks.ps1' 0
function Get-NinjaOneDisks {
    <#
        .SYNOPSIS
            Gets the disks from the NinjaOne API.
        .DESCRIPTION
            Retrieves the disks from the NinjaOne v2 API.
        .FUNCTIONALITY
            Disks Query
        .EXAMPLE
            PS> Get-NinjaOneDisks
 
            Gets all disks.
        .EXAMPLE
            PS> Get-NinjaOneDisks -deviceFilter 'org = 1'
 
            Gets the disks for the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneDisks -timeStamp 1619712000
 
            Gets the disks with a monitoring timestamp at or after 1619712000.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/disksquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnodi')]
    [MetadataAttribute(
        '/v2/queries/disks',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Monitoring timestamp filter.
        [Parameter(Position = 1)]
        [Alias('ts')]
        [DateTime]$timeStamp,
        # Monitoring timestamp filter in unix time.
        [Parameter(Position = 1)]
        [Int]$timeStampUnixEpoch,
        # Cursor name.
        [Parameter(Position = 2)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 3)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # If the [DateTime] parameter $timeStamp is set convert the value to a Unix Epoch.
        if ($timeStamp) {
            [int]$timeStamp = ConvertTo-UnixEpoch -DateTime $timeStamp
        }
        # If the Unix Epoch parameter $timeStampUnixEpoch is set assign the value to the $timeStamp variable and null $timeStampUnixEpoch.
        if ($timeStampUnixEpoch) {
            $Parameters.Remove('timeStampUnixEpoch') | Out-Null
            [int]$timeStamp = $timeStampUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/disks'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $Disks = New-NinjaOneGETRequest @RequestParams
            if ($Disks) {
                return $Disks
            } else {
                throw 'No disks found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneDisks.ps1' 85
#Region '.\Public\Get\Queries\Get-NinjaOneLoggedOnUsers.ps1' 0
function Get-NinjaOneLoggedOnUsers {
    <#
        .SYNOPSIS
            Gets the logged on users from the NinjaOne API.
        .DESCRIPTION
            Retrieves the logged on users from the NinjaOne v2 API.
        .FUNCTIONALITY
            Logged On Users Query
        .EXAMPLE
            PS> Get-NinjaOneLoggedOnUsers
 
            Gets all logged on users.
        .EXAMPLE
            PS> Get-NinjaOneLoggedOnUsers -deviceFilter 'org = 1'
 
            Gets the logged on users for the organisation with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/loggedonusersquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnolou')]
    [MetadataAttribute(
        '/v2/queries/logged-on-users',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Cursor name.
        [Parameter(Position = 1)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 2)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/logged-on-users'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $LoggedOnUsers = New-NinjaOneGETRequest @RequestParams
            if ($LoggedOnUsers) {
                return $LoggedOnUsers
            } else {
                throw 'No logged on users found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneLoggedOnUsers.ps1' 65
#Region '.\Public\Get\Queries\Get-NinjaOneNetworkInterfaces.ps1' 0
function Get-NinjaOneNetworkInterfaces {
    <#
        .SYNOPSIS
            Gets the network interfaces from the NinjaOne API.
        .DESCRIPTION
            Retrieves the network interfaces for each device from the NinjaOne v2 API.
        .FUNCTIONALITY
            Network Interfaces Query
        .EXAMPLE
            PS> Get-NinjaOneNetworkInterfaces
 
            Gets all network interfaces.
        .EXAMPLE
            PS> Get-NinjaOneNetworkInterfaces -deviceFilter 'org = 1'
 
            Gets the network interfaces for all devices for the organisation with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/networkinterfacesquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnoni')]
    [MetadataAttribute(
        '/v2/queries/network-interfaces',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Cursor name.
        [Parameter(Position = 1)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 2)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/network-interfaces'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $NetworkInterfaces = New-NinjaOneGETRequest @RequestParams
            if ($NetworkInterfaces) {
                return $NetworkInterfaces
            } else {
                throw 'No network interfaces found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneNetworkInterfaces.ps1' 65
#Region '.\Public\Get\Queries\Get-NinjaOneOperatingSystems.ps1' 0
function Get-NinjaOneOperatingSystems {
    <#
        .SYNOPSIS
            Gets the operating systems from the NinjaOne API.
        .DESCRIPTION
            Retrieves the operating systems from the NinjaOne v2 API.
        .FUNCTIONALITY
            Operating Systems Query
        .EXAMPLE
            PS> Get-NinjaOneOperatingSystems
  
            Gets all operating systems.
        .EXAMPLE
            PS> Get-NinjaOneOperatingSystems -deviceFilter 'org = 1'
  
            Gets the operating systems for the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneOperatingSystems -timeStamp 1619712000
 
            Gets the operating systems with a monitoring timestamp at or after 1619712000.
        .EXAMPLE
            PS> Get-NinjaOneOperatingSystems | Group-Object -Property 'name'
 
            Gets all operating systems grouped by the name property.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/operatingsystemsquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnoos')]
    [MetadataAttribute(
        '/v2/queries/operating-systems',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Monitoring timestamp filter.
        [Parameter(Position = 1)]
        [Alias('ts')]
        [DateTime]$timeStamp,
        # Monitoring timestamp filter in unix time.
        [Parameter(Position = 1)]
        [Int]$timeStampUnixEpoch,
        # Cursor name.
        [Parameter(Position = 2)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 3)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # If the [DateTime] parameter $timeStamp is set convert the value to a Unix Epoch.
        if ($timeStamp) {
            [int]$timeStamp = ConvertTo-UnixEpoch -DateTime $timeStamp
        }
        # If the Unix Epoch parameter $timeStampUnixEpoch is set assign the value to the $timeStamp variable and null $timeStampUnixEpoch.
        if ($timeStampUnixEpoch) {
            $Parameters.Remove('timeStampUnixEpoch') | Out-Null
            [int]$timeStamp = $timeStampUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/operating-systems'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $OperatingSystems = New-NinjaOneGETRequest @RequestParams
            if ($OperatingSystems) {
                return $OperatingSystems
            } else {
                throw 'No operating systems found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneOperatingSystems.ps1' 89
#Region '.\Public\Get\Queries\Get-NinjaOneOSPatches.ps1' 0
function Get-NinjaOneOSPatches {
    <#
        .SYNOPSIS
            Gets the OS patches from the NinjaOne API.
        .DESCRIPTION
            Retrieves the OS patches from the NinjaOne v2 API.
        .FUNCTIONALITY
            OS Patches Query
        .EXAMPLE
            PS> Get-NinjaOneOSPatches
 
            Gets all OS patches.
        .EXAMPLE
            PS> Get-NinjaOneOSPatches -deviceFilter 'org = 1'
 
            Gets the OS patches for the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneOSPatches -timeStamp 1619712000
 
            Gets the OS patches with a monitoring timestamp at or after 1619712000.
        .EXAMPLE
            PS> Get-NinjaOneOSPatches -status 'APPROVED'
 
            Gets the OS patches with a status of APPROVED.
        .EXAMPLE
            PS> Get-NinjaOneOSPatches -type 'SECURITY_UPDATES'
 
            Gets the OS patches with a type of SECURITY_UPDATES.
        .EXAMPLE
            PS> Get-NinjaOneOSPatches -severity 'CRITICAL'
 
            Gets the OS patches with a severity of CRITICAL.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/ospatchesquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnoosp')]
    [MetadataAttribute(
        '/v2/queries/os-patches',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Monitoring timestamp filter.
        [Parameter(Position = 1)]
        [Alias('ts')]
        [DateTime]$timeStamp,
        # Monitoring timestamp filter in unix time.
        [Parameter(Position = 1)]
        [Int]$timeStampUnixEpoch,
        # Filter patches by patch status.
        [Parameter(Position = 2, ValueFromPipelineByPropertyName)]
        [ValidateSet('MANUAL', 'APPROVED', 'FAILED', 'REJECTED')]
        [String]$status,
        # Filter patches by type.
        [Parameter(Position = 3, ValueFromPipelineByPropertyName)]
        [ValidateSet('UPDATE_ROLLUPS', 'SECURITY_UPDATES', 'DEFINITION_UPDATES', 'CRITICAL_UPDATES', 'REGULAR_UPDATES', 'FEATURE_PACKS', 'DRIVER_UPDATES')]
        [String]$type,
        # Filter patches by severity.
        [Parameter(Position = 4, ValueFromPipelineByPropertyName)]
        [ValidateSet('OPTIONAL', 'MODERATE', 'IMPORTANT', 'CRITICAL')]
        [String]$severity,
        # Cursor name.
        [Parameter(Position = 5)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 6)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # If the [DateTime] parameter $timeStamp is set convert the value to a Unix Epoch.
        if ($timeStamp) {
            [int]$timeStamp = ConvertTo-UnixEpoch -DateTime $timeStamp
        }
        # If the Unix Epoch parameter $timeStampUnixEpoch is set assign the value to the $timeStamp variable and null $timeStampUnixEpoch.
        if ($timeStampUnixEpoch) {
            $Parameters.Remove('timeStampUnixEpoch') | Out-Null
            [int]$timeStamp = $timeStampUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/os-patches'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $OSPatches = New-NinjaOneGETRequest @RequestParams
            if ($OSPatches) {
                return $OSPatches
            } else {
                throw 'No OS patches found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneOSPatches.ps1' 109
#Region '.\Public\Get\Queries\Get-NinjaOneOSPatchInstalls.ps1' 0
function Get-NinjaOneOSPatchInstalls {
    <#
        .SYNOPSIS
            Gets the OS patch installs from the NinjaOne API.
        .DESCRIPTION
            Retrieves the OS patch installs from the NinjaOne v2 API.
        .FUNCTIONALITY
            OS Patch Installs Query
        .EXAMPLE
            PS> Get-NinjaOneOSPatchInstalls
 
            Gets all OS patch installs.
        .EXAMPLE
            PS> Get-NinjaOneOSPatchInstalls -deviceFilter 'org = 1'
 
            Gets the OS patch installs for the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneOSPatchInstalls -timeStamp 1619712000
 
            Gets the OS patch installs with a monitoring timestamp at or after 1619712000.
        .EXAMPLE
            PS> Get-NinjaOneOSPatchInstalls -status 'FAILED'
 
            Gets the OS patch installs with a status of 'FAILED'.
        .EXAMPLE
            PS> Get-NinjaOneOSPatchInstalls -installedBefore (Get-Date)
 
            Gets the OS patch installs installed before the current date.
        .EXAMPLE
            PS> Get-NinjaOneOSPatchInstalls -installedBeforeUnixEpoch 1619712000
 
            Gets the OS patch installs installed before 1619712000.
        .EXAMPLE
            PS> Get-NinjaOneOSPatchInstalls -installedAfter (Get-Date).AddDays(-1)
 
            Gets the OS patch installs installed after the previous day.
        .EXAMPLE
            PS> Get-NinjaOneOSPatchInstalls -installedAfterUnixEpoch 1619712000
 
            Gets the OS patch installs installed after 1619712000.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/ospatchinstallsquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnoospi')]
    [MetadataAttribute(
        '/v2/queries/os-patch-installs',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Monitoring timestamp filter. PowerShell DateTime object.
        [Parameter(Position = 1)]
        [Alias('ts')]
        [DateTime]$timeStamp,
        # Monitoring timestamp filter. Unix Epoch time.
        [Parameter(Position = 1)]
        [Int]$timeStampUnixEpoch,
        # Filter patches by patch status.
        [Parameter(Position = 2, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ValidateSet('FAILED', 'INSTALLED')]
        [String]$status,
        # Filter patches to those installed before this date.
        [Parameter(Position = 3)] 
        [DateTime]$installedBefore,
        # Filter patches to those installed after this date. Unix Epoch time.
        [Parameter(Position = 3)]
        [Int]$installedBeforeUnixEpoch,
        # Filter patches to those installed after this date. PowerShell DateTime object.
        [Parameter(Position = 4)]
        [DateTime]$installedAfter,
        # Filter patches to those installed after this date. Unix Epoch time.
        [Parameter(Position = 4)]
        [Int]$installedAfterUnixEpoch,
        # Cursor name.
        [Parameter(Position = 5)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 6)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # If the [DateTime] parameter $installedBefore is set convert the value to a Unix Epoch.
        if ($installedBefore) {
            [Int]$installedBefore = ConvertTo-UnixEpoch -DateTime $installedBefore
        }
        # If the Unix Epoch parameter $installedBeforeUnixEpoch is set assign the value to the $installedBefore variable and null $installedBeforeUnixEpoch.
        if ($installedBeforeUnixEpoch) {
            $Parameters.Remove('installedBeforeUnixEpoch') | Out-Null
            [Int]$installedBefore = $installedBeforeUnixEpoch
        }
        # If the [DateTime] parameter $installedAfter is set convert the value to a Unix Epoch.
        if ($installedAfter) {
            [Int]$installedAfter = ConvertTo-UnixEpoch -DateTime $installedAfter
        }
        # If the Unix Epoch parameter $installedAfterUnixEpoch is set assign the value to the $installedAfter variable and null $installedAfterUnixEpoch.
        if ($installedAfterUnixEpoch) {
            $Parameters.Remove('installedAfterUnixEpoch') | Out-Null
            [Int]$installedAfter = $installedAfterUnixEpoch
        }
        # If the [DateTime] parameter $timeStamp is set convert the value to a Unix Epoch.
        if ($timeStamp) {
            [int]$timeStamp = ConvertTo-UnixEpoch -DateTime $timeStamp
        }
        # If the Unix Epoch parameter $timeStampUnixEpoch is set assign the value to the $timeStamp variable and null $timeStampUnixEpoch.
        if ($timeStampUnixEpoch) {
            $Parameters.Remove('timeStampUnixEpoch') | Out-Null
            [int]$timeStamp = $timeStampUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/os-patch-installs'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $OSPatchInstalls = New-NinjaOneGETRequest @RequestParams
            if ($OSPatchInstalls) {
                return $OSPatchInstalls
            } else {
                throw 'No OS patch installs found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneOSPatchInstalls.ps1' 139
#Region '.\Public\Get\Queries\Get-NinjaOnePolicyOverrides.ps1' 0
function Get-NinjaOnePolicyOverrides {
    <#
        .SYNOPSIS
            Gets the policy overrides by device from the NinjaOne API.
        .DESCRIPTION
            Retrieves the policy override sections by device from the NinjaOne v2 API.
        .FUNCTIONALITY
            Policy Overrides Query
        .EXAMPLE
            PS> Get-NinjaOnePolicyOverrides
 
            Gets the policy overrides by device.
        .EXAMPLE
            PS> Get-NinjaOnePolicyOverrides -deviceFilter 'org = 1'
 
            Gets the policy overrides by device for the organisation with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/policyoverridesquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnopo')]
    [MetadataAttribute(
        '/v2/queries/policy-overrides',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Cursor name.
        [Parameter(Position = 0)]
        [String]$cursor,
        # Device filter.
        [Parameter(Position = 1)]
        [Alias('df')]
        [String]$deviceFilter,
        # Number of results per page.
        [Parameter(Position = 2)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/policy-overrides'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $PolicyOverrides = New-NinjaOneGETRequest @RequestParams
            if ($PolicyOverrides) {
                return $PolicyOverrides
            } else {
                throw 'No policy overrides found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOnePolicyOverrides.ps1' 65
#Region '.\Public\Get\Queries\Get-NinjaOneProcessors.ps1' 0
function Get-NinjaOneProcessors {
    <#
        .SYNOPSIS
            Gets the processors from the NinjaOne API.
        .DESCRIPTION
            Retrieves the processors from the NinjaOne v2 API.
        .FUNCTIONALITY
            Processors Query
        .EXAMPLE
            PS> Get-NinjaOneProcessors
 
            Gets the processors.
        .EXAMPLE
            PS> Get-NinjaOneProcessors -deviceFilter 'org = 1'
 
            Gets the processors for the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneProcessors -timeStamp 1619712000
 
            Gets the processors with a monitoring timestamp at or after 1619712000.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/processorsquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnop')]
    [MetadataAttribute(
        '/v2/queries/processors',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Monitoring timestamp filter. PowerShell DateTime object.
        [Parameter(Position = 1)]
        [Alias('ts')]
        [DateTime]$timeStamp,
        # Monitoring timestamp filter. Unix Epoch time.
        [Parameter(Position = 1)]
        [Int]$timeStampUnixEpoch,
        # Cursor name.
        [Parameter(Position = 2)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 3)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # If the [DateTime] parameter $timeStamp is set convert the value to a Unix Epoch.
        if ($timeStamp) {
            [int]$timeStamp = ConvertTo-UnixEpoch -DateTime $timeStamp
        }
        # If the Unix Epoch parameter $timeStampUnixEpoch is set assign the value to the $timeStamp variable and null $timeStampUnixEpoch.
        if ($timeStampUnixEpoch) {
            $Parameters.Remove('timeStampUnixEpoch') | Out-Null
            [int]$timeStamp = $timeStampUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/processors'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $Processors = New-NinjaOneGETRequest @RequestParams
            if ($Processors) {
                return $Processors
            } else {
                throw 'No processors found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneProcessors.ps1' 85
#Region '.\Public\Get\Queries\Get-NinjaOneRAIDControllers.ps1' 0
function Get-NinjaOneRAIDControllers {
    <#
        .SYNOPSIS
            Gets the RAID controllers from the NinjaOne API.
        .DESCRIPTION
            Retrieves the RAID controllers from the NinjaOne v2 API.
        .FUNCTIONALITY
            RAID Controllers Query
        .EXAMPLE
            PS> Get-NinjaOneRAIDControllers
 
            Gets the RAID controllers.
        .EXAMPLE
            PS> Get-NinjaOneRAIDControllers -deviceFilter 'org = 1'
 
            Gets the RAID controllers for the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneRAIDControllers -timeStamp 1619712000
 
            Gets the RAID controllers with a monitoring timestamp at or after 1619712000.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/raidcontrollersquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnoraidc')]
    [MetadataAttribute(
        '/v2/queries/raid-controllers',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Monitoring timestamp filter. PowerShell DateTime object.
        [Parameter(Position = 1)]
        [Alias('ts')]
        [DateTime]$timeStamp,
        # Monitoring timestamp filter. Unix Epoch time.
        [Parameter(Position = 1)]
        [Int]$timeStampUnixEpoch,
        # Cursor name.
        [Parameter(Position = 2)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 3)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # If the [DateTime] parameter $timeStamp is set convert the value to a Unix Epoch.
        if ($timeStamp) {
            [int]$timeStamp = ConvertTo-UnixEpoch -DateTime $timeStamp
        }
        # If the Unix Epoch parameter $timeStampUnixEpoch is set assign the value to the $timeStamp variable and null $timeStampUnixEpoch.
        if ($timeStampUnixEpoch) {
            $Parameters.Remove('timeStampUnixEpoch') | Out-Null
            [int]$timeStamp = $timeStampUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/raid-controllers'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $RAIDControllers = New-NinjaOneGETRequest @RequestParams
            if ($RAIDControllers) {
                return $RAIDControllers
            } else {
                throw 'No RAID controllers found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneRAIDControllers.ps1' 85
#Region '.\Public\Get\Queries\Get-NinjaOneRAIDDrives.ps1' 0
function Get-NinjaOneRAIDDrives {
    <#
        .SYNOPSIS
            Gets the RAID drives from the NinjaOne API.
        .DESCRIPTION
            Retrieves the RAID drives from the NinjaOne v2 API.
        .FUNCTIONALITY
            RAID Drives Query
        .EXAMPLE
            PS> Get-NinjaOneRAIDDrives
 
            Gets the RAID drives.
        .EXAMPLE
            PS> Get-NinjaOneRAIDDrives -deviceFilter 'org = 1'
 
            Gets the RAID drives for the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneRAIDDrives -timeStamp 1619712000
 
            Gets the RAID drives with a monitoring timestamp at or after 1619712000.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/raiddrivesquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnoraidd')]
    [MetadataAttribute(
        '/v2/queries/raid-drives',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Monitoring timestamp filter. PowerShell DateTime object.
        [Parameter(Position = 1)]
        [Alias('ts')]
        [DateTime]$timeStamp,
        # Monitoring timestamp filter. Unix Epoch time.
        [Parameter(Position = 1)]
        [Int]$timeStampUnixEpoch,
        # Cursor name.
        [Parameter(Position = 2)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 3)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # If the [DateTime] parameter $timeStamp is set convert the value to a Unix Epoch.
        if ($timeStamp) {
            [int]$timeStamp = ConvertTo-UnixEpoch -DateTime $timeStamp
        }
        # If the Unix Epoch parameter $timeStampUnixEpoch is set assign the value to the $timeStamp variable and null $timeStampUnixEpoch.
        if ($timeStampUnixEpoch) {
            $Parameters.Remove('timeStampUnixEpoch') | Out-Null
            [int]$timeStamp = $timeStampUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/raid-drives'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $RAIDDrives = New-NinjaOneGETRequest @RequestParams
            if ($RAIDDrives) {
                return $RAIDDrives
            } else {
                throw 'No RAID drives found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneRAIDDrives.ps1' 85
#Region '.\Public\Get\Queries\Get-NinjaOneSoftwareInventory.ps1' 0
function Get-NinjaOneSoftwareInventory {
    <#
        .SYNOPSIS
            Gets the software inventory from the NinjaOne API.
        .DESCRIPTION
            Retrieves the software inventory from the NinjaOne v2 API.
        .FUNCTIONALITY
            Software Inventory Query
        .EXAMPLE
            PS> Get-NinjaOneSoftwareInventory
 
            Gets the software inventory.
        .EXAMPLE
            PS> Get-NinjaOneSoftwareInventory -deviceFilter 'org = 1'
 
            Gets the software inventory for the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneSoftwareInventory -installedBefore (Get-Date)
 
            Gets the software inventory for software installed before the current date.
        .EXAMPLE
            PS> Get-NinjaOneSoftwareInventory -installedBeforeUnixEpoch 1619712000
 
            Gets the software inventory for software installed before 1619712000.
        .EXAMPLE
            PS> Get-NinjaOneSoftwareInventory -installedAfter (Get-Date).AddDays(-1)
 
            Gets the software inventory for software installed after the previous day.
        .EXAMPLE
            PS> Get-NinjaOneSoftwareInventory -installedAfterUnixEpoch 1619712000
 
            Gets the software inventory for software installed after 1619712000.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/softwareinventoryquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnosi')]
    [MetadataAttribute(
        '/v2/queries/software',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Cursor name.
        [Parameter(Position = 1)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 2)]
        [Int]$pageSize,
        # Filter software to those installed before this date. PowerShell DateTime object.
        [Parameter(Position = 3)]
        [DateTime]$installedBefore,
        # Filter software to those installed after this date. Unix Epoch time.
        [Parameter(Position = 3)]
        [Int]$installedBeforeUnixEpoch,
        # Filter software to those installed after this date. PowerShell DateTime object.
        [Parameter(Position = 4)]
        [DateTime]$installedAfter,
        # Filter software to those installed after this date. Unix Epoch time.
        [Parameter(Position = 4)]
        [Int]$installedAfterUnixEpoch
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        if ($installedBefore) {
            [Int]$installedBefore = ConvertTo-UnixEpoch -DateTime $installedBefore
        }
        if ($installedBeforeUnixEpoch) {
            $Parameters.Remove('installedBeforeUnixEpoch') | Out-Null
            [Int]$installedBefore = $installedBeforeUnixEpoch
        }
        if ($installedAfter) {
            [Int]$installedAfter = ConvertTo-UnixEpoch -DateTime $installedAfter
        }
        if ($installedAfterUnixEpoch) {
            $Parameters.Remove('installedAfterUnixEpoch') | Out-Null
            [Int]$installedAfter = $installedAfterUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/software'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $SoftwareInventory = New-NinjaOneGETRequest @RequestParams
            if ($SoftwareInventory) {
                return $SoftwareInventory
            } else {
                throw 'No software inventory found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneSoftwareInventory.ps1' 107
#Region '.\Public\Get\Queries\Get-NinjaOneSoftwarePatches.ps1' 0
function Get-NinjaOneSoftwarePatches {
    <#
        .SYNOPSIS
            Gets the software patches from the NinjaOne API.
        .DESCRIPTION
            Retrieves the software patches from the NinjaOne v2 API.
        .FUNCTIONALITY
            Software Patches Query
        .EXAMPLE
            PS> Get-NinjaOneSoftwarePatches
 
            Gets all software patches.
        .EXAMPLE
            PS> Get-NinjaOneSoftwarePatches -deviceFilter 'org = 1'
 
            Gets the software patches for the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneSoftwarePatches -timeStamp 1619712000
 
            Gets the software patches with a monitoring timestamp at or after 1619712000.
        .EXAMPLE
            PS> Get-NinjaOneSoftwarePatches -status 'FAILED'
 
            Gets the software patches with a status of 'FAILED'.
        .EXAMPLE
            PS> Get-NinjaOneSoftwarePatches -productIdentifier 23e4567-e89b-12d3-a456-426614174000
 
            Gets the software patches with a product identifier of '23e4567-e89b-12d3-a456-426614174000'.
        .EXAMPLE
            PS> Get-NinjaOneSoftwarePatches -type 'PATCH'
 
            Gets the software patches with a type of 'PATCH'.
        .EXAMPLE
            PS> Get-NinjaOneSoftwarePatches -impact 'OPTIONAL'
 
            Gets the software patches with an impact of 'OPTIONAL'.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/softwarepatchesquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnosp')]
    [MetadataAttribute(
        '/v2/queries/software-patches',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Monitoring timestamp filter. PowerShell DateTime object.
        [Parameter(Position = 1)]
        [Alias('ts')]
        [DateTime]$timeStamp,
        # Monitoring timestamp filter. Unix Epoch time.
        [Parameter(Position = 1)]
        [Int]$timeStampUnixEpoch,
        # Filter patches by patch status.
        [Parameter(Position = 2, ValueFromPipelineByPropertyName)]
        [ValidateSet('MANUAL', 'APPROVED', 'FAILED', 'REJECTED')]
        [String]$status,
        # Filter patches by product identifier.
        [Parameter(Position = 3, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [String]$productIdentifier,
        # Filter patches by type.
        [Parameter(Position = 4, ValueFromPipelineByPropertyName)]
        [ValidateSet('PATCH', 'INSTALLER')]
        [String]$type,
        # Filter patches by impact.
        [Parameter(Position = 5, ValueFromPipelineByPropertyName)]
        [ValidateSet('OPTIONAL', 'RECOMMENDED', 'CRITICAL')]
        [String]$impact,
        # Cursor name.
        [Parameter(Position = 6)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 7)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # If the [DateTime] parameter $timeStamp is set convert the value to a Unix Epoch.
        if ($timeStamp) {
            [int]$timeStamp = ConvertTo-UnixEpoch -DateTime $timeStamp
        }
        # If the Unix Epoch parameter $timeStampUnixEpoch is set assign the value to the $timeStamp variable and null $timeStampUnixEpoch.
        if ($timeStampUnixEpoch) {
            $Parameters.Remove('timeStampUnixEpoch') | Out-Null
            [int]$timeStamp = $timeStampUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/software-patches'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $SoftwarePatches = New-NinjaOneGETRequest @RequestParams
            if ($SoftwarePatches) {
                return $SoftwarePatches
            } else {
                throw 'No software patches found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneSoftwarePatches.ps1' 116
#Region '.\Public\Get\Queries\Get-NinjaOneSoftwarePatchInstalls.ps1' 0
function Get-NinjaOneSoftwarePatchInstalls {
    <#
        .SYNOPSIS
            Gets the software patch installs from the NinjaOne API.
        .DESCRIPTION
            Retrieves the software patch installs from the NinjaOne v2 API.
        .FUNCTIONALITY
            Software Patch Installs Query
        .EXAMPLE
            PS> Get-NinjaOneSoftwarePatchInstalls
 
            Gets all software patch installs.
        .EXAMPLE
            PS> Get-NinjaOneSoftwarePatchInstalls -deviceFilter 'org = 1'
 
            Gets the software patch installs for the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneSoftwarePatchInstalls -timeStamp 1619712000
 
            Gets the software patch installs with a monitoring timestamp at or after 1619712000.
        .EXAMPLE
            PS> Get-NinjaOneSoftwarePatchInstalls -type 'PATCH'
 
            Gets the software patch installs with a type of 'PATCH'.
        .EXAMPLE
            PS> Get-NinjaOneSoftwarePatchInstalls -impact 'OPTIONAL'
 
            Gets the software patch installs with an impact of 'OPTIONAL'.
        .EXAMPLE
            Get-NinjaOneSoftwarePatchInstalls -status 'FAILED'
 
            Gets the software patch installs with a status of 'FAILED'.
        .EXAMPLE
            PS> Get-NinjaOneSoftwarePatchInstalls -productIdentifier 23e4567-e89b-12d3-a456-426614174000
 
            Gets the software patch installs with a product identifier of '23e4567-e89b-12d3-a456-426614174000'.
        .EXAMPLE
            PS> Get-NinjaOneSoftwarePatchInstalls -installedBefore (Get-Date)
 
            Gets the software patch installs installed before the current date.
        .EXAMPLE
            PS> Get-NinjaOneSoftwarePatchInstalls -installedBeforeUnixEpoch 1619712000
 
            Gets the software patch installs installed before 1619712000.
        .EXAMPLE
            PS> Get-NinjaOneSoftwarePatchInstalls -installedAfter (Get-Date)
 
            Gets the software patch installs installed after the current date.
        .EXAMPLE
            PS> Get-NinjaOneSoftwarePatchInstalls -installedAfterUnixEpoch 1619712000
 
            Gets the software patch installs installed after 1619712000.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/softwarepatchinstallsquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnospi')]
    [MetadataAttribute(
        '/v2/queries/software-patch-installs',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Monitoring timestamp filter. PowerShell DateTime object.
        [Parameter(Position = 1)]
        [Alias('ts')]
        [DateTime]$timeStamp,
        # Monitoring timestamp filter. Unix Epoch time.
        [Parameter(Position = 1)]
        [Int]$timeStampUnixEpoch,
        # Filter patches by patch status.
        [Parameter(Position = 2, ValueFromPipelineByPropertyName)]
        [ValidateSet('PATCH', 'INSTALLER')]
        [String]$type,
        # Filter patches by impact.
        [Parameter(Position = 3, ValueFromPipelineByPropertyName)]
        [ValidateSet('OPTIONAL', 'RECOMMENDED', 'CRITICAL')]
        [String]$impact,
        # Filter patches by patch status.
        [Parameter(Position = 4, ValueFromPipelineByPropertyName)]
        [ValidateSet('FAILED', 'INSTALLED')]
        [String]$status,
        # Filter patches by product identifier.
        [Parameter(Position = 5, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [String]$productIdentifier,
        # Filter patches to those installed before this date. PowerShell DateTime object.
        [Parameter(Position = 6)]
        [DateTime]$installedBefore,
        # Filter patches to those installed after this date. Unix Epoch time.
        [Parameter(Position = 6)]
        [Int]$installedBeforeUnixEpoch,
        # Filter patches to those installed after this date. PowerShell DateTime object.
        [Parameter(Position = 7)]
        [DateTime]$installedAfter,
        # Filter patches to those installed after this date. Unix Epoch time.
        [Parameter(Position = 7)]
        [Int]$installedAfterUnixEpoch,
        # Cursor name.
        [Parameter(Position = 8)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 9)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # If the [DateTime] parameter $installedBefore is set convert the value to a Unix Epoch.
        if ($installedBefore) {
            [Int]$installedBefore = ConvertTo-UnixEpoch -DateTime $installedBefore
        }
        # If the Unix Epoch parameter $installedBeforeUnixEpoch is set assign the value to the $installedBefore variable and null $installedBeforeUnixEpoch.
        if ($installedBeforeUnixEpoch) {
            $Parameters.Remove('installedBeforeUnixEpoch') | Out-Null
            [Int]$installedBefore = $installedBeforeUnixEpoch
        }
        # If the [DateTime] parameter $installedAfter is set convert the value to a Unix Epoch.
        if ($installedAfter) {
            [Int]$installedAfter = ConvertTo-UnixEpoch -DateTime $installedAfter
        }
        # If the Unix Epoch parameter $installedAfterUnixEpoch is set assign the value to the $installedAfter variable and null $installedAfterUnixEpoch.
        if ($installedAfterUnixEpoch) {
            $Parameters.Remove('installedAfterUnixEpoch') | Out-Null
            [Int]$installedAfter = $installedAfterUnixEpoch
        }
        # If the [DateTime] parameter $timeStamp is set convert the value to a Unix Epoch.
        if ($timeStamp) {
            [int]$timeStamp = ConvertTo-UnixEpoch -DateTime $timeStamp
        }
        # If the Unix Epoch parameter $timeStampUnixEpoch is set assign the value to the $timeStamp variable and null $timeStampUnixEpoch.
        if ($timeStampUnixEpoch) {
            $Parameters.Remove('timeStampUnixEpoch') | Out-Null
            [int]$timeStamp = $timeStampUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/software-patch-installs'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $SoftwarePatchInstalls = New-NinjaOneGETRequest @RequestParams
            if ($SoftwarePatchInstalls) {
                return $SoftwarePatchInstalls
            } else {
                throw 'No software patch installs found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneSoftwarePatchInstalls.ps1' 162
#Region '.\Public\Get\Queries\Get-NinjaOneVolumes.ps1' 0
function Get-NinjaOneVolumes {
    <#
        .SYNOPSIS
            Gets the volumes from the NinjaOne API.
        .DESCRIPTION
            Retrieves the volumes from the NinjaOne v2 API.
        .FUNCTIONALITY
            Volumes Query
        .EXAMPLE
            PS> Get-NinjaOneVolumes
 
            Gets all volumes.
        .EXAMPLE
            PS> Get-NinjaOneVolumes -deviceFilter 'org = 1'
 
            Gets the volumes for the organisation with id 1.
        .EXAMPLE
            PS> Get-NinjaOneVolumes -timeStamp 1619712000
 
            Gets the volumes with a monitoring timestamp at or after 1619712000.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/volumesquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnov')]
    [MetadataAttribute(
        '/v2/queries/volumes',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Monitoring timestamp filter. PowerShell DateTime object.
        [Parameter(Position = 1)]
        [Alias('ts')]
        [DateTime]$timeStamp,
        # Monitoring timestamp filter. Unix Epoch time.
        [Parameter(Position = 1)]
        [Int]$timeStampUnixEpoch,
        # Cursor name.
        [Parameter(Position = 2)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 3)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # If the [DateTime] parameter $timeStamp is set convert the value to a Unix Epoch.
        if ($timeStamp) {
            [int]$timeStamp = ConvertTo-UnixEpoch -DateTime $timeStamp
        }
        # If the Unix Epoch parameter $timeStampUnixEpoch is set assign the value to the $timeStamp variable and null $timeStampUnixEpoch.
        if ($timeStampUnixEpoch) {
            $Parameters.Remove('timeStampUnixEpoch') | Out-Null
            [int]$timeStamp = $timeStampUnixEpoch
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/volumes'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $Volumes = New-NinjaOneGETRequest @RequestParams
            if ($Volumes) {
                return $Volumes
            } else {
                throw 'No volumes found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneVolumes.ps1' 85
#Region '.\Public\Get\Queries\Get-NinjaOneWindowsServices.ps1' 0
function Get-NinjaOneWindowsServices {
    <#
        .SYNOPSIS
            Gets the windows services from the NinjaOne API.
        .DESCRIPTION
            Retrieves the windows services from the NinjaOne v2 API.
        .FUNCTIONALITY
            Windows Services Query
        .EXAMPLE
            PS> Get-NinjaOneWindowsServices
 
            Gets the windows services.
        .EXAMPLE
            PS> Get-NinjaOneWindowsServices -deviceFilter 'organization in (1,2,3)'
 
            Gets the windows services for devices in organisations 1, 2 and 3.
        .EXAMPLE
            PS> Get-NinjaOneWindowsServices -name 'NinjaOne'
 
            Gets the windows services with the name 'NinjaOne'.
        .EXAMPLE
            PS> Get-NinjaOneWindowsServices -state 'RUNNING'
 
            Gets the windows services with the state 'RUNNING'.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/windowsservicesquery
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnows')]
    [MetadataAttribute(
        '/v2/queries/windows-services',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter devices.
        [Parameter(Position = 0)]
        [Alias('df')]
        [String]$deviceFilter,
        # Filter by service name.
        [Parameter(Position = 1, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [String]$name,
        # Filter by service state.
        [Parameter(Position = 2, ValueFromPipelineByPropertyName)]
        [ValidateSet(
            'UNKNOWN',
            'STOPPED',
            'START_PENDING',
            'RUNNING',
            'STOP_PENDING',
            'PAUSE_PENDING',
            'PAUSED',
            'CONTINUE_PENDING'
        )]
        [String]$state,
        # Cursor name.
        [Parameter(Position = 3)]
        [String]$cursor,
        # Number of results per page.
        [Parameter(Position = 4)]
        [Int]$pageSize
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/queries/windows-services'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $WindowsServices = New-NinjaOneGETRequest @RequestParams
            if ($WindowsServices) {
                return $WindowsServices
            } else {
                throw 'No windows services found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Queries\Get-NinjaOneWindowsServices.ps1' 89
#Region '.\Public\Get\RelatedItems\Get-NinjaOneRelatedItems.ps1' 0
function Get-NinjaOneRelatedItems {
    <#
        .SYNOPSIS
            Gets items related to an entity or entity type from the NinjaOne API.
        .DESCRIPTION
            Retrieves related items related to a given entity or entity type from the NinjaOne v2 API.
        .FUNCTIONALITY
            Related Items
        .EXAMPLE
            PS> Get-NinjaOneRelatedItems -all
 
            Gets all related items.
        .EXAMPLE
            PS> Get-NinjaOneRelatedItems -relatedTo -entityType 'organization'
 
            Gets all items which have a relation to an organization.
        .EXAMPLE
            PS> Get-NinjaOneRelatedItems -relatedTo -entityType 'organization' -entityId 1
 
            Gets all items which have a relation to the organization with id 1.
        .EXAMPLE
            PS> Get-NinjaOneRelatedItems -relatedFrom -entityType 'organization'
 
            Gets all items which have a relation from an organization.
        .EXAMPLE
            PS> Get-NinjaOneRelatedItems -relatedFrom -entityType 'organization' -entityId 1
 
            Gets all items which have a relation from the organization with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/relateditems
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnori')]
    [MetadataAttribute(
        '/v2/related-items',
        'get',
        '/v2/related-items/with-entity/{entityType}/{entityId}',
        'get',
        '/v2/related-items/with-entity-type/{entityType}',
        'get',
        '/v2/related-items/with-related-entity/{relEntityType}/{relEntityId}',
        'get',
        '/v2/related-items/with-related-entity-type/{relatedEntityType}',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Return all related items.
        [Parameter(Mandatory, ParameterSetName = 'all')]
        [Switch]$all,
        # Find items related to the given entity type/id.
        [Parameter(Mandatory, ParameterSetName = 'relatedTo')]
        [Switch]$relatedTo,
        # Find items with related entities of the given type/id.
        [Parameter(Mandatory, ParameterSetName = 'relatedFrom')]
        [Switch]$relatedFrom,
        # The entity type to get related items for.
        [Parameter(Mandatory, ParameterSetName = 'relatedTo', Position = 0)]
        [Parameter(Mandatory, ParameterSetName = 'relatedFrom', Position = 0)]
        [ValidateSet('ORGANIZATION', 'DOCUMENT', 'LOCATION', 'NODE', 'CHECKLIST', 'KB_DOCUMENT')]
        [String]$entityType,
        # The entity id to get related items for.
        [Parameter(ParameterSetName = 'relatedTo', Position = 1)]
        [Parameter(ParameterSetName = 'relatedFrom', Position = 1)]
        [Int64]$entityId,
        # The scope of the related items.
        [Parameter(ParameterSetName = 'relatedTo', Position = 2)]
        [Parameter(ParameterSetName = 'relatedFrom', Position = 2)]
        [ValidateSet('ALL', 'RELATIONS', 'REFERENCES')]
        [String]$scope
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
        # Workaround to prevent the query string processor from adding an 'all=true' parameter by removing it from the set parameters.
        if ($all) {
            $Parameters.Remove('all') | Out-Null
        }
        # Similarly we don't want a `relatedTo=true` parameter since we're targetting a different resource.
        if ($relatedTo) {
            $Parameters.Remove('relatedTo') | Out-Null
        }
        # Similarly we don't want a `relatedFrom=true` parameter since we're targetting a different resource.
        if ($relatedFrom) {
            $Parameters.Remove('relatedFrom') | Out-Null
        }
        # Similarly we don't want a `entityType=` parameter since that's a path fragment.
        if ($entityType) {
            $Parameters.Remove('entityType') | Out-Null
        }
        # Similarly we don't want a `entityId=` parameter since that's a path fragment.
        if ($entityId) {
            $Parameters.Remove('entityId') | Out-Null
        }
    }
    process {
        try {
            if ($PSCmdlet.ParameterSetName -eq 'all') {
                Write-Verbose 'Getting all related items from NinjaOne API.'
                $Resource = 'v2/related-items'
            } elseif ($PSCmdlet.ParameterSetName -eq 'relatedTo' -and $entityType -and $entityId) {
                Write-Verbose ('Getting items related to entity of type {0} with id {1}.' -f $entityType, $entityId)
                $Resource = ('v2/related-items/with-entity/{0}/{1}' -f $entityType, $entityId)
            } elseif ($PSCmdlet.ParameterSetName -eq 'relatedTo' -and $entityType) {
                Write-Verbose ('Getting items related to entity of type {0}.' -f $entityType)
                $Resource = ('v2/related-items/with-entity-type/{0}' -f $entityType)
            } elseif ($PSCmdlet.ParameterSetName -eq 'relatedFrom' -and $entityType -and $entityId) {
                Write-Verbose ('Getting items with related entities of type {0} with id {1}.' -f $entityType, $entityId)
                $Resource = ('v2/related-items/with-related-entity/{0}/{1}' -f $entityType, $entityId)
            } elseif ($PSCmdlet.ParameterSetName -eq 'relatedFrom' -and $entityType) {
                Write-Verbose ('Getting items with related entities of type {0}.' -f $entityType)
                $Resource = ('v2/related-items/with-related-entity-type/{0}' -f $entityType)
            }
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $RelatedItemResults = New-NinjaOneGETRequest @RequestParams
            if ($RelatedItemResults) {
                return $RelatedItemResults
            } else {
                throw 'No related items found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\RelatedItems\Get-NinjaOneRelatedItems.ps1' 133
#Region '.\Public\Get\Ticketing\Get-NinjaOneContacts.ps1' 0
function Get-NinjaOneContacts {
    <#
        .SYNOPSIS
            Gets contacts from the NinjaOne API.
        .DESCRIPTION
            Retrieves contacts from the NinjaOne v2 API.
        .FUNCTIONALITY
            Contacts
        .EXAMPLE
            PS> Get-NinjaOneContacts
             
            Gets all contacts.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/contacts
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnoc')]
    [MetadataAttribute(
        '/v2/ticketing/contact/contacts',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param()
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/ticketing/contact/contacts'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $Contacts = New-NinjaOneGETRequest @RequestParams
            if ($Contacts) {
                return $Contacts
            } else {
                throw 'No contacts found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Ticketing\Get-NinjaOneContacts.ps1' 50
#Region '.\Public\Get\Ticketing\Get-NinjaOneTicketAttributes.ps1' 0
function Get-NinjaOneTicketAttributes {
    <#
        .SYNOPSIS
            Gets ticket attributes from the NinjaOne API.
        .DESCRIPTION
            Retrieves a list of the ticket attributes from the NinjaOne v2 API.
        .FUNCTIONALITY
            Ticket Attributes
        .EXAMPLE
            PS> Get-NinjaOneTicketAttributes
 
            Gets all ticket attributes.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/ticketattributes
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnota')]
    [MetadataAttribute(
        '/v2/ticketing/attributes',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param()
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/ticketing/attributes'
            $RequestParams = @{
                QSCollection = $QSCollection
                Resource = $Resource
            }
            $TicketAttributes = New-NinjaOneGETRequest @RequestParams
            if ($TicketAttributes) {
                return $TicketAttributes
            } else {
                throw 'No ticket attributes found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Ticketing\Get-NinjaOneTicketAttributes.ps1' 50
#Region '.\Public\Get\Ticketing\Get-NinjaOneTicketBoards.ps1' 0
function Get-NinjaOneTicketBoards {
    <#
        .SYNOPSIS
            Gets boards from the NinjaOne API.
        .DESCRIPTION
            Retrieves boards from the NinjaOne v2 API.
        .FUNCTIONALITY
            Ticket Boards
        .EXAMPLE
            PS> Get-NinjaOneTicketBoards
 
            Gets all boards.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/ticketboards
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnotb')]
    [MetadataAttribute(
        '/v2/ticketing/trigger/boards',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param()
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/ticketing/trigger/boards'
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $Boards = New-NinjaOneGETRequest @RequestParams
            if ($Boards) {
                return $Boards
            } else {
                throw 'No boards found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Ticketing\Get-NinjaOneTicketBoards.ps1' 50
#Region '.\Public\Get\Ticketing\Get-NinjaOneTicketForms.ps1' 0
function Get-NinjaOneTicketForms {
    <#
        .SYNOPSIS
            Gets ticket forms from the NinjaOne API.
        .DESCRIPTION
            Retrieves ticket forms from the NinjaOne v2 API.
        .FUNCTIONALITY
            Ticket Forms
        .EXAMPLE
            PS> Get-NinjaOneTicketForms
 
            Gets all ticket forms.
        .EXAMPLE
            PS> Get-NinjaOneTicketForms -ticketFormId 1
 
            Gets ticket form with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/ticketforms
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnotf')]
    [MetadataAttribute(
        '/v2/ticketing/ticket-form',
        'get',
        '/v2/ticketing/ticket-form/{id}',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Ticket form id.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$ticketFormId
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            if ($ticketFormId) {
                Write-Verbose ('Getting ticket form with id {0}.' -f $ticketFormId)
                $Resource = ('/v2/ticketing/ticket-form/{0}' -f $ticketFormId)
            } else {
                Write-Verbose 'Retrieving ticket forms'
                $Resource = '/v2/ticketing/ticket-form'
            }
            $RequestParams = @{
                QSCollection = $QSCollection
                Resource = $Resource
            }
            $TicketForms = New-NinjaOneGETRequest @RequestParams
            if ($TicketForms) {
                return $TicketForms
            } else {
                throw 'No ticket forms found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Ticketing\Get-NinjaOneTicketForms.ps1' 67
#Region '.\Public\Get\Ticketing\Get-NinjaOneTicketLogEntries.ps1' 0
function Get-NinjaOneTicketLogEntries {
    <#
        .SYNOPSIS
            Gets ticket log entries from the NinjaOne API.
        .DESCRIPTION
            Retrieves ticket log entries from the NinjaOne v2 API.
        .FUNCTIONALITY
            Ticket Log Entries
        .EXAMPLE
            PS> Get-NinjaOneTicketLogEntries -ticketId 1
 
            Gets all ticket log entries for ticket with id 1.
        .EXAMPLE
            PS> Get-NinjaOneTicketLogEntries -ticketId 1 -type DESCRIPTION
 
            Gets all ticket log entries for ticket with id 1 with type DESCRIPTION.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/ticketlogentries
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnotle')]
    [MetadataAttribute(
        '/v2/ticketing/ticket/{ticketId}/log-entry',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # Filter by ticket id.
        [Parameter(Mandatory)]
        [Alias('id')]
        [String]$ticketId,
        # Filter log entries by type.
        [ValidateSet('DESCRIPTION', 'COMMENT', 'CONDITION', 'SAVE', 'DELETE')]
        [String]$type
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'ticketid=' parameter by removing it from the set parameters.
        $Parameters.Remove('ticketId') | Out-Null
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = ('v2/ticketing/ticket/{0}/log-entry' -f $ticketId)
            $RequestParams = @{
                Resource = $Resource
                QSCollection = $QSCollection
            }
            $TicketLogEntries = New-NinjaOneGETRequest @RequestParams
            if ($TicketLogEntries) {
                return $TicketLogEntries
            } else {
                if ($type) {
                    throw ('No ticket log entries found for ticket {0} with type {1}.' -f $ticketId, $type)
                } else {
                    throw ('No ticket log entries found for ticket {0}.' -f $ticketId)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Ticketing\Get-NinjaOneTicketLogEntries.ps1' 68
#Region '.\Public\Get\Ticketing\Get-NinjaOneTickets.ps1' 0
function Get-NinjaOneTickets {
    <#
        .SYNOPSIS
            Gets tickets from the NinjaOne API.
        .DESCRIPTION
            Retrieves tickets from the NinjaOne v2 API.
        .FUNCTIONALITY
            Tickets
        .EXAMPLE
            PS> Get-NinjaOneTickets -ticketId 1
 
            Gets the ticket with id 1.
        .EXAMPLE
            PS> Get-NinjaOneTickets -boardId 1
 
            Gets all tickets for the board with id 1.
        .EXAMPLE
            PS> Get-NinjaOneTickets -boardId 1 -filters @{status = 'open'}
 
            Gets all open tickets for the board with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/tickets
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnot')]
    [MetadataAttribute(
        '/v2/ticketing/ticket/{ticketId}',
        'get',
        '/v2/ticketing/trigger/board/{boardId}/run',
        'post'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The ticket id to get.
        [Parameter(Mandatory, ParameterSetName = 'Single', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$ticketId,
        # The board id to get tickets for.
        [Parameter(Mandatory, ParameterSetName = 'Board', Position = 0, ValueFromPipeline)]
        [String]$boardId,
        # The sort rules to apply to the request. Create these using `[NinjaOneTicketBoardSort]::new()`.
        [Parameter(ParameterSetName = 'Board', Position = 1)]
        [NinjaOneTicketBoardSort[]]$sort,
        # Any filters to apply to the request. Create these using `[NinjaOneTicketBoardFilter]::new()`.
        [Parameter(ParameterSetName = 'Board', Position = 2)]
        [NinjaOneTicketBoardFilter[]]$filters,
        # The last cursor id to use for the request.
        [Parameter(ParameterSetName = 'Board', Position = 3)]
        [String]$lastCursorId,
        # The number of results to return.
        [Parameter(ParameterSetName = 'Board', Position = 4)]
        [Int]$pageSize,
        # The search criteria to apply to the request.
        [Parameter(ParameterSetName = 'Board', Position = 5)]
        [String]$searchCriteria,
        # Include the metadata in the response.
        [Parameter(ParameterSetName = 'Board', Position = 6)]
        [Switch]$includeMetadata
    )
    begin {
    }
    process {
        try {
            if ($ticketId) {
                Write-Verbose ('Getting ticket with id {0}.' -f $ticketId)
                $Resource = ('v2/ticketing/ticket/{0}' -f $ticketId)
                $Method = 'GET'
            } else {
                Write-Verbose ('Getting tickets for board with id {0}.' -f $boardId)
                $Resource = ('v2/ticketing/trigger/board/{0}/run' -f $boardId)
                $Method = 'POST'
            }
            $RequestParams = @{
                Resource = $Resource
            }
            if ($QSCollection) {
                $RequestParams.QSCollection = $QSCollection
            }
            if ($PSCmdlet.ParameterSetName -eq 'Board') {
                $RequestParams.Body = [hashtable]@{}
            }
            if ($sort) {
                $RequestParams.Body.sort = $sort
            }
            if ($filters) {
                $RequestParams.Body.filters = $filters
            }
            if ($lastCursorId) {
                $RequestParams.Body.lastCursorId = $lastCursorId
            }
            if ($searchCriteria) {
                $RequestParams.Body.searchCriteria = $searchCriteria
            }
            if ($Method -eq 'GET') {
                $Tickets = New-NinjaOneGETRequest @RequestParams
            } elseif ($Method -eq 'POST') {
                $Tickets = New-NinjaOnePOSTRequest @RequestParams
            }
            if ($Tickets) {
                if ($includeMetadata -or $PSCmdlet.ParameterSetName -ne 'Board') {
                    Write-Verbose 'Returning full response.'
                    return $Tickets
                } else {
                    # Return just the `data` property which lists the tickets.
                    Write-Verbose 'Returning just the ticket data.'
                    return $Tickets.data
                }
            } else {
                throw 'No tickets found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Ticketing\Get-NinjaOneTickets.ps1' 119
#Region '.\Public\Get\Ticketing\Get-NinjaOneTicketStatuses.ps1' 0
function Get-NinjaOneTicketStatuses {
    <#
        .SYNOPSIS
            Gets ticket statuses from the NinjaOne API.
        .DESCRIPTION
            Retrieves a list of ticket statuses from the NinjaOne v2 API.
        .FUNCTIONALITY
            Ticket Statuses
        .EXAMPLE
            PS> Get-NinjaOneTicketStatuses
 
            Gets the ticket statuses.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Get/ticketstatuses
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('gnots')]
    [MetadataAttribute(
        '/v2/ticketing/statuses',
        'get'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param()
    process {
        try {
            Write-Verbose 'Retrieving ticket statuses from NinjaOne API.'
            $Resource = 'v2/ticketing/statuses'
            $RequestParams = @{
                Resource = $Resource
            }
            $TicketStatuses = New-NinjaOneGETRequest @RequestParams
            if ($TicketStatuses) {
                return $TicketStatuses
            } else {
                throw 'No ticket statuses found.'
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Get\Ticketing\Get-NinjaOneTicketStatuses.ps1' 45
#Region '.\Public\Invoke\Invoke-NinjaOneDeviceScript.ps1' 0
function Invoke-NinjaOneDeviceScript {
    <#
        .SYNOPSIS
            Runs a script or built-in action against the given device.
        .DESCRIPTION
            Runs a script or built-in action against a single device using the NinjaOne v2 API.
        .FUNCTIONALITY
            Script or Action
        .OUTPUTS
            A powershell object containing the response.
        .EXAMPLE
            PS> Invoke-NinjaOneDeviceScript -deviceId 1 -type 'SCRIPT' -scriptId 1
             
            Runs the script with id 1 against the device with id 1.
        .EXAMPLE
            PS> Invoke-NinjaOneDeviceScript -deviceId 1 -type 'ACTION' -actionUId '00000000-0000-0000-0000-000000000000'
 
            Runs the built-in action with uid 00000000-0000-0000-0000-000000000000 against the device with id 1.
        .EXAMPLE
 
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Invoke/scriptoraction
    #>

    [CmdletBinding()]
    [OutputType([Object])]
    [Alias('inods')]
    [MetadataAttribute(
        '/v2/device/{id}/script/run',
        'post'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The device to run a script on.
        [Parameter(Mandatory, ParameterSetName = 'SCRIPT', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Parameter(Mandatory, ParameterSetName = 'ACTION', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # The type - script or action.
        [Parameter(Mandatory, ParameterSetName = 'SCRIPT', Position = 1, ValueFromPipelineByPropertyName)]
        [Parameter(Mandatory, ParameterSetName = 'ACTION', Position = 1, ValueFromPipelineByPropertyName)]
        [ValidateSet('SCRIPT', 'ACTION')]
        [String]$type,
        # The id of the script to run. Only used if the type is script.
        [Parameter(Mandatory, ParameterSetName = 'SCRIPT', Position = 2, ValueFromPipelineByPropertyName)]
        [Int]$scriptId,
        # The unique uid of the action to run. Only used if the type is action.
        [Parameter(Mandatory, ParameterSetName = 'ACTION', Position = 2, ValueFromPipelineByPropertyName)]
        [GUID]$actionUId,
        # The parameters to pass to the script or action.
        [Parameter(ParameterSetName = 'SCRIPT', Position = 3, ValueFromPipelineByPropertyName)]
        [Parameter(ParameterSetName = 'ACTION', Position = 3, ValueFromPipelineByPropertyName)]
        [String]$parameters,
        # The credential/role identifier to use when running the script.
        [Parameter(ParameterSetName = 'SCRIPT', Position = 4, ValueFromPipelineByPropertyName)]
        [Parameter(ParameterSetName = 'ACTION', Position = 4, ValueFromPipelineByPropertyName)]
        [ValidateScript(
            { $_ -is [String] -AND $_ -in @('system', 'SR_MAC_SCRIPT,') }
        )]
        [String]$runAs
    )
    begin {
        if ($Script:NRAPIConnectionInformation.AuthMode -eq 'Client Credentials') {
            throw ('This function is not available when using client_credentials authentication. If this is unexpected please report this to api@ninjarmm.com.')
            exit 1
        }
    }
    process {
        try {
            if ($type -eq 'SCRIPT') {
                $prettyAction = 'script'
            } else {
                $prettyAction = 'action'
            }
            $Device = Get-NinjaOneDevice -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Getting device scripting options for device {0}.' -f $Device.SystemName)
                if ($type -eq 'SCRIPT') {
                    $ScriptOrAction = Get-NinjaOneDeviceScriptingOptions -deviceId $deviceId -Scripts | Where-Object { $_.id -eq $scriptId -AND $_.type -eq $type }
                } else {
                    $ScriptOrAction = Get-NinjaOneDeviceScriptingOptions -deviceId $deviceId -Scripts | Where-Object { $_.uid -eq $actionUId -AND $_.type -eq $type }
                }
                if ($ScriptOrAction.Count -gt 1) {
                    Write-Warning ('More than one {0} matched for device {1}.' -f $prettyAction, $Device.SystemName)
                    Write-Verbose ('Raw {0} options: {1}' -f $prettyAction, ($ScriptOrAction | Out-String))
                }
                if ($ScriptOrAction) {
                    Write-Verbose ('Running {0} {1} on device {2}.' -f $prettyAction, $ScriptOrAction.Name, $Device.SystemName)
                    $Resource = ('v2/device/{0}/script/run' -f $deviceId)
                    $RunRequest = @{
                        type = $type
                    }
                    if ($scriptId) {
                        $RunRequest.id = $scriptId
                    }
                    if ($actionUId) {
                        $RunRequest.uid = $actionUId
                    }
                    if ($parameters) {
                        $RunRequest.parameters = $parameters
                    }
                    if ($runAs) {
                        $RunRequest.runAs = $runAs
                    }
                    Write-Verbose ('Raw run request: {0}' -f ($RunRequest | Out-String))
                } else {
                    if ($scriptId) {
                        throw ('Script with id {0} not found for device {1}.' -f $scriptId, $Device.SystemName)
                    } elseif ($actionUId) {
                        throw ('Action with uid {0} not found for device {1}.' -f $actionUId, $Device.SystemName)
                    }
                }
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
                Body = $RunRequest
            }
            $ScriptRun = New-NinjaOnePOSTRequest @RequestParams
            if ($ScriptRun -eq 204) {
                $OIP = $InformationPreference
                $InformationPreference = 'Continue'
                Write-Information ('Requested run for {0} {1} on device {2} successfully.' -f $prettyAction, $ScriptOrAction.Name, $Device.SystemName)
                $InformationPreference = $OIP
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Invoke\Invoke-NinjaOneDeviceScript.ps1' 131
#Region '.\Public\Invoke\Invoke-NinjaOneRequest.ps1' 0

function Invoke-NinjaOneRequest {
    <#
        .SYNOPSIS
            Sends a request to the NinjaOne API.
        .DESCRIPTION
            Wrapper function to send web requests to the NinjaOne API.
        .FUNCTIONALITY
            API Request
        .EXAMPLE
            PS> Invoke-NinjaOneRequest -Method 'GET' -Uri 'https://eu.ninjarmm.com/v2/activities'
             
            Make a GET request to the activities resource.
        .OUTPUTS
            Outputs an object containing the response from the web request.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Invoke/apirequest
    #>

    [Cmdletbinding()]
    [OutputType([Object])]
    [Alias('inor')]
    [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)]
        [String]$Uri,
        # The body of the request.
        [Parameter(Position = 2)]
        [String]$Body,
        # Return the raw response - don't convert from JSON.
        [Switch]$Raw

    )
    begin {
        if ($null -eq $Script:NRAPIConnectionInformation) {
            throw "Missing NinjaOne connection information, please run 'Connect-NinjaOne' first."
        }
        if ($null -eq $Script:NRAPIAuthenticationInformation) {
            throw "Missing NinjaOne authentication tokens, please run 'Connect-NinjaOne' first."
        }
        $Now = Get-Date
        if ($Script:NRAPIAuthenticationInformation.Expires -le $Now) {
            Write-Verbose 'The auth token has expired, renewing.'
            Update-NinjaOneToken -Verbose:$VerbosePreference
        }
        if ($null -ne $Script:NRAPIAuthenticationInformation) {
            $AuthHeaders = @{
                Authorization = "$($Script:NRAPIAuthenticationInformation.Type) $($Script:NRAPIAuthenticationInformation.Access)"
            }
        } else {
            $AuthHeaders = $null
        }
    }
    process {
        try {
            Write-Verbose ('Making a {0} request to {1}' -f $WebRequestParams.Method, $WebRequestParams.Uri)
            $WebRequestParams = @{
                Method = $Method
                Uri = $Uri
            }
            if ($Body) {
                Write-Verbose ('Body is {0}' -f ($Body | Out-String))
                $WebRequestParams.Add('Body', $Body)
            } else {
                Write-Verbose 'No body present.'
            }
            $Response = Invoke-WebRequest @WebRequestParams -Headers $AuthHeaders -ContentType 'application/json;charset=utf-8'
            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) {
                $ResponseContent = $Response.Content
            } else {
                $ResponseContent = 'No content'
            }
            if ($Response.Content) {
                Write-Verbose ('Response content: {0}' -f ($ResponseContent | Out-String))
            } else {
                Write-Verbose 'No response content.'
            }
            if ($Raw) {
                Write-Verbose 'Raw switch present, returning raw response.'
                $Results = $Response.Content
            } else {
                Write-Verbose 'Raw switch not present, converting response from JSON.'
                $Results = $Response.Content | ConvertFrom-Json
            }
            if ($null -eq $Results) {
                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)
                    $Results = $Response.StatusCode
                } else {
                    Write-Verbose 'Request completed with no results and/or no status code.'
                    $Results = @{}
                }
            }
            return $Results
        } catch {
            throw $_
        }
    }
}
#EndRegion '.\Public\Invoke\Invoke-NinjaOneRequest.ps1' 107
#Region '.\Public\Invoke\Invoke-NinjaOneWindowsServiceAction.ps1' 0
function Invoke-NinjaOneWindowsServiceAction {
    <#
        .SYNOPSIS
            Runs an action against the given Windows Service for the given device.
        .DESCRIPTION
            Runs an action against a windows service on a single device using the NinjaOne v2 API.
        .FUNCTIONALITY
            Windows Service Action
        .OUTPUTS
            System.Void
 
            This commandlet returns no output. A success message will be written to the information stream if the API returns a 204 success code. Use `-InformationAction Continue` to see this message.
        .EXAMPLE
 
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Invoke/windowsserviceaction
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    # This commandlet returns no output. A success message will be written to the information stream if the API returns a 204 success code. Use `-InformationAction Continue` to see this message.
    [OutputType([System.Void])]
    [Alias('inowsa')]
    [MetadataAttribute(
        '/v2/device/{id}/windows-service/{serviceId}/control',
        'post'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The device(s) to change service configuration for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [int]$deviceId,
        # The service to alter configuration for.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [Alias('service', 'serviceName')]
        [string]$serviceId,
        # The action to invoke.
        [Parameter(Mandatory, Position = 2, ValueFromPipelineByPropertyName)]
        [ValidateSet('START', 'PAUSE', 'STOP', 'RESTART')]
        [string]$action
    )
    process {
        try {
            $Device = Get-NinjaOneDevice -deviceId $deviceId
            if ($Device) {
                $Service = Get-NinjaOneDeviceWindowsServices -deviceId $deviceId -name $serviceId
                if ($Service) {
                    Write-Verbose ('Performing action {0} on service {1} on device {2}.' -f $action, $Service.DisplayName, $Device.SystemName)
                    $Resource = ('v2/device/{0}/windows-service/{1}/control' -f $deviceId, $serviceId)
                } else {
                    throw ('Service with id {0} not found.' -f $serviceId)
                }
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
                Body = @{
                    action = $action
                }
            }
            if ($PSCmdlet.ShouldProcess("Service $($serviceId) configuration", 'Set')) {
                $ServiceAction = New-NinjaOnePOSTRequest @RequestParams
                if ($ServiceAction -eq 204) {
                    Write-Information ('Requested {0} on service {1} on device {2} successfully.' -f $action, $serviceId, $deviceId)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Invoke\Invoke-NinjaOneWindowsServiceAction.ps1' 72
#Region '.\Public\New\New-NinjaOneDocumentTemplate.ps1' 0
function New-NinjaOneDocumentTemplate {
    <#
        .SYNOPSIS
            Creates a new document template using the NinjaOne API.
        .DESCRIPTION
            Create a new document template using the NinjaOne v2 API.
        .FUNCTIONALITY
            Document Template
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/New/documenttemplate
    #>

    [CmdletBinding( SupportsShouldProcess, ConfirmImpact = 'Medium' )]
    [OutputType([Object])]
    [Alias('nnodt')]
    [MetadataAttribute(
        '/v2/document-templates',
        'post'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The name of the document template.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [String]$name,
        # The description of the document template.
        [Parameter(Position = 1, ValueFromPipelineByPropertyName)]
        [String]$description,
        # Allow multiple instances of this document template to be used per organisation.
        [Parameter(Position = 2, ValueFromPipelineByPropertyName)]
        [Switch]$allowMultiple,
        # Is this document template mandatory for all organisations.
        [Parameter(Position = 3, ValueFromPipelineByPropertyName)]
        [Switch]$mandatory,
        # The document template fields.
        [Parameter(Mandatory, Position = 4, ValueFromPipelineByPropertyName)]
        [Object[]]$fields,
        # Show the document template that was created.
        [Switch]$show
    )
    begin {
        # Validate the fields parameter.
        foreach ($field in $fields) {
            if ($field.fieldType -in ('DROPDOWN', 'MULTI_SELECT')) {
                if ($null -eq $field.fieldContent) {
                    throw 'Field content must be specified for field type {0}.' -f $field.fieldType
                } elseif ($null -eq $field.fieldContent.values) {
                    throw 'Field content values must be specified for field type {0}.' -f $field.fieldType
                }
            }
        }
    }
    process {
        try {
            $DocumentTemplate = @{
                name = $name
                description = $description
                allowMultiple = $allowMultiple
                mandatory = $mandatory
                fields = $fields
            }
            $Resource = 'v2/document-templates'
            $RequestParams = @{
                Resource = $Resource
                Body = $DocumentTemplate
            }
            if ($PSCmdlet.ShouldProcess(('Document Template {0}' -f $DocumentTemplate.name), 'Create')) {
                $DocumentTemplateCreate = New-NinjaOnePOSTRequest @RequestParams
                if ($show) {
                    return $DocumentTemplateCreate
                } else {
                    Write-Information ('Document Template {0} created.' -f $DocumentTemplateCreate.name)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\New\New-NinjaOneDocumentTemplate.ps1' 80
#Region '.\Public\New\New-NinjaOneInstaller.ps1' 0
function New-NinjaOneInstaller {
    <#
        .SYNOPSIS
            Creates a new installer using the NinjaOne API.
        .DESCRIPTION
            Create a new installer download link using the NinjaOne v2 API.
        .FUNCTIONALITY
            Installer
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/New/installer
    #>

    [CmdletBinding( SupportsShouldProcess, ConfirmImpact = 'Medium' )]
    [OutputType([Object])]
    [Alias('nnoi')]
    [MetadataAttribute(
        '/v2/organization/generate-installer',
        'post'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The organization id to use when creating the installer.
        [Parameter(Mandatory, Position = 0, ValueFromPipelineByPropertyName)]
        [Alias('id', 'organizationId')]
        [Int]$organisationId,
        # The location id to use when creating the installer.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [Int]$locationId,
        # The installer type to use when creating the installer.
        [Parameter(Mandatory, Position = 2, ValueFromPipelineByPropertyName)]
        [ValidateSet('WINDOWS_MSI', 'MAC_DMG', 'MAC_PKG', 'LINUX_DEB', 'LINUX_RPM')]
        [String]$installerType,
        # The number of uses permitted for the installer.
        [Parameter(Position = 3, ValueFromPipelineByPropertyName)]
        [Int]$usageLimit,
        # The node role id to use when creating the installer.
        [Parameter(Position = 4, ValueFromPipelineByPropertyName)]
        [ValidateNodeRoleId()]
        [Object]$nodeRoleId = 'auto'
    )
    process {
        try {
            $Resource = 'v2/organization/generate-installer'
            $InstallerBody = @{
                organization_id = $organisationId
                location_id = $locationId
                installer_type = $installerType
                usage_limit = $usageLimit
                content = @{
                    nodeRoleId = $nodeRoleId
                }
            }
            $RequestParams = @{
                Resource = $Resource
                Body = $InstallerBody
            }
            $OrganisationExists = (Get-NinjaOneOrganisations -organisationId $organisationId).Count -gt 0
            $LocationExists = (Get-NinjaOneLocations -organisationId $organisationId | Where-Object { $_.id -eq $locationId }).Count -gt 0
            if ($OrganisationExists -and $LocationExists) {
                if ($PSCmdlet.ShouldProcess('Installer', 'Create')) {
                    $InstallerCreate = New-NinjaOnePOSTRequest @RequestParams
                    return $InstallerCreate.url
                }
            } else {
                throw "Organisation '$organisationId' or location '$locationId' does not exist."
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\New\New-NinjaOneInstaller.ps1' 73
#Region '.\Public\New\New-NinjaOneLocation.ps1' 0
function New-NinjaOneLocation {
    <#
        .SYNOPSIS
            Creates a new location using the NinjaOne API.
        .DESCRIPTION
            Create an location using the NinjaOne v2 API.
        .FUNCTIONALITY
            Location
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/New/location
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('nnol')]
    [MetadataAttribute(
        '/v2/organization/{id}/locations',
        'post'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The organization Id to use when creating the location.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id', 'organizationId')]
        [Int]$organisationId,
        # An object containing the location to create.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [Alias('body')]
        [Object]$location,
        # Show the location that was created.
        [Switch]$show
    )
    process {
        try {
            $Resource = ('v2/organization/{0}/locations' -f $organisationId)
            $RequestParams = @{
                Resource = $Resource
                Body = $location
            }
            $OrganisationExists = (Get-NinjaOneOrganisations -organisationId $organisationId).Count -gt 0
            if ($OrganisationExists) {
                if ($PSCmdlet.ShouldProcess(('Location {0}' -f $location.name), 'Create')) {
                    $LocationCreate = New-NinjaOnePOSTRequest @RequestParams
                    if ($show) {
                        return $LocationCreate
                    } else {
                        $OIP = $InformationPreference
                        $InformationPreference = 'Continue'
                        Write-Information ('Location {0} created.' -f $LocationCreate.name)
                        $InformationPreference = $OIP
                    }
                }
            } else {
                throw ('Organisation with id {0} not found.' -f $organisationId)
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\New\New-NinjaOneLocation.ps1' 62
#Region '.\Public\New\New-NinjaOneOrganisation.ps1' 0
function New-NinjaOneOrganisation {
    <#
        .SYNOPSIS
            Creates a new organisation using the NinjaOne API.
        .DESCRIPTION
            Create an organisation using the NinjaOne v2 API.
        .FUNCTIONALITY
            Organisation
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/New/organisation
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('nnoo', 'New-NinjaOneOrganization')]
    [MetadataAttribute(
        '/v2/organizations',
        'post'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The Id of the organisation to use as a template.
        [Parameter(Position = 0, ValueFromPipelineByPropertyName)]
        [Alias('templateOrganizationId', 'templateId')]
        [String]$templateOrganisationId,
        # An object containing the organisation to create.
        [Parameter(Mandatory, Position = 1, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('organization', 'body')]
        [Object]$organisation,
        # Show the organisation that was created.
        [Switch]$show
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'organisation=' parameter by removing it from the set parameters.
        if ($organisation) {
            $Parameters.Remove('organisation') | Out-Null
        }
        # Workaround to prevent the query string processor from adding a 'show=' parameter by removing it from the set parameters.
        if ($show) {
            $Parameters.Remove('show') | Out-Null
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/organizations'
            $RequestParams = @{
                Resource = $Resource
                Body = $organisation
                QSCollection = $QSCollection
            }
            if ($PSCmdlet.ShouldProcess(('Organisation {0}' -f $organisation.name), 'Create')) {
                $OrganisationCreate = New-NinjaOnePOSTRequest @RequestParams
                if ($show) {
                    return $OrganisationCreate
                } else {
                    $OIP = $InformationPreference
                    $InformationPreference = 'Continue'
                    Write-Information ('Organisation {0} created.' -f $OrganisationCreate.name)
                    $InformationPreference = $OIP
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\New\New-NinjaOneOrganisation.ps1' 71
#Region '.\Public\New\New-NinjaOneOrganisationDocument.ps1' 0
function New-NinjaOneOrganisationDocument {
    <#
        .SYNOPSIS
            Creates new organisation document(s) using the NinjaOne API.
        .DESCRIPTION
            Create one or more organisation documents using the NinjaOne v2 API.
        .FUNCTIONALITY
            Organisation Documents
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/New/organisationdocument
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('nnood', 'New-NinjaOneOrganizationDocument')]
    [MetadataAttribute(
        '/v2/organization/documents',
        'post'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # An object containing an array of organisation documents to create.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('organizationDocuments', 'body')]
        [NinjaOneOrganisationDocument[]]$organisationDocuments,
        # Show the organisation that was created.
        [Switch]$show
    )
    begin {
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        # Workaround to prevent the query string processor from adding an 'organisationDocuments=' parameter by removing it from the set parameters.
        if ($organisationDocuments) {
            $Parameters.Remove('organisationDocuments') | Out-Null
        }
        # Workaround to prevent the query string processor from adding a 'show=' parameter by removing it from the set parameters.
        if ($show) {
            $Parameters.Remove('show') | Out-Null
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/organization/documents'
            $RequestParams = @{
                Resource = $Resource
                Body = $organisationDocuments
                QSCollection = $QSCollection
            }
            if ($PSCmdlet.ShouldProcess(('Organisation documents for organisation(s) {0}' -f $organisationDocuments.organizationId), 'Create')) {
                $OrganisationDocumentsCreate = New-NinjaOnePOSTRequest @RequestParams
                if ($show) {
                    return $OrganisationDocumentsCreate
                } else {
                    Write-Information ('Organisation documents for {0} created.' -f $OrganisationDocumentsCreate.organizationId)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\New\New-NinjaOneOrganisationDocument.ps1' 64
#Region '.\Public\New\New-NinjaOnePolicy.ps1' 0
function New-NinjaOnePolicy {
    <#
        .SYNOPSIS
            Creates a new policy using the NinjaOne API.
        .DESCRIPTION
            Create a new policy using the NinjaOne v2 API.
        .FUNCTIONALITY
            Policy
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/New/policy
    #>

    [CmdletBinding( SupportsShouldProcess, ConfirmImpact = 'Medium' )]
    [OutputType([Object])]
    [Alias('nnop')]
    [MetadataAttribute(
        '/v2/policies',
        'post'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The mode to run in, new, child or copy.
        [Parameter(Mandatory, Position = 0, ValueFromPipelineByPropertyName)]
        [ValidateSet('NEW', 'CHILD', 'COPY')]
        [String]$mode,
        # An object containing the policy to create.
        [Parameter(Mandatory, Position = 1, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Object]$policy,
        # The Id of the template policy to copy from.
        [Parameter(Position = 2, ValueFromPipelineByPropertyName)]
        [Alias('templateId')]
        [Int]$templatePolicyId,
        # Show the policy that was created.
        [Switch]$show
    )
    begin {
        if ($Script:NRAPIConnectionInformation.AuthMode -eq 'Client Credentials') {
            throw ('This function is not available when using client_credentials authentication. If this is unexpected please report this to api@ninjarmm.com.')
            exit 1
        }
        if ($mode -eq 'CHILD' -and $null -eq $policy.parentPolicyId) {
            throw 'The policy must have a parent policy id if using "CHILD" mode.'
        } elseif ($mode -eq 'COPY' -and $null -eq $templatePolicyId) {
            throw 'The policy must have a template policy id if using "COPY" mode.'
        }
        $CommandName = $MyInvocation.InvocationName
        $Parameters = (Get-Command -Name $CommandName).Parameters
        if ($policy) {
            $Parameters.Remove('policy') | Out-Null
        }
        if ($templatePolicyId) {
            $Parameters.Remove('templatePolicyId') | Out-Null
        }
        if ($show) {
            $Parameters.Remove('show') | Out-Null
        }
        $QSCollection = New-NinjaOneQuery -CommandName $CommandName -Parameters $Parameters
    }
    process {
        try {
            $Resource = 'v2/policies'
            $RequestParams = @{
                Resource = $Resource
                Body = $policy
                QSCollection = $QSCollection
            }
            if ($PSCmdlet.ShouldProcess(('Policy {0}' -f $policy.Name), 'Create')) {
                $PolicyCreate = New-NinjaOnePOSTRequest @RequestParams
                if ($show) {
                    return $PolicyCreate
                } else {
                    $OIP = $InformationPreference
                    $InformationPreference = 'Continue'
                    Write-Information ('Policy {0} created.' -f $PolicyCreate.name)
                    $InformationPreference = $OIP
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\New\New-NinjaOnePolicy.ps1' 84
#Region '.\Public\New\New-NinjaOneTicket.ps1' 0
function New-NinjaOneTicket {
    <#
        .SYNOPSIS
            Creates a new ticket using the NinjaOne API.
        .DESCRIPTION
            Create a ticket using the NinjaOne v2 API.
        .FUNCTIONALITY
            Ticket
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/New/ticket
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('nnot')]
    [MetadataAttribute(
        '/v2/ticketing/ticket',
        'post'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # An object containing the ticket to create.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Object]$ticket,
        # Show the ticket that was created.
        [Switch]$show
    )
    begin {
        if ($Script:NRAPIConnectionInformation.AuthMode -eq 'Client Credentials') {
            throw ('This function is not available when using client_credentials authentication. If this is unexpected please report this to api@ninjarmm.com.')
            exit 1
        }
    }
    process {
        try {
            $Resource = 'v2/ticketing/ticket'
            $RequestParams = @{
                Resource = $Resource
                Body = $ticket
            }
            if ($PSCmdlet.ShouldProcess(('Ticket {0}' -f $ticket.Subject), 'Create')) {
                $TicketCreate = New-NinjaOnePOSTRequest @RequestParams
                if ($show) {
                    return $TicketCreate
                } else {
                    $OIP = $InformationPreference
                    $InformationPreference = 'Continue'
                    Write-Information ('Ticket {0} created.' -f $TicketCreate.Subject)
                    $InformationPreference = $OIP
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\New\New-NinjaOneTicket.ps1' 58
#Region '.\Public\New\New-NinjaOneTicketComment.ps1' 0
## WIP Untested Code

function New-NinjaOneTicketComment {
    <#
        .SYNOPSIS
            Creates a new ticket comment using the NinjaOne API.
        .DESCRIPTION
            Create a ticket comment using the NinjaOne v2 API.
        .FUNCTIONALITY
            Ticket Comment
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/New/ticketcomment
    #>

    [CmdletBinding( SupportsShouldProcess, ConfirmImpact = 'Medium' )]
    [OutputType([Object])]
    [Alias('nnotc')]
    [MetadataAttribute(
        '/v2/ticketing/ticket/{ticketId}/comment',
        'post'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The ticket Id to use when creating the ticket comment.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$ticketId,
        # An object containing the ticket comment to create.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [Object]$comment,
        # Show the ticket comment that was created.
        [Switch]$show
    )
    begin {
        if ($Script:NRAPIConnectionInformation.AuthMode -eq 'Client Credentials') {
            throw ('This function is not available when using client_credentials authentication. If this is unexpected please report this to api@ninjarmm.com.')
            exit 1
        }
    }
    process {
        try {
            $Ticket = Get-NinjaOneTicket -ticketId $ticketId
            if ($Ticket) {
                $Resource = ('v2/ticketing/ticket/{0}/comment' -f $ticketId)
            } else {
                throw ('Ticket with id {0} not found.' -f $ticketId)
            }
            $RequestParams = @{
                Resource = $Resource
                Body = $ticket
            }
            if ($PSCmdlet.ShouldProcess(('Ticket comment on ticket {0} ({1})' -f $Ticket.id, $Ticket.summary), 'Create')) {
                $TicketCreate = New-NinjaOnePOSTRequest @RequestParams
                if ($show) {
                    return $TicketCreate
                } else {
                    $OIP = $InformationPreference
                    $InformationPreference = 'Continue'
                    Write-Information ('Ticket comment on ticket {0} ({1}) created.' -f $Ticket.id, $Ticket.summary)
                    $InformationPreference = $OIP
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\New\New-NinjaOneTicketComment.ps1' 69
#Region '.\Public\Remove\Remove-NinjaOneDeviceMaintenance.ps1' 0
function Remove-NinjaOneDeviceMaintenance {
    <#
        .SYNOPSIS
            Cancels scheduled maintenance for the given device.
        .DESCRIPTION
            Cancels scheduled maintenance for the given device using the NinjaOne v2 API.
        .FUNCTIONALITY
            Maintenance
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Remove/maintenance
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('rnodm')]
    [MetadataAttribute(
        '/v2/device/{id}/maintenance',
        'delete'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The device Id to cancel maintenance for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId
    )
    process {
        try {
            $Device = Get-NinjaOneDevice -deviceId $deviceId
            if ($Device) {
                $Resource = ('v2/device/{0}/maintenance' -f $deviceId)
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
            }
            if ($PSCmdlet.ShouldProcess(('{0} Maintenance' -f $Device.SystemName), 'Delete')) {
                $DeviceMaintenance = New-NinjaOneDELETERequest @RequestParams
                if ($DeviceMaintenance -eq 204) {
                    Write-Information ('Scheduled device maintenance for device {0} deleted successfully.' -f $Device.SystemName)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Remove\Remove-NinjaOneDeviceMaintenance.ps1' 50
#Region '.\Public\Remove\Remove-NinjaOneDocumentTemplate.ps1' 0
function Remove-NinjaOneDocumentTemplate {
    <#
        .SYNOPSIS
            Removes a document template using the NinjaOne API.
        .DESCRIPTION
            Removes the specified document template NinjaOne v2 API.
        .FUNCTIONALITY
            Document Template
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Remove/documenttemplate
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('rnodt')]
    [MetadataAttribute(
        '/v2/document-templates/{documentTemplateId}',
        'delete'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The document template to delete.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$documentTemplateId
    )
    process {
        try {
            $DocumentTemplate = Get-NinjaOneDocumentTemplates -documentTemplateId $documentTemplateId
            if ($DocumentTemplate) {
                $Resource = ('v2/document-templates/{0}' -f $documentTemplateId)
            } else {
                throw ('Document template with id {0} not found.' -f $documentTemplateId)
            }
            $RequestParams = @{
                Resource = $Resource
            }
            if ($PSCmdlet.ShouldProcess(('Document Template {0}' -f $DocumentTemplate.Name), 'Delete')) {
                $DocumentTemplateDelete = New-NinjaOneDELETERequest @RequestParams
                if ($DocumentTemplateDelete -eq 204) {
                    Write-Information ('Document template {0} deleted successfully.' -f $DocumentTemplate.Name)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Remove\Remove-NinjaOneDocumentTemplate.ps1' 50
#Region '.\Public\Remove\Remove-NinjaOneWebhook.ps1' 0
function Remove-NinjaOneWebhook {
    <#
        .SYNOPSIS
            Removes webhook configuration for the current application/API client.
        .DESCRIPTION
            Removes webhook configuration for the current application/API client using the NinjaOne v2 API.
        .FUNCTIONALITY
            Webhook
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Remove/webhook
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('rnow')]
    [MetadataAttribute(
        '/v2/webhook',
        'delete'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param()
    process {
        try {
            $Resource = 'v2/webhook'
            $RequestParams = @{
                Resource = $Resource
            }
            if ($PSCmdlet.ShouldProcess('Webhook Configuration', 'Delete')) {
                $WebhookConfiguration = New-NinjaOneDELETERequest @RequestParams
                if ($WebhookConfiguration -eq 204) {
                    Write-Information 'Webhook configuration deleted successfully.'
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Remove\Remove-NinjaOneWebhook.ps1' 40
#Region '.\Public\Reset\Reset-NinjaOneAlert.ps1' 0
function Reset-NinjaOneAlert {
    <#
        .SYNOPSIS
            Resets alerts using the NinjaOne API.
        .DESCRIPTION
            Resets the status of alerts using the NinjaOne v2 API.
        .FUNCTIONALITY
            Alert
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Reset/alert
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('rnoa')]
    [MetadataAttribute(
        '/v2/alert/{uid}/reset',
        'post',
        '/v2/alert/{uid}',
        'delete'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The alert Id to reset status for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [String]$uid,
        # The reset activity data.
        [Parameter(Position = 1, ValueFromPipelineByPropertyName)]
        [Object]$activityData
    )
    process {
        try {
            if ($activityData) {
                $Resource = ('v2/alert/{0}/reset' -f $uid)
                $RequestParams = @{
                    Resource = $Resource
                    Body = $activityData
                }
                if ($PSCmdlet.ShouldProcess(('Alert {0}' -f $uid), 'Reset')) {
                    $Alert = New-NinjaOnePOSTRequest @RequestParams
                    if ($Alert -eq 204) {
                        $OIP = $InformationPreference
                        $InformationPreference = 'Continue'
                        Write-Information 'Alert reset successfully.'
                        $InformationPreference = $OIP
                    }
                }
            } else {
                $Resource = ('v2/alert/{0}' -f $uid)
                $RequestParams = @{
                    Resource = $Resource
                }
                if ($PSCmdlet.ShouldProcess(('Alert {0}' -f $uid), 'Reset')) {
                    $Alert = New-NinjaOneDELETERequest @RequestParams
                    if ($Alert -eq 204) {
                        Write-Information 'Alert reset successfully.'
                    }
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Reset\Reset-NinjaOneAlert.ps1' 67
#Region '.\Public\Reset\Reset-NinjaOneDevicePolicyOverrides.ps1' 0
function Reset-NinjaOneDevicePolicyOverrides {
    <#
        .SYNOPSIS
            Resets (removes) device policy overrides using the NinjaOne API.
        .DESCRIPTION
            Resets (removes) all configured device policy overrides using the NinjaOne v2 API.
        .FUNCTIONALITY
            Device Policy Overrides
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Reset/devicepolicyoverrides
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('rnodpo')]
    [MetadataAttribute(
        '/v2/device/{id}/policy/overrides',
        'delete'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The device Id to reset policy overrides for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId
    )
    process {
        try {
            $Device = Get-NinjaOneDevice -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Resetting device policy overrides for device {0}.' -f $Device.SystemName)
                $Resource = ('v2/device/{0}/policy/overrides' -f $deviceId)
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
            }
            if ($PSCmdlet.ShouldProcess(('Device Policy Overrides for {0}' -f $Device.SystemName), 'Reset')) {
                $PolicyOverrides = New-NinjaOneDELETERequest @RequestParams
                if ($PolicyOverrides -eq 204) {
                    Write-Information ('Device policy overrides for {0} reset successfully.' -f $Device.SystemName)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Reset\Reset-NinjaOneDevicePolicyOverrides.ps1' 51
#Region '.\Public\Restart\Restart-NinjaOneDevice.ps1' 0
function Restart-NinjaOneDevice {
    <#
        .SYNOPSIS
            Reboots a device using the NinjaOne API.
        .DESCRIPTION
            Triggers a device reboot using the NinjaOne v2 API.
        .FUNCTIONALITY
            Device
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Restart/device
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('rnod')]
    [MetadataAttribute(
        '/v2/device/{id}/reboot/{mode}',
        'post'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The device Id to reset status for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # The reboot mode.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [ValidateSet('NORMAL', 'FORCED')]
        [String]$mode,
        # The reboot reason.
        [Parameter(Position = 3, ValueFromPipelineByPropertyName)]
        [String]$reason
    )
    process {
        try {
            $Device = Get-NinjaOneDevice -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Rebooting device {0}.' -f $Device.SystemName)
                $Resource = ('v2/device/{0}/reboot/{1}' -f $deviceId, $mode)
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
            }
            if ($reason) {
                $reasonObject = @{
                    reason = $reason
                }
                $RequestParams.Add('body', $reasonObject)
            }
            if ($PSCmdlet.ShouldProcess(('Device' -f $Device.SystemName), 'Reboot')) {
                $Alert = New-NinjaOnePOSTRequest @RequestParams
                if ($Alert -eq 204) {
                    Write-Information ('Device {0} rebooted command sent successfully.' -f $Device.SystemName)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Restart\Restart-NinjaOneDevice.ps1' 64
#Region '.\Public\Set\Set-NinjaOneDevice.ps1' 0
function Set-NinjaOneDevice {
    <#
        .SYNOPSIS
            Sets device information, like friendly name, user data etc.
        .DESCRIPTION
            Sets device information using the NinjaOne v2 API.
        .FUNCTIONALITY
            Device
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Set/device
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('snod', 'unod', 'Update-NinjaOneDevice')]
    [MetadataAttribute(
        '/v2/device/{id}',
        'patch'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The device to set the information for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # The device information body object.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [Object]$deviceInformation
    )
    process {
        try {
            $Device = Get-NinjaOneDevice -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Setting device information for device {0}.' -f $Device.SystemName)
                $Resource = ('v2/device/{0}' -f $deviceId)
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
                Body = $deviceInformation
            }
            if ($PSCmdlet.ShouldProcess(('Device {0} information' -f $Device.SystemName), 'Update')) {
                $DeviceUpdate = New-NinjaOnePATCHRequest @RequestParams
                if ($DeviceUpdate -eq 204) {
                    Write-Information ('Device {0} information updated successfully.' -f $Device.SystemName)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Set\Set-NinjaOneDevice.ps1' 55
#Region '.\Public\Set\Set-NinjaOneDeviceApproval.ps1' 0
function Set-NinjaOneDeviceApproval {
    <#
        .SYNOPSIS
            Sets the approval status of the specified device(s)
        .DESCRIPTION
            Sets the approval status of the specified device(s) using the NinjaOne v2 API.
        .FUNCTIONALITY
            Device Approval
        .OUTPUTS
            A powershell object containing the response.
        .LINK
             
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('snoda', 'unoda', 'Update-NinjaOneDeviceApproval')]
    [MetadataAttribute(
        '/v2/devices/approval/{mode}',
        'post'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The approval mode.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ValidateSet('APPROVE', 'REJECT')]
        [String]$mode,
        # The device(s) to set the approval status for.
        [Parameter(Mandatory, Position = 1, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id', 'ids')]
        [Int[]]$deviceIds
    )
    begin {
        if ($Script:NRAPIConnectionInformation.AuthMode -eq 'Client Credentials') {
            throw ('This function is not available when using client_credentials authentication. If this is unexpected please report this to api@ninjarmm.com.')
            exit 1
        }
    }
    process {
        try {
            $DeviceResults = foreach ($deviceId in $deviceIds) {
                $deviceId | Get-NinjaOneDevice
            }
            if ($DeviceResults.count -ne $deviceIds.count) {
                throw ('One or more of the specified id(s) was not found.')
            } else {
                $Resource = ('v2/devices/approval/{0}' -f $mode)
            }
            if ($deviceIds -is [array]) {
                $devices = @{
                    'devices' = $deviceIds
                }
            } else {
                $devices = @{
                    'devices' = @($deviceIds)
                }
            }
            $RequestParams = @{
                Resource = $Resource
                Body = $devices
            }
            if ($PSCmdlet.ShouldProcess('Device Approval', 'Set')) {
                $DeviceApprovals = New-NinjaOnePOSTRequest @RequestParams
                if ($DeviceApprovals -eq 204) {
                    if ($mode -eq 'APPROVE') {
                        $approvalResult = 'approved'
                    } else {
                        $approvalResult = 'rejected'
                    }
                    Write-Information ('Device(s) {0} {1} successfully.' -f (($DeviceResults | Select-Object -ExpandProperty SystemName) -join ', '), $approvalResult)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Set\Set-NinjaOneDeviceApproval.ps1' 77
#Region '.\Public\Set\Set-NinjaOneDeviceCustomFields.ps1' 0
function Set-NinjaOneDeviceCustomFields {
    <#
        .SYNOPSIS
            Sets the value of the specified device custom fields.
        .DESCRIPTION
            Sets the value of the specified device custom fields using the NinjaOne v2 API.
        .FUNCTIONALITY
            Device Custom Fields
        .OUTPUTS
            A powershell object containing the response.
        .EXAMPLE
            PS> Set-NinjaOneDeviceCustomFields -deviceId 1 -customFields @{ CustomField1 = 'Value1'; CustomField2 = 'Value2' }
             
            Set `CustomField1` to `Value1` and `CustomField2` to `Value2` respectively for the device with id 1.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Set/devicecustomfields
    #>

    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('snodcf', 'unodcf', 'Update-NinjaOneDeviceCustomFields')]
    [MetadataAttribute(
        '/v2/device/{id}/custom-fields',
        'patch'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The device to set the custom field value(s) for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # The custom field(s) body object.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [Alias('customFields', 'body')]
        [Object]$deviceCustomFields
    )
    process {
        try {
            $Device = Get-NinjaOneDevice -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Setting custom fields for device {0}.' -f $Device.SystemName)
                $Resource = ('v2/device/{0}/custom-fields' -f $deviceId)
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $RequestParams = @{
                Resource = $Resource
                Body = $deviceCustomFields
            }
            if ($PSCmdlet.ShouldProcess(('Custom Fields for {0}' -f $Device.SystemName), 'Set')) {
                $CustomFieldUpdate = New-NinjaOnePATCHRequest @RequestParams
                if ($CustomFieldUpdate -eq 204) {
                    Write-Information ('Custom fields for {0} updated successfully.' -f $Device.SystemName)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Set\Set-NinjaOneDeviceCustomFields.ps1' 60
#Region '.\Public\Set\Set-NinjaOneDeviceMaintenance.ps1' 0
function Set-NinjaOneDeviceMaintenance {
    <#
        .SYNOPSIS
            Sets a new maintenance window for the specified device(s)
        .DESCRIPTION
            Schedule a new maintenance window for the given device(s) using the NinjaOne v2 API.
        .FUNCTIONALITY
            Device Maintenance
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Set/devicemaintenance
    #>

    [CmdletBinding( SupportsShouldProcess, ConfirmImpact = 'Medium' )]
    [OutputType([Object])]
    [Alias('snodm', 'unodm', 'Update-NinjaOneDeviceMaintenance')]
    [MetadataAttribute(
        '/v2/device/{id}/maintenance',
        'put'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The device to set a maintenance window for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # The features to disable during maintenance.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [ValidateSet('ALERTS', 'PATCHING', 'AVSCANS', 'TASKS')]
        [String[]]$disabledFeatures,
        # The start date/time for the maintenance window - PowerShell DateTime object.
        [Parameter(Position = 2)]
        [DateTime]$start,
        # The start date/time for the maintenance window - Unix Epoch time.
        [Parameter(Position = 2)]
        [Int]$unixStart,
        # The end date/time for the maintenance window - PowerShell DateTime object.
        [Parameter(Position = 3)]
        [DateTime]$end,
        # The end date/time for the maintenance window - Unix Epoch time.
        [Parameter(Position = 3)]
        [Int]$unixEnd
    )
    process {
        try {
            $Device = Get-NinjaOneDevice -deviceId $deviceId
            if ($Device) {
                Write-Verbose ('Setting maintenance window for device {0}.' -f $Device.SystemName)
                if ($start) {
                    [Int]$start = ConvertTo-UnixEpoch -DateTime $start
                } elseif ($unixStart) {
                    $Parameters.Remove('unixStart') | Out-Null
                    [Int]$start = $unixStart
                }
                if ($end) {
                    [Int]$end = ConvertTo-UnixEpoch -DateTime $end
                } elseif ($unixEnd) {
                    $Parameters.Remove('unixEnd') | Out-Null
                    [Int]$end = $unixEnd
                } else {
                    throw 'An end date/time must be specified.'
                }
                $Resource = ('v2/device/{0}/maintenance' -f $deviceId)
            } else {
                throw ('Device with id {0} not found.' -f $deviceId)
            }
            $MaintenanceWindow = @{
                disabledFeatures = [Array]$disabledFeatures
                start = $start
                end = $end
            }
            $RequestParams = @{
                Resource = $Resource
                Body = $MaintenanceWindow
            }
            if ($PSCmdlet.ShouldProcess(('Device Maintenance for {0}' -f $Device.SystemName), 'Set')) {
                $DeviceMaintenance = New-NinjaOnePUTRequest @RequestParams -ErrorAction Stop
                if ($DeviceMaintenance -eq 204) {
                    Write-Information ('Maintenance window for {0} set successfully.' -f $Device.SystemName)
                }
            }
        } catch [System.IO.InvalidDataException] {
            throw $_
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Set\Set-NinjaOneDeviceMaintenance.ps1' 89
#Region '.\Public\Set\Set-NinjaOneDocumentTemplate.ps1' 0
function Set-NinjaOneDocumentTemplate {
    <#
        .SYNOPSIS
            Sets a document template.
        .DESCRIPTION
            Updates a document template using the NinjaOne v2 API.
        .FUNCTIONALITY
            Document Template
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Set/documenttemplate
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('snodt', 'unodt', 'Update-NinjaOneDocumentTemplate')]
    [MetadataAttribute(
        '/v2/document-templates/{documentTemplateId}',
        'put'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The document template id to update.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$documentTemplateId,
        # The name of the document template.
        [Parameter(Position = 1, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [String]$name,
        # The description of the document template.
        [Parameter(Position = 2, ValueFromPipelineByPropertyName)]
        [String]$description,
        # Allow multiple instances of this document template to be used per organisation.
        [Parameter(Position = 3, ValueFromPipelineByPropertyName)]
        [Switch]$allowMultiple,
        # Is this document template mandatory for all organisations.
        [Parameter(Position = 4, ValueFromPipelineByPropertyName)]
        [Switch]$mandatory,
        # The document template fields.
        [Parameter(Mandatory, Position = 5, ValueFromPipelineByPropertyName)]
        [Object[]]$fields,
        # Show the document template that was created.
        [Switch]$show
    )
    begin {
        # Validate the fields parameter.
        foreach ($field in $fields) {
            if ($field.fieldType -in ('DROPDOWN', 'MULTI_SELECT')) {
                if ($null -eq $field.fieldContent) {
                    throw 'Field content must be specified for field type {0}.' -f $field.fieldType
                } elseif ($null -eq $field.fieldContent.values) {
                    throw 'Field content values must be specified for field type {0}.' -f $field.fieldType
                }
            }
        }
    }
    process {
        try {
            $DocumentTemplate = Get-NinjaOneDocumentTemplates -documentTemplateId $documentTemplateId
            if ($DocumentTemplate) {
                Write-Verbose ('Setting document template {0}.' -f $DocumentTemplate.Name)
                $Resource = ('v2/document-templates/{1}' -f $documentTemplateId)
            } else {
                throw ('Document Template with id {0} not found.' -f $documentTemplateId)
            }
            $UpdatedDocumentTemplate = @{}
            if ($name) {
                $UpdatedDocumentTemplate.Add('name', $name)
            }
            if ($description) {
                $UpdatedDocumentTemplate.Add('description', $description)
            }
            if ($allowMultiple) {
                $UpdatedDocumentTemplate.Add('allowMultiple', $allowMultiple)
            }
            if ($mandatory) {
                $UpdatedDocumentTemplate.Add('mandatory', $mandatory)
            }
            if ($fields) {
                $UpdatedDocumentTemplate.Add('fields', $fields)
            }
            $RequestParams = @{
                Resource = $Resource
                Body = $UpdatedDocumentTemplate
            }
            if ($PSCmdlet.ShouldProcess(('Document Template {0}' -f $DocumentTemplate.Name), 'Update')) {
                $DocumentTemplateUpdate = New-NinjaOnePOSTRequest @RequestParams
                if ($show) {
                    return $DocumentTemplateUpdate    
                } elseif ($DocumentTemplateUpdate -eq 204) {
                    Write-Information ('Document Template {0} updated successfully.' -f $UpdatedDocumentTemplate.Name)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Set\Set-NinjaOneDocumentTemplate.ps1' 99
#Region '.\Public\Set\Set-NinjaOneLocation.ps1' 0
function Set-NinjaOneLocation {
    <#
        .SYNOPSIS
            Sets location information, like name, address, description etc.
        .DESCRIPTION
            Sets location information using the NinjaOne v2 API.
        .FUNCTIONALITY
            Location
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Set/location
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('snol', 'unol', 'Update-NinjaOneLocation')]
    [MetadataAttribute(
        '/v2/organization/{id}/locations/{locationId}',
        'patch'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The organisation to set the location information for.
        [Parameter(Mandatory, Position = 0, ValueFromPipelineByPropertyName)]
        [Alias('id', 'organizationId')]
        [Int]$organisationId,
        # The location to set the information for.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [Int]$locationId,
        # The location information body object.
        [Parameter(Mandatory, Position = 2, ValueFromPipelineByPropertyName)]
        [Object]$locationInformation
    )
    process {
        try {
            $Organisation = Get-NinjaOneOrganisations -OrganisationId $organisationId
            if ($Organisation) {
                Write-Verbose ('Getting location {0} from NinjaOne API.' -f $locationId)
                $Location = Get-NinjaOneLocations -OrganisationId $organisationId | Where-Object { $_.id -eq $locationId }
                if ($Location) {
                    Write-Verbose ('Setting location information for location {0}.' -f $Location.name)
                    $Resource = ('v2/organization/{0}/locations/{1}' -f $organisationId, $locationId)
                } else {
                    throw ('Location with id {0} not found in organisation {1}' -f $locationId, $Organisation.Name)
                }
            } else {
                throw ('Organisation with id {0} not found.' -f $organisationId)
            }
            $RequestParams = @{
                Resource = $Resource
                Body = $locationInformation
            }
            if ($PSCmdlet.ShouldProcess(('Location information for {0} in {1}' -f $Location.Name, $Organisation.Name), 'Update')) {
                $LocationUpdate = New-NinjaOnePATCHRequest @RequestParams
                if ($LocationUpdate -eq 204) {
                    Write-Information ('Location {0} information updated successfully.' -f $Location.Name)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Set\Set-NinjaOneLocation.ps1' 64
#Region '.\Public\Set\Set-NinjaOneLocationCustomFields.ps1' 0
function Set-NinjaOneLocationCustomFields {
    <#
        .SYNOPSIS
            Sets an location's custom fields.
        .DESCRIPTION
            Sets location custom field values using the NinjaOne v2 API.
        .FUNCTIONALITY
            Location Custom Fields
        .EXAMPLE
            PS> $LocationCustomFields = @{
                field1 = 'value1'
                field2 = 'value2'
            }
            PS> Update-NinjaOneLocationCustomFields -organisationId 1 -locationId 2 -locationCustomFields $LocationCustomFields
 
            Updates the custom fields for the location with id 2 belonging to the organisation with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Set/locationcustomfields
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('snolcf', 'unolcf', 'Update-NinjaOneLocationCustomFields')]
    [MetadataAttribute(
        '/v2/organization/{id}/location/{locationId}/custom-fields',
        'patch'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The organisation to set the custom fields for.
        [Parameter(Mandatory, Position = 0, ValueFromPipelineByPropertyName)]
        [Alias('id', 'organizationId')]
        [Int]$organisationId,
        # The location to set the custom fields for.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [Int]$locationId,
        # The organisation custom field body object.
        [Parameter(Mandatory, Position = 2, ValueFromPipelineByPropertyName)]
        [Alias('customFields', 'body')]
        [Object]$locationCustomFields
    )
    process {
        try {
            $Organisation = Get-NinjaOneOrganisations -OrganisationId $organisationId
            if ($Organisation) {
                Write-Verbose ('Getting location {0} from NinjaOne API.' -f $locationId)
                $Location = Get-NinjaOneLocations -OrganisationId $organisationId | Where-Object { $_.id -eq $locationId }
                if ($Location) {
                    Write-Verbose ('Setting location custom fields for location {0}.' -f $Location.name)
                    $Resource = ('v2/organization/{0}/locations/{1}/custom-fields' -f $organisationId, $locationId)
                } else {
                    throw ('Location with id {0} not found in organisation {1}' -f $locationId, $Organisation.Name)
                }
            } else {
                throw ('Organisation with id {0} not found.' -f $organisationId)
            }
            $RequestParams = @{
                Resource = $Resource
                Body = $locationCustomFields
            }
            if ($PSCmdlet.ShouldProcess(('Location custom fields for {0} in {1}' -f $Location.Name, $Organisation.Name), 'Update')) {
                $LocationCustomFieldsUpdate = New-NinjaOnePATCHRequest @RequestParams
                if ($LocationCustomFieldsUpdate -eq 204) {
                    Write-Information ('Location {0} custom fields updated successfully.' -f $Location.Name)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Set\Set-NinjaOneLocationCustomFields.ps1' 73
#Region '.\Public\Set\Set-NinjaOneOrganisation.ps1' 0
function Set-NinjaOneOrganisation {
    <#
        .SYNOPSIS
            Sets organisation information, like name, node approval mode etc.
        .DESCRIPTION
            Sets organisation information using the NinjaOne v2 API.
        .FUNCTIONALITY
            Organisation
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Set/organisation
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('snoo', 'Set-NinjaOneOrganization', 'unoo', 'Update-NinjaOneOrganisation', 'Update-NinjaOneOrganization')]
    [MetadataAttribute(
        '/v2/organization/{id}',
        'patch'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The organisation to set the information for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id', 'organizationId')]
        [Int]$organisationId,
        # The organisation information body object.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [Alias('organizationInformation', 'body')]
        [Object]$organisationInformation
    )
    process {
        try {
            $Organisation = Get-NinjaOneOrganisations -OrganisationId $organisationId
            if ($Organisation) {
                Write-Verbose ('Setting organisation information for organisation {0}.' -f $Organisation.Name)
                $Resource = ('v2/organization/{0}' -f $organisationId)
            } else {
                throw ('Organisation with id {0} not found.' -f $organisationId)
            }
            $RequestParams = @{
                Resource = $Resource
                Body = $organisationInformation
            }
            if ($PSCmdlet.ShouldProcess(('Organisation {0} information' -f $Organisation.Name), 'Update')) {
                $OrganisationUpdate = New-NinjaOnePATCHRequest @RequestParams
                if ($OrganisationUpdate -eq 204) {
                    Write-Information ('Organisation {0} information updated successfully.' -f $Organisation.Name)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Set\Set-NinjaOneOrganisation.ps1' 56
#Region '.\Public\Set\Set-NinjaOneOrganisationCustomFields.ps1' 0
function Set-NinjaOneOrganisationCustomFields {
    <#
        .SYNOPSIS
            Updates an organisation's custom fields.
        .DESCRIPTION
            Updates organisation custom field values using the NinjaOne v2 API.
        .FUNCTIONALITY
            Organisation Custom Fields
        .EXAMPLE
            PS> $OrganisationCustomFields = @{
                field1 = 'value1'
                field2 = 'value2'
            }
            PS> Update-NinjaOneOrganisationCustomFields -organisationId 1 -organisationCustomFields $OrganisationCustomFields
 
            Updates the custom fields for the organisation with id 1.
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Set/organisationcustomfields
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('snocf', 'Set-NinjaOneOrganizationCustomFields', 'unocf', 'Update-NinjaOneOrganisationCustomFields', 'Update-NinjaOneOrganizationCustomFields')]
    [MetadataAttribute(
        '/v2/organization/{id}/custom-fields',
        'patch'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The organisation to set the custom fields for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id', 'organizationId')]
        [Int]$organisationId,
        # The organisation custom field body object.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [Alias('customFields', 'body', 'organizationCustomFields')]
        [Object]$organisationCustomFields
    )
    process {
        try {
            $Organisation = Get-NinjaOneOrganisations -OrganisationId $organisationId
            if ($Organisation) {
                Write-Verbose ('Setting organisation custom fields for organisation {0}.' -f $Organisation.Name)
                $Resource = ('v2/organization/{0}/custom-fields' -f $organisationId)
            } else {
                throw ('Organisation with id {0} not found.' -f $organisationId)
            }
            $RequestParams = @{
                Resource = $Resource
                Body = $organisationCustomFields
            }
            if ($PSCmdlet.ShouldProcess(('Organisation {0} custom fields' -f $Organisation.Name), 'Update')) {
                $OrganisationCustomFieldsUpdate = New-NinjaOnePATCHRequest @RequestParams
                if ($OrganisationCustomFieldsUpdate -eq 204) {
                    Write-Information ('Organisation {0} custom fields updated successfully.' -f $Organisation.Name)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Set\Set-NinjaOneOrganisationCustomFields.ps1' 64
#Region '.\Public\Set\Set-NinjaOneOrganisationDocument.ps1' 0
function Set-NinjaOneOrganisationDocument {
    <#
        .SYNOPSIS
            Sets an organisation document.
        .DESCRIPTION
            Sets organisation documents using the NinjaOne v2 API.
        .FUNCTIONALITY
            Organisation Document
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Set/organisationdocument
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('snood', 'Set-NinjaOneOrganizationDocument', 'unood', 'Update-NinjaOneOrganisationDocument', 'Update-NinjaOneOrganizationDocument')]
    [MetadataAttribute(
        '/v2/organization/{organizationId}/document/{documentId}',
        'post'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The organisation to set the information for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id', 'organizationId')]
        [Int]$organisationId,
        # The organisation document id to update.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [Int]$documentId,
        # The organisation information body object.
        [Parameter(Mandatory, Position = 2, ValueFromPipelineByPropertyName)]
        [Alias('organizationDocument', 'body')]
        [Object]$organisationDocument
    )
    begin {
        if ($Script:NRAPIConnectionInformation.AuthMode -eq 'Client Credentials') {
            throw ('This function is not available when using client_credentials authentication. If this is unexpected please report this to api@ninjarmm.com.')
            exit 1
        }
    }
    process {
        try {
            $Organisation = Get-NinjaOneOrganisations -OrganisationId $organisationId
            if ($Organisation) {
                Write-Verbose ('Getting organisation document {0} from NinjaOne API.' -f $documentId)
                $Document = Get-NinjaOneOrganisationDocuments -OrganisationId $organisationId | Where-Object { $_.documentId -eq $documentId }
                if ($Document) {
                    Write-Verbose ('Setting organisation document for organisation {0}.' -f $Organisation.Name)
                    $Resource = ('v2/organization/{0}/document/{1}' -f $organisationId, $documentId)
                } else {
                    throw ('Organisation document with id {0} not found in organisation {1}' -f $documentId, $Organisation.Name)
                }
            } else {
                throw ('Organisation with id {0} not found.' -f $organisationId)
            }
            $RequestParams = @{
                Resource = $Resource
                Body = $organisationDocument
            }
            if ($PSCmdlet.ShouldProcess(('Organisation {0} document {1}' -f $Organisation.Name, $Document.Name), 'Update')) {
                $OrganisationDocumentUpdate = New-NinjaOnePOSTRequest @RequestParams
                if ($OrganisationDocumentUpdate -eq 204) {
                    Write-Information ('Organisation {0} document {1} updated successfully.' -f $Organisation.Name, $Document.Name)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Set\Set-NinjaOneOrganisationDocument.ps1' 71
#Region '.\Public\Set\Set-NinjaOneOrganisationDocuments.ps1' 0
function Set-NinjaOneOrganisationDocuments {
    <#
        .SYNOPSIS
            Sets one or more organisation documents.
        .DESCRIPTION
            Sets one or more organisation documents using the NinjaOne v2 API.
        .FUNCTIONALITY
            Organisation Documents
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Set/organisationdocument
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('snoods', 'Set-NinjaOneOrganizationDocuments', 'unoods', 'Update-NinjaOneOrganisationDocuments', 'Update-NinjaOneOrganizationDocuments')]
    [MetadataAttribute(
        '/v2/organization/documents',
        'patch'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The organisation documents to update.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('organizationDocuments', 'body')]
        [NinjaOneOrganisationDocument[]]$organisationDocuments
    )
    begin {
        if ($Script:NRAPIConnectionInformation.AuthMode -eq 'Client Credentials') {
            throw ('This function is not available when using client_credentials authentication. If this is unexpected please report this to api@ninjarmm.com.')
            exit 1
        }
    }
    process {
        try {
            foreach ($Document in $organisationDocuments) {
                Write-Verbose ('Getting organisation document {0} from NinjaOne API.' -f $Document.documentId)
                $Document = Get-NinjaOneOrganisationDocuments -OrganisationId $organisationId | Where-Object { $_.documentId -eq $documentId }
                if (-not $Document) {
                    throw ('Organisation document with id {0} not found in organisation {1}' -f $documentId, $Organisation.Name)
                    $Resource = ('v2/organization/documents' -f $organisationId, $documentId)
                    $RequestParams = @{
                        Resource = $Resource
                        Body = $organisationDocuments
                    }
                }
                if ($PSCmdlet.ShouldProcess(('Organisation {0} documents {1}' -f $organisationDocuments.organizationId, $organisationDocuments.documentId), 'Update')) {
                    $OrganisationDocumentsUpdate = New-NinjaOnePATCHRequest @RequestParams
                    if ($OrganisationDocumentsUpdate -eq 204) {
                        Write-Information ('Organisation documents updated successfully.')
                    } else {
                        return $OrganisationDocumentsUpdate
                    }
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Set\Set-NinjaOneOrganisationDocuments.ps1' 61
#Region '.\Public\Set\Set-NinjaOneOrganisationPolicies.ps1' 0
function Set-NinjaOneOrganisationPolicies {
    <#
        .SYNOPSIS
            Sets policy assignment for node role(s) for an organisation.
        .DESCRIPTION
            Sets policy assignment for node role(s) for an organisation using the NinjaOne v2 API.
        .FUNCTIONALITY
            Organisation Policies
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/set/organisationpolicies
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Array])]
    [Alias('snoop', 'Set-NinjaOneOrganizationPolicies', 'snorpa', 'Set-NinjaOneNodeRolePolicyAssignment', 'unorpa', 'Update-NinjaOneNodeRolePolicyAssignment')]
    [MetadataAttribute(
        '/v2/organization/{id}/policies',
        'put'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The organisation to update the policy assignment for.
        [Parameter(Mandatory, ParameterSetName = 'Single', Position = 0, ValueFromPipelineByPropertyName)]
        [Parameter(Mandatory, ParameterSetName = 'Multiple', Position = 0, ValueFromPipelineByPropertyName)]
        [Alias('id', 'organizationId')]
        [Int]$organisationId,
        # The node role id to update the policy assignment for.
        [Parameter(Mandatory, ParameterSetName = 'Single', Position = 1, ValueFromPipelineByPropertyName)]
        [Int]$nodeRoleId,
        # The policy id to assign to the node role.
        [Parameter(Mandatory, ParameterSetName = 'Single', Position = 2, ValueFromPipelineByPropertyName)]
        [Int]$policyId,
        # The node role policy assignments to update. Should be an array of objects with the following properties: nodeRoleId, policyId.
        [Parameter(Mandatory, ParameterSetName = 'Multiple', Position = 1, ValueFromPipelineByPropertyName)]
        [Object[]]$policyAssignments
    )
    process {
        function ValidateNodeRoleAndPolicy {
            [CmdletBinding()]
            param(
                [Int]$nodeRoleId,
                [Int]$policyId
            )
            Write-Verbose ('Getting node role {0} from NinjaOne API.' -f $nodeRoleId)
            $Role = Get-NinjaOneRoles | Where-Object { $_.id -eq $nodeRoleId }
            if ($Role) {
                Write-Verbose ('Getting policy {0} from NinjaOne API.' -f $policyId)
                $Policy = Get-NinjaOnePolicies | Where-Object { $_.id -eq $policyId }
                if ($Policy) {
                    return $Policy
                } else {
                    throw ('Policy with id {0} not found.' -f $policyId)
                }
            } else {
                throw ('Node role with id {0} not found in organisation {1}' -f $nodeRoleId, $Organisation.Name)
            }
        }
        try {
            $Organisation = Get-NinjaOneOrganisations -OrganisationId $organisationId
            if ($Organisation) {
                if ($PSCmdlet.ParameterSetName -eq 'Single') {
                    try {
                        ValidateNodeRoleAndPolicy -nodeRoleId $nodeRoleId -policyId $policyId
                        $Body = @{
                            'nodeRoleId' = $nodeRoleId
                            'policyId' = $policyId
                        }
                    } catch {
                        New-NinjaOneError -ErrorRecord $_
                    }
                } elseif ($PSCmdlet.ParameterSetName -eq 'Multiple') {
                    $Body = [System.Collections.Generic.List[Object]]::new()
                    $policyAssignments | ForEach-Object {
                        try {
                            ValidateNodeRoleAndPolicy -nodeRoleId $_.nodeRoleId -policyId $_.policyId
                            $Body.Add(
                                @{
                                    'nodeRoleId' = $_.nodeRoleId
                                    'policyId' = $_.policyId
                                }
                            ) | Out-Null
                        } catch {
                            New-NinjaOneError -ErrorRecord $_
                        }
                    }
                }
            } else {
                throw ('Organisation with id {0} not found.' -f $organisationId)
            }
            $RequestParams = @{
                Resource = $Resource
                Body = $Body
            }
            if ($PSCmdlet.ParameterSetName -eq 'Single') {
                $RequestParams.AsArray = $true
            } elseif ($PSCmdlet.ParameterSetName -eq 'Multiple') {
                $RequestParams.AsArray = $false
            }
            if ($PSCmdlet.ShouldProcess(('Assign policy {0} to role {1} for {2}.' -f $Policy.Name, $Role.Name, $Organisation.Name), 'Update')) {
                $NodeRolePolicyAssignment = New-NinjaOnePUTRequest @RequestParams
                if ($NodeRolePolicyAssignment -eq 204) {
                    Write-Information ('Policy {0} assigned to role {1} for {2}.' -f $Policy.Name, $Role.Name, $Organisation.Name)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Set\Set-NinjaOneOrganisationPolicies.ps1' 111
#Region '.\Public\Set\Set-NinjaOneTicket.ps1' 0
function Set-NinjaOneTicket {
    <#
        .SYNOPSIS
            Sets a ticket.
        .DESCRIPTION
            Sets a ticket using the NinjaOne v2 API.
        .FUNCTIONALITY
            Ticket
        .OUTPUTS
            A powershell object containing the response.
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Set/ticket
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('snot', 'unot', 'Update-NinjaOneTicket')]
    [MetadataAttribute(
        '/v2/ticketing/ticket/{ticketId}',
        'put'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The ticket Id.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$ticketId,
        # The ticket object.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [Object]$ticket 
    )
    begin {
        if ($Script:NRAPIConnectionInformation.AuthMode -eq 'Client Credentials') {
            throw ('This function is not available when using client_credentials authentication. If this is unexpected please report this to api@ninjarmm.com.')
            exit 1
        }
    }
    process {
        try {
            $Ticket = Get-NinjaOneTickets -ticketId $ticketId
            if ($Ticket) {
                Write-Verbose ('Updating ticket {0}.' -f $Ticket.Subject)
                $Resource = "v2/ticketing/ticket/$ticketId"
            } else {
                throw ('Ticket with id { 0 } not found.' -f $ticketId)
            }
            $RequestParams = @{
                Resource = $Resource
                Body = $ticket
            }
            if ($PSCmdlet.ShouldProcess(('Ticket {0} ({1})' -f $Ticket.Subject, $ticketId), 'Update')) {
                $TicketUpdate = New-NinjaOnePUTRequest @RequestParams
                if ($TicketUpdate -eq 204) {
                    Write-Information ('Ticket {0} ({1}) updated successfully.' -f $Ticket.Subject, $ticketId)
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Set\Set-NinjaOneTicket.ps1' 61
#Region '.\Public\Set\Set-NinjaOneWindowsServiceConfiguration.ps1' 0
function Set-NinjaOneWindowsServiceConfiguration {
    <#
        .SYNOPSIS
            Sets the configuration of the given Windows Service for the given device.
        .DESCRIPTION
            Sets the configuration of the Windows Service for a single device using the NinjaOne v2 API.
        .FUNCTIONALITY
            Windows Service Configuration
        .OUTPUTS
            A powershell object containing the response.
        .EXAMPLE
            Set-NinjaOneWindowsServiceConfiguration -deviceId "12345" -serviceId "NinjaRMMAgent" -Configuration @{ startType = "AUTO_START"; userName = "LocalSystem" }
        .LINK
            https://docs.homotechsual.dev/modules/ninjaone/commandlets/Set/windowsserviceconfiguration
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    [OutputType([Object])]
    [Alias('snowsc', 'unowsc', 'Update-NinjaOneWindowsServiceConfiguration')]
    [MetadataAttribute(
        '/v2/device/{id}/windows-service/{serviceId}/configure',
        'post'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The device to change servce configuration for.
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [Alias('id')]
        [Int]$deviceId,
        # The service to alter configuration for.
        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [Int]$serviceId,
        # The configuration to set.
        [Parameter(Mandatory, Position = 2, ValueFromPipelineByPropertyName)]
        [Object]$configuration
    )
    process {
        try {
            $Resource = ('v2/device/{0}/windows-service/{1}/configure' -f $deviceId, $serviceId)
            $RequestParams = @{
                Resource = $Resource
                Body = $configuration
            }
            if ($PSCmdlet.ShouldProcess(('Service {0} configuration' -f $serviceId), 'Set')) {
                $ServiceConfiguration = New-NinjaOnePOSTRequest @RequestParams
                if ($ServiceConfiguration -eq 204) {
                    $OIP = $InformationPreference
                    $InformationPreference = 'Continue'
                    Write-Information ('Service {0} configuration updated successfully.' -f $serviceId)
                    $InformationPreference = $OIP
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Set\Set-NinjaOneWindowsServiceConfiguration.ps1' 57
#Region '.\Public\Set\Update-NinjaOneWebhook.ps1' 0
function Update-NinjaOneWebhook {
    <#
        .SYNOPSIS
            Update webhook configuration for the current application/API client.
        .DESCRIPTION
            Updates webhook configuration for the current application/API client using the NinjaOne v2 API.
        .FUNCTIONALITY
            Webhook
        .OUTPUTS
            A powershell object containing the response.
    #>

    [CmdletBinding( SupportsShouldProcess, ConfirmImpact = 'Medium' )]
    [OutputType([Object])]
    [Alias('unow', 'snow', 'Set-NinjaOneWebhook')]
    [MetadataAttribute(
        '/v2/webhook',
        'put'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'Uses dynamic parameter parsing.')]
    Param(
        # The webhook configuration object.
        [Parameter( Mandatory )]
        [Object]$webhookConfiguration
    )
    process {
        try {
            $Resource = 'v2/webhook'
            $RequestParams = @{
                Resource = $Resource
                Body = $webhookConfiguration
            }
            if ($PSCmdlet.ShouldProcess('Webhook Configuration', 'Update')) {
                $WebhookUpdate = New-NinjaOnePUTRequest @RequestParams
                if ($WebhookUpdate -eq 204) {
                    Write-Information 'Webhook configuration updated successfully.'
                }
            }
        } catch {
            New-NinjaOneError -ErrorRecord $_
        }
    }
}
#EndRegion '.\Public\Set\Update-NinjaOneWebhook.ps1' 43