PSc8y.psm1


#########################################################################################
#
# PSc8y Module
#
#########################################################################################

#Microsoft.PowerShell.Core\Set-StrictMode -Version Latest

#region script variables

$script:IsWindows = (-not (Get-Variable -Name IsWindows -ErrorAction Ignore)) -or $IsWindows
$script:IsLinux = (Get-Variable -Name IsLinux -ErrorAction Ignore) -and $IsLinux
$script:IsMacOS = (Get-Variable -Name IsMacOS -ErrorAction Ignore) -and $IsMacOS
$script:IsCoreCLR = $PSVersionTable.ContainsKey('PSEdition') -and $PSVersionTable.PSEdition -eq 'Core'
$script:Dependencies = Join-Path -Path $PSScriptRoot -ChildPath "Dependencies"
$script:Templates = Join-Path -Path $PSScriptRoot -ChildPath "Templates"

#endregion

#region Private Functions
Function Format-CommandParameter {
    [cmdletbinding()]
    Param(
        [Parameter(
            Mandatory = $true,
            Position = 0
        )]
        [object] $ParameterList
    )
    $Parameters = @{}

    $ParameterList = (Get-Command -Name $CommandName).Parameters

    # Grab each parameter value, using Get-Variable
    foreach ($Name in ($ParameterList.Keys -notmatch "^Raw$")) {
        $iParam = Get-Variable -Name $Name -ErrorAction SilentlyContinue;

        if ($iParam.Value -is [Switch]) {
            if ($iParam.Value.IsPresent -and $iParam) {
                $Parameters[$Name] = $true
            }
        } elseif ($iParam.Value -is [hashtable]) {
            $Parameters[$Name] = "{0}" -f ((ConvertTo-Json $iParam.Value -Depth 100 -Compress) -replace '"', '\"')
        } elseif ($iParam.Value -is [datetime]) {
            $Parameters[$Name] = Format-Date $iParam.Value
        } else {
            if ("$iParam" -notmatch "^$") {
                $Parameters[$Name] = $iParam.Value
            }
        }
    }

    $Parameters
}
Function Format-ConfirmationMessage {
<#
.SYNOPSIS
Format the confirmation message from a cmdlet name and input object
#>

    [cmdletbinding()]
    Param(
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            Position = 0)]
        [string] $Name,

        [Parameter(
            Mandatory = $true,
            Position = 1)]
        [AllowNull()]
        [object[]] $inputObject,

        [string] $IgnorePrefix = ""
    )

    Process {
    
        $parts = New-Object System.Collections.ArrayList;

        # Remove fully qualified module name
        $Name = $Name -replace "^\w+\\", ""

        foreach ($item in ($Name -csplit '(?=[A-Z\-])')) {
            if ($item -eq "-" -or $item -eq "" -or $item -eq $IgnorePrefix) {
                continue;
            }
            $item = $item -replace "^-", ""
            if ($parts.Count -eq 0) {
                $null = $parts.Add($item);
            } else {
                $null = $parts.Add("$item".ToLowerInvariant());
            }
        }

        foreach ($item in $inputObject) {
            if ($item -is [string]) {
                if ($item.StartsWith("{")) {
                    $item = ConvertFrom-Json $item -Depth 100 -WarningAction SilentlyContinue -ErrorAction SilentlyContinue
                }
            }
            if ($item.id -and $item.name) {
                $null = $parts.Add(("[{1} ({0})]" -f $item.id, $item.name))
            } elseif ($item.id) {
                $null = $parts.Add(("[{0}]" -f $item.id))
            } elseif ($item) {
                $null = $parts.Add("[{0}]" -f $item)
            } else {
                # Don't add anything
            }
        }

        $parts -join " "
    }
}
Function Get-ClientOutputOption {
    [cmdletbinding()]
    Param(
        
        [Parameter(
            Mandatory = $true,
            Position = 0)]
        [hashtable]
        $BoundParameters
    )

    Process {
        $ConvertToPS = $BoundParameters["AsHashTable"] `
            -or $BoundParameters["AsPSObject"]
        $UsePowershellTypes = $BoundParameters["Select"]

        [PSCustomObject]@{
            ConvertToPS = $ConvertToPS
            UsePowershellTypes = $UsePowershellTypes
        }
    }   
}
Function Get-NestedProperty {
    [cmdletbinding()]
    Param(
        [Parameter(
            Mandatory = $true,
            Position = 0
        )]
        [AllowNull()]
        [AllowEmptyCollection()]
        [object[]] $InputObject,

        [Parameter(
            Mandatory = $true,
            Position = 1
        )]
        [AllowNull()]
        [AllowEmptyString()]
        [string] $Name
    )

    if (!$Name) {
        $null
        return
    }

    $Output = $InputObject

    foreach ($part in ($Name -split "\.")) {
        if ($null -eq $Output.$part -and $null -eq $Output.$part.Count) {
            $Output = $null
            break;
        }
        $Output = $Output.$part
    }
    $Output
}
Function New-ClientArgument {
    <#
    .SYNOPSIS
    Run a Cumulocity client command using the c8y binary. Only intended for internal usage only

    .DESCRIPTION
    The command is a wrapper around the c8y binary which is used to send the rest request to Cumulocity.

    The result will also be parsed, and Powershell type information will be added to the result set, so
    only relevant information is shown.
    #>

    [cmdletbinding()]
    Param(
        # Parameters which should be passed to the c8y binary
        # The full parameter name should be used (i.e. --header, and not -H)
        [hashtable] $Parameters,

        # Command
        [string] $Command,

        # List of names to exclude when parsing the parameters
        [string[]] $Exclude
    )

    Process {

        $c8yargs = New-Object System.Collections.ArrayList
        $BoundParameters = @{} + $Parameters

        # strip automatic variables
        $BoundParameters.Keys -match "(Verbose|WhatIf|WhatIfFormat|Variable|Action|Buffer|Debug|AsHashtable|AsPSObject|Color|Pretty)$" | ForEach-Object {
            $BoundParameters.Remove($_)
        }

        # Exclude select keys
        if ($Exclude -and $Exclude.Count -gt 0) {
            foreach ($key in (@() + $BoundParameters.Keys)) {
                if ($Exclude -contains $key) {
                    $BoundParameters.Remove($key)
                }
            }
        }

        foreach ($iKey in $BoundParameters.Keys) {
            $Value = $BoundParameters[$iKey]

            if ($null -ne $Value) {
                $key = $iKey[0].ToString().ToLowerInvariant() + $iKey.SubString(1)

                switch ($Value) {
                    # boolean
                    { $Value -is [bool] -and $Value } {
                        $null = $c8yargs.AddRange(@("--${key}"))
                        break
                    }

                    { $Value -is [switch] } {
                        if ($Value) {
                            $null = $c8yargs.AddRange(@("--${key}"))
                        } else {
                            $null = $c8yargs.AddRange(@("--${key}=false"))
                        }
                        break
                    }

                    { $Value -is [int] } {
                        $null = $c8yargs.AddRange(@("--${key}=$Value"))
                        break
                    }

                    # json like values
                    { $key -eq "data" -or $Value -is [hashtable] -or $Value -is [PSCustomObject] } {
                        $ArgValue = ConvertTo-JsonArgument $Value
                        # due to cli parsing, data needs to be sent using "="
                        $null = $c8yargs.AddRange(@("--${key}", $ArgValue))
                        break
                    }

                    { $Value -is [array] } {
                        $items = Expand-Id $Value
                        if ($items.Count -eq 1) {
                            $null = $c8yargs.Add("--${key}=$($items -join ',')")

                        } elseif ($items.Count -gt 1) {
                            $null = $c8yargs.Add("--${key}=`"$($items -join ',')`"")
                        }
                        break
                    }

                    { $Value -match " " -and ![string]::IsNullOrWhiteSpace($Value) } {
                        $null = $c8yargs.Add("--${key}=`"$Value`"")
                        break
                    }

                    default {
                        if (![string]::IsNullOrWhiteSpace($Value)) {
                            $null = $c8yargs.Add("--${key}=$Value")
                        }
                    }
                }
            }
        }

        if ($DebugPreference -ne "SilentlyContinue") {
            $null = $c8yargs.Add("--debug")
        }

        if (-Not $Parameters.ContainsKey("Dry") -and $WhatIfPreference) {
            $null = $c8yargs.Add("--dry")
        }

        if (-Not $Parameters.ContainsKey("DryFormat") -and $Parameters["WhatIfFormat"]) {
            $null = $c8yargs.Add(("--dryFormat={0}" -f $Parameters["WhatIfFormat"]))
        }

        # Always use verbose as information is extracted from it
        if ($VerbosePreference) {
            $null = $c8yargs.Add("--verbose")
        }

        if ($Parameters["WithTotalPages"]) {
            $null = $c8yargs.Add("--raw")
        }

        if ($Parameters["Color"]) {
            $null = $c8yargs.Add("--noColor=false")
        } elseif ($Parameters["NoColor"]) {
            $null = $c8yargs.Add("--noColor")
        }

        if ($Parameters["Pretty"]) {
            $null = $c8yargs.Add("--compact=false")
        }

        ,$c8yargs
    }
}
Function New-DynamicParam {
    <#
        .SYNOPSIS
            Helper function to simplify creating dynamic parameters
        
        .DESCRIPTION
            Helper function to simplify creating dynamic parameters
    
            Example use cases:
                Include parameters only if your environment dictates it
                Include parameters depending on the value of a user-specified parameter
                Provide tab completion and intellisense for parameters, depending on the environment
    
            Please keep in mind that all dynamic parameters you create will not have corresponding variables created.
               One of the examples illustrates a generic method for populating appropriate variables from dynamic parameters
               Alternatively, manually reference $PSBoundParameters for the dynamic parameter value
    
        .NOTES
            Credit to http://jrich523.wordpress.com/2013/05/30/powershell-simple-way-to-add-dynamic-parameters-to-advanced-function/
                Added logic to make option set optional
                Added logic to add RuntimeDefinedParameter to existing DPDictionary
                Added a little comment based help
    
            Credit to BM for alias and type parameters and their handling
    
        .PARAMETER Name
            Name of the dynamic parameter
    
        .PARAMETER Type
            Type for the dynamic parameter. Default is string
    
        .PARAMETER Alias
            If specified, one or more aliases to assign to the dynamic parameter
    
        .PARAMETER ValidateSet
            If specified, set the ValidateSet attribute of this dynamic parameter
    
        .PARAMETER Mandatory
            If specified, set the Mandatory attribute for this dynamic parameter
    
        .PARAMETER ParameterSetName
            If specified, set the ParameterSet attribute for this dynamic parameter
    
        .PARAMETER Position
            If specified, set the Position attribute for this dynamic parameter
    
        .PARAMETER ValueFromPipelineByPropertyName
            If specified, set the ValueFromPipelineByPropertyName attribute for this dynamic parameter
    
        .PARAMETER HelpMessage
            If specified, set the HelpMessage for this dynamic parameter
        
        .PARAMETER DPDictionary
            If specified, add resulting RuntimeDefinedParameter to an existing RuntimeDefinedParameterDictionary (appropriate for multiple dynamic parameters)
            If not specified, create and return a RuntimeDefinedParameterDictionary (appropriate for a single dynamic parameter)
    
            See final example for illustration
    
        .EXAMPLE
            
            function Show-Free
            {
                [CmdletBinding()]
                Param()
                DynamicParam {
                    $options = @( gwmi win32_volume | %{$_.driveletter} | sort )
                    New-DynamicParam -Name Drive -ValidateSet $options -Position 0 -Mandatory
                }
                begin{
                    #have to manually populate
                    $drive = $PSBoundParameters.drive
                }
                process{
                    $vol = gwmi win32_volume -Filter "driveletter='$drive'"
                    "{0:N2}% free on {1}" -f ($vol.Capacity / $vol.FreeSpace),$drive
                }
            } #Show-Free
    
            Show-Free -Drive <tab>
    
        # This example illustrates the use of New-DynamicParam to create a single dynamic parameter
        # The Drive parameter ValidateSet populates with all available volumes on the computer for handy tab completion / intellisense
    
        .EXAMPLE
    
        # I found many cases where I needed to add more than one dynamic parameter
        # The DPDictionary parameter lets you specify an existing dictionary
        # The block of code in the Begin block loops through bound parameters and defines variables if they don't exist
    
            Function Test-DynPar{
                [cmdletbinding()]
                param(
                    [string[]]$x = $Null
                )
                DynamicParam
                {
                    #Create the RuntimeDefinedParameterDictionary
                    $Dictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
            
                    New-DynamicParam -Name AlwaysParam -ValidateSet @( gwmi win32_volume | %{$_.driveletter} | sort ) -DPDictionary $Dictionary
    
                    #Add dynamic parameters to $dictionary
                    if($x -eq 1)
                    {
                        New-DynamicParam -Name X1Param1 -ValidateSet 1,2 -mandatory -DPDictionary $Dictionary
                        New-DynamicParam -Name X1Param2 -DPDictionary $Dictionary
                        New-DynamicParam -Name X3Param3 -DPDictionary $Dictionary -Type DateTime
                    }
                    else
                    {
                        New-DynamicParam -Name OtherParam1 -Mandatory -DPDictionary $Dictionary
                        New-DynamicParam -Name OtherParam2 -DPDictionary $Dictionary
                        New-DynamicParam -Name OtherParam3 -DPDictionary $Dictionary -Type DateTime
                    }
            
                    #return RuntimeDefinedParameterDictionary
                    $Dictionary
                }
                Begin
                {
                    #This standard block of code loops through bound parameters...
                    #If no corresponding variable exists, one is created
                        #Get common parameters, pick out bound parameters not in that set
                        Function _temp { [cmdletbinding()] param() }
                        $BoundKeys = $PSBoundParameters.keys | Where-Object { (get-command _temp | select -ExpandProperty parameters).Keys -notcontains $_}
                        foreach($param in $BoundKeys)
                        {
                            if (-not ( Get-Variable -name $param -scope 0 -ErrorAction SilentlyContinue ) )
                            {
                                New-Variable -Name $Param -Value $PSBoundParameters.$param
                                Write-Verbose "Adding variable for dynamic parameter '$param' with value '$($PSBoundParameters.$param)'"
                            }
                        }
    
                    #Appropriate variables should now be defined and accessible
                        Get-Variable -scope 0
                }
            }
    
        # This example illustrates the creation of many dynamic parameters using New-DynamicParam
            # You must create a RuntimeDefinedParameterDictionary object ($dictionary here)
            # To each New-DynamicParam call, add the -DPDictionary parameter pointing to this RuntimeDefinedParameterDictionary
            # At the end of the DynamicParam block, return the RuntimeDefinedParameterDictionary
            # Initialize all bound parameters using the provided block or similar code
    
        .FUNCTIONALITY
            PowerShell Language
    
    #>

    param(
        
        [string]
        $Name,
        
        [System.Type]
        $Type = [string],
    
        [string[]]
        $Alias = @(),
    
        [string[]]
        $ValidateSet,
        
        [switch]
        $Mandatory,
        
        [string]
        $ParameterSetName="__AllParameterSets",
        
        [int]
        $Position,
        
        [switch]
        $ValueFromPipelineByPropertyName,
        
        [string]
        $HelpMessage,
    
        [validatescript({
            if(-not ( $_ -is [System.Management.Automation.RuntimeDefinedParameterDictionary] -or -not $_) )
            {
                Throw "DPDictionary must be a System.Management.Automation.RuntimeDefinedParameterDictionary object, or not exist"
            }
            $True
        })]
        $DPDictionary = $false
     
    )
        #Create attribute object, add attributes, add to collection
            $ParamAttr = New-Object System.Management.Automation.ParameterAttribute
            $ParamAttr.ParameterSetName = $ParameterSetName
            if($mandatory)
            {
                $ParamAttr.Mandatory = $True
            }
            if($Position -ne $null)
            {
                $ParamAttr.Position=$Position
            }
            if($ValueFromPipelineByPropertyName)
            {
                $ParamAttr.ValueFromPipelineByPropertyName = $True
            }
            if($HelpMessage)
            {
                $ParamAttr.HelpMessage = $HelpMessage
            }
     
            $AttributeCollection = New-Object 'Collections.ObjectModel.Collection[System.Attribute]'
            $AttributeCollection.Add($ParamAttr)
        
        #param validation set if specified
            if($ValidateSet)
            {
                $ParamOptions = New-Object System.Management.Automation.ValidateSetAttribute -ArgumentList $ValidateSet
                $AttributeCollection.Add($ParamOptions)
            }
    
        #Aliases if specified
            if($Alias.count -gt 0) {
                $ParamAlias = New-Object System.Management.Automation.AliasAttribute -ArgumentList $Alias
                $AttributeCollection.Add($ParamAlias)
            }
    
     
        #Create the dynamic parameter
            $Parameter = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter -ArgumentList @($Name, $Type, $AttributeCollection)
        
        #Add the dynamic parameter to an existing dynamic parameter dictionary, or create the dictionary and add it
            if($DPDictionary)
            {
                $DPDictionary.Add($Name, $Parameter)
            }
            else
            {
                $Dictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
                $Dictionary.Add($Name, $Parameter)
                $Dictionary
            }
    }
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Use-CallerPreference
{
    <#
    .SYNOPSIS
    Sets the PowerShell preference variables in a module's function based on the callers preferences.
 
    .DESCRIPTION
    Script module functions do not automatically inherit their caller's variables, including preferences set by common parameters. This means if you call a script with switches like `-Verbose` or `-WhatIf`, those that parameter don't get passed into any function that belongs to a module.
 
    When used in a module function, `Use-CallerPreference` will grab the value of these common parameters used by the function's caller:
 
     * ErrorAction
     * Debug
     * Confirm
     * InformationAction
     * Verbose
     * WarningAction
     * WhatIf
     
    This function should be used in a module's function to grab the caller's preference variables so the caller doesn't have to explicitly pass common parameters to the module function.
 
    This function is adapted from the [`Get-CallerPreference` function written by David Wyatt](https://gallery.technet.microsoft.com/scriptcenter/Inherit-Preference-82343b9d).
 
    There is currently a [bug in PowerShell](https://connect.microsoft.com/PowerShell/Feedback/Details/763621) that causes an error when `ErrorAction` is implicitly set to `Ignore`. If you use this function, you'll need to add explicit `-ErrorAction $ErrorActionPreference` to every function/cmdlet call in your function. Please vote up this issue so it can get fixed.
 
    .LINK
    about_Preference_Variables
 
    .LINK
    about_CommonParameters
 
    .LINK
    https://gallery.technet.microsoft.com/scriptcenter/Inherit-Preference-82343b9d
 
    .LINK
    http://powershell.org/wp/2014/01/13/getting-your-script-module-functions-to-inherit-preference-variables-from-the-caller/
 
    .EXAMPLE
    Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
 
    Demonstrates how to set the caller's common parameter preference variables in a module function.
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        #[Management.Automation.PSScriptCmdlet]
        # The module function's `$PSCmdlet` object. Requires the function be decorated with the `[CmdletBinding()]` attribute.
        $Cmdlet,

        [Parameter(Mandatory = $true)]
        [Management.Automation.SessionState]
        # The module function's `$ExecutionContext.SessionState` object. Requires the function be decorated with the `[CmdletBinding()]` attribute.
        #
        # Used to set variables in its callers' scope, even if that caller is in a different script module.
        $SessionState
    )

    Set-StrictMode -Version 'Latest'

    # List of preference variables taken from the about_Preference_Variables and their common parameter name (taken from about_CommonParameters).
    $commonPreferences = @{
                              'ErrorActionPreference' = 'ErrorAction';
                              'DebugPreference' = 'Debug';
                              'ConfirmPreference' = 'Confirm';
                              'InformationPreference' = 'InformationAction';
                              'VerbosePreference' = 'Verbose';
                              'WarningPreference' = 'WarningAction';
                              'WhatIfPreference' = 'WhatIf';
                          }

    foreach( $prefName in $commonPreferences.Keys )
    {
        $parameterName = $commonPreferences[$prefName]

        # Don't do anything if the parameter was passed in.
        if( $Cmdlet.MyInvocation.BoundParameters.ContainsKey($parameterName) )
        {
            continue
        }

        $variable = $Cmdlet.SessionState.PSVariable.Get($prefName)
        # Don't do anything if caller didn't use a common parameter.
        if( -not $variable )
        {
            continue
        }

        if( $SessionState -eq $ExecutionContext.SessionState )
        {
            if ($variable.Value -ne "") {
                Set-Variable -Scope 1 -Name $variable.Name -Value $variable.Value -Force -Confirm:$false -WhatIf:$false
            }
        }
        else
        {
            if ($variable.Value -ne "") {
                $SessionState.PSVariable.Set($variable.Name, $variable.Value)
            }
        }
    }

}
#Requires -Version 5.0
<#
    .SYNOPSIS
        Writes messages to the information stream, optionally with
        color when written to the host.
    .DESCRIPTION
        An alternative to Write-Host which will write to the information stream
        and the host (optionally in colors specified) but will honor the
        $InformationPreference of the calling context.
        In PowerShell 5.0+ Write-Host calls through to Write-Information but
        will _always_ treats $InformationPreference as 'Continue', so the caller
        cannot use other options to the preference variable as intended.
    
    .NOTES
        Reference: https://blog.kieranties.com/2018/03/26/write-information-with-colours
#>

Function Write-InformationColored {
    [CmdletBinding()]
    param(
        # Message data
        [Parameter(Mandatory = $true)]
        [Object] $MessageData,

        # Foreground color
        [System.ConsoleColor] $ForegroundColor, # Make sure we use the current colours by default

        # Background color
        [System.ConsoleColor] $BackgroundColor,

        # Do not append a newline character
        [Switch] $NoNewline,

        # Show the information on the host by default. This will set -InformationAction to continue
        # so that the message is displayed on the console
        [switch] $ShowHost,

        # Tags to add to the information
        [string[]] $Tags
    )

    $msg = [System.Management.Automation.HostInformationMessage]@{
        Message         = $MessageData
        ForegroundColor = $ForegroundColor
        BackgroundColor = $BackgroundColor
        NoNewline       = $NoNewline.IsPresent
    }

    $options = @{
        MessageData = $msg
        Tags = $Tags
    }

    if ($ShowHost) {
        $options["InformationAction"] = "Continue"
    }

    Write-Information @options
}

#endregion

#region Public Functions
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Add-AssetToGroup {
<#
.SYNOPSIS
Assign child asset

.DESCRIPTION
Assigns a group or device to an existing group and marks them as assets

.LINK
c8y inventory assets assign

.EXAMPLE
PS> Add-AssetToGroup -Group $Group1.id -NewChildGroup $Group2.id

Create group hierarchy (parent group -> child group)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Group (required)
        [Parameter(Mandatory = $true)]
        [object[]]
        $Group,

        # New child device to be added to the group as an asset
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $NewChildDevice,

        # New child device group to be added to the group as an asset
        [Parameter()]
        [object[]]
        $NewChildGroup
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "inventory assets assign"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObjectReference+json"
            ItemType = "application/vnd.com.nsn.cumulocity.managedObject+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $NewChildDevice `
            | Group-ClientRequests `
            | c8y inventory assets assign $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $NewChildDevice `
            | Group-ClientRequests `
            | c8y inventory assets assign $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Add-ChildAddition {
<#
.SYNOPSIS
Assign child addition

.DESCRIPTION
Add an existing managed object as a child addition to another existing managed object

.LINK
c8y inventory additions assign

.EXAMPLE
PS> Add-ChildAddition -Id $software.id -NewChild $version.id

Add a related managed object as a child to an existing managed object


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Managed object id where the child addition will be added to (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # New managed object that will be added as a child addition (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $NewChild
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "inventory additions assign"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObjectReference+json"
            ItemType = "application/vnd.com.nsn.cumulocity.managedObject+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $NewChild `
            | Group-ClientRequests `
            | c8y inventory additions assign $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $NewChild `
            | Group-ClientRequests `
            | c8y inventory additions assign $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Add-ChildDeviceToDevice {
<#
.SYNOPSIS
Assign child device

.DESCRIPTION
Create a child device reference

.LINK
c8y devices assignChild

.EXAMPLE
PS> Add-ChildDeviceToDevice -Device $Device.id -NewChild $ChildDevice.id

Assign a device as a child device to an existing device

.EXAMPLE
PS> Get-ManagedObject -Id $ChildDevice.id | Add-ChildDeviceToDevice -Device $Device.id

Assign a device as a child device to an existing device (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device. (required)
        [Parameter(Mandatory = $true)]
        [object[]]
        $Device,

        # New child device (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $NewChild
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devices assignChild"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObjectReference+json"
            ItemType = "application/vnd.com.nsn.cumulocity.managedObject+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $NewChild `
            | Group-ClientRequests `
            | c8y devices assignChild $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $NewChild `
            | Group-ClientRequests `
            | c8y devices assignChild $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Add-ChildGroupToGroup {
<#
.SYNOPSIS
Assign child group

.DESCRIPTION
Assigns a group to a group. The group will be a childAsset of the group

.LINK
c8y devicegroups assignGroup

.EXAMPLE
PS> Add-ChildGroupToGroup -Group $Group.id -NewChildGroup $ChildGroup1.id

Add a group to a group as a child

.EXAMPLE
PS> Get-DeviceGroup $SubGroup1.name, $SubGroup2.name | Add-ChildGroupToGroup -Group $CustomGroup.id

Add multiple devices to a group. Alternatively `Get-DeviceCollection` can be used
to filter for a collection of devices and assign the results to a single group.



#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Group (required)
        [Parameter(Mandatory = $true)]
        [object[]]
        $Group,

        # New child group to be added to the group as an child asset (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $NewChildGroup
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devicegroups assignGroup"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObjectReference+json"
            ItemType = "application/vnd.com.nsn.cumulocity.managedObject+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $NewChildGroup `
            | Group-ClientRequests `
            | c8y devicegroups assignGroup $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $NewChildGroup `
            | Group-ClientRequests `
            | c8y devicegroups assignGroup $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Add-DeviceToGroup {
<#
.SYNOPSIS
Assign device to group

.DESCRIPTION
Assigns a device to a group. The device will be a childAsset of the group

.LINK
c8y devicegroups assignDevice

.EXAMPLE
PS> Add-DeviceToGroup -Group $Group.id -NewChildDevice $Device.id

Add a device to a group

.EXAMPLE
PS> Add-DeviceToGroup -Group $Group -NewChildDevice $Device

Add a device to a group by passing device and groups instead of an id or name

.EXAMPLE
PS> Get-Device $Device1.name, $Device2.name | Add-DeviceToGroup -Group $Group.id

Add multiple devices to a group. Alternatively `Get-DeviceCollection` can be used
to filter for a collection of devices and assign the results to a single group.



#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Group (required)
        [Parameter(Mandatory = $true)]
        [object[]]
        $Group,

        # New device to be added to the group as an child asset (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $NewChildDevice
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devicegroups assignDevice"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObjectReference+json"
            ItemType = "application/vnd.com.nsn.cumulocity.managedObject+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $NewChildDevice `
            | Group-ClientRequests `
            | c8y devicegroups assignDevice $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $NewChildDevice `
            | Group-ClientRequests `
            | c8y devicegroups assignDevice $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Add-RoleToGroup {
<#
.SYNOPSIS
Add role to user group

.DESCRIPTION
Add a role to an existing user group

.LINK
c8y userroles addRoleToGroup

.EXAMPLE
PS> Add-RoleToGroup -Group "${NamePattern}*" -Role "*ALARM_*"

Add a role to a group using wildcards

.EXAMPLE
PS> Get-RoleCollection -PageSize 100 | Where-Object Name -like "*ALARM*" | Add-RoleToGroup -Group "${NamePattern}*"

Add a role to a group using wildcards (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Group ID (required)
        [Parameter(Mandatory = $true)]
        [object[]]
        $Group,

        # User role id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Role,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "userroles addRoleToGroup"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.roleReference+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Role `
            | Group-ClientRequests `
            | c8y userroles addRoleToGroup $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Role `
            | Group-ClientRequests `
            | c8y userroles addRoleToGroup $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Add-RoleToUser {
<#
.SYNOPSIS
Add Role to user

.DESCRIPTION
Add a role to an existing user

.LINK
c8y userroles addRoleToUser

.EXAMPLE
PS> Add-RoleToUser -User $User.id -Role "ROLE_ALARM_READ"

Add a role (ROLE_ALARM_READ) to a user

.EXAMPLE
PS> Add-RoleToUser -User "customUser_*" -Role "*ALARM_*"

Add a role to a user using wildcards

.EXAMPLE
PS> Get-RoleCollection -PageSize 100 | Where-Object Name -like "*ALARM*" | Add-RoleToUser -User "customUser_*"

Add a role to a user using wildcards (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # User prefix or full username (required)
        [Parameter(Mandatory = $true)]
        [object[]]
        $User,

        # User role id
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Role,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "userroles addRoleToUser"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.roleReference+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Role `
            | Group-ClientRequests `
            | c8y userroles addRoleToUser $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Role `
            | Group-ClientRequests `
            | c8y userroles addRoleToUser $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Add-UserToGroup {
<#
.SYNOPSIS
Add user to group

.DESCRIPTION
Add an existing user to a group

.LINK
c8y userreferences addUserToGroup

.EXAMPLE
PS> Add-UserToGroup -Group $Group.id -User $User.id

Add a user to a user group


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Group ID (required)
        [Parameter(Mandatory = $true)]
        [object[]]
        $Group,

        # User id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $User,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "userreferences addUserToGroup"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.userReference+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $User `
            | Group-ClientRequests `
            | c8y userreferences addUserToGroup $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $User `
            | Group-ClientRequests `
            | c8y userreferences addUserToGroup $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Approve-DeviceRequest {
<#
.SYNOPSIS
Approve device request

.DESCRIPTION
Approve a new device request. Note: a device can only be approved if the platform has received a request for device credentials.

.LINK
c8y deviceregistration approve

.EXAMPLE
PS> Approve-DeviceRequest -Id $DeviceRequest.id

Approve a new device request


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device identifier (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Status of registration
        [Parameter()]
        [ValidateSet('ACCEPTED')]
        [string]
        $Status
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "deviceregistration approve"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.newDeviceRequest+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y deviceregistration approve $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y deviceregistration approve $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Copy-Application {
<#
.SYNOPSIS
Copy application

.DESCRIPTION
A POST request to the 'clone' resource creates a new application based on an already existing one.
The properties are copied to the newly created application. For name, key and context path a 'clone' prefix is added in order to be unique.
If the target application is hosted and has an active version, the new application will have the active version with the same content.
The response contains a representation of the newly created application.
Required role ROLE_APPLICATION_MANAGEMENT_ADMIN


.LINK
c8y applications copy

.EXAMPLE
PS> Copy-Application -Id $App.id

Copy an existing application


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Application id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "applications copy"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.application+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y applications copy $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y applications copy $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Disable-Application {
<#
.SYNOPSIS
Unsubscribe application

.DESCRIPTION
Disable/unsubscribe an application from a tenant

.LINK
c8y tenants disableApplication

.EXAMPLE
PS> Disable-Application -Tenant mycompany -Application myMicroservice

Disable an application of a tenant


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Application id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Application,

        # Tenant id. Defaults to current tenant (based on credentials)
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenants disableApplication"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Application `
            | Group-ClientRequests `
            | c8y tenants disableApplication $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Application `
            | Group-ClientRequests `
            | c8y tenants disableApplication $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Disable-Microservice {
<#
.SYNOPSIS
unsubscribe microservice

.DESCRIPTION
Disable (unsubscribe) a microservice from the current tenant


.LINK
c8y microservices disable

.EXAMPLE
PS> Disable-Microservice -Id $App.id

Disable (unsubscribe) to a microservice


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Microservice id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Tenant id
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "microservices disable"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y microservices disable $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y microservices disable $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Enable-Application {
<#
.SYNOPSIS
Subscribe application

.DESCRIPTION
Enable/subscribe an application to a tenant

.LINK
c8y tenants enableApplication

.EXAMPLE
PS> Enable-Application -Tenant mycompany -Application myMicroservice

Enable an application of a tenant


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Application id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Application,

        # Tenant id. Defaults to current tenant (based on credentials)
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenants enableApplication"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.applicationReference+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Application `
            | Group-ClientRequests `
            | c8y tenants enableApplication $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Application `
            | Group-ClientRequests `
            | c8y tenants enableApplication $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Enable-Microservice {
<#
.SYNOPSIS
subscribe to microservice

.DESCRIPTION
Enabling (subscribing) a microservice will activate the application in the tenant


.LINK
c8y microservices enable

.EXAMPLE
PS> Enable-Microservice -Id $App.id

Enable (subscribe) to a microservice


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Microservice id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Tenant id
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "microservices enable"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.applicationReference+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y microservices enable $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y microservices enable $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Find-ByTextManagedObjectCollection {
<#
.SYNOPSIS
Find managed object by text collection

.DESCRIPTION
Find a collection of managedObjects which match a given text value

.LINK
c8y inventory findByText

.EXAMPLE
PS> Find-ByTextManagedObjectCollection -Text $Device1.name

Find a list of managed objects by text

.EXAMPLE
PS> Find-ByTextManagedObjectCollection -Text $Device1.name

Find managed objects which contain the text 'myText' (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # managed objects containing a text value starting with the given text (placeholder {text}). Text value is any alphanumeric string starting with a latin letter (A-Z or a-z). (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Text,

        # ManagedObject type.
        [Parameter()]
        [string]
        $Type,

        # ManagedObject fragment type.
        [Parameter()]
        [string]
        $FragmentType,

        # include a flat list of all parents and grandparents of the given object
        [Parameter()]
        [switch]
        $WithParents,

        # Don't include the child devices names in the response. This can improve the API response because the names don't need to be retrieved
        [Parameter()]
        [switch]
        $SkipChildrenNames
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "inventory findByText"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObjectCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.managedObject+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Text `
            | Group-ClientRequests `
            | c8y inventory findByText $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Text `
            | Group-ClientRequests `
            | c8y inventory findByText $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-Agent {
<#
.SYNOPSIS
Get agent

.DESCRIPTION
Get an agent's managed object representation

.LINK
c8y agents get

.EXAMPLE
PS> Get-Agent -Id $agent.id

Get agent by id

.EXAMPLE
PS> Get-Agent -Id $agent.name

Get agent by name


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Agent ID (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "agents get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.customAgent+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y agents get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y agents get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-Alarm {
<#
.SYNOPSIS
Get alarm

.DESCRIPTION
Get an alarm by its id

.LINK
c8y alarms get

.EXAMPLE
PS> Get-Alarm -Id {{ NewAlarm }}

Get alarm


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Alarm id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "alarms get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.alarm+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y alarms get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y alarms get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-AlarmCollection {
<#
.SYNOPSIS
Get alarm collection

.DESCRIPTION
Get a collection of alarms based on filter parameters

.LINK
c8y alarms list

.EXAMPLE
PS> Get-AlarmCollection -Severity MAJOR -PageSize 100

Get alarms with the severity set to MAJOR

.EXAMPLE
PS> Get-AlarmCollection -DateFrom "-10m" -Status ACTIVE

Get active alarms which occurred in the last 10 minutes

.EXAMPLE
PS> Get-DeviceCollection -Name $Device.name | Get-AlarmCollection -Status ACTIVE

Get active alarms from a device (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Source device id.
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device,

        # Start date or date and time of alarm occurrence.
        [Parameter()]
        [string]
        $DateFrom,

        # End date or date and time of alarm occurrence.
        [Parameter()]
        [string]
        $DateTo,

        # Alarm type.
        [Parameter()]
        [string]
        $Type,

        # Alarm fragment type.
        [Parameter()]
        [string]
        $FragmentType,

        # Comma separated alarm statuses, for example ACTIVE,CLEARED.
        [Parameter()]
        [ValidateSet('ACTIVE','ACKNOWLEDGED','CLEARED')]
        [string]
        $Status,

        # Alarm severity, for example CRITICAL, MAJOR, MINOR or WARNING.
        [Parameter()]
        [ValidateSet('CRITICAL','MAJOR','MINOR','WARNING')]
        [string]
        $Severity,

        # When set to true only resolved alarms will be removed (the one with status CLEARED), false means alarms with status ACTIVE or ACKNOWLEDGED.
        [Parameter()]
        [switch]
        $Resolved,

        # Include assets
        [Parameter()]
        [switch]
        $WithAssets,

        # Include devices
        [Parameter()]
        [switch]
        $WithDevices
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "alarms list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.alarmCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.alarm+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y alarms list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y alarms list $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-AllTenantUsageSummaryStatistics {
<#
.SYNOPSIS
Get all tenant usage summary statistics

.DESCRIPTION
Get collection of tenant usage statistics summary

.LINK
c8y tenantstatistics listSummaryAllTenants

.EXAMPLE
PS> Get-AllTenantUsageSummaryStatistics

Get tenant summary statistics for all tenants

.EXAMPLE
PS> Get-AllTenantUsageSummaryStatistics -DateFrom "-30d"

Get tenant summary statistics collection for the last 30 days

.EXAMPLE
PS> Get-AllTenantUsageSummaryStatistics -DateFrom "-10d" -DateTo "-9d"

Get tenant summary statistics collection for the last 10 days, only return until the last 9 days


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Start date or date and time of the statistics.
        [Parameter()]
        [string]
        $DateFrom,

        # End date or date and time of the statistics.
        [Parameter()]
        [string]
        $DateTo
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenantstatistics listSummaryAllTenants"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y tenantstatistics listSummaryAllTenants $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y tenantstatistics listSummaryAllTenants $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-Application {
<#
.SYNOPSIS
Get application

.DESCRIPTION
Get an existing application

.LINK
c8y applications get

.EXAMPLE
PS> Get-Application -Id $App.id

Get an application by id

.EXAMPLE
PS> Get-Application -Id $App.name

Get an application by name


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Application id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "applications get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.application+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y applications get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y applications get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-ApplicationBinaryCollection {
<#
.SYNOPSIS
Get application binaries

.DESCRIPTION
A list of all binaries related to the given application will be returned


.LINK
c8y applications listApplicationBinaries

.EXAMPLE
PS> Get-ApplicationBinaryCollection -Id $App.id

List all of the binaries related to a Hosted (web) application

.EXAMPLE
PS> Get-Application $App.id | Get-ApplicationBinaryCollection

List all of the binaries related to a Hosted (web) application (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Application id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "applications listApplicationBinaries"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.customAttachmentCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.customBinaryAttachment+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y applications listApplicationBinaries $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y applications listApplicationBinaries $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-ApplicationCollection {
<#
.SYNOPSIS
Get application collection

.DESCRIPTION
Get a collection of applications by a given filter

.LINK
c8y applications list

.EXAMPLE
PS> Get-ApplicationCollection -PageSize 100

Get applications


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Application type
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [ValidateSet('APAMA_CEP_RULE','EXTERNAL','HOSTED','MICROSERVICE')]
        [object[]]
        $Type
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "applications list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.applicationCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.application+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Type `
            | Group-ClientRequests `
            | c8y applications list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Type `
            | Group-ClientRequests `
            | c8y applications list $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-ApplicationReferenceCollection {
<#
.SYNOPSIS
Get application reference collection

.DESCRIPTION
Get a collection of application references on a tenant

.LINK
c8y tenants listReferences

.EXAMPLE
PS> Get-ApplicationReferenceCollection -Tenant mycompany

Get a list of referenced applications on a given tenant (from management tenant)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Tenant id
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenants listReferences"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.applicationReferenceCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.applicationReference+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Tenant `
            | Group-ClientRequests `
            | c8y tenants listReferences $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Tenant `
            | Group-ClientRequests `
            | c8y tenants listReferences $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-AuditRecord {
<#
.SYNOPSIS
Get audit record

.DESCRIPTION
Get an audit record

.LINK
c8y auditrecords get

.EXAMPLE
PS> Get-AuditRecord -Id $Record.id

Get an audit record by id


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Audit id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "auditrecords get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.auditRecord+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y auditrecords get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y auditrecords get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-AuditRecordCollection {
<#
.SYNOPSIS
Get audit record collection

.DESCRIPTION
Audit records contain information about modifications to other Cumulocity entities. For example the audit records contain each operation state transition, so they can be used to check when an operation transitioned from PENDING -> EXECUTING -> SUCCESSFUL.


.LINK
c8y auditrecords list

.EXAMPLE
PS> Get-AuditRecordCollection -PageSize 100

Get a list of audit records

.EXAMPLE
PS> Get-AuditRecordCollection -Source $Device2.id

Get a list of audit records related to a managed object

.EXAMPLE
PS> Get-Operation -Id $Operation.id | Get-AuditRecordCollection

Get a list of audit records related to an operation


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Source Id or object containing an .id property of the element that should be detected. i.e. AlarmID, or Operation ID. Note: Only one source can be provided
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object]
        $Source,

        # Type
        [Parameter()]
        [string]
        $Type,

        # Username
        [Parameter()]
        [string]
        $User,

        # Application
        [Parameter()]
        [string]
        $Application,

        # Start date or date and time of audit record occurrence.
        [Parameter()]
        [string]
        $DateFrom,

        # End date or date and time of audit record occurrence.
        [Parameter()]
        [string]
        $DateTo,

        # Return the newest instead of the oldest audit records. Must be used with dateFrom and dateTo parameters
        [Parameter()]
        [switch]
        $Revert
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "auditrecords list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.auditRecordCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.auditRecord+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Source `
            | Group-ClientRequests `
            | c8y auditrecords list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Source `
            | Group-ClientRequests `
            | c8y auditrecords list $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-Binary {
<#
.SYNOPSIS
Download binary

.DESCRIPTION
Download a binary stored in Cumulocity and display it on the console. For non text based binaries or if the output should be saved to file, the output parameter should be used to write the file directly to a local file.


.LINK
c8y binaries get

.EXAMPLE
PS> Get-Binary -Id $Binary.id

Get a binary and display the contents on the console

.EXAMPLE
PS> Get-Binary -Id $Binary.id -OutputFile ./download-binary1.txt

Get a binary and save it to a file


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Inventory binary id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "binaries get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "*/*"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y binaries get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y binaries get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-BinaryCollection {
<#
.SYNOPSIS
Get binary collection

.DESCRIPTION
Get a collection of inventory binaries. The results include the meta information about binary and not the binary itself.


.LINK
c8y binaries list

.EXAMPLE
PS> Get-BinaryCollection -PageSize 100

Get a list of binaries


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(

    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "binaries list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObjectCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.managedObject+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y binaries list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y binaries list $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-BulkOperation {
<#
.SYNOPSIS
Get bulk operation

.DESCRIPTION
Get an existing bulk operation

.LINK
c8y bulkoperations get

.EXAMPLE
PS> Get-BulkOperation -Id $BulkOp.id

Get bulk operation by id


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Bulk Operation id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "bulkoperations get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.bulkoperation+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y bulkoperations get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y bulkoperations get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-BulkOperationCollection {
<#
.SYNOPSIS
Get bulk operation collection

.DESCRIPTION
Get a collection of bulk operations

.LINK
c8y bulkoperations list

.EXAMPLE
PS> Get-BulkOperationCollection

Get a list of bulk operations


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Include CANCELLED bulk operations
        [Parameter()]
        [switch]
        $WithDeleted
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "bulkoperations list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.bulkOperationCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.bulkoperation+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y bulkoperations list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y bulkoperations list $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-ChildAdditionCollection {
<#
.SYNOPSIS
Get child addition collection

.DESCRIPTION
Get a collection of managedObjects child additions

.LINK
c8y inventory additions list

.EXAMPLE
PS> Get-ChildAdditionCollection -Id $software.id

Get a list of the child additions of an existing managed object

.EXAMPLE
PS> Get-ManagedObject -Id $software.id | Get-ChildAdditionCollection

Get a list of the child additions of an existing managed object (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Managed object id. (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "inventory additions list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObjectReferenceCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.managedObject+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y inventory additions list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y inventory additions list $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-ChildAssetCollection {
<#
.SYNOPSIS
Get child asset collection

.DESCRIPTION
Get a collection of managedObjects child references

.LINK
c8y inventory assets list

.EXAMPLE
PS> Get-ChildAssetCollection -Id 12345

Get a list of the child assets of an existing device


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Managed object.
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "inventory assets list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObjectReferenceCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.managedObject+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y inventory assets list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y inventory assets list $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-ChildAssetReference {
<#
.SYNOPSIS
Get child asset reference

.DESCRIPTION
Get managed object child asset reference

.LINK
c8y inventory assets get

.EXAMPLE
PS> Get-ChildAssetReference -Asset $Agent.id -Reference $Ref.id

Get an existing child asset reference


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Asset id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Asset,

        # Asset reference id (required)
        [Parameter(Mandatory = $true)]
        [object[]]
        $Reference
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "inventory assets get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObjectReference+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Asset `
            | Group-ClientRequests `
            | c8y inventory assets get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Asset `
            | Group-ClientRequests `
            | c8y inventory assets get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-ChildDeviceCollection {
<#
.SYNOPSIS
Get child device collection

.DESCRIPTION
Get a collection of managedObjects child references

.LINK
c8y devices listChildren

.EXAMPLE
PS> Get-ChildDeviceCollection -Device $Device.id

Get a list of the child devices of an existing device

.EXAMPLE
PS> Get-ManagedObject -Id $Device.id | Get-ChildDeviceCollection

Get a list of the child devices of an existing device (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device. (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devices listChildren"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObjectReferenceCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.managedObject+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y devices listChildren $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y devices listChildren $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-ChildDeviceReference {
<#
.SYNOPSIS
Get child device reference

.DESCRIPTION
Get managed object child device reference

.LINK
c8y devices getChild

.EXAMPLE
PS> Get-ChildDeviceReference -Device $Agent.id -Reference $Ref.id

Get an existing child device reference


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # ManagedObject id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device,

        # Device reference id (required)
        [Parameter(Mandatory = $true)]
        [object[]]
        $Reference
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devices getChild"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObjectReference+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y devices getChild $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y devices getChild $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-CurrentApplication {
<#
.SYNOPSIS
Get current application

.DESCRIPTION
Getting the current application only works when using bootstrap credentials from an application (not user credentials)


.LINK
c8y currentapplication get

.EXAMPLE
PS> Get-CurrentApplication

Get the current application (requires using application credentials)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(

    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "currentapplication get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.application+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y currentapplication get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y currentapplication get $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-CurrentApplicationSubscription {
<#
.SYNOPSIS
Get current application subscriptions

.DESCRIPTION
Requires authentication with the application bootstrap user

.LINK
c8y currentapplication listSubscriptions

.EXAMPLE
PS> Get-CurrentApplicationSubscription

List the current application users/subscriptions


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(

    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "currentapplication listSubscriptions"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.applicationUserCollection+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y currentapplication listSubscriptions $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y currentapplication listSubscriptions $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-CurrentTenant {
<#
.SYNOPSIS
Get current tenant

.DESCRIPTION
Get the current tenant associated with the current session

.LINK
c8y currenttenant get

.EXAMPLE
PS> Get-CurrentTenant

Get the current tenant (based on your current credentials)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(

    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "currenttenant get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.currentTenant+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y currenttenant get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y currenttenant get $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-CurrentTenantApplicationCollection {
<#
.SYNOPSIS
List applications in current tenant

.DESCRIPTION
Get the applications of the current tenant

.LINK
c8y currenttenant listApplications

.EXAMPLE
PS> Get-CurrentTenantApplicationCollection

Get a list of applications in the current tenant


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(

    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "currenttenant listApplications"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.currentTenant+json"
            ItemType = "application/vnd.com.nsn.cumulocity.application+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y currenttenant listApplications $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y currenttenant listApplications $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-CurrentUser {
<#
.SYNOPSIS
Get current user

.DESCRIPTION
Get the user representation associated with the current credentials used by the request

.LINK
c8y currentuser get

.EXAMPLE
PS> Get-CurrentUser

Get the current user


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(

    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "currentuser get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.currentUser+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y currentuser get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y currentuser get $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-DataBrokerConnector {
<#
.SYNOPSIS
Get data broker

.DESCRIPTION
Get an existing data broker connector

.LINK
c8y databroker get

.EXAMPLE
PS> Get-DataBrokerConnector -Id $DataBroker.id

Get a data broker connector


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Data broker connector id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "databroker get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.databrokerConnector+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y databroker get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y databroker get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-DataBrokerConnectorCollection {
<#
.SYNOPSIS
Get data broker collection

.DESCRIPTION
Get a collection of existing data broker connectors

.LINK
c8y databroker list

.EXAMPLE
PS> Get-DataBrokerConnectorCollection

Get a list of data broker connectors


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(

    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "databroker list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.databrokerConnectorCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.databrokerConnector+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y databroker list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y databroker list $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-Device {
<#
.SYNOPSIS
Get device

.DESCRIPTION
Get an existing device

.LINK
c8y devices get

.EXAMPLE
PS> Get-Device -Id $device.id

Get device by id

.EXAMPLE
PS> Get-Device -Id $device.name

Get device by name


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device ID (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devices get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.customDevice+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y devices get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y devices get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-DeviceChildAssetCollection {
<#
.SYNOPSIS
Get child asset collection

.DESCRIPTION
Get a collection of managedObjects child references

.LINK
c8y devices listAssets

.EXAMPLE
PS> Get-DeviceChildAssetCollection -Id $Group.id

Get a list of the child assets of an existing device

.EXAMPLE
PS> Get-DeviceChildAssetCollection -Id $Group.id

Get a list of the child assets of an existing group


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device. (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devices listAssets"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObjectReferenceCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.managedObject+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y devices listAssets $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y devices listAssets $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-DeviceGroup {
<#
.SYNOPSIS
Get device group

.DESCRIPTION
Get a device group


.LINK
c8y devicegroups get

.EXAMPLE
PS> Get-DeviceGroup -Id $group.id

Get device group by id

.EXAMPLE
PS> Get-DeviceGroup -Id $group.name

Get device group by name


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device group ID (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devicegroups get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.customDeviceGroup+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y devicegroups get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y devicegroups get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-DeviceGroupChildAssetCollection {
<#
.SYNOPSIS
Get child asset collection

.DESCRIPTION
Get a collection of managedObjects child references

.LINK
c8y devicegroups listAssets

.EXAMPLE
PS> Get-DeviceGroupChildAssetCollection -Id $Group.id

Get a list of the child assets of an existing device

.EXAMPLE
PS> Get-DeviceGroupChildAssetCollection -Id $Group.id

Get a list of the child assets of an existing group


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device Group. (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devicegroups listAssets"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObjectReferenceCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.managedObject+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y devicegroups listAssets $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y devicegroups listAssets $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-DeviceRequest {
<#
.SYNOPSIS
Get device request

.DESCRIPTION
Get a device registration request

.LINK
c8y deviceregistration get

.EXAMPLE
PS> Get-DeviceRequest -Id "010af8dd0c102"

Get a new device request


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # New Device Request ID (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "deviceregistration get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.newDeviceRequest+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y deviceregistration get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y deviceregistration get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-DeviceRequestCollection {
<#
.SYNOPSIS
Get device request collection

.DESCRIPTION
Get a collection of device registration requests

.LINK
c8y deviceregistration list

.EXAMPLE
PS> Get-DeviceRequestCollection

Get a list of new device requests


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(

    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "deviceregistration list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.newDeviceRequestCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.newDeviceRequest+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y deviceregistration list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y deviceregistration list $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-Event {
<#
.SYNOPSIS
Get event

.DESCRIPTION
Get an existing event by id

.LINK
c8y events get

.EXAMPLE
PS> Get-Event -Id {{ NewEvent }}

Get event


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Event id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "events get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.event+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y events get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y events get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-EventBinary {
<#
.SYNOPSIS
Get event binary

.DESCRIPTION
Get the binary associated with an event

.LINK
c8y events downloadBinary

.EXAMPLE
PS> Get-EventBinary -Id $Event.id -OutputFile ./eventbinary.txt

Download a binary related to an event


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Event id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "events downloadBinary"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "*/*"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y events downloadBinary $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y events downloadBinary $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-EventCollection {
<#
.SYNOPSIS
Get event collection

.DESCRIPTION
Get a collection of events based on filter parameters

.LINK
c8y events list

.EXAMPLE
PS> Get-EventCollection -Type "my_CustomType2" -DateFrom "-10d"

Get events with type 'my_CustomType' that were created in the last 10 days

.EXAMPLE
PS> Get-EventCollection -Device $Device.id

Get events from a device

.EXAMPLE
PS> Get-DeviceCollection -Name $Device.name | Get-EventCollection

Get events from a device (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device ID
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device,

        # Event type.
        [Parameter()]
        [string]
        $Type,

        # Fragment name from event.
        [Parameter()]
        [string]
        $FragmentType,

        # Start date or date and time of event occurrence.
        [Parameter()]
        [string]
        $DateFrom,

        # End date or date and time of event occurrence.
        [Parameter()]
        [string]
        $DateTo,

        # Return the newest instead of the oldest events. Must be used with dateFrom and dateTo parameters
        [Parameter()]
        [switch]
        $Revert
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "events list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.eventCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.event+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y events list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y events list $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-ExternalId {
<#
.SYNOPSIS
Get external id

.DESCRIPTION
Get an external identity object. An external identify will include the reference to a single device managed object


.LINK
c8y identity get

.EXAMPLE
PS> Get-ExternalId -Type "my_SerialNumber" -Name "myserialnumber"

Get external identity


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # External identity type
        [Parameter()]
        [string]
        $Type,

        # External identity id/name (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Name
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "identity get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.externalId+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Name `
            | Group-ClientRequests `
            | c8y identity get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Name `
            | Group-ClientRequests `
            | c8y identity get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-ExternalIdCollection {
<#
.SYNOPSIS
Get external id collection

.DESCRIPTION
Get a collection of external ids related to an existing managed object

.LINK
c8y identity list

.EXAMPLE
PS> Get-ExternalIdCollection -Device $Device.id

Get a list of external ids


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "identity list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.externalIdCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.externalId+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y identity list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y identity list $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-InventoryRole {
<#
.SYNOPSIS
Get inventory role

.DESCRIPTION
Get a specific inventory role

.LINK
c8y users getInventoryRole

.EXAMPLE
PS> Get-InventoryRoleCollection -PageSize 1 | Get-InventoryRole

Get an inventory role (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Role id. Note: lookup by name is not yet supported (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "users getInventoryRole"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.inventoryrole+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y users getInventoryRole $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y users getInventoryRole $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-InventoryRoleCollection {
<#
.SYNOPSIS
Get inventory role collection

.DESCRIPTION
Get a list of inventory roles

.LINK
c8y users listInventoryRoles

.EXAMPLE
PS> Get-InventoryRoleCollection

Get list of inventory roles


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(

    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "users listInventoryRoles"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.inventoryrolecollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.inventoryrole+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y users listInventoryRoles $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y users listInventoryRoles $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-ManagedObject {
<#
.SYNOPSIS
Get managed objects

.DESCRIPTION
Get an existing managed object

.LINK
c8y inventory get

.EXAMPLE
PS> Get-ManagedObject -Id $mo.id

Get a managed object

.EXAMPLE
PS> Get-ManagedObject -Id $mo.id | Get-ManagedObject

Get a managed object (using pipeline)

.EXAMPLE
PS> Get-ManagedObject -Id $mo.id -WithParents

Get a managed object with parent references


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # ManagedObject id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # include a flat list of all parents and grandparents of the given object
        [Parameter()]
        [switch]
        $WithParents
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "inventory get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.inventory+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y inventory get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y inventory get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-ManagedObjectCollection {
<#
.SYNOPSIS
Get managed object collection

.DESCRIPTION
Get a collection of managedObjects based on filter parameters

.LINK
c8y inventory list

.EXAMPLE
PS> Get-ManagedObjectCollection

Get a list of managed objects

.EXAMPLE
PS> Get-ManagedObjectCollection -Ids $Device1.id, $Device2.id

Get a list of managed objects by id


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # List of ids.
        [Parameter()]
        [string[]]
        $Ids,

        # ManagedObject type.
        [Parameter()]
        [string]
        $Type,

        # ManagedObject fragment type.
        [Parameter()]
        [string]
        $FragmentType,

        # managed objects containing a text value starting with the given text (placeholder {text}). Text value is any alphanumeric string starting with a latin letter (A-Z or a-z).
        [Parameter()]
        [string]
        $Text,

        # include a flat list of all parents and grandparents of the given object
        [Parameter()]
        [switch]
        $WithParents,

        # Don't include the child devices names in the response. This can improve the API response because the names don't need to be retrieved
        [Parameter()]
        [switch]
        $SkipChildrenNames
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "inventory list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObjectCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.managedObject+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y inventory list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y inventory list $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-Measurement {
<#
.SYNOPSIS
Get measurement

.DESCRIPTION
Get an existing measurement

.LINK
c8y measurements get

.EXAMPLE
PS> Get-Measurement -Id $Measurement.id

Get measurement


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Measurement id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "measurements get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.measurement+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y measurements get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y measurements get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-MeasurementCollection {
<#
.SYNOPSIS
Get measurement collection

.DESCRIPTION
Get a collection of measurements based on filter parameters

.LINK
c8y measurements list

.EXAMPLE
PS> Get-MeasurementCollection

Get a list of measurements

.EXAMPLE
PS> Get-MeasurementCollection -Device $Device.id -Type "TempReading"

Get a list of measurements for a particular device

.EXAMPLE
PS> Get-DeviceCollection -Name $Device.name | Get-MeasurementCollection

Get measurements from a device (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device ID
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device,

        # Measurement type.
        [Parameter()]
        [string]
        $Type,

        # value fragment type
        [Parameter()]
        [string]
        $ValueFragmentType,

        # value fragment series
        [Parameter()]
        [string]
        $ValueFragmentSeries,

        # Fragment name from measurement (deprecated).
        [Parameter()]
        [string]
        $FragmentType,

        # Start date or date and time of measurement occurrence.
        [Parameter()]
        [string]
        $DateFrom,

        # End date or date and time of measurement occurrence.
        [Parameter()]
        [string]
        $DateTo,

        # Return the newest instead of the oldest measurements. Must be used with dateFrom and dateTo parameters
        [Parameter()]
        [switch]
        $Revert,

        # Results will be displayed in csv format. Note: -IncludeAll, is not supported when using using this parameter
        [Parameter()]
        [switch]
        $CsvFormat,

        # Results will be displayed in Excel format Note: -IncludeAll, is not supported when using using this parameter
        [Parameter()]
        [switch]
        $ExcelFormat,

        # Every measurement fragment which contains 'unit' property will be transformed to use required system of units.
        [Parameter()]
        [ValidateSet('imperial','metric')]
        [string]
        $Unit
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "measurements list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.measurementCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.measurement+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y measurements list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y measurements list $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-MeasurementSeries {
<#
.SYNOPSIS
Get measurement series

.DESCRIPTION
Get a collection of measurements based on filter parameters

.LINK
c8y measurements getSeries

.EXAMPLE
PS> Get-MeasurementSeries -Device $Device.id -Series "c8y_Temperature.T" -DateFrom "1970-01-01" -DateTo "0s"

Get a list of measurements for a particular device

.EXAMPLE
PS> Get-MeasurementSeries -Device $Measurement2.source.id -Series "c8y_Temperature.T" -DateFrom "1970-01-01" -DateTo "0s"

Get measurement series c8y_Temperature.T on a device

.EXAMPLE
PS> Get-DeviceCollection -Name $Device.name | Get-MeasurementSeries -Series "c8y_Temperature.T"

Get measurement series from a device (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device ID
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device,

        # measurement type and series name, e.g. c8y_AccelerationMeasurement.acceleration
        [Parameter()]
        [string[]]
        $Series,

        # Fragment name from measurement.
        [Parameter()]
        [ValidateSet('DAILY','HOURLY','MINUTELY')]
        [string]
        $AggregationType,

        # Start date or date and time of measurement occurrence. Defaults to last 7 days
        [Parameter()]
        [string]
        $DateFrom,

        # End date or date and time of measurement occurrence. Defaults to the current time
        [Parameter()]
        [string]
        $DateTo
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "measurements getSeries"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y measurements getSeries $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y measurements getSeries $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-Microservice {
<#
.SYNOPSIS
Get microservice

.DESCRIPTION
Get an existing microservice

.LINK
c8y microservices get

.EXAMPLE
PS> Get-Microservice -Id $App.id

Get an microservice by id

.EXAMPLE
PS> Get-Microservice -Id $App.name

Get an microservice by name


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Microservice id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "microservices get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.application+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y microservices get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y microservices get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-MicroserviceBootstrapUser {
<#
.SYNOPSIS
Get microservice bootstrap user

.DESCRIPTION
Get the bootstrap user associated to a microservice. The bootstrap user is required when running a microservice locally (i.e. during development)


.LINK
c8y microservices getBootstrapUser

.EXAMPLE
PS> Get-MicroserviceBootstrapUser -Id $App.name

Get application bootstrap user


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Microservice id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "microservices getBootstrapUser"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.bootstrapuser+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y microservices getBootstrapUser $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y microservices getBootstrapUser $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-MicroserviceCollection {
<#
.SYNOPSIS
Get microservice collection

.DESCRIPTION
Get a collection of microservices in the current tenant


.LINK
c8y microservices list

.EXAMPLE
PS> Get-MicroserviceCollection -PageSize 100

Get microservices


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Application type
        [Parameter()]
        [ValidateSet('MICROSERVICE')]
        [string]
        $Type
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "microservices list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.applicationCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.application+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y microservices list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y microservices list $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-Operation {
<#
.SYNOPSIS
Get operation

.DESCRIPTION
Get an existing operation

.LINK
c8y operations get

.EXAMPLE
PS> Get-Operation -Id {{ NewOperation }}

Get operation by id


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Operation id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "operations get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.operation+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y operations get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y operations get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-OperationCollection {
<#
.SYNOPSIS
Get operation collection

.DESCRIPTION
Get a collection of operations based on filter parameters

.LINK
c8y operations list

.EXAMPLE
PS> Get-OperationCollection -Status PENDING

Get a list of pending operations

.EXAMPLE
PS> Get-OperationCollection -Agent $Agent.id -Status PENDING

Get a list of pending operations for a given agent and all of its child devices

.EXAMPLE
PS> Get-OperationCollection -Device $Device.id -Status PENDING

Get a list of pending operations for a device

.EXAMPLE
PS> Get-DeviceCollection -Name $Agent2.name | Get-OperationCollection

Get operations from a device (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Agent ID
        [Parameter()]
        [object[]]
        $Agent,

        # Device ID
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device,

        # Start date or date and time of operation.
        [Parameter()]
        [string]
        $DateFrom,

        # End date or date and time of operation.
        [Parameter()]
        [string]
        $DateTo,

        # Operation status, can be one of SUCCESSFUL, FAILED, EXECUTING or PENDING.
        [Parameter()]
        [ValidateSet('PENDING','EXECUTING','SUCCESSFUL','FAILED')]
        [string]
        $Status,

        # Bulk operation id. Only retrieve operations related to the given bulk operation.
        [Parameter()]
        [string]
        $BulkOperationId
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "operations list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.operationCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.operation+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y operations list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y operations list $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-RetentionRule {
<#
.SYNOPSIS
Get retention rule

.DESCRIPTION
Get an existing retention by id


.LINK
c8y retentionrules get

.EXAMPLE
PS> Get-RetentionRule -Id $RetentionRule.id

Get a retention rule


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Retention rule id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "retentionrules get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.retentionRule+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y retentionrules get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y retentionrules get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-RetentionRuleCollection {
<#
.SYNOPSIS
Get retention rule collection

.DESCRIPTION
Get a collection of retention rules configured in the current tenant


.LINK
c8y retentionrules list

.EXAMPLE
PS> Get-RetentionRuleCollection

Get a list of retention rules


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(

    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "retentionrules list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.retentionRuleCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.retentionRule+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y retentionrules list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y retentionrules list $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-RoleCollection {
<#
.SYNOPSIS
Get role collection

.DESCRIPTION
Get collection of user roles

.LINK
c8y userroles list

.EXAMPLE
PS> Get-RoleCollection -PageSize 100

Get a list of roles


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(

    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "userroles list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.roleCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.role+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y userroles list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y userroles list $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-RoleReferenceCollectionFromGroup {
<#
.SYNOPSIS
Get role references from user group

.DESCRIPTION
Get collection of user role references from a group

.LINK
c8y userroles getRoleReferenceCollectionFromGroup

.EXAMPLE
PS> Get-RoleReferenceCollectionFromGroup -Group $Group.id

Get a list of role references for a user group


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Group id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Group,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "userroles getRoleReferenceCollectionFromGroup"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.roleReferenceCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.roleReference+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Group `
            | Group-ClientRequests `
            | c8y userroles getRoleReferenceCollectionFromGroup $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Group `
            | Group-ClientRequests `
            | c8y userroles getRoleReferenceCollectionFromGroup $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-RoleReferenceCollectionFromUser {
<#
.SYNOPSIS
Get role references from user

.DESCRIPTION
Get collection of user role references from a user

.LINK
c8y userroles getRoleReferenceCollectionFromUser

.EXAMPLE
PS> Get-RoleReferenceCollectionFromUser -User $User.id

Get a list of role references for a user


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # User (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $User,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "userroles getRoleReferenceCollectionFromUser"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.roleReferenceCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.roleReference+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $User `
            | Group-ClientRequests `
            | c8y userroles getRoleReferenceCollectionFromUser $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $User `
            | Group-ClientRequests `
            | c8y userroles getRoleReferenceCollectionFromUser $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-SupportedMeasurements {
<#
.SYNOPSIS
Get supported measurements

.DESCRIPTION
Returns a list of fragments (valueFragmentTypes) related to the device


.LINK
c8y devices getSupportedMeasurements

.EXAMPLE
PS> Get-SupportedMeasurements -Device $device.id

Get the supported measurements of a device by name

.EXAMPLE
PS> Get-SupportedMeasurements -Device $device.id

Get the supported measurements of a device (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device ID (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devices getSupportedMeasurements"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.inventory+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y devices getSupportedMeasurements $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y devices getSupportedMeasurements $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-SupportedSeries {
<#
.SYNOPSIS
Get supported measurement series

.DESCRIPTION
Get supported measurement series/s of a device


.LINK
c8y devices getSupportedSeries

.EXAMPLE
PS> Get-SupportedSeries -Device $device.id

Get the supported measurement series of a device by name

.EXAMPLE
PS> Get-SupportedSeries -Device $device.id

Get the supported measurement series of a device (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device ID (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devices getSupportedSeries"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.inventory+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y devices getSupportedSeries $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y devices getSupportedSeries $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-SystemOption {
<#
.SYNOPSIS
Get system option

.DESCRIPTION
Get a system option by category and key

.LINK
c8y systemoptions get

.EXAMPLE
PS> Get-SystemOption -Category "system" -Key "version"

Get system option value


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # System Option category (required)
        [Parameter(Mandatory = $true)]
        [string]
        $Category,

        # System Option key (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Key
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "systemoptions get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.option+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Key `
            | Group-ClientRequests `
            | c8y systemoptions get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Key `
            | Group-ClientRequests `
            | c8y systemoptions get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-SystemOptionCollection {
<#
.SYNOPSIS
Get system option collection

.DESCRIPTION
Get a collection of system options. This endpoint provides a set of read-only properties pre-defined in platform configuration. The response format is exactly the same as for OptionCollection.

.LINK
c8y systemoptions list

.EXAMPLE
PS> Get-SystemOptionCollection

Get a list of system options


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(

    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "systemoptions list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.optionCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.option+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y systemoptions list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y systemoptions list $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-Tenant {
<#
.SYNOPSIS
Get tenant

.DESCRIPTION
Get an existing tenant

.LINK
c8y tenants get

.EXAMPLE
PS> Get-Tenant -Id mycompany

Get a tenant by name (from the management tenant)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Tenant id
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenants get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.tenant+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y tenants get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y tenants get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-TenantCollection {
<#
.SYNOPSIS
Get tenant collection

.DESCRIPTION
Get collection of tenants

.LINK
c8y tenants list

.EXAMPLE
PS> Get-TenantCollection

Get a list of tenants


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(

    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenants list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.tenantCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.tenant+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y tenants list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y tenants list $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-TenantOption {
<#
.SYNOPSIS
Get tenant option

.DESCRIPTION
Get an existing tenant option

.LINK
c8y tenantoptions get

.EXAMPLE
PS> Get-TenantOption -Category "c8y_cli_tests" -Key "$option2"

Get a tenant option


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Tenant Option category (required)
        [Parameter(Mandatory = $true)]
        [string]
        $Category,

        # Tenant Option key (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Key
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenantoptions get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.option+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Key `
            | Group-ClientRequests `
            | c8y tenantoptions get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Key `
            | Group-ClientRequests `
            | c8y tenantoptions get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-TenantOptionCollection {
<#
.SYNOPSIS
Get tenant option collection

.DESCRIPTION
Get collection of tenant options

.LINK
c8y tenantoptions list

.EXAMPLE
PS> Get-TenantOptionCollection

Get a list of tenant options


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(

    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenantoptions list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.optionCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.option+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y tenantoptions list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y tenantoptions list $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-TenantOptionForCategory {
<#
.SYNOPSIS
Get tenant options by category

.DESCRIPTION
Get existing tenant options for a category

.LINK
c8y tenantoptions getForCategory

.EXAMPLE
PS> Get-TenantOptionForCategory -Category "c8y_cli_tests"

Get a list of options for a category


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Tenant Option category (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Category
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenantoptions getForCategory"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.optionCollection+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Category `
            | Group-ClientRequests `
            | c8y tenantoptions getForCategory $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Category `
            | Group-ClientRequests `
            | c8y tenantoptions getForCategory $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-TenantStatisticsCollection {
<#
.SYNOPSIS
Get tenant usage statistics

.DESCRIPTION
Get collection of tenant usage statistics

.LINK
c8y tenantstatistics list

.EXAMPLE
PS> Get-TenantStatisticsCollection

Get tenant statistics collection

.EXAMPLE
PS> Get-TenantStatisticsCollection -DateFrom "-30d" -PageSize 30

Get tenant statistics collection for the last 30 days

.EXAMPLE
PS> Get-TenantStatisticsCollection -DateFrom "-3d" -DateTo "-2d"

Get tenant statistics collection for the day before yesterday


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Start date or date and time of the statistics.
        [Parameter()]
        [string]
        $DateFrom,

        # End date or date and time of the statistics.
        [Parameter()]
        [string]
        $DateTo
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenantstatistics list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.tenantUsageStatisticsCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.tenantUsageStatisticsSummary+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y tenantstatistics list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y tenantstatistics list $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-TenantUsageSummaryStatistics {
<#
.SYNOPSIS
Get tenant usage summary statistics

.DESCRIPTION
Get summary of requests and database usage from the start of this month until now

.LINK
c8y tenantstatistics listSummaryForTenant

.EXAMPLE
PS> Get-TenantUsageSummaryStatistics

Get tenant summary statistics for the current tenant

.EXAMPLE
PS> Get-TenantUsageSummaryStatistics -DateFrom "-30d"

Get tenant summary statistics collection for the last 30 days

.EXAMPLE
PS> Get-TenantUsageSummaryStatistics -DateFrom "-10d" -DateTo "-9d"

Get tenant summary statistics collection for the last 10 days, only return until the last 9 days


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Start date or date and time of the statistics.
        [Parameter()]
        [string]
        $DateFrom,

        # End date or date and time of the statistics.
        [Parameter()]
        [string]
        $DateTo
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenantstatistics listSummaryForTenant"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.tenantUsageStatisticsSummary+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y tenantstatistics listSummaryForTenant $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y tenantstatistics listSummaryForTenant $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-TenantVersion {
<#
.SYNOPSIS
Get tenant version

.DESCRIPTION
Get tenant platform (backend) version

.LINK
c8y currenttenant version

.EXAMPLE
PS> Get-TenantVersion

Get the Cumulocity backend version


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(

    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "currenttenant version"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.option+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y currenttenant version $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y currenttenant version $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-User {
<#
.SYNOPSIS
Get user

.DESCRIPTION
Get information about a user

.LINK
c8y users get

.EXAMPLE
PS> Get-User -Id $User.id

Get a user


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # User id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "users get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.user+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y users get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y users get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-UserByName {
<#
.SYNOPSIS
Get user by name

.DESCRIPTION
Get the user details by referencing their username instead of id

.LINK
c8y users getUserByName

.EXAMPLE
PS> Get-UserByName -Name $User.userName

Get a user by name


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Username (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Name,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "users getUserByName"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.user+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Name `
            | Group-ClientRequests `
            | c8y users getUserByName $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Name `
            | Group-ClientRequests `
            | c8y users getUserByName $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-UserCollection {
<#
.SYNOPSIS
Get user collection

.DESCRIPTION
Get a collection of users based on filter parameters

.LINK
c8y users list

.EXAMPLE
PS> Get-UserCollection

Get a list of users


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # prefix or full username
        [Parameter()]
        [string]
        $Username,

        # numeric group identifiers separated by commas; result will contain only users which belong to at least one of specified groups
        [Parameter()]
        [string]
        $Groups,

        # exact username
        [Parameter()]
        [string]
        $Owner,

        # If set to 'true', result will contain only users created during bootstrap process (starting with 'device_'). If flag is absent (or false) the result will not contain 'device_' users.
        [Parameter()]
        [switch]
        $OnlyDevices,

        # if set to 'true', then each of returned users will contain additional field 'subusersCount' - number of direct subusers (users with corresponding 'owner').
        [Parameter()]
        [switch]
        $WithSubusersCount,

        # Include applications related to the user
        [Parameter()]
        [switch]
        $WithApps,

        # Include group information
        [Parameter()]
        [switch]
        $WithGroups,

        # Include role information
        [Parameter()]
        [switch]
        $WithRoles,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "users list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.userCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.user+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y users list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y users list $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-UserGroup {
<#
.SYNOPSIS
Get user group

.DESCRIPTION
Get an existing user group

.LINK
c8y usergroups get

.EXAMPLE
PS> Get-UserGroup -Id $Group.id

Get a user group


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Group id
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "usergroups get"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.group+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y usergroups get $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y usergroups get $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-UserGroupByName {
<#
.SYNOPSIS
Get user group by name

.DESCRIPTION
Get an existing user group by name

.LINK
c8y usergroups getByName

.EXAMPLE
PS> Get-UserGroupByName -Name $Group.name

Get user group by its name


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Group name
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Name,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "usergroups getByName"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.group+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Name `
            | Group-ClientRequests `
            | c8y usergroups getByName $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Name `
            | Group-ClientRequests `
            | c8y usergroups getByName $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-UserGroupCollection {
<#
.SYNOPSIS
Get user group collection

.DESCRIPTION
Get collection of (user) groups

.LINK
c8y usergroups list

.EXAMPLE
PS> Get-UserGroupCollection

Get a list of user groups for the current tenant


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "usergroups list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.groupCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.group+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y usergroups list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y usergroups list $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-UserGroupMembershipCollection {
<#
.SYNOPSIS
Get users in group

.DESCRIPTION
Get all users in a user group

.LINK
c8y userreferences listGroupMembership

.EXAMPLE
PS> Get-UserGroupMembershipCollection -Id $Group.id

List the users within a user group

.EXAMPLE
PS> Get-UserGroupByName -Name "business" | Get-UserGroupMembershipCollection

List the users within a user group (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Group ID (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "userreferences listGroupMembership"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.userReferenceCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.user+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y userreferences listGroupMembership $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y userreferences listGroupMembership $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Get-UserMembershipCollection {
<#
.SYNOPSIS
get user membership collection

.DESCRIPTION
Get information about all groups that a user is a member of

.LINK
c8y users listUserMembership

.EXAMPLE
PS> Get-UserMembershipCollection -Id $User.id

Get a list of groups that a user belongs to


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # User (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "users listUserMembership"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.groupReferenceCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.groupReference+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y users listUserMembership $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y users listUserMembership $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Invoke-UserLogout {
<#
.SYNOPSIS
Logout current user

.DESCRIPTION
Logout the current user. This will invalidate the token associated with the user when using OAUTH_INTERNAL

.LINK
c8y currentuser logout

.EXAMPLE
PS> Invoke-UserLogout

Log out the current user


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(

    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "currentuser logout"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y currentuser logout $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y currentuser logout $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-Agent {
<#
.SYNOPSIS
Create agent

.DESCRIPTION
Create an agent managed object. An agent is a special device managed object with both the
c8y_IsDevice and com_cumulocity_model_Agent fragments.


.LINK
c8y agents create

.EXAMPLE
PS> New-Agent -Name $AgentName

Create agent

.EXAMPLE
PS> New-Agent -Name $AgentName -Data @{ myValue = @{ value1 = $true } }

Create agent with custom properties


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Agent name
        [Parameter()]
        [string]
        $Name,

        # Agent type
        [Parameter()]
        [string]
        $Type
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "agents create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.customAgent+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y agents create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y agents create $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-Alarm {
<#
.SYNOPSIS
Create alarm

.DESCRIPTION
Create an alarm on a device or agent.

.LINK
c8y alarms create

.EXAMPLE
PS> New-Alarm -Device $device.id -Type c8y_TestAlarm -Time "-0s" -Text "Test alarm" -Severity MAJOR

Create a new alarm for device

.EXAMPLE
PS> Get-Device -Id $device.id | PSc8y\New-Alarm -Type c8y_TestAlarm -Time "-0s" -Text "Test alarm" -Severity MAJOR

Create a new alarm for device (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # The ManagedObject that the alarm originated from
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device,

        # Identifies the type of this alarm, e.g. 'com_cumulocity_events_TamperEvent'.
        [Parameter()]
        [string]
        $Type,

        # Time of the alarm. Defaults to current timestamp.
        [Parameter()]
        [string]
        $Time,

        # Text description of the alarm.
        [Parameter()]
        [string]
        $Text,

        # The severity of the alarm: CRITICAL, MAJOR, MINOR or WARNING. Must be upper-case.
        [Parameter()]
        [ValidateSet('CRITICAL','MAJOR','MINOR','WARNING')]
        [string]
        $Severity,

        # The status of the alarm: ACTIVE, ACKNOWLEDGED or CLEARED. If status was not appeared, new alarm will have status ACTIVE. Must be upper-case.
        [Parameter()]
        [ValidateSet('ACTIVE','ACKNOWLEDGED','CLEARED')]
        [string]
        $Status
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "alarms create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.alarm+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y alarms create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y alarms create $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-Application {
<#
.SYNOPSIS
Create application

.DESCRIPTION
Create a new application using explicit settings

.LINK
c8y applications create

.EXAMPLE
PS> New-Application -Name $AppName -Key "${AppName}-key" -ContextPath $AppName -Type HOSTED

Create a new hosted application


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Name of application
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Name,

        # Shared secret of application
        [Parameter()]
        [string]
        $Key,

        # Type of application. Possible values are EXTERNAL, HOSTED, MICROSERVICE
        [Parameter()]
        [ValidateSet('EXTERNAL','HOSTED','MICROSERVICE')]
        [string]
        $Type,

        # Access level for other tenants. Possible values are : MARKET, PRIVATE (default)
        [Parameter()]
        [ValidateSet('MARKET','PRIVATE')]
        [string]
        $Availability,

        # contextPath of the hosted application. Required when application type is HOSTED
        [Parameter()]
        [string]
        $ContextPath,

        # URL to application base directory hosted on an external server. Required when application type is HOSTED
        [Parameter()]
        [string]
        $ResourcesUrl,

        # authorization username to access resourcesUrl
        [Parameter()]
        [string]
        $ResourcesUsername,

        # authorization password to access resourcesUrl
        [Parameter()]
        [string]
        $ResourcesPassword,

        # URL to the external application. Required when application type is EXTERNAL
        [Parameter()]
        [string]
        $ExternalUrl
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "applications create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.application+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Name `
            | Group-ClientRequests `
            | c8y applications create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Name `
            | Group-ClientRequests `
            | c8y applications create $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-ApplicationBinary {
<#
.SYNOPSIS
New application binary

.DESCRIPTION
For the applications of type microservice and web application to be available for Cumulocity platform users, a binary zip file must be uploaded.
For the microservice application, the zip file must consist of * cumulocity.json - file describing the deployment
    * image.tar - executable docker image

For the web application, the zip file must include index.html in the root directory.


.LINK
c8y applications createBinary

.EXAMPLE
PS> New-ApplicationBinary -Id $App.id -File $MicroserviceZip

Upload application microservice binary


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Application id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # File to be uploaded as a binary (required)
        [Parameter(Mandatory = $true)]
        [string]
        $File
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "applications createBinary"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObject+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y applications createBinary $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y applications createBinary $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-AuditRecord {
<#
.SYNOPSIS
Create audit record

.DESCRIPTION
Create a new audit record for a given action

.LINK
c8y auditrecords create

.EXAMPLE
PS> New-AuditRecord -Type "ManagedObject" -Time "0s" -Text "Managed Object updated: my_Prop: value" -Source $Device.id -Activity "Managed Object updated" -Severity "information"

Create an audit record for a custom managed object update


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Identifies the type of this audit record. (required)
        [Parameter(Mandatory = $true)]
        [string]
        $Type,

        # Time of the audit record. Defaults to current timestamp.
        [Parameter()]
        [string]
        $Time,

        # Text description of the audit record. (required)
        [Parameter(Mandatory = $true)]
        [string]
        $Text,

        # An optional ManagedObject that the audit record originated from (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Source,

        # The activity that was carried out. (required)
        [Parameter(Mandatory = $true)]
        [string]
        $Activity,

        # The severity of action: critical, major, minor, warning or information. (required)
        [Parameter(Mandatory = $true)]
        [ValidateSet('critical','major','minor','warning','information')]
        [string]
        $Severity,

        # The user responsible for the audited action.
        [Parameter()]
        [string]
        $User,

        # The application used to carry out the audited action.
        [Parameter()]
        [string]
        $Application
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "auditrecords create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.auditRecord+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Source `
            | Group-ClientRequests `
            | c8y auditrecords create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Source `
            | Group-ClientRequests `
            | c8y auditrecords create $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-Binary {
<#
.SYNOPSIS
Create binary

.DESCRIPTION
Create/upload a new binary to Cumulocity

.LINK
c8y binaries create

.EXAMPLE
PS> New-Binary -File $File

Upload a log file

.EXAMPLE
PS> New-Binary -File $File -Data @{ c8y_Global = @{}; type = "c8y_upload" }

Upload a config file and make it globally accessible for all users


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # File to be uploaded as a binary (required)
        [Parameter(Mandatory = $true)]
        [string]
        $File
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "binaries create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObject+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y binaries create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y binaries create $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-BulkOperation {
<#
.SYNOPSIS
Create bulk operation

.DESCRIPTION
Create a new bulk operation

.LINK
c8y bulkoperations create

.EXAMPLE
PS> New-BulkOperation -Group $Group.id -StartDate "60s" -CreationRampSec 15 -Operation @{ c8y_Restart = @{} }

Create bulk operation for a group

.EXAMPLE
PS> Get-DeviceGroup $Group.id | New-BulkOperation -StartDate "10s" -CreationRampSec 15 -Operation @{ c8y_Restart = @{} }

Create bulk operation for a group (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Identifies the target group on which this operation should be performed.
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Group,

        # Time when operations should be created. Defaults to 300s
        [Parameter()]
        [string]
        $StartDate,

        # Delay between every operation creation. (required)
        [Parameter(Mandatory = $true)]
        [float]
        $CreationRampSec,

        # Operation prototype to send to each device in the group (required)
        [Parameter(Mandatory = $true)]
        [object]
        $Operation
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "bulkoperations create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.bulkoperation+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Group `
            | Group-ClientRequests `
            | c8y bulkoperations create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Group `
            | Group-ClientRequests `
            | c8y bulkoperations create $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-Device {
<#
.SYNOPSIS
Create device

.DESCRIPTION
Create a device (managed object) with the special c8y_IsDevice fragment.


.LINK
c8y devices create

.EXAMPLE
PS> New-Device -Name $DeviceName

Create device

.EXAMPLE
PS> New-Device -Name $DeviceName -Data @{ myValue = @{ value1 = $true } }

Create device with custom properties

.EXAMPLE
PS> New-Device -Template "{ name: '$DeviceName' }"


Create device using a template


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device name
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Name,

        # Device type
        [Parameter()]
        [string]
        $Type
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devices create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.customDevice+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Name `
            | Group-ClientRequests `
            | c8y devices create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Name `
            | Group-ClientRequests `
            | c8y devices create $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-DeviceGroup {
<#
.SYNOPSIS
Create device group

.DESCRIPTION
Create a new device group to logically group one or more devices


.LINK
c8y devicegroups create

.EXAMPLE
PS> New-DeviceGroup -Name $GroupName

Create device group

.EXAMPLE
PS> New-DeviceGroup -Name $GroupName -Data @{ "myValue" = @{ value1 = $true } }

Create device group with custom properties


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device group name
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Name,

        # Device group type (c8y_DeviceGroup (root folder) or c8y_DeviceSubGroup (sub folder)). Defaults to c8y_DeviceGroup
        [Parameter()]
        [ValidateSet('c8y_DeviceGroup','c8y_DeviceSubGroup')]
        [string]
        $Type
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devicegroups create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.customDeviceGroup+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Name `
            | Group-ClientRequests `
            | c8y devicegroups create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Name `
            | Group-ClientRequests `
            | c8y devicegroups create $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-Event {
<#
.SYNOPSIS
Create event

.DESCRIPTION
Create a new event for a device

.LINK
c8y events create

.EXAMPLE
PS> New-Event -Device $device.id -Type c8y_TestAlarm -Text "Test event"

Create a new event for a device

.EXAMPLE
PS> Get-Device -Id $device.id | PSc8y\New-Event -Type c8y_TestAlarm -Time "-0s" -Text "Test event"

Create a new event for a device (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # The ManagedObject which is the source of this event.
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device,

        # Time of the event. Defaults to current timestamp.
        [Parameter()]
        [string]
        $Time,

        # Identifies the type of this event.
        [Parameter()]
        [string]
        $Type,

        # Text description of the event.
        [Parameter()]
        [string]
        $Text
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "events create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.event+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y events create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y events create $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-EventBinary {
<#
.SYNOPSIS
Create event binary

.DESCRIPTION
Upload a new binary file to an event

.LINK
c8y events createBinary

.EXAMPLE
PS> New-EventBinary -Id $Event.id -File $TestFile

Add a binary to an event


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Event id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # File to be uploaded as a binary (required)
        [Parameter(Mandatory = $true)]
        [string]
        $File
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "events createBinary"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.event+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y events createBinary $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y events createBinary $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-ExternalId {
<#
.SYNOPSIS
Create external id

.DESCRIPTION
Create a new external id for an existing managed object

.LINK
c8y identity create

.EXAMPLE
PS> New-ExternalId -Device $Device.id -Type "$my_SerialNumber" -Name "myserialnumber"

Create external identity

.EXAMPLE
PS> Get-Device $Device.id | New-ExternalId -Type "$my_SerialNumber" -Name "myserialnumber"

Create external identity (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # The ManagedObject linked to the external ID. (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device,

        # The type of the external identifier as string, e.g. 'com_cumulocity_model_idtype_SerialNumber'.
        [Parameter()]
        [string]
        $Type,

        # The identifier used in the external system that Cumulocity interfaces with.
        [Parameter()]
        [string]
        $Name
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "identity create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.externalId+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y identity create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y identity create $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-ManagedObject {
<#
.SYNOPSIS
Create managed object

.DESCRIPTION
Create a new inventory managed object

.LINK
c8y inventory create

.EXAMPLE
PS> New-ManagedObject -Name "testMO" -Type $type -Data @{ custom_data = @{ value = 1 } }

Create a managed object


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # name
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Name,

        # type
        [Parameter()]
        [string]
        $Type
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "inventory create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.inventory+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Name `
            | Group-ClientRequests `
            | c8y inventory create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Name `
            | Group-ClientRequests `
            | c8y inventory create $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-Measurement {
<#
.SYNOPSIS
Create measurement

.DESCRIPTION
Create a new measurement

.LINK
c8y measurements create

.EXAMPLE
PS> New-Measurement -Device {{ randomdevice }} -Time "0s" -Type "myType" -Data @{ c8y_Winding = @{ temperature = @{ value = 1.2345; unit = "°C" } } }

Create measurement


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # The ManagedObject which is the source of this measurement.
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device,

        # Time of the measurement. Defaults to current timestamp.
        [Parameter()]
        [string]
        $Time,

        # The most specific type of this entire measurement.
        [Parameter()]
        [string]
        $Type
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "measurements create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.measurement+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y measurements create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y measurements create $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-MicroserviceBinary {
<#
.SYNOPSIS
Create microservice binary

.DESCRIPTION
Create/upload a new microservice binary. For the applications of type 'MICROSERVICE' to be available for Cumulocity platform users, a binary zip file must be uploaded.
For the microservice application, the zip file must consist of * cumulocity.json - file describing the deployment
    * image.tar - executable docker image

For the web application, the zip file must include index.html in the root directory.


.LINK
c8y microservices createBinary

.EXAMPLE
PS> New-MicroserviceBinary -Id $App.id -File $MicroserviceZip

Upload microservice binary


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Microservice id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # File to be uploaded as a binary (required)
        [Parameter(Mandatory = $true)]
        [string]
        $File
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "microservices createBinary"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObject+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y microservices createBinary $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y microservices createBinary $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-Operation {
<#
.SYNOPSIS
Create operation

.DESCRIPTION
Create a new operation for an agent or device

.LINK
c8y operations create

.EXAMPLE
PS> New-Operation -Device $device.id -Description "Restart device" -Data @{ c8y_Restart = @{} }

Create operation for a device

.EXAMPLE
PS> Get-Device $device.id | New-Operation -Description "Restart device" -Data @{ c8y_Restart = @{} }

Create operation for a device (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Identifies the target device on which this operation should be performed.
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device,

        # Text description of the operation.
        [Parameter()]
        [string]
        $Description
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "operations create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.operation+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y operations create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y operations create $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-RetentionRule {
<#
.SYNOPSIS
Create retention rule

.DESCRIPTION
Create a new retention rule to managed when data is deleted in the tenant


.LINK
c8y retentionrules create

.EXAMPLE
PS> New-RetentionRule -DataType ALARM -MaximumAge 180

Create a retention rule to delete all alarms after 180 days


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # RetentionRule will be applied to this type of documents, possible values [ALARM, AUDIT, EVENT, MEASUREMENT, OPERATION, *]. (required)
        [Parameter(Mandatory = $true)]
        [ValidateSet('ALARM','AUDIT','EVENT','MEASUREMENT','OPERATION','*')]
        [string]
        $DataType,

        # RetentionRule will be applied to documents with fragmentType.
        [Parameter()]
        [string]
        $FragmentType,

        # RetentionRule will be applied to documents with type.
        [Parameter()]
        [string]
        $Type,

        # RetentionRule will be applied to documents with source.
        [Parameter()]
        [string]
        $Source,

        # Maximum age of document in days. (required)
        [Parameter(Mandatory = $true)]
        [long]
        $MaximumAge,

        # Whether the rule is editable. Can be updated only by management tenant.
        [Parameter()]
        [switch]
        $Editable
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "retentionrules create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.retentionRule+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y retentionrules create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y retentionrules create $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-Tenant {
<#
.SYNOPSIS
Create tenant

.DESCRIPTION
Create a new tenant

.LINK
c8y tenants create

.EXAMPLE
PS> New-Tenant -Company "mycompany" -Domain "mycompany" -AdminName "admin" -Password "mys3curep9d8"

Create a new tenant (from the management tenant)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Company name. Maximum 256 characters (required)
        [Parameter(Mandatory = $true)]
        [string]
        $Company,

        # Domain name to be used for the tenant. Maximum 256 characters (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Domain,

        # Username of the tenant administrator
        [Parameter()]
        [string]
        $AdminName,

        # Password of the tenant administrator
        [Parameter()]
        [string]
        $AdminPass,

        # A contact name, for example an administrator, of the tenant
        [Parameter()]
        [string]
        $ContactName,

        # An international contact phone number
        [Parameter()]
        [string]
        $ContactPhone,

        # The tenant ID. This should be left bank unless you know what you are doing. Will be auto-generated if not present.
        [Parameter()]
        [string]
        $TenantId
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenants create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.tenant+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Domain `
            | Group-ClientRequests `
            | c8y tenants create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Domain `
            | Group-ClientRequests `
            | c8y tenants create $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-TenantOption {
<#
.SYNOPSIS
Create tenant option

.DESCRIPTION
Create tenant option

.LINK
c8y tenantoptions create

.EXAMPLE
PS> New-TenantOption -Category "c8y_cli_tests" -Key "$option1" -Value "1"

Create a tenant option


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Category of option (required)
        [Parameter(Mandatory = $true)]
        [string]
        $Category,

        # Key of option (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Key,

        # Value of option (required)
        [Parameter(Mandatory = $true)]
        [string]
        $Value
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenantoptions create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.option+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Key `
            | Group-ClientRequests `
            | c8y tenantoptions create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Key `
            | Group-ClientRequests `
            | c8y tenantoptions create $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-User {
<#
.SYNOPSIS
Create user

.DESCRIPTION
Create a new user so that they can access the tenant

.LINK
c8y users create

.EXAMPLE
PS> New-user -Username "$Username" -Password "$NewPassword"

Create a user


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # User name, unique for a given domain. Max: 1000 characters
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $UserName,

        # User first name
        [Parameter()]
        [string]
        $FirstName,

        # User last name
        [Parameter()]
        [string]
        $LastName,

        # User phone number. Format: '+[country code][number]', has to be a valid MSISDN
        [Parameter()]
        [string]
        $Phone,

        # User email address
        [Parameter()]
        [string]
        $Email,

        # User activation status (true/false)
        [Parameter()]
        [switch]
        $Enabled,

        # User password. Min: 6, max: 32 characters. Only Latin1 chars allowed
        [Parameter()]
        [string]
        $Password,

        # User activation status (true/false)
        [Parameter()]
        [ValidateSet('true','false')]
        [switch]
        $SendPasswordResetEmail,

        # Custom properties to be added to the user
        [Parameter()]
        [object]
        $CustomProperties,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "users create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.user+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $UserName `
            | Group-ClientRequests `
            | c8y users create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $UserName `
            | Group-ClientRequests `
            | c8y users create $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function New-UserGroup {
<#
.SYNOPSIS
Create user group

.DESCRIPTION
Create a new user group

.LINK
c8y usergroups create

.EXAMPLE
PS> New-UserGroup -Name "$GroupName"

Create a user group


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Group name
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Name,

        # List of device permissions
        [Parameter()]
        [string[]]
        $DeviceProperties,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "usergroups create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.group+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Name `
            | Group-ClientRequests `
            | c8y usergroups create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Name `
            | Group-ClientRequests `
            | c8y usergroups create $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Register-Device {
<#
.SYNOPSIS
Register device

.DESCRIPTION
Register a new device (request)

.LINK
c8y deviceregistration register

.EXAMPLE
PS> Register-Device -Id "ASDF098SD1J10912UD92JDLCNCU8"

Register a new device


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device identifier. Max: 1000 characters. E.g. IMEI (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "deviceregistration register"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.newDeviceRequest+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y deviceregistration register $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y deviceregistration register $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-Agent {
<#
.SYNOPSIS
Delete agent

.DESCRIPTION
Delete an agent from the platform. This will delete all data associated to the agent
(i.e. alarms, events, operations and measurements)


.LINK
c8y agents delete

.EXAMPLE
PS> Remove-Agent -Id $agent.id

Remove agent by id

.EXAMPLE
PS> Remove-Agent -Id $agent.name

Remove agent by name


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Agent ID (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "agents delete"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y agents delete $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y agents delete $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-AlarmCollection {
<#
.SYNOPSIS
Delete alarm collection

.DESCRIPTION
Delete a collection of alarms by a given filter

.LINK
c8y alarms deleteCollection

.EXAMPLE
PS> Remove-AlarmCollection -Device "{{ randomdevice }}" -Severity MAJOR

Remove alarms on the device with the severity set to MAJOR

.EXAMPLE
PS> Remove-AlarmCollection -Device $device.id -DateFrom "-10m" -Status ACTIVE

Remove alarms on the device which are active and created in the last 10 minutes

.EXAMPLE
PS> Get-Device -Id $device.id | PSc8y\Remove-AlarmCollection -DateFrom "-10m" -Status ACTIVE

Remove alarms on the device which are active and created in the last 10 minutes (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Source device id.
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device,

        # Start date or date and time of alarm occurrence.
        [Parameter()]
        [string]
        $DateFrom,

        # End date or date and time of alarm occurrence.
        [Parameter()]
        [string]
        $DateTo,

        # Alarm type.
        [Parameter()]
        [string]
        $Type,

        # Alarm fragment type.
        [Parameter()]
        [string]
        $FragmentType,

        # Comma separated alarm statuses, for example ACTIVE,CLEARED.
        [Parameter()]
        [ValidateSet('ACTIVE','ACKNOWLEDGED','CLEARED')]
        [string]
        $Status,

        # Alarm severity, for example CRITICAL, MAJOR, MINOR or WARNING.
        [Parameter()]
        [ValidateSet('CRITICAL','MAJOR','MINOR','WARNING')]
        [string]
        $Severity,

        # When set to true only resolved alarms will be removed (the one with status CLEARED), false means alarms with status ACTIVE or ACKNOWLEDGED.
        [Parameter()]
        [switch]
        $Resolved,

        # When set to true also alarms for related source assets will be removed. When this parameter is provided also source must be defined.
        [Parameter()]
        [switch]
        $WithSourceAssets,

        # When set to true also alarms for related source devices will be removed. When this parameter is provided also source must be defined.
        [Parameter()]
        [switch]
        $WithSourceDevices
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "alarms deleteCollection"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y alarms deleteCollection $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y alarms deleteCollection $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-Application {
<#
.SYNOPSIS
Delete application

.DESCRIPTION
The application can only be removed when its availability is PRIVATE or in other case when it has no subscriptions.

.LINK
c8y applications delete

.EXAMPLE
PS> Remove-Application -Id $App.id

Delete an application by id

.EXAMPLE
PS> Remove-Application -Id $App.name

Delete an application by name


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Application id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "applications delete"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y applications delete $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y applications delete $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-ApplicationBinary {
<#
.SYNOPSIS
Delete application binary

.DESCRIPTION
Remove an application binaries related to the given application
The active version can not be deleted and the server will throw an error if you try.


.LINK
c8y applications deleteApplicationBinary

.EXAMPLE
PS> Remove-ApplicationBinary -Application $app.id -BinaryId $appBinary.id

Remove an application binary related to a Hosted (web) application

.EXAMPLE
PS> Get-ApplicationBinaryCollection -Id $app.id | Remove-ApplicationBinary -Application $app.id

Remove all application binaries (except for the active one) for an application (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Application id (required)
        [Parameter(Mandatory = $true)]
        [object[]]
        $Application,

        # Application binary id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [Alias("id")]
        [string[]]
        $BinaryId
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "applications deleteApplicationBinary"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $BinaryId `
            | Group-ClientRequests `
            | c8y applications deleteApplicationBinary $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $BinaryId `
            | Group-ClientRequests `
            | c8y applications deleteApplicationBinary $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-Asset {
<#
.SYNOPSIS
Unassign asset from managed object

.DESCRIPTION
Unassign/delete an asset from an existing managed object

.LINK
c8y inventory assets unassign

.EXAMPLE
PS> Remove-Asset -Id $Group.id -Child $ChildDevice.id

Unassign a child device from its parent asset


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Asset id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Child id
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Child
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "inventory assets unassign"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Child `
            | Group-ClientRequests `
            | c8y inventory assets unassign $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Child `
            | Group-ClientRequests `
            | c8y inventory assets unassign $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-Binary {
<#
.SYNOPSIS
Delete binary

.DESCRIPTION
Delete a binary from the tenant. This delete operation can not be undone.

.LINK
c8y binaries delete

.EXAMPLE
PS> Remove-Binary -Id $Binary.id

Delete a binary


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Inventory binary id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "binaries delete"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y binaries delete $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y binaries delete $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-BulkOperation {
<#
.SYNOPSIS
Delete bulk operation

.DESCRIPTION
Delete bulk operation/s. Only bulk operations that are in ACTIVE or IN_PROGRESS can be deleted

.LINK
c8y bulkoperations delete

.EXAMPLE
PS> Remove-BulkOperation -Id $BulkOp.id

Remove bulk operation by id


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Bulk Operation id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "bulkoperations delete"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y bulkoperations delete $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y bulkoperations delete $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-ChildAddition {
<#
.SYNOPSIS
Unassign child addition

.DESCRIPTION
Unassign/delete a child addition from an existing managed object

.LINK
c8y inventory additions unassign

.EXAMPLE
PS> Remove-ChildAddition -Id $software.id -ChildId $version.id

Unassign a child addition from its parent managed object


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Managed object id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Child managed object id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $ChildId
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "inventory additions unassign"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $ChildId `
            | Group-ClientRequests `
            | c8y inventory additions unassign $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $ChildId `
            | Group-ClientRequests `
            | c8y inventory additions unassign $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-ChildDeviceFromDevice {
<#
.SYNOPSIS
Delete child device reference

.DESCRIPTION
Delete child device reference

.LINK
c8y devices unassignChild

.EXAMPLE
PS> Remove-ChildDeviceFromDevice -Device $Device.id -ChildDevice $ChildDevice.id

Unassign a child device from its parent device


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # ManagedObject id (required)
        [Parameter(Mandatory = $true)]
        [object[]]
        $Device,

        # Child device reference (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $ChildDevice
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devices unassignChild"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $ChildDevice `
            | Group-ClientRequests `
            | c8y devices unassignChild $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $ChildDevice `
            | Group-ClientRequests `
            | c8y devices unassignChild $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-Device {
<#
.SYNOPSIS
Delete device

.DESCRIPTION
Delete an existing device by id or name. Deleting the object will remove all of its data (i.e. alarms, events, operations and measurements)


.LINK
c8y devices delete

.EXAMPLE
PS> Remove-Device -Id $device.id

Remove device by id

.EXAMPLE
PS> Remove-Device -Id $device.name

Remove device by name


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device ID (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Remove all child devices and child assets will be deleted recursively. By default, the delete operation is propagated to the subgroups only if the deleted object is a group
        [Parameter()]
        [switch]
        $Cascade
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devices delete"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y devices delete $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y devices delete $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-DeviceFromGroup {
<#
.SYNOPSIS
Unassign device from group

.DESCRIPTION
Unassign/delete a device from a group

.LINK
c8y devicegroups unassignDevice

.EXAMPLE
PS> Remove-DeviceFromGroup -Group $Group.id -ChildDevice $ChildDevice.id

Unassign a child device from its parent asset


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Asset id (required)
        [Parameter(Mandatory = $true)]
        [object[]]
        $Group,

        # Child device (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $ChildDevice
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devicegroups unassignDevice"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $ChildDevice `
            | Group-ClientRequests `
            | c8y devicegroups unassignDevice $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $ChildDevice `
            | Group-ClientRequests `
            | c8y devicegroups unassignDevice $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-DeviceGroup {
<#
.SYNOPSIS
Delete device group

.DESCRIPTION
Delete an existing device group, and optionally all of it's children


.LINK
c8y devicegroups delete

.EXAMPLE
PS> Remove-DeviceGroup -Id $group.id

Remove device group by id

.EXAMPLE
PS> Remove-DeviceGroup -Id $group.name

Remove device group by name


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device group ID (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Remove all child devices and child assets will be deleted recursively. By default, the delete operation is propagated to the subgroups only if the deleted object is a group
        [Parameter()]
        [switch]
        $Cascade
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devicegroups delete"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y devicegroups delete $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y devicegroups delete $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-DeviceRequest {
<#
.SYNOPSIS
Delete device request

.DESCRIPTION
Delete an existing device registration request

.LINK
c8y deviceregistration delete

.EXAMPLE
PS> Remove-DeviceRequest -Id "$serial_91019192078"

Delete a new device request


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # New Device Request ID (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "deviceregistration delete"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y deviceregistration delete $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y deviceregistration delete $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-Event {
<#
.SYNOPSIS
Delete event

.DESCRIPTION
Delete an existing event

.LINK
c8y events delete

.EXAMPLE
PS> Remove-Event -Id {{ NewEvent }}

Delete an event


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Event id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "events delete"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y events delete $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y events delete $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-EventBinary {
<#
.SYNOPSIS
Delete event binary

.DESCRIPTION
Delete a binary which has been attached to an event


.LINK
c8y events deleteBinary

.EXAMPLE
PS> Remove-EventBinary -Id $Event.id

Delete an binary attached to an event


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Event id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "events deleteBinary"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y events deleteBinary $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y events deleteBinary $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-EventCollection {
<#
.SYNOPSIS
Delete event collection

.DESCRIPTION
Delete a collection of events by using a filter

.LINK
c8y events deleteCollection

.EXAMPLE
PS> Remove-EventCollection -Type my_CustomType -DateFrom "-10d"

Remove events with type 'my_CustomType' that were created in the last 10 days

.EXAMPLE
PS> Remove-EventCollection -Device "{{ randomdevice }}"

Remove events from a device


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device ID
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device,

        # Event type.
        [Parameter()]
        [string]
        $Type,

        # Fragment name from event.
        [Parameter()]
        [string]
        $FragmentType,

        # Start date or date and time of event occurrence.
        [Parameter()]
        [string]
        $DateFrom,

        # End date or date and time of event occurrence.
        [Parameter()]
        [string]
        $DateTo,

        # Return the newest instead of the oldest events. Must be used with dateFrom and dateTo parameters
        [Parameter()]
        [switch]
        $Revert
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "events deleteCollection"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y events deleteCollection $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y events deleteCollection $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-ExternalId {
<#
.SYNOPSIS
Delete external id

.DESCRIPTION
Delete an existing external id. This does not delete the device managed object

.LINK
c8y identity delete

.EXAMPLE
PS> Remove-ExternalId -Type "my_SerialNumber" -Name "myserialnumber2"

Delete external identity


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # External identity type
        [Parameter()]
        [string]
        $Type,

        # External identity id/name (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Name
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "identity delete"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Name `
            | Group-ClientRequests `
            | c8y identity delete $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Name `
            | Group-ClientRequests `
            | c8y identity delete $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-GroupFromGroup {
<#
.SYNOPSIS
Delete child group reference

.DESCRIPTION
Delete child group reference

.LINK
c8y devicegroups unassignGroup

.EXAMPLE
PS> Remove-GroupFromGroup -Id $Group.id -Child $ChildGroup.id

Unassign a child group from its parent


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device group (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Child device group (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Child
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devicegroups unassignGroup"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Child `
            | Group-ClientRequests `
            | c8y devicegroups unassignGroup $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Child `
            | Group-ClientRequests `
            | c8y devicegroups unassignGroup $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-ManagedObject {
<#
.SYNOPSIS
Delete managed object

.DESCRIPTION
Delete an existing managed object

.LINK
c8y inventory delete

.EXAMPLE
PS> Remove-ManagedObject -Id $mo.id

Delete a managed object

.EXAMPLE
PS> Get-ManagedObject -Id $mo.id | Remove-ManagedObject

Delete a managed object (using pipeline)

.EXAMPLE
PS> Get-ManagedObject -Id $Device.id | Remove-ManagedObject -Cascade

Delete a managed object and all child devices


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # ManagedObject id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Remove all child devices and child assets will be deleted recursively. By default, the delete operation is propagated to the subgroups only if the deleted object is a group
        [Parameter()]
        [switch]
        $Cascade
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "inventory delete"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y inventory delete $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y inventory delete $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-Measurement {
<#
.SYNOPSIS
Delete measurement

.DESCRIPTION
Delete an existing measurement

.LINK
c8y measurements delete

.EXAMPLE
PS> Remove-Measurement -id $Measurement.id

Delete measurement


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Measurement id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "measurements delete"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y measurements delete $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y measurements delete $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-MeasurementCollection {
<#
.SYNOPSIS
Delete measurement collection

.DESCRIPTION
Delete measurements using a filter

.LINK
c8y measurements deleteCollection

.EXAMPLE
PS> Remove-MeasurementCollection -Device $Measurement.source.id

Delete measurement collection for a device


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device ID
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device,

        # Measurement type.
        [Parameter()]
        [string]
        $Type,

        # Fragment name from measurement (deprecated).
        [Parameter()]
        [string]
        $FragmentType,

        # Start date or date and time of measurement occurrence.
        [Parameter()]
        [string]
        $DateFrom,

        # End date or date and time of measurement occurrence.
        [Parameter()]
        [string]
        $DateTo
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "measurements deleteCollection"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y measurements deleteCollection $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y measurements deleteCollection $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-Microservice {
<#
.SYNOPSIS
Delete microservice

.DESCRIPTION
Info: The application can only be removed when its availability is PRIVATE or in other case when it has no subscriptions.

.LINK
c8y microservices delete

.EXAMPLE
PS> Remove-Microservice -Id $App.id

Delete a microservice by id

.EXAMPLE
PS> Remove-Microservice -Id $App.name

Delete a microservice by name


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Microservice id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "microservices delete"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y microservices delete $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y microservices delete $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-OperationCollection {
<#
.SYNOPSIS
Delete operation collection

.DESCRIPTION
Delete a collection of operations using a set of filter criteria. Be careful when deleting operations. Where possible update operations to FAILED (with a failure reason) instead of deleting them as it is easier to track.


.LINK
c8y operations deleteCollection

.EXAMPLE
PS> Remove-OperationCollection -Device "{{ randomdevice }}" -Status PENDING

Remove all pending operations for a given device


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Agent ID
        [Parameter()]
        [object[]]
        $Agent,

        # Device ID
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device,

        # Start date or date and time of operation.
        [Parameter()]
        [string]
        $DateFrom,

        # End date or date and time of operation.
        [Parameter()]
        [string]
        $DateTo,

        # Operation status, can be one of SUCCESSFUL, FAILED, EXECUTING or PENDING.
        [Parameter()]
        [ValidateSet('PENDING','EXECUTING','SUCCESSFUL','FAILED')]
        [string]
        $Status
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "operations deleteCollection"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y operations deleteCollection $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y operations deleteCollection $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-RetentionRule {
<#
.SYNOPSIS
Delete retention rule

.DESCRIPTION
Delete an existing retention rule


.LINK
c8y retentionrules delete

.EXAMPLE
PS> Remove-RetentionRule -Id $RetentionRule.id

Delete a retention rule

.EXAMPLE
PS> Get-RetentionRule -Id $RetentionRule.id | Remove-RetentionRule

Delete a retention rule (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Retention rule id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "retentionrules delete"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y retentionrules delete $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y retentionrules delete $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-RoleFromGroup {
<#
.SYNOPSIS
Unassign role from group

.DESCRIPTION
Unassign/delete role from a group

.LINK
c8y userroles deleteRoleFromGroup

.EXAMPLE
PS> Remove-RoleFromGroup -Group $UserGroup.id -Role "ROLE_MEASUREMENT_READ"

Remove a role from the given user group


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Group id (required)
        [Parameter(Mandatory = $true)]
        [object[]]
        $Group,

        # Role name, e.g. ROLE_TENANT_MANAGEMENT_ADMIN (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Role,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "userroles deleteRoleFromGroup"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Role `
            | Group-ClientRequests `
            | c8y userroles deleteRoleFromGroup $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Role `
            | Group-ClientRequests `
            | c8y userroles deleteRoleFromGroup $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-RoleFromUser {
<#
.SYNOPSIS
Unassign role from user

.DESCRIPTION
Unassign/delete role from a user

.LINK
c8y userroles deleteRoleFromUser

.EXAMPLE
PS> Remove-RoleFromUser -User $User.id -Role "ROLE_MEASUREMENT_READ"

Remove a role from the given user


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # User (required)
        [Parameter(Mandatory = $true)]
        [object[]]
        $User,

        # Role name (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Role,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "userroles deleteRoleFromUser"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Role `
            | Group-ClientRequests `
            | c8y userroles deleteRoleFromUser $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Role `
            | Group-ClientRequests `
            | c8y userroles deleteRoleFromUser $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-Tenant {
<#
.SYNOPSIS
Delete tenant

.DESCRIPTION
Delete an existing tenant

.LINK
c8y tenants delete

.EXAMPLE
PS> Remove-Tenant -Id mycompany

Delete a tenant by name (from the management tenant)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Tenant id
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenants delete"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y tenants delete $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y tenants delete $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-TenantOption {
<#
.SYNOPSIS
Delete tenant option

.DESCRIPTION
Delete an existing tenant option

.LINK
c8y tenantoptions delete

.EXAMPLE
PS> Remove-TenantOption -Category "c8y_cli_tests" -Key "$option3"

Delete a tenant option


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Tenant Option category (required)
        [Parameter(Mandatory = $true)]
        [string]
        $Category,

        # Tenant Option key (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Key
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenantoptions delete"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Key `
            | Group-ClientRequests `
            | c8y tenantoptions delete $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Key `
            | Group-ClientRequests `
            | c8y tenantoptions delete $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-User {
<#
.SYNOPSIS
Delete user

.DESCRIPTION
Delete a user from a tenant. This will remove the user completely from the tenant and can not be reversed.
Alternatively a user can be disabled via updating the users properties instead of deleting the user.


.LINK
c8y users delete

.EXAMPLE
PS> Remove-User -Id $User.id

Delete a user


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # User id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "users delete"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y users delete $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y users delete $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-UserFromGroup {
<#
.SYNOPSIS
Delete user from group

.DESCRIPTION
Delete an existing user from a user group

.LINK
c8y userreferences deleteUserFromGroup

.EXAMPLE
PS> Remove-UserFromGroup -Group $Group.id -User $User.id

Add a user to a user group


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Group ID (required)
        [Parameter(Mandatory = $true)]
        [object[]]
        $Group,

        # User id/username (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $User,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "userreferences deleteUserFromGroup"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $User `
            | Group-ClientRequests `
            | c8y userreferences deleteUserFromGroup $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $User `
            | Group-ClientRequests `
            | c8y userreferences deleteUserFromGroup $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Remove-UserGroup {
<#
.SYNOPSIS
Delete user group

.DESCRIPTION
Delete an existing user group

.LINK
c8y usergroups delete

.EXAMPLE
PS> Remove-UserGroup -Id $Group.id

Delete a user group

.EXAMPLE
PS> Get-UserGroupByName -Name $Group.name | Remove-UserGroup

Delete a user group (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Group id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Delete"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "usergroups delete"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y usergroups delete $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y usergroups delete $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Request-DeviceCredentials {
<#
.SYNOPSIS
Request device credentials

.DESCRIPTION
Device credentials can be enquired by devices that do not have credentials for accessing a tenant yet. Since the device does not have credentials yet, a set of fixed credentials is used for this API. The credentials can be obtained by contacting support. Do not use your tenant credentials with this API.

.LINK
c8y deviceregistration getCredentials

.EXAMPLE
PS> Request-DeviceCredentials -Id "device-AD76-matrixer"

Request credentials for a new device


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device identifier. Max: 1000 characters. E.g. IMEI (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "deviceregistration getCredentials"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.deviceCredentials+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y deviceregistration getCredentials $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y deviceregistration getCredentials $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Reset-UserPassword {
<#
.SYNOPSIS
Reset user password

.DESCRIPTION
The password can be reset either by issuing a password reset email (default), or be specifying a new password.

.LINK
c8y users resetUserPassword

.EXAMPLE
PS> Reset-UserPassword -Id $User.id -Dry 2>&1

Resets a user's password by sending a reset email to the user

.EXAMPLE
PS> Reset-UserPassword -Id $User.id -NewPassword (New-RandomPassword)

Resets a user's password by generating a new password


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # User id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # New user password. Min: 6, max: 32 characters. Only Latin1 chars allowed
        [Parameter()]
        [string]
        $NewPassword,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "users resetUserPassword"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.user+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y users resetUserPassword $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y users resetUserPassword $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Set-DeviceRequiredAvailability {
<#
.SYNOPSIS
Set required availability

.DESCRIPTION
Set the required availability of a device. Devices that have not sent any message in the response interval are considered unavailable. Response interval can have value between -32768 and 32767 and any values out of range will be shrink to range borders. Such devices are marked as unavailable (see below) and an unavailability alarm is raised. Devices with a response interval of zero minutes are considered to be under maintenance. No alarm is raised while a device is under maintenance. Devices that do not contain 'c8y_RequiredAvailability' are not monitored.

.LINK
c8y devices setRequiredAvailability

.EXAMPLE
PS> Set-DeviceRequiredAvailability -Device $device.id -Interval 10

Set the required availability of a device by name to 10 minutes

.EXAMPLE
PS> Get-ManagedObject -Id $device.id | PSc8y\Set-DeviceRequiredAvailability -Interval 10

Set the required availability of a device (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device ID (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device,

        # Interval in minutes (required)
        [Parameter(Mandatory = $true)]
        [long]
        $Interval
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devices setRequiredAvailability"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.inventory+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y devices setRequiredAvailability $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y devices setRequiredAvailability $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-Agent {
<#
.SYNOPSIS
Update agent

.DESCRIPTION
Update properties of an agent

.LINK
c8y agents update

.EXAMPLE
PS> Update-Agent -Id $agent.id -NewName "MyNewName"

Update agent by id

.EXAMPLE
PS> Update-Agent -Id $agent.name -NewName "MyNewName"

Update agent by name

.EXAMPLE
PS> Update-Agent -Id $agent.name -Data @{ "myValue" = @{ value1 = $true } }

Update agent custom properties


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Agent ID (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Agent name
        [Parameter()]
        [string]
        $NewName
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "agents update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.customAgent+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y agents update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y agents update $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-Alarm {
<#
.SYNOPSIS
Update alarm

.DESCRIPTION
Update an alarm by its id

.LINK
c8y alarms update

.EXAMPLE
PS> Update-Alarm -Id $Alarm.id -Status ACKNOWLEDGED

Acknowledge an existing alarm

.EXAMPLE
PS> Get-Alarm -Id $Alarm.id | PSc8y\Update-Alarm -Status ACKNOWLEDGED

Acknowledge an existing alarm (using pipeline)

.EXAMPLE
PS> Update-Alarm -Id $Alarm.id -Severity CRITICAL

Update severity of an existing alarm to CRITICAL


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Alarm id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Comma separated alarm statuses, for example ACTIVE,CLEARED.
        [Parameter()]
        [ValidateSet('ACTIVE','ACKNOWLEDGED','CLEARED')]
        [string]
        $Status,

        # Alarm severity, for example CRITICAL, MAJOR, MINOR or WARNING.
        [Parameter()]
        [ValidateSet('CRITICAL','MAJOR','MINOR','WARNING')]
        [string]
        $Severity,

        # Text description of the alarm.
        [Parameter()]
        [string]
        $Text
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "alarms update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.alarm+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y alarms update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y alarms update $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-AlarmCollection {
<#
.SYNOPSIS
Update alarm collection

.DESCRIPTION
Update the status of a collection of alarms by using a filter. Currently only the status of alarms can be changed

.LINK
c8y alarms updateCollection

.EXAMPLE
PS> Update-AlarmCollection -Device $Device.id -Status ACTIVE -NewStatus ACKNOWLEDGED

Update the status of all active alarms on a device to ACKNOWLEDGED

.EXAMPLE
PS> Get-Device -Id $Device.id | PSc8y\Update-AlarmCollection -Status ACTIVE -NewStatus ACKNOWLEDGED

Update the status of all active alarms on a device to ACKNOWLEDGED (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # The ManagedObject that the alarm originated from
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Device,

        # The status of the alarm: ACTIVE, ACKNOWLEDGED or CLEARED. If status was not appeared, new alarm will have status ACTIVE. Must be upper-case.
        [Parameter()]
        [ValidateSet('ACTIVE','ACKNOWLEDGED','CLEARED')]
        [string]
        $Status,

        # The severity of the alarm: CRITICAL, MAJOR, MINOR or WARNING. Must be upper-case.
        [Parameter()]
        [ValidateSet('CRITICAL','MAJOR','MINOR','WARNING')]
        [string]
        $Severity,

        # When set to true only resolved alarms will be removed (the one with status CLEARED), false means alarms with status ACTIVE or ACKNOWLEDGED.
        [Parameter()]
        [switch]
        $Resolved,

        # Start date or date and time of alarm occurrence.
        [Parameter()]
        [string]
        $DateFrom,

        # End date or date and time of alarm occurrence.
        [Parameter()]
        [string]
        $DateTo,

        # New status to be applied to all of the matching alarms (required)
        [Parameter(Mandatory = $true)]
        [ValidateSet('ACTIVE','ACKNOWLEDGED','CLEARED')]
        [string]
        $NewStatus
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "alarms updateCollection"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = ""
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y alarms updateCollection $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y alarms updateCollection $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-Application {
<#
.SYNOPSIS
Update application details

.DESCRIPTION
Update details of an existing application

.LINK
c8y applications update

.EXAMPLE
PS> Update-Application -Id $App.name -Availability "MARKET"

Update application availability to MARKET


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Application id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Name of application
        [Parameter()]
        [string]
        $Name,

        # Shared secret of application
        [Parameter()]
        [string]
        $Key,

        # Access level for other tenants. Possible values are : MARKET, PRIVATE (default)
        [Parameter()]
        [ValidateSet('MARKET','PRIVATE')]
        [string]
        $Availability,

        # contextPath of the hosted application
        [Parameter()]
        [string]
        $ContextPath,

        # URL to application base directory hosted on an external server
        [Parameter()]
        [string]
        $ResourcesUrl,

        # authorization username to access resourcesUrl
        [Parameter()]
        [string]
        $ResourcesUsername,

        # authorization password to access resourcesUrl
        [Parameter()]
        [string]
        $ResourcesPassword,

        # URL to the external application
        [Parameter()]
        [string]
        $ExternalUrl
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "applications update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.application+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y applications update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y applications update $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-Binary {
<#
.SYNOPSIS
Update binary

.DESCRIPTION
Update an existing binary


.LINK
c8y binaries update

.EXAMPLE
PS> Update-Binary -Id $Binary1.id -File $File2

Update an existing binary file


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Inventory binary id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # File to be uploaded as a binary (required)
        [Parameter(Mandatory = $true)]
        [string]
        $File
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "binaries update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObject+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y binaries update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y binaries update $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-BulkOperation {
<#
.SYNOPSIS
Update bulk operation

.DESCRIPTION
Update bulk operation. Making update on a started bulk operation cancels it and creates/schedules a new one.

.LINK
c8y bulkoperations update

.EXAMPLE
PS> Update-BulkOperation -Id $BulkOp.id -CreationRamp 1.5

Update bulk operation wait period between the creation of each operation to 1.5 seconds


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Bulk Operation id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Delay between every operation creation. (required)
        [Parameter(Mandatory = $true)]
        [float]
        $CreationRampSec
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "bulkoperations update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.bulkoperation+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y bulkoperations update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y bulkoperations update $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-CurrentApplication {
<#
.SYNOPSIS
Update current application

.DESCRIPTION
Required authentication with bootstrap user

.LINK
c8y currentapplication update

.EXAMPLE
PS> Update-CurrentApplication -Data @{ myCustomProp = @{ value1 = 1}}

Update custom properties of the current application (requires using application credentials)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Name of application
        [Parameter()]
        [string]
        $Name,

        # Shared secret of application
        [Parameter()]
        [string]
        $Key,

        # Application will be applied to this type of documents, possible values [ALARM, AUDIT, EVENT, MEASUREMENT, OPERATION, *].
        [Parameter()]
        [ValidateSet('MARKET','PRIVATE')]
        [string]
        $Availability,

        # contextPath of the hosted application
        [Parameter()]
        [string]
        $ContextPath,

        # URL to application base directory hosted on an external server
        [Parameter()]
        [string]
        $ResourcesUrl,

        # authorization username to access resourcesUrl
        [Parameter()]
        [string]
        $ResourcesUsername,

        # authorization password to access resourcesUrl
        [Parameter()]
        [string]
        $ResourcesPassword,

        # URL to the external application
        [Parameter()]
        [string]
        $ExternalUrl
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "currentapplication update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.application+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y currentapplication update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y currentapplication update $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-CurrentUser {
<#
.SYNOPSIS
Update current user

.DESCRIPTION
Update properties or settings of your user such as first/last name, email or password


.LINK
c8y currentuser update

.EXAMPLE
PS> Update-CurrentUser -LastName "Smith"

Update the current user's last name


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # User first name
        [Parameter()]
        [string]
        $FirstName,

        # User last name
        [Parameter()]
        [string]
        $LastName,

        # User phone number. Format: '+[country code][number]', has to be a valid MSISDN
        [Parameter()]
        [string]
        $Phone,

        # User email address
        [Parameter()]
        [string]
        $Email,

        # User activation status (true/false)
        [Parameter()]
        [ValidateSet('true','false')]
        [string]
        $Enabled,

        # User password. Min: 6, max: 32 characters. Only Latin1 chars allowed
        [Parameter()]
        [string]
        $Password
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "currentuser update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.currentUser+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y currentuser update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y currentuser update $c8yargs
        }
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-DataBrokerConnector {
<#
.SYNOPSIS
Update data broker

.DESCRIPTION
Update an existing data broker connector

.LINK
c8y databroker update

.EXAMPLE
PS> Update-DataBroker -Id 12345 -Status SUSPENDED

Change the status of a specific data broker connector by given connector id


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Data broker connector id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # DataBroker status [SUSPENDED]. (required)
        [Parameter(Mandatory = $true)]
        [ValidateSet('SUSPENDED')]
        [string]
        $Status
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "databroker update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.databrokerConnector+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y databroker update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y databroker update $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-Device {
<#
.SYNOPSIS
Update device

.DESCRIPTION
Update properties of an existing device

.LINK
c8y devices update

.EXAMPLE
PS> Update-Device -Id $device.id -NewName "MyNewName"

Update device by id

.EXAMPLE
PS> Update-Device -Id $device.name -NewName "MyNewName"

Update device by name

.EXAMPLE
PS> Update-Device -Id $device.name -Data @{ "myValue" = @{ value1 = $true } }

Update device custom properties


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device ID (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Device name
        [Parameter()]
        [string]
        $NewName
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devices update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.customDevice+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y devices update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y devices update $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-DeviceGroup {
<#
.SYNOPSIS
Update device group

.DESCRIPTION
Update properties of an existing device group, for example name or any other custom properties.


.LINK
c8y devicegroups update

.EXAMPLE
PS> Update-DeviceGroup -Id $group.id -Name "MyNewName"

Update device group by id

.EXAMPLE
PS> Update-DeviceGroup -Id $group.name -Name "MyNewName"

Update device group by name

.EXAMPLE
PS> Update-DeviceGroup -Id $group.name -Data @{ "myValue" = @{ value1 = $true } }

Update device group custom properties


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device group ID (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Device group name
        [Parameter()]
        [string]
        $Name
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devicegroups update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.customDeviceGroup+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y devicegroups update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y devicegroups update $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-Event {
<#
.SYNOPSIS
Update event

.DESCRIPTION
Update an existing event

.LINK
c8y events update

.EXAMPLE
PS> Update-Event -Id $Event.id -Text "example text 1"

Update the text field of an existing event

.EXAMPLE
PS> Update-Event -Id $Event.id -Data @{ my_event = @{ active = $true } }

Update custom properties of an existing event

.EXAMPLE
PS> Get-Event -Id $Event.id | Update-Event -Data @{ my_event = @{ active = $true } }

Update custom properties of an existing event (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Event id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Text description of the event.
        [Parameter()]
        [string]
        $Text
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "events update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.event+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y events update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y events update $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-EventBinary {
<#
.SYNOPSIS
Update event binary

.DESCRIPTION
Update an existing event binary


.LINK
c8y events updateBinary

.EXAMPLE
PS> Update-EventBinary -Id $Event.id -File $TestFile

Update a binary related to an event


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Event id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # File to be uploaded as a binary (required)
        [Parameter(Mandatory = $true)]
        [string]
        $File
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "events updateBinary"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.event+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y events updateBinary $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y events updateBinary $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-ManagedObject {
<#
.SYNOPSIS
Update inventory

.DESCRIPTION
Update an existing managed object

.LINK
c8y inventory update

.EXAMPLE
PS> Update-ManagedObject -Id $mo.id -Data @{ com_my_props = @{ value = 1 } }

Update a managed object

.EXAMPLE
PS> Get-ManagedObject -Id $mo.id | Update-ManagedObject -Data @{ com_my_props = @{ value = 1 } }

Update a managed object (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # ManagedObject id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # name
        [Parameter()]
        [string]
        $NewName
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "inventory update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.inventory+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y inventory update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y inventory update $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-Microservice {
<#
.SYNOPSIS
Update microservice details

.DESCRIPTION
Update details of an existing microservice, i.e. availability, context path etc.


.LINK
c8y microservices update

.EXAMPLE
PS> Update-Microservice -Id $App.id -Availability "MARKET"

Update microservice availability to MARKET


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Microservice id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Shared secret of microservice
        [Parameter()]
        [string]
        $Key,

        # Access level for other tenants. Possible values are : MARKET, PRIVATE (default)
        [Parameter()]
        [ValidateSet('MARKET','PRIVATE')]
        [string]
        $Availability,

        # contextPath of the hosted application
        [Parameter()]
        [string]
        $ContextPath,

        # URL to microservice base directory hosted on an external server
        [Parameter()]
        [string]
        $ResourcesUrl
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "microservices update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.application+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y microservices update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y microservices update $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-Operation {
<#
.SYNOPSIS
Update operation

.DESCRIPTION
Update an operation. This is commonly used to change an operation's status. For example the operation can be set to FAILED along with a failure reason.


.LINK
c8y operations update

.EXAMPLE
PS> Update-Operation -Id {{ NewOperation }} -Status EXECUTING

Update an operation

.EXAMPLE
PS> Get-OperationCollection -Device $Agent.id -Status PENDING | Update-Operation -Status FAILED -FailureReason "manually cancelled"

Update multiple operations


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Operation id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # Operation status, can be one of SUCCESSFUL, FAILED, EXECUTING or PENDING.
        [Parameter()]
        [ValidateSet('PENDING','EXECUTING','SUCCESSFUL','FAILED')]
        [string]
        $Status,

        # Reason for the failure. Use when setting status to FAILED
        [Parameter()]
        [string]
        $FailureReason
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "operations update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.operation+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y operations update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y operations update $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-RetentionRule {
<#
.SYNOPSIS
Update retention rule

.DESCRIPTION
Update an existing retention rule, i.e. change maximum number of days or the data type.


.LINK
c8y retentionrules update

.EXAMPLE
PS> Update-RetentionRule -Id $RetentionRule.id -DataType MEASUREMENT -FragmentType "custom_FragmentType"

Update a retention rule

.EXAMPLE
PS> Get-RetentionRule -Id $RetentionRule.id | Update-RetentionRule -DataType MEASUREMENT -FragmentType "custom_FragmentType"

Update a retention rule (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Retention rule id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # RetentionRule will be applied to this type of documents, possible values [ALARM, AUDIT, EVENT, MEASUREMENT, OPERATION, *]. (required)
        [Parameter(Mandatory = $true)]
        [ValidateSet('ALARM','AUDIT','EVENT','MEASUREMENT','OPERATION','*')]
        [string]
        $DataType,

        # RetentionRule will be applied to documents with fragmentType.
        [Parameter()]
        [string]
        $FragmentType,

        # RetentionRule will be applied to documents with type.
        [Parameter()]
        [string]
        $Type,

        # RetentionRule will be applied to documents with source.
        [Parameter()]
        [string]
        $Source,

        # Maximum age of document in days.
        [Parameter()]
        [long]
        $MaximumAge,

        # Whether the rule is editable. Can be updated only by management tenant.
        [Parameter()]
        [switch]
        $Editable
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "retentionrules update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.retentionRule+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y retentionrules update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y retentionrules update $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-Tenant {
<#
.SYNOPSIS
Update tenant

.DESCRIPTION
Update an existing tenant

.LINK
c8y tenants update

.EXAMPLE
PS> Update-Tenant -Id mycompany -ContactName "John Smith"

Update a tenant by name (from the management tenant)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Tenant id
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object]
        $Id,

        # Company name. Maximum 256 characters
        [Parameter()]
        [string]
        $Company,

        # Domain name to be used for the tenant. Maximum 256 characters
        [Parameter()]
        [string]
        $Domain,

        # Username of the tenant administrator
        [Parameter()]
        [string]
        $AdminName,

        # Password of the tenant administrator
        [Parameter()]
        [string]
        $AdminPass,

        # A contact name, for example an administrator, of the tenant
        [Parameter()]
        [string]
        $ContactName,

        # An international contact phone number
        [Parameter()]
        [string]
        $ContactPhone
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenants update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.tenant+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y tenants update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y tenants update $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-TenantOption {
<#
.SYNOPSIS
Update tenant option

.DESCRIPTION
Update an existing tenant option

.LINK
c8y tenantoptions update

.EXAMPLE
PS> Update-TenantOption -Category "c8y_cli_tests" -Key "$option4" -Value "0"

Update a tenant option


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Tenant Option category (required)
        [Parameter(Mandatory = $true)]
        [string]
        $Category,

        # Tenant Option key (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Key,

        # New value (required)
        [Parameter(Mandatory = $true)]
        [string]
        $Value
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenantoptions update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.option+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Key `
            | Group-ClientRequests `
            | c8y tenantoptions update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Key `
            | Group-ClientRequests `
            | c8y tenantoptions update $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-TenantOptionBulk {
<#
.SYNOPSIS
Update multiple tenant options

.DESCRIPTION
Update multiple tenant options in provided category

.LINK
c8y tenantoptions updateBulk

.EXAMPLE
PS> Update-TenantOptionBulk -Category "c8y_cli_tests" -Data @{ $option5 = 0; $option6 = 1 }

Update multiple tenant options


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Tenant Option category (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Category
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenantoptions updateBulk"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.option+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Category `
            | Group-ClientRequests `
            | c8y tenantoptions updateBulk $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Category `
            | Group-ClientRequests `
            | c8y tenantoptions updateBulk $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-TenantOptionEditable {
<#
.SYNOPSIS
Update tenant option edit setting

.DESCRIPTION
Update read-only setting of an existing tenant option Required role:: ROLE_OPTION_MANAGEMENT_ADMIN, Required tenant management Example Request:: Update access.control.allow.origin option.


.LINK
c8y tenantoptions updateEdit

.EXAMPLE
PS> Update-TenantOptionEditable -Category "c8y_cli_tests" -Key "$option8" -Editable "true"

Update editable property for an existing tenant option


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Tenant Option category (required)
        [Parameter(Mandatory = $true)]
        [string]
        $Category,

        # Tenant Option key (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Key,

        # Whether the tenant option should be editable or not (required)
        [Parameter(Mandatory = $true)]
        [ValidateSet('true','false')]
        [string]
        $Editable
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "tenantoptions updateEdit"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.option+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Key `
            | Group-ClientRequests `
            | c8y tenantoptions updateEdit $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Key `
            | Group-ClientRequests `
            | c8y tenantoptions updateEdit $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-User {
<#
.SYNOPSIS
Update user

.DESCRIPTION
Update properties, reset password or enable/disable for a user in a tenant

.LINK
c8y users update

.EXAMPLE
PS> Update-User -Id $User.id -FirstName "Simon"

Update a user


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # User id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # User first name
        [Parameter()]
        [string]
        $FirstName,

        # User last name
        [Parameter()]
        [string]
        $LastName,

        # User phone number. Format: '+[country code][number]', has to be a valid MSISDN
        [Parameter()]
        [string]
        $Phone,

        # User email address
        [Parameter()]
        [string]
        $Email,

        # User activation status (true/false)
        [Parameter()]
        [switch]
        $Enabled,

        # User password. Min: 6, max: 32 characters. Only Latin1 chars allowed
        [Parameter()]
        [string]
        $Password,

        # User activation status (true/false)
        [Parameter()]
        [ValidateSet('true','false')]
        [switch]
        $SendPasswordResetEmail,

        # Custom properties to be added to the user
        [Parameter()]
        [object]
        $CustomProperties,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "users update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.user+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y users update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y users update $c8yargs
        }
        
    }

    End {}
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Update-UserGroup {
<#
.SYNOPSIS
Update user group

.DESCRIPTION
Update an existing user group

.LINK
c8y usergroups update

.EXAMPLE
PS> Update-UserGroup -Id $Group -Name $GroupName

Update a user group

.EXAMPLE
PS> Get-UserGroupByName -Name $Group.name | Update-UserGroup -Name $NewGroupName

Update a user group (using pipeline)


#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Group id (required)
        [Parameter(Mandatory = $true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Id,

        # name
        [Parameter()]
        [string]
        $Name,

        # Tenant
        [Parameter()]
        [object]
        $Tenant
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Update", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "usergroups update"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.group+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Id `
            | Group-ClientRequests `
            | c8y usergroups update $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Id `
            | Group-ClientRequests `
            | c8y usergroups update $c8yargs
        }
        
    }

    End {}
}
Function Add-ClientResponseType {
    <#
    .SYNOPSIS
    Add a PowerShell type to a Cumulocity object

    .DESCRIPTION
    This allows a custom type name to be given to powershell objects, so that the view formatting can be used (i.e. .ps1xml)

    .EXAMPLE
    $data | Add-ClientResponseType -Type "customType1"

    Add a type `customType1` to the input object

    .INPUTS
    Object[]

    .OUTPUTS
    Object[]
    #>

    [cmdletbinding()]
    Param(
        # Object to add the type name to
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true)]
        [Object[]]
        $InputObject,

        # Type name to assign to the input objects
        [AllowNull()]
        [AllowEmptyString()]
        [Parameter(
            Mandatory = $true,
            Position = 1)]
        [string]
        $Type
    )

    Process {
        # check if raw values are being used (by statistics?), if not then add normal
        # look for value: switch on inventory, alarms, auditRecords, events, etc.
        if ($InputObject.statistics) {
            $TypeDefinitions = @(
                @{
                    property = "alarms"
                    type = "application/vnd.com.nsn.cumulocity.alarmCollection+json"
                },
                @{
                    property = "events"
                    type = "application/vnd.com.nsn.cumulocity.eventCollection+json"
                },
                @{
                    property = "managedObjects"
                    type = "application/vnd.com.nsn.cumulocity.managedObjectCollection+json"
                },
                @{
                    property = "operations"
                    type = "application/vnd.com.nsn.cumulocity.operationCollection+json"
                },
                @{
                    property = "auditRecords"
                    type = "application/vnd.com.nsn.cumulocity.auditRecordCollection+json"
                },
                @{
                    property = "applications"
                    type = "application/vnd.com.nsn.cumulocity.applicationCollection+json"
                },
                @{
                    property = "bulkOperations"
                    type = "application/vnd.com.nsn.cumulocity.bulkOperationCollection+json"
                },
                @{
                    property = "users"
                    type = "application/vnd.com.nsn.cumulocity.userCollection+json"
                }
            )

            $RawType = $null
            foreach ($iTypeDefinition in $TypeDefinitions) {
                if ($InputObject.$($iTypeDefinition.property)) {
                    $RawType = $iTypeDefinition.type
                    break
                }
            }

            if ($RawType) {
                $InputObject | Add-PowershellType -Type $RawType
                return
            }
        }

        foreach ($InObject in $InputObject) {
            if (-Not [string]::IsNullOrWhiteSpace($Type)) {
                [void]$InObject.PSObject.TypeNames.Insert(0, $Type)
            }
            $InObject
        }
    }
}
Function Add-PowershellType {
<#
.SYNOPSIS
Add a powershell type name to a powershell object

.DESCRIPTION
This allows a custom type name to be given to powershell objects, so that the view formatting can be used (i.e. .ps1xml)

.EXAMPLE
$data | Add-PowershellType -Type "customType1"

Add a type `customType1` to the input object

.INPUTS
Object[]

.OUTPUTS
Object[]
#>

  [cmdletbinding()]
  Param(
    # Object to add the type name to
    [Parameter(
      Mandatory = $true,
      ValueFromPipeline = $true,
      ValueFromPipelineByPropertyName = $true)]
    [Object[]]
    $InputObject,

    # Type name to assign to the input objects
    [AllowNull()]
    [AllowEmptyString()]
    [Parameter(
      Mandatory = $true,
      Position = 1)]
    [string]
    $Type
  )

  Process {
    foreach ($InObject in $InputObject) {
      if (-Not [string]::IsNullOrWhiteSpace($Type)) {
        [void]$InObject.PSObject.TypeNames.Insert(0, $Type)
      }
      $InObject
    }
  }
}
Function Clear-Session {
<#
.SYNOPSIS
Clear the active Cumulocity Session

.DESCRIPTION
Clear the active Cumulocity Session

.LINK
c8y sessions clear

.EXAMPLE
Clear-Session

Clears the current Cumulocity session

.OUTPUTS
None
#>

    [CmdletBinding()]
    Param()
    c8y sessions clear --shell powershell | Out-String | Invoke-Expression
}
Function ConvertFrom-Base64String {
<#
.SYNOPSIS
Convert a base64 encoded string to UTF8

.DESCRIPTION
Convert a base64 encoded string to UTF8

.NOTES
If the the string has spaces in it, then only the last part of the string (with no spaces in it) will be used. This makes it easier when trying decode the basic auth string

.PARAMETER InputObject
Base64 encoded string

.EXAMPLE
ConvertFrom-Base64String ZWFzdGVyZWdn

Convert the base64 to utf8

.EXAMPLE
ConvertFrom-Base64String "Authorization: Basic s7sd81kkzyzldjkzkhejhug3kh"

Convert the base64 to utf8
#>

    [CmdletBinding()]
    Param(
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position=0)]
        [string[]] $InputObject
    )

    Process {
        foreach ($Item in $InputObject) {
            $Base64 = ($Item -split "\s+") | Select-Object -Last 1
            [System.Text.Encoding]::UTF8.Getstring([System.Convert]::FromBase64String($Base64))
        }
    }
}
Function ConvertFrom-ClientOutput {
    [CmdletBinding()]
    param (
        [Parameter(
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0,
            Mandatory = $true
        )]
        [object[]]
        $InputObject,

        [string]
        $Type = "application/json",

        [string]
        $ItemType = "application/json",

        # Existing bound parameters from the cmdlet. Common parameters will be retrieved from it
        [Parameter()]
        [AllowNull()]
        [hashtable]
        $BoundParameters
    )

    Begin {
        $Depth = if ($BoundParameters.ContainsKey("Depth")) { $BoundParameters["Depth"] } else { 100 }
        $AsHashTable = if ($BoundParameters.ContainsKey("AsHashTable")) { $BoundParameters["AsHashTable"] } else { $false }
        $Raw = $BoundParameters["WithTotalPages"] `
            -or $BoundParameters["Raw"]
        
        $UseNativeOutput = $BoundParameters["AsJSON"] `
            -or $BoundParameters["Output"] -eq "csv" `
            -or $BoundParameters["Output"] -eq "csvheader" `
            -or $BoundParameters["Output"] -eq "table" `
            -or $BoundParameters["CsvFormat"] `
            -or $BoundParameters["ExcelFormat"] `
            -or $BoundParameters["Pretty"] `
            -or $BoundParameters["Compress"] `
            -or $BoundParameters["Dry"] `
            -or $WhatIfPreference

        $SelectedType = if ($ItemType) { $ItemType } else { $Type }
        if ($Raw) {
            $SelectedType = $Type
        }

        # Ignore powershell type when using custom select properties, otherwise the user might not see the properties they want on the console
        $IgnorePowershellType = $BoundParameters["Select"].Count -gt 0
    }

    Process {
        foreach ($item in $InputObject) {
            if ($UseNativeOutput) {
                $item
            }
            else {
                # Detect json responses automatically
                if ($SelectedType -match "json") {
                    # Strip color codes (if present)
                    $item = $item -replace '\x1b\[[0-9;]*m'

                    $output = ConvertFrom-Json -InputObject $item -Depth:$Depth -AsHashtable:$AsHashTable `

                    if (-Not $IgnorePowershellType) {
                        $output = $output | Add-PowershellType -Type $SelectedType
                    }                
                    $output
                } else {
                    $item
                }
            }
        }
    }
}
Function ConvertFrom-JsonStream {
    <#
.SYNOPSIS
Convert json text to powershell objects as the objects are piped to it

.DESCRIPTION
The cmdlet will convert each input as a separate json line, and it will convert it as soon as it is
received in the pipeline (instead of waiting for the entire input).

Each input should contain a single json object.

.NOTES
ConvertFrom-Json can not be used for streamed json as it waits to receive all piped input before it starts trying
to convert the json to PowerShell objects.

.EXAMPLE
Get-DeviceCollection | Get-Device -AsPSObject:$false | ConvertFrom-JsonStream

Convert the pipeline objects to json as they come through the pipeline.

#>

    [CmdletBinding()]
    param(
        # Input json lines
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
        [AllowNull()]
        [object[]]
        ${InputObject},
    
        # Maximum object depth to allow
        [ValidateRange(1, 2147483647)]
        [int]
        ${Depth} = 100,

        # Convert json to a hashtable instead of a PSCustom Object
        [switch]
        $AsHashtable
    )    
    process {
        foreach ($item in $inputObject) {
            # Strip color codes (if present)
            $item = $item -replace '\x1b\[[0-9;]*m'
            Write-Output (ConvertFrom-Json $item -Depth:$Depth -AsHashtable:$AsHashtable) -NoEnumerate
        }
    }
}
Function ConvertTo-Base64String {
<#
.SYNOPSIS
Convert a UTF8 string to a base64 encoded string

.DESCRIPTION
Convert a UTF8 string to a base64 encoded string

.PARAMETER InputObject
UTF8 encoded string

.EXAMPLE
ConvertTo-Base64String tenant/username:password

Encode a string to base64 encoded string
#>

    [CmdletBinding()]
    Param(
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position=0)]
        [string[]] $InputObject
    )

    Process {
        foreach ($Item in $InputObject) {
            [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($Item))
        }
    }
}
Function ConvertTo-JsonArgument {
<#
.SYNOPSIS
Convert a powershell hashtable/object to a json escaped string

.DESCRIPTION
Helper function is used when passing Powershell hashtable or PSCustomObjects to
the c8y binary. Before the c8y cli binary can accept it, it must be converted to json.

The necessary character escaping of literal backslashed `\` will be done automatically.

If Data parameter is a file path then it is returned as is.

.EXAMPLE
ConvertTo-JsonArgument @{ myValue = "1" }

Converts the hashtable to an escaped json string

```json
{\"myValue\":\"1\"}
```
#>

    [cmdletbinding()]
    Param(
        # Input object to be converted
        [Parameter(
            Mandatory = $true,
            Position = 0
        )]
        [object] $Data
    )

    if ($Data -is [string] -or $data -is [System.IO.FileSystemInfo]) {
        if ($Data -and (Test-Path $Data)) {
            # Return path as is (and let c8y binary handle it)
            return $Data
        }
        # If string, then validate if json was provided
        
        try {
            $JSONArgs = @{
                InputObject = $Data
                ErrorAction = "Stop"
            }
            $DataObj = (ConvertFrom-Json @JSONArgs)
        } catch {
            # Return as is (and let c8y binary handle it)
            return $Data
        }
    } else {
        $DataObj = $Data
    }

    # Note: replace \" with the unicode character to prevent intepretation errors on the command line
    $jsonRaw = (ConvertTo-Json $DataObj -Compress -Depth 100) -replace '\\"', '\u0022'
    $strArg = "{0}" -f ($jsonRaw -replace '(?<!\\)"', '\"')

    # Replace space with unicode char, as space can have console parsing problems
    $strArg = $strArg -replace " ", "\u0020"
    $strArg
}
Function ConvertTo-NestedJson {
<#

.ForwardHelpTargetName Microsoft.PowerShell.Utility\ConvertTo-Json
.ForwardHelpCategory Cmdlet

#>

    [CmdletBinding(HelpUri = 'https://go.microsoft.com/fwlink/?LinkID=2096925', RemotingCapability = 'None')]
    param(
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
        [AllowNull()]
        [System.Object]
        ${InputObject},

        [ValidateRange(1, 2147483647)]
        [int]
        ${Depth} = 20,

        [switch]
        ${Compress})

    begin {
        try {
            $outBuffer = $null
            if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
                $PSBoundParameters['OutBuffer'] = 1
            }

            $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Utility\ConvertTo-Json', [System.Management.Automation.CommandTypes]::Cmdlet)
            $scriptCmd = { & $wrappedCmd @PSBoundParameters }

            $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
            $steppablePipeline.Begin($PSCmdlet)
        }
        catch {
            throw
        }
    }

    process {
        try {
            $steppablePipeline.Process($_)
        }
        catch {
            throw
        }
    }

    end {
        try {
            $steppablePipeline.End()
        }
        catch {
            throw
        }
    }
}
Function Expand-Application {
<#
.SYNOPSIS
Expand a list of applications replacing any ids or names with the actual application object.

.DESCRIPTION
The list of applications will be expanded to include the full application representation by fetching
the data from Cumulocity.

.NOTES
If the given object is already an application object, then it is added with no additional lookup

.PARAMETER InputObject
List of ids, names or application objects

.PARAMETER Type
Limit the types of object by a specific type

.EXAMPLE
Expand-Application "app-name"

Retrieve the application objects by name or id

.EXAMPLE
Get-C8yApplicationCollection *app* | Expand-Application

Get all the application object (with app in their name). Note the Expand cmdlet won't do much here except for returning the input objects.

.EXAMPLE
Expand-Application * -Type MICROSERVICE

Expand applications that match a name of "*" and have a type of "MICROSERVICE"

#>

    [cmdletbinding()]
    Param(
        [Parameter(
            Mandatory=$true,
            ValueFromPipeline=$true,
            Position=0
        )]
        [object[]] $InputObject
    )

    Begin {
        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }
    }

    Process {
        [array] $AllApplications = foreach ($iApp in $InputObject)
        {
            # Already an app object, so do nothing
            if ($iApp.id) {
                $iApp
                continue
            }

            if ($iApp.applicationId) {
                PSc8y\Get-Application -Id $iApp.applicationId -Dry:$false -AsPSObject
                continue
            }

            if ("$iApp" -match "^\d+$") {
                # Provided with an id
                $iApp
                # PSc8y\Get-Application -Id $iApp -Dry:$false
            } else {
                # Provided with a query
                PSc8y\Get-ApplicationCollection -PageSize 2000 -AsPSObject |
                        Where-Object { $_.name -like "$iApp" }
            }
        }

        $AllApplications
    }
}
Function Expand-Device {
<#
.SYNOPSIS
Expand a list of devices replacing any ids or names with the actual device object.

.DESCRIPTION
The list of devices will be expanded to include the full device representation by fetching
the data from Cumulocity.

.NOTES
If the function calling the Expand-Device has a "Force" parameter and it is set to True, then Expand-Device will not fetch the device managed object
from the server. Instead it will return an object with only the id and name set (and the name will be set to [id={}]). This is to save the
number of calls to the server as usually the ID is the item you need to use in subsequent calls.

If the given object is already an device object, then it is added with no additional lookup

The following cases describe when the managed object is fetched from the server and when not.

Cases when the managed object IS fetched from the server
* Calling function does not have -Force on its function, and the user does not use it. OR
* OR User provides input a string which does not only contain digits
* OR User sets the -Fetch parameter on Expand-Device

Cases when the managed object IS NOT fetched from the server
* User passes an ID like object to Expand-Device
* AND -Force is not used on the calling function
* AND user does not use -Fetch when calling Expand-Device


.OUTPUTS
# Without fetch
[pscustomobject]@{
    id = "1234"
    name = "[id=1234]"
}

# With fetch
[pscustomobject]@{
    id = "1234"
    name = "mydevice"
}

.PARAMETER InputObject
List of ids, names or device objects

.EXAMPLE
Expand-Device "mydevice"

Retrieve the device objects by name or id

.EXAMPLE
Get-DeviceCollection *test* | Expand-Device

Get all the device object (with app in their name). Note the Expand cmdlet won't do much here except for returning the input objects.

.EXAMPLE
Get-DeviceCollection *test* | Expand-Device

Get all the device object (with app in their name). Note the Expand cmdlet won't do much here except for returning the input objects.

.EXAMPLE
"12345", "mydevice" | Expand-Device -Fetch

Expand the devices and always fetch device managed object if an object is not provided via the pipeline

#>

    [cmdletbinding()]
    Param(
        [Parameter(
            Mandatory=$true,
            ValueFromPipeline=$true,
            Position=0
        )]
        [object[]] $InputObject,

        # Fetch the full managed object if only the id or name is provided.
        [switch] $Fetch
    )

    Begin {
        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }
    }

    Process {
        $FetchFullDevice = $Fetch
        $callstack = Get-PSCallStack | Select-Object -Skip 1 -First 1
        if ($null -ne $callstack.InvocationInfo.MyCommand.Parameters -and $null -ne $callstack.InvocationInfo.BoundParameters) {
            $CanPromptUser = $callstack.InvocationInfo.MyCommand.Parameters.ContainsKey("Force")
            $ForceEnabled = (($callstack.InvocationInfo.BoundParameters["Force"] -eq $true) -or ($ConfirmPreference -match "None"))

            if (!$Fetch) {
                $FetchFullDevice = $CanPromptUser -and !$ForceEnabled
            }
        }
        

        [array] $AllDevices = foreach ($iDevice in $InputObject)
        {
            if ($iDevice.deviceId) {
                # operation
                [PSCustomObject]@{
                    id = $iDevice.deviceId
                    name = $iDevice.deviceName
                }
            } elseif ($iDevice.source.id) {
                # alarms/events/measurements etc.
                [PSCustomObject]@{
                    id = $iDevice.source.id
                    name = $iDevice.source.name
                }
            } elseif ($iDevice.id) {
                $iDevice
            } else {
                if ($iDevice -match "^\d+$") {
                    
                    if ($WhatIfPreference) {
                        # Fake the reponse of the managed object
                        [PSCustomObject]@{
                            id = $iDevice
                            # Dummy value
                            name = "name of $iDevice"
                        }
                    } else {
                        if ($FetchFullDevice) {
                            Get-ManagedObject -Id $iDevice -Dry:$false -AsPSObject
                        } else {
                            [PSCustomObject]@{
                                id = $iDevice
                                # Dummy value
                                name = "[id=$iDevice]"
                            }
                        }
                    }
                } else {
                    Get-DeviceCollection -Name $iDevice -Dry:$false -AsPSObject
                }
            }
        }

        $AllDevices
    }
}
Function Expand-DeviceGroup {
<#
.SYNOPSIS
Expand a list of device groups

.DESCRIPTION
Expand a list of device groups replacing any ids or names with the actual user object.

.NOTES
If the given object is already an user object, then it is added with no additional lookup

.EXAMPLE
Expand-DeviceGroup "myGroup"

Retrieve the user objects by name or id

.EXAMPLE
Get-DeviceGroupCollection *test* | Expand-DeviceGroup

Get all the device groups (with "test" in their name). Note the Expand cmdlet won't do much here except for returning the input objects.

#>

    [cmdletbinding()]
    Param(
        # List of ids, names or user objects
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            Position = 0
        )]
        [object[]] $InputObject
    )

    Begin {
        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }
    }

    Process {
        [array] $AllItems = foreach ($item in $InputObject) {
            if (($item -is [string])) {
                if ($item -match "\*") {
                    PSc8y\Get-DeviceGroupCollection -Name $item -Dry:$false -PageSize 100 -AsPSObject
                }
                else {
                    $item
                }
            }
            else {
                $item
            }
        }

        $AllItems
    }
}
Function Expand-Id {
<#
.SYNOPSIS
Expand a list of ids.

.DESCRIPTION
Expand the list of objects and only return the ids instead of the full objects.

.EXAMPLE
Expand-Id 12345

Normalize a list of ids

.EXAMPLE
"12345", "56789" | Expand-Id

Normalize a list of ids

#>

    [cmdletbinding()]
    Param(
        # List of ids
        [Parameter(
            Mandatory=$true,
            ValueFromPipeline=$true,
            Position=0
        )]
        [AllowEmptyCollection()]
        [AllowNull()]
        [object[]] $InputObject,

        # Exclude all non-id like values
        [switch] $Strict
    )

    Process {
        [array] $AllIds = foreach ($iID in $InputObject)
        {
            $currentID = $iID
            if ($null -ne $iID.id) {
                $currentID = $iID.id
            } elseif ($null -ne $iID.managedObject.id) {
                # managed object reference object
                $currentID = $iID.managedObject.id
            }

            if (!$Strict) {
                $currentID
                continue
            }

            # Allow for matching integer or strings types, hence the the quotes around the $currentID variable
            if ("$currentID" -match "^[0-9a-z_\-*]+$")
            {
                $currentID
            }
        }
        $AllIds
    }
}
Function Expand-Microservice {
<#
.SYNOPSIS
Expand a list of microservices objects

.DESCRIPTION
Expand a list of microservices replacing any ids or names with the actual microservice object.

.NOTES
If the given object is already an microservice object, then it is added with no additional lookup

.PARAMETER InputObject
List of ids, names or microservice objects

.EXAMPLE
Expand-Microservice "app-name"

Retrieve the microservice objects by name or id

.EXAMPLE
Get-C8yMicroserviceCollection *app* | Expand-Microservice

Get all the microservice object (with app in their name). Note the Expand cmdlet won't do much here except for returning the input objects.

#>

    [cmdletbinding()]
    Param(
        [Parameter(
            Mandatory=$true,
            ValueFromPipeline=$true,
            Position=0
        )]
        [object[]] $InputObject
    )

    Begin {
        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }
    }

    Process {
        [array] $AllMicroservices = foreach ($iApp in $InputObject)
        {
            # Already an app object, so do nothing
            if ($iApp.id) {
                $iApp
                continue
            }

            if ($iApp.applicationId) {
                PSc8y\Get-Microservice -Id $iApp.applicationId -Dry:$false -AsPSObject
                continue
            }

            if ("$iApp" -match "^\d+$") {
                # Provided with an id
                $iApp
            } else {
                # Provided with a query
                PSc8y\Get-MicroserviceCollection -PageSize 2000 -AsPSObject |
                        Where-Object { $_.name -like "$iApp" }
            }
        }

        $AllMicroservices
    }
}
Function Expand-PaginationObject {
<#
.SYNOPSIS
Expand a Cumulocity pagination result

.DESCRIPTION
Iterate through a Cumulocity pagination result set, and keep fetching the results
until the last page is found.

The cmdlet will only return once the total result set has been fetched, and the
items will be returned in one array.

.EXAMPLE
Invoke-ClientRequest -Uri "/inventory/managedObjects" -QueryParameters @{ pageSize = 2000 } -Raw | ConvertFrom-Json | Expand-PaginationObject

Get all managed objects in the platform (rest requests will be done in chunks of 2000)

.EXAMPLE
$data = Get-MeasurementCollection -Device testDevice -Raw -PageSize 2000 | Expand-PaginationObject

Get a measurement collection, then retrieve all the measurements by iterating through the pagination object

#>

  [cmdletbinding()]
  Param(
    # Response from a Cumulocity rest request. It must have the next property.
    [Parameter(
        Mandatory=$true,
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true)]
    [object]
    $InputObject,

    # Maximum number of pages to retrieve. If Zero or less, then it will retrieve all of the results
    [int]
    $MaxPage = 0
  )
  Begin {
    $InputCollection = New-Object System.Collections.ArrayList

    Function Get-ResultProperty {
      Param(
        [object] $InputObject
      )
      # Detect the type of c8y object
      $Prop = $null
      if ($null -ne $InputObject.managedObjects) {
        $Prop = "managedObjects"
      } elseif ($null -ne $InputObject.operations) {
        $Prop = "operations"
      } elseif ($null -ne $InputObject.alarms) {
        $Prop = "alarms"
      } elseif ($null -ne $InputObject.measurements) {
        $Prop = "measurements"
      } elseif ($null -ne $InputObject.events) {
        $Prop = "events"
      } elseif ($null -ne $InputObject.auditRecords) {
        $Prop = "auditRecords"
      } elseif ($null -ne $InputObject.connectors) {
        $Prop = "connectors"
      } elseif ($null -ne $InputObject.newDeviceRequests) {
        $Prop = "newDeviceRequests"
      } elseif ($null -ne $InputObject.externalIds) {
        $Prop = "externalIds"
      } elseif ($null -ne $InputObject.retentionRules) {
        $Prop = "retentionRules"
      } elseif ($null -ne $InputObject.groups) {
        $Prop = "groups"
      } elseif ($null -ne $InputObject.roles) {
        $Prop = "roles"
      } elseif ($null -ne $InputObject.users) {
        $Prop = "users"
      } elseif ($null -ne $InputObject.references) {
        $Prop = "references"
      } elseif ($null -ne $InputObject.tenants) {
        $Prop = "tenants"
      } elseif ($null -ne $InputObject.options) {
        $Prop = "options"
      }

      $Prop
    }
  }

  Process {
    $null = $InputCollection.Add($InputObject)
  }

  End {
    $ProcessObject = $InputCollection | Select-Object -First 1

    Write-Verbose "Input Collection Count: $($InputCollection.Count)"

    if (($InputCollection.Count -eq 0) -or (($InputCollection.Count -gt 1) -and !$InputCollection[0].next)) {
      Write-Warning "Input object is not a Cumulocity Pagination Object"
      $ProcessObject
      return;
    }

    $ResultCollection = New-Object System.Collections.ArrayList

    $Result = $ProcessObject

    $Prop = Get-ResultProperty -InputObject $Result
    if ($Result.$Prop -is [array]) {
      $null = $ResultCollection.AddRange($Result.$Prop)
    } else {
      $null = $ResultCollection.Add($Result.$Prop)
    }

    $Iteration = 1

    $Done = $false

    if ($Result.next) {
      while (!$Done) {
        Write-Verbose "Requesting next item: (iteration $Iteration)"

        $Result = Invoke-ClientRequest -Method Get -Uri $Result.next -Raw -AsPSObject:$false | ConvertFrom-Json

        # Detect the type of c8y object
        $Prop = Get-ResultProperty -InputObject $Result

        if ($null -eq $Prop)
        {
          Write-Warning "Could not find the array object property. Only alarms, events, managedObjects, measurments and operations properties are supported"
        }
        else
        {
          Write-Verbose "Found array object property [$Prop]"
        }

        if ($Result -and $Prop) {
          if ($Result.$Prop -is [array]) {
            $null = $ResultCollection.AddRange($Result.$Prop)
          } else {
            $null = $ResultCollection.Add($Result.$Prop)
          }
        }

        $Done = !$Result -or !$Result.next -or ($Result.$Prop.Count -eq 0) `
          -or ($MaxPage -gt 0 -and $Iteration -ge $MaxPage) `
          -or ($Result.$Prop.Count -lt $Result.statistics.pageSize)
        $Iteration += 1
      }
    }

    $ResultCollection
  }
}
Function Expand-Source {
<#
.SYNOPSIS
Expand a list of source ids.

.DESCRIPTION
Expand the list of input objects and return the source using the following logic:

    1. Look for a source.id property
    2. Look for a deviceId property
    3. Look for a id property
    4. Check if the given is a string or int and is integer like

.EXAMPLE
Expand-Source 12345

Normalize a list of ids

.EXAMPLE
"12345", "56789" | Expand-Source

Normalize a list of ids

.EXAMPLE
Get-OperationCollection -PageSize 1000 | Expand-Source | Select-Object -Unique

Get a unique list of device ids from a list of operations

#>

    [cmdletbinding()]
    Param(
        # List of objects which can either be operations, alarms, measurements or managed objects
        [Parameter(
            Mandatory=$true,
            ValueFromPipeline=$true,
            Position=0
        )]
        [AllowEmptyCollection()]
        [AllowNull()]
        [object[]] $InputObject
    )

    Process {
        [array] $AllIds = foreach ($iObject in $InputObject)
        {
            $currentID = $iObject

            if ($null -ne $iObject.source.id) {
                $currentID = $iObject.source.id
            } elseif ($null -ne $iObject.deviceId) {
                $currentID = $iObject.deviceId
            } elseif ($null -ne $iObject.id) {
                $currentID = $iObject.id
            }

            # Allow for matching integer or strings types, hence the the quotes around the $currentID variable
            if ("$currentID" -match "^[0-9]+$")
            {
                $currentID
            }
        }
        $AllIds
    }
}
Function Expand-Tenant {
<#
.SYNOPSIS
Expand the tenants by id or name

.DESCRIPTION
Expand a list of tenants replacing any ids or names with the actual tenant object.

.NOTES
If the given object is already an tenant object, then it is added with no additional lookup

.EXAMPLE
Expand-Tenant "mytenant"

Retrieve the tenant objects by name or id

.EXAMPLE
Get-Tenant *test* | Expand-Tenant

Get all the tenant object (with app in their name). Note the Expand cmdlet won't do much here except for returning the input objects.

#>

    [cmdletbinding()]
    Param(
        # List of ids, names or tenant objects
        [Parameter(
            Mandatory=$true,
            ValueFromPipeline=$true,
            Position=0
        )]
        [object[]] $InputObject
    )

    Begin {
        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }
    }

    Process {
        [array] $AllTenants = foreach ($iTenant in $InputObject)
        {
            if ("$iTenant".Contains("*"))
            {
                Get-TenantCollection -PageSize 2000 -AsPSObject | Where-Object {
                    $_.id -like $iTenant
                } -Dry:$false
            }
            else
            {
                $iTenant
            }
        }

        $AllTenants
    }
}
Function Expand-User {
<#
.SYNOPSIS
Expand a list of users

.DESCRIPTION
Expand a list of users replacing any ids or names with the actual user object.

.NOTES
If the given object is already an user object, then it is added with no additional lookup

.EXAMPLE
Expand-User "myuser"

Retrieve the user objects by name or id

.EXAMPLE
Get-UserCollection *test* | Expand-User

Get all the user object (with app in their name). Note the Expand cmdlet won't do much here except for returning the input objects.

#>

    [cmdletbinding()]
    Param(
        # List of ids, names or user objects
        [Parameter(
            Mandatory=$true,
            ValueFromPipeline=$true,
            Position=0
        )]
        [object[]] $InputObject
    )

    Begin {
        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }
    }

    Process {
        [array] $AllUsers = foreach ($iUser in $InputObject)
        {
            if (($iUser -is [string]))
            {
                if ($iUser -match "\*") {
                    # Remove any wildcard characters, as they are not supported by c8y
                    $iUserNormalized = $iUser -replace "\*", ""

                    PSc8y\Get-UserCollection -Username $iUserNormalized -Dry:$false -PageSize 100 -AsPSObject |
                        Where-Object { $_.id -like $iUser -or $_.userName -like $iUser }
                } else {
                    $iUser
                }
            }
            else
            {
                $iUser
            }
        }

        $AllUsers
    }
}
# Code generated from specification version 1.0.0: DO NOT EDIT
Function Find-ManagedObjectCollection {
<#
.SYNOPSIS
Get a collection of managedObjects based on Cumulocity query language

.DESCRIPTION
Get a collection of managedObjects based on Cumulocity query language

.LINK
c8y inventory find

.EXAMPLE
PS> Find-ManagedObjectCollection -Query "name eq 'roomUpperFloor_*'"
Find all devices with their names starting with 'roomUpperFloor_'


#>

    [cmdletbinding(PositionalBinding=$true, HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # ManagedObject query. (required)
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object[]]
        $Query,

        # String template to be used when applying the given query. Use %s to reference the query/pipeline input
        [Parameter(Mandatory = $false)]
        [string]
        $QueryTemplate,

        # ManagedObject sort results by.
        [Parameter(Mandatory = $false)]
        [string]
        $OrderBy,

        # include a flat list of all parents and grandparents of the given object
        [Parameter()]
        [switch]
        $WithParents,

        # only include devices (i.e. add has(c8y_IsDevice) to the query)
        [Parameter()]
        [switch]        
        $OnlyDevices
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "inventory find"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.managedObjectCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.managedObject+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            $Query `
            | Group-ClientRequests `
            | c8y inventory find $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Query `
            | Group-ClientRequests `
            | c8y inventory find $c8yargs
        }
    }

    End {}
}
Function Format-Date {
<#
.SYNOPSIS
Gets a Cumulocity (ISO-8601) formatted DateTime string in the specified timezone

.DESCRIPTION
All Cumulocity REST API calls that require a date, must be in the ISO-8601 format. This function
allows the user to easily generate the correct format including the correct timezone information.

.NOTES
The standard powershell Get-Date does not have any timezone information.

.EXAMPLE
Format-Date

Get current datetime (now) as an ISO8601 formatted string

.EXAMPLE
[TimeZoneInfo]::GetSystemTimeZones() | Foreach-Object { Format-Date -Timezone $_ }

Get current datetime (now) as an ISO8601 formatted string in each of the timezones

.OUTPUTS
String
#>

    [CmdletBinding()]
    Param(
        # DateTime to be converted to ISO-8601 format. Accepts piped input
        [Parameter(Mandatory=$false,
                   Position = 0,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [datetime[]] $InputObject = @(),

        # Timezone to use when converting the DateTime object. Defaults to Local System Timezone
        [TimeZoneInfo] $TimeZone = $null
    )

    Begin {
        if ($null -eq $TimeZone) {
            $TimeZone = [TimeZoneInfo]::Local
        }

        $InputDates = New-Object System.Collections.ArrayList
    }

    Process {
        if ($null -ne $InputObject -and $InputObject.Count -ne 0) {
            $null = $InputDates.AddRange($InputObject)
        } else {
            $null = $InputDates.Add((Get-Date))
        }
    }

    End {
        foreach ($iDate in $InputDates) {

            # Get DateTime as ISO 8601 formatted string
            # It does not contain the timezone, this will have to be added manually
            $DateWithoutTimezone = Get-Date $iDate -Format "yyyy-MM-ddTHH:mm:ss.fff"

            # Get the time zone offset at a specific time
            $TimeZoneOffset = $TimeZone.GetUtcOffset($iDate)

            if (!($TimeZoneOffset.Hours -eq 0 -and $TimeZoneOffset.Minutes -eq 0)) {
                if ($TimeZoneOffset.TotalSeconds -ge 0) {
                    $OffsetStr = "+" + "$($TimeZoneOffset.Hours)".PadLeft(2, '0')
                } else {
                    # The minus sign is automatically in the hours.
                    $OffsetStr = "" + "$($TimeZoneOffset.Hours)".PadLeft(2, '0')
                }

                if ($TimeZoneOffset.Minutes -ne 0) {
                    # Math Absolute is required because when a timezone is before GMT, then the Minutes are negative
                    $OffsetStr += ":" + "$([math]::Abs($TimeZoneOffset.Minutes))".PadLeft(2, '0')
                }

                $DateWithTimezone = "${DateWithoutTimezone}${OffsetStr}"
            } else {
                # GMT 0 / UTC
                $DateWithTimezone = "${DateWithoutTimezone}Z"
            }

            $DateWithTimezone
        }
    }
}
Function Get-AgentCollection {
<#
.SYNOPSIS
Get a collection of agents

.DESCRIPTION
Get a collection of agent in the current tenant

.LINK
c8y agents list

.EXAMPLE
Get-AgentCollection -Name *sensor*

Get all agents with "sensor" in their name

.EXAMPLE
Get-AgentCollection -Name *sensor* -Type *c8y_* -PageSize 100

Get the first 100 agents with "sensor" in their name and has a type matching "c8y_"

.EXAMPLE
Get-AgentCollection -Query "lastUpdated.date gt '2020-01-01T00:00:00Z'"

Get a list of agents which have been updated more recently than 2020-01-01

#>

    [cmdletbinding(PositionalBinding=$true, HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Agent name. Wildcards accepted
        [Parameter(Mandatory = $false)]
        [string]
        $Name,

        # Agent type.
        [Parameter(Mandatory = $false)]
        [string]
        $Type,

        # Agent fragment type.
        [Parameter(Mandatory = $false)]
        [string]
        $FragmentType,

        # Agent owner.
        [Parameter(Mandatory = $false)]
        [string]
        $Owner,

        # Query.
        [Parameter(Mandatory = $false)]
        [string]
        $Query,

        # include a flat list of all parents and grandparents of the given object
        [Parameter()]
        [switch]
        $WithParents
    )

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "agents list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.customAgentCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.customAgent+json"
            BoundParameters = $PSBoundParameters
        }
    }
    DynamicParam {
        Get-ClientCommonParameters -Type "Collection"
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            ,(c8y agents list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions)
        }
        else {
            c8y agents list $c8yargs
        }
    }
}
Function Get-AssetParent {
<#
.SYNOPSIS
Get asset parent references for a asset

.DESCRIPTION
Get the parent of an existing assert by using the references. The cmdlet supports returning
various forms of the parent references, i.e. immediate parent, parent or the parent, or the
full parental references.

.EXAMPLE
Get-AssetParent asset0*

Get the direct (immediate) parent of the given asset

.EXAMPLE
Get-AssetParent -All

Return an array of parent assets where the first element in the array is the root asset, and the last is the direct parent of the given asset.

.EXAMPLE
Get-AssetParent -RootParent

Returns the root parent. In most cases this will be the agent

#>

    [cmdletbinding(
        PositionalBinding=$true,
        DefaultParameterSetName = "ByLevel",
        HelpUri='')]
    Param(
        # Asset id, name or object. Wildcards accepted
        [Parameter(
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0)]
        [object[]] $Asset,


        # Level to navigate backward from the given asset to its parent/s
        # 1 = direct parent
        # 2 = parent of its parent
        # If the Level is too large, then the root parent will be returned
        [Parameter(
            ParameterSetName = "ByLevel",
            Position = 1)]
        [ValidateRange(1,100)]
        [int] $Level = 1,

        # Return the top level / root parent
        [Parameter(
            ParameterSetName = "Root")]
        [switch] $RootParent,

        # Return a list of all parent assets
        [Parameter(
            ParameterSetName = "All")]
        [switch] $All
    )

    Process {
        # Get list of ids
        $Ids = Expand-Id $Asset
        
        $Results = foreach ($iasset in @(Get-ManagedObjectCollection -Ids $Ids -WithParents -AsPSObject))
        {
            $Parents = @($iasset.assetParents.references.managedObject | Foreach-Object {
                if ($null -ne $_.id) {
                    New-Object psobject -Property @{
                        id = $_.id;
                        name = $_.name;
                    }
                }
            })

            # Reverse the order because Cumulocity returns the references in order from number of steps from the given asset.
            # So the asset closest to the given asset is first.
            [array]::Reverse($Parents)

            switch ($PSCmdlet.ParameterSetName) {
                "ByLevel" {
                    # Convert to array index (don't need minus 1 because Level is also a 1 based index (same as Count))
                    $Index = $Parents.Count - $Level
                    
                    if ($Index -lt 0) {
                        $Index = 0
                    }
                    if ($Index -ge $Parents.Count) {
                        $Index = $Parents.Count - 1
                    }

                    if ($null -ne $Parents[$Index].id) {
                        $Parents[$Index]
                    }
                }

                "Root" {
                    if ($null -ne $Parents[0].id) {
                        $Parents[0]
                    }
                }

                "All" {
                    $Parents
                }
            }
        }

        $Results `
            | Select-Object `
            | Add-PowershellType -Type "c8y.parentReferences"
    }
}
Function Get-C8ySessionProperty {
<#
.SYNOPSIS
Get a property from the current c8y session

.DESCRIPTION
An interface to read properties from the current c8y session, i.e. tenant or host. This is mostly used
internally my other cmdlets in the module to abstract the accessing of such variables in case the environment
variables change in the future (i.e. $env:C8Y_TENANT or $env:C8Y_HOST).

.EXAMPLE
Get-C8ySessionProperty tenant

Get the tenant name of the current c8y cli session

.OUTPUTS
string
#>

    [cmdletbinding()]
    Param(
        # Property name
        [Parameter(
            Mandatory = $true,
            Position = 0
        )]
        [ValidateSet("tenant", "host")]
        [string] $Name
    )

    $Values = [PSCustomObject]@{
        host = $env:C8Y_HOST
        tenant = $env:C8Y_TENANT
    }

    $Session = (Get-PSCallStack).InvocationInfo.BoundParameters.Session | Select-Object -First 1

    if ($Session) {
        $Values = Get-Session -Session:$Session
    }
    $Values | Select-Object -ExpandProperty $Name
}
Function Get-ClientBinary {
<#
.SYNOPSIS
Get the path to the Cumulocity Binary

.DESCRIPTION
Get the full path to the Cumulocity Binary which is compatible with the current Operating system

.EXAMPLE
Get-ClientBinary

Returns the fullname of the path to the Cumulocity binary
#>

    [cmdletbinding()]
    [OutputType([String])]
    Param()

    if ($IsLinux) {
        Resolve-Path (Join-Path $script:Dependencies "c8y.linux")
    } elseif ($IsMacOS) {
        Resolve-Path (Join-Path $script:Dependencies "c8y.macos")
    } else {
        Resolve-Path (Join-Path $script:Dependencies "c8y.windows.exe")
    }
}
Function Get-ClientBinaryVersion {
<#
.SYNOPSIS
Get the c8y client binary version

.DESCRIPTION
The c8y client binary version is the only dependency of the PSc8y module, and hence
the version number is helpful to determine what functions are available

.EXAMPLE
Get-ClientBinaryVersion

Show the client binary version on the console
#>

    [cmdletbinding()]
    Param()
    c8y version
}
Function Get-ClientCommonParameters {
<#
.SYNOPSIS
Get the common parameters which can be added to a function which extends PSc8y functionality

.DESCRIPTION
* PageSize

.EXAMPLE
Function Get-MyObject {
    [cmdletbinding()]
    Param()

    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Process {
        Find-ManagedObjects @PSBoundParameters
    }
}
Inherit common parameters to a custom function. This will add parameters such as "PageSize", "TotalPages", "Template" to your function
#>

    [cmdletbinding()]
    Param(
        # Parameter types to include
        [Parameter(
            Mandatory = $true,
            Position = 0
        )]
        [ValidateSet("Collection", "Get", "Create", "Update", "Delete", "Template", "TemplateVars", "")]
        [string[]]
        $Type,

        # Ignore confirm parameter (i.e. when using inbuilt powershell -Confirm)
        [switch] $SkipConfirm
    )

    Process {
        $ParentCommand = @(Get-PSCallStack)[1].InvocationInfo.MyCommand

        $Dictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
        foreach ($iType in $Type) {
            switch ($iType) {
                "Collection" {
                    New-DynamicParam -Name "PageSize" -Type "int" -DPDictionary $Dictionary
                    New-DynamicParam -Name "WithTotalPages" -Type "switch" -DPDictionary $Dictionary
                    New-DynamicParam -Name "CurrentPage" -Type "int" -DPDictionary $Dictionary
                    New-DynamicParam -Name "TotalPages" -Type "int" -DPDictionary $Dictionary
                    New-DynamicParam -Name "IncludeAll" -Type "switch" -DPDictionary $Dictionary
                }

                {$_ -match "Create|Update|Delete" } {
                    if ($_ -notmatch "Delete") {
                        New-DynamicParam -Name "Data" -Type "object" -DPDictionary $Dictionary
                    }
                    New-DynamicParam -Name "NoAccept" -Type "switch" -DPDictionary $Dictionary
                    New-DynamicParam -Name "ProcessingMode" -Type "string" -ValidateSet @("PERSISTENT", "QUIESCENT", "TRANSIENT", "CEP", "") -DPDictionary $Dictionary
                    New-DynamicParam -Name "Force" -Type "switch" -DPDictionary $Dictionary
                }

                "Template" {
                    New-DynamicParam -Name "Template" -Type "string" -DPDictionary $Dictionary
                    New-DynamicParam -Name "TemplateVars" -Type "string" -DPDictionary $Dictionary

                    # Completions
                    if ($ParentCommand) {
                        Register-ArgumentCompleter -CommandName $ParentCommand -ParameterName Template -ScriptBlock $script:CompletionTemplate
                    }
                }

                # Only template variables
                "TemplateVars" {
                    New-DynamicParam -Name "TemplateVars" -Type "string" -DPDictionary $Dictionary
                }
            }
        }

        # Common parameters
        New-DynamicParam -Name Raw -Type "switch" -DPDictionary $Dictionary
        New-DynamicParam -Name OutputFile -Type "string" -DPDictionary $Dictionary
        New-DynamicParam -Name OutputFileRaw -Type "string" -DPDictionary $Dictionary
        New-DynamicParam -Name Proxy -Type "switch" -DPDictionary $Dictionary
        New-DynamicParam -Name NoProxy -Type "switch" -DPDictionary $Dictionary
        New-DynamicParam -Name Timeout -Type "double" -DPDictionary $Dictionary
        
        # Session
        New-DynamicParam -Name Session -Type "string" -DPDictionary $Dictionary
        if ($ParentCommand) {
            Register-ArgumentCompleter -CommandName $ParentCommand -ParameterName Session -ScriptBlock $script:CompletionSession
        }

        # JSON parsing options
        New-DynamicParam -Name Output -Type "string" -ValidateSet @("json", "csv", "csvheader", "table") -DPDictionary $Dictionary
        New-DynamicParam -Name View -Type "string" -ValidateSet @("off", "auto") -DPDictionary $Dictionary
        New-DynamicParam -Name AsHashTable -Type "switch" -DPDictionary $Dictionary
        New-DynamicParam -Name AsPSObject -Type "switch" -DPDictionary $Dictionary
        New-DynamicParam -Name Flatten -Type "switch" -DPDictionary $Dictionary
        New-DynamicParam -Name Compress -Type "switch" -DPDictionary $Dictionary
        New-DynamicParam -Name Pretty -Type "switch" -DPDictionary $Dictionary
        New-DynamicParam -Name NoColor -Type "switch" -DPDictionary $Dictionary
        New-DynamicParam -Name Color -Type "switch" -DPDictionary $Dictionary

        # Confirmation
        if (-Not $SkipConfirm) {
            New-DynamicParam -Name Confirm -Type "switch" -DPDictionary $Dictionary
        }
        New-DynamicParam -Name ConfirmText -Type "string" -DPDictionary $Dictionary

        # Error options
        New-DynamicParam -Name WithError -Type "switch" -DPDictionary $Dictionary
        New-DynamicParam -Name SilentStatusCodes -Type "string" -DPDictionary $Dictionary

        # Dry options
        New-DynamicParam -Name Dry -Type "switch" -DPDictionary $Dictionary
        New-DynamicParam -Name DryFormat -Type "string" -ValidateSet @("markdown", "json", "dump", "curl") -DPDictionary $Dictionary

        # Workers
        New-DynamicParam -Name Workers -Type "int" -DPDictionary $Dictionary
        New-DynamicParam -Name Delay -Type "int" -DPDictionary $Dictionary
        New-DynamicParam -Name MaxJobs -Type "int" -DPDictionary $Dictionary
        New-DynamicParam -Name Progress -Type "switch" -DPDictionary $Dictionary

        # Activity logger
        New-DynamicParam -Name NoLog -Type "switch" -DPDictionary $Dictionary
        New-DynamicParam -Name LogMessage -Type "string" -DPDictionary $Dictionary

        # Select
        New-DynamicParam -Name Select -Type "string[]" -DPDictionary $Dictionary
        # New-DynamicParam -Name Filter -Type "string" -DPDictionary $Dictionary

        $Dictionary
    }
}
Function Get-ClientSetting {
    <#
    .SYNOPSIS
    Get the Cumulocity binary settings
    
    .DESCRIPTION
    Get the Cumulocity binary settings which used by the cli tool

    .LINK
    c8y settings list
    
    .EXAMPLE
    Get-ClientSetting
    
    Show the current c8y cli tool settings
    #>

    [cmdletbinding()]
    Param()

    $settings = c8y settings list
    
    if ($LASTEXITCODE -ne 0) {
        Write-Error "Client error when getting settings"
        return
    }

    $settings | ConvertFrom-JSON
}
Function Get-DeviceBootstrapCredential {
<#
.SYNOPSIS
Get the device bootstrap credential as a PowerShell credential object (for use in Rest requests)

.DESCRIPTION
The PSCredentials object also has two additional methods to make the usage of the credentials easier in

The device bootstrap credentials should be already set in the following environment variables

```powershell
$env:C8Y_DEVICEBOOTSTRAP_TENANT
$env:C8Y_DEVICEBOOTSTRAP_USERNAME
$env:C8Y_DEVICEBOOTSTRAP_PASSWORD
```

Then the credentials can be retrieved using

```powershell
$Credential = Get-DeviceBootstrapCredential
$Credential.GetPlainText() # => returns credentials in format "{username}/{password}"
$Credential.GetBasicAuth() # => returns credentials in format "Basic {base64 encoded username/password}"
```

The credentials can be obtained by contacting support. For security reasons, do not use your tenant credentials.

.OUTPUTS
System.Management.Automation.PSCredential

.EXAMPLE
New-DeviceBootstrapCredential

Get a credential object containing the devicebootstrap credentials

.EXAMPLE
$Cred = New-DeviceBootstrapCredential; $Cred.GetBasicAuth()

Get device bootstrap credentials in the format of basic auth (for use in the 'Authorization' header)
#>

    [cmdletbinding()]
    Param()

    $ErrorMessages = New-Object System.Collections.ArrayList
    if (!$env:C8Y_DEVICEBOOTSTRAP_TENANT) {
        $null = $ErrorMessages.Add("Missing env variable: C8Y_DEVICEBOOTSTRAP_TENANT")
    }
    if (!$env:C8Y_DEVICEBOOTSTRAP_USERNAME) {
        $null = $ErrorMessages.Add("Missing env variable: C8Y_DEVICEBOOTSTRAP_USERNAME")
    }
    if (!$env:C8Y_DEVICEBOOTSTRAP_PASSWORD) {
        $null = $ErrorMessages.Add("Missing env variable: C8Y_DEVICEBOOTSTRAP_PASSWORD")
    }

    if ($ErrorMessages.Count -ne 0) {
        Write-Warning ("The following environment variables are missing:`n {0}" -f ($ErrorMessages -join "`n "))
        return
    }

    # Get credentials from environment variables
    $Tenant = $env:C8Y_DEVICEBOOTSTRAP_TENANT
    $Username = $env:C8Y_DEVICEBOOTSTRAP_USERNAME
    $Password = $env:C8Y_DEVICEBOOTSTRAP_PASSWORD | ConvertTo-SecureString -asPlainText -Force

    $Credential = New-Object System.Management.Automation.PSCredential("$Tenant/$Username", $password)

    # Add helper to return clear text username/password
    $Credential | Add-Member -MemberType ScriptMethod -Name "GetPlainText" -Value {
        "{0}:{1}" -f $this.GetNetworkCredential().UserName, $this.GetNetworkCredential().Password
    }

    # Add helper to return basic auth header info
    $Credential | Add-Member -MemberType ScriptMethod -Name "GetBasicAuth" -Value {
        "Basic " + [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes(("{0}:{1}" -f @(
            $this.GetNetworkCredential().UserName,
            $this.GetNetworkCredential().Password
        ))))
    }

    $Credential
}
Function Get-DeviceCollection {
<#
.SYNOPSIS
Get a collection of devices

.DESCRIPTION
Get a collection of devices in Cumulocity by using the inventory API.

.LINK
c8y devices list

.EXAMPLE
Get-DeviceCollection -Name *sensor*

Get all devices with "sensor" in their name

.EXAMPLE
Get-DeviceCollection -Name *sensor* -Type *c8y_* -PageSize 100

Get the first 100 devices with "sensor" in their name and has a type matching "c8y_"

.EXAMPLE
Get-DeviceCollection -Query "lastUpdated.date gt '2020-01-01T00:00:00Z'"

Get a list of devices which have been updated more recently than 2020-01-01

#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    # [OutputType([object])]
    Param(
        # Device name. Wildcards accepted
        [Parameter(Mandatory = $false)]
        [string]
        $Name,

        # Device type.
        [Parameter(Mandatory = $false)]
        [string]
        $Type,

        # Device fragment type.
        [Parameter(Mandatory = $false)]
        [string]
        $FragmentType,

        # Device owner.
        [Parameter(Mandatory = $false)]
        [string]
        $Owner,

        # Query.
        [Parameter(Mandatory = $false)]
        [string]
        $Query,

        # Order results by a specific field. i.e. "name", "_id desc" or "creationTime.date asc".
        [Parameter(Mandatory = $false)]
        [string]
        $OrderBy,

        # Only include agents.
        [Parameter()]
        [switch]
        $Agents,

        # include a flat list of all parents and grandparents of the given object
        [Parameter()]
        [switch]
        $WithParents
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devices list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.customDeviceCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.customDevice+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y devices list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y devices list $c8yargs
        }
    }
}
Function Get-DeviceGroupCollection {
<#
.SYNOPSIS
Get a collection of device groups

.DESCRIPTION
Get a collection of device groups. Device groups are used to arrange devices together.

.LINK
c8y devicegroups list

.EXAMPLE
Get-DeviceGroupCollection -Name *Room*

Get all device groups with "Room" in their name

.EXAMPLE
Get-DeviceGroupCollection -Query "creationTime.date gt '2020-01-01T00:00:00Z'"

Get a list of devices groups which have been created more recently than 2020-01-01

#>

    [cmdletbinding(PositionalBinding=$true, HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device group name. Wildcards accepted
        [Parameter(Mandatory = $false)]
        [string]
        $Name,

        # Device group type.
        [Parameter(Mandatory = $false)]
        [string]
        $Type,

        # Device group fragment type.
        [Parameter(Mandatory = $false)]
        [string]
        $FragmentType,

        # Device group owner.
        [Parameter(Mandatory = $false)]
        [string]
        $Owner,

        # Query.
        [Parameter(Mandatory = $false)]
        [string]
        $Query,

        # Exclude root groups from the list
        [Parameter(Mandatory = $false)]
        [switch]
        $ExcludeRootGroup,

        # Include a flat list of all parents and grandparents of the given object
        [Parameter()]
        [switch]
        $WithParents
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get", "Collection"
    }

    Begin {
        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devicegroups list"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.customDeviceGroupCollection+json"
            ItemType = "application/vnd.com.nsn.cumulocity.customDeviceGroup+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y devicegroups list $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y devicegroups list $c8yargs
        }
    }

    End {}
}
Function Get-DeviceParent {
<#
.SYNOPSIS
Get device parent references for a device

.DESCRIPTION
Get the parent of a device by using the references stored in the device managed object.

.EXAMPLE
Get-DeviceParent device0*

Get the direct (immediate) parent of the given device

.EXAMPLE
Get-DeviceParent -All

Return an array of parent devices where the first element in the array is the root device, and the last is the direct parent of the given device.

.EXAMPLE
Get-DeviceParent -RootParent

Returns the root parent. In most cases this will be the agent

#>

    [cmdletbinding(
        PositionalBinding=$true,
        DefaultParameterSetName = "ByLevel",
        HelpUri='')]
    Param(
        # Device id, name or object. Wildcards accepted
        [Parameter(
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0)]
        [object[]] $Device,


        # Level to navigate backward from the given device to its parent/s
        # 1 = direct parent
        # 2 = parent of its parent
        # If the Level is too large, then the root parent will be returned
        [Parameter(
            ParameterSetName = "ByLevel",
            Position = 1)]
        [ValidateRange(1,100)]
        [int] $Level = 1,

        # Return the top level / root parent
        [Parameter(
            ParameterSetName = "Root")]
        [switch] $RootParent,

        # Return a list of all parent devices
        [Parameter(
            ParameterSetName = "All")]
        [switch] $All
    )

    Process {
        # Get list of ids
        $Ids = (Expand-Device $Device) | Select-Object -ExpandProperty id
        
        $Results = foreach ($iDevice in @(Get-ManagedObjectCollection -Ids $Ids -WithParents -AsPSObject))
        {
            $Parents = @($iDevice.deviceParents.references.managedObject | Foreach-Object {
                if ($null -ne $_.id) {
                    New-Object psobject -Property @{
                        id = $_.id;
                        name = $_.name;
                    }
                }
            })

            # Reverse the order because Cumulocity returns the references in order from number of steps from the given device.
            # So the device closest to the given device is first.
            [array]::Reverse($Parents)

            switch ($PSCmdlet.ParameterSetName) {
                "ByLevel" {
                    # Convert to array index (don't need minus 1 because Level is also a 1 based index (same as Count))
                    $Index = $Parents.Count - $Level
                    
                    if ($Index -lt 0) {
                        $Index = 0
                    }
                    if ($Index -ge $Parents.Count) {
                        $Index = $Parents.Count - 1
                    }

                    if ($null -ne $Parents[$Index].id) {
                        $Parents[$Index]
                    }
                }

                "Root" {
                    if ($null -ne $Parents[0].id) {
                        $Parents[0]
                    }
                }

                "All" {
                    $Parents
                }
            }
        }

        $Results `
            | Expand-Device `
            | Select-Object `
            | Add-PowershellType -Type "c8y.parentReferences"
    }
}
Function Get-ServiceUser {
    <#
    .SYNOPSIS
    Get service user

    .DESCRIPTION
    Get the service user associated to a microservice

    .LINK
    c8y microservices serviceusers get

    .EXAMPLE
    PS> Get-ServiceUser -Id $App.name

    Get application service user

    #>

    [cmdletbinding(PositionalBinding=$true, HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Microservice id (required)
        [Parameter(Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true)]
        [object[]]
        $Id
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Collection"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "microservices serviceusers get" -Exclude "Id"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type            = "application/vnd.com.nsn.cumulocity.applicationUserCollection+json"
            ItemType        = "application/vnd.com.nsn.cumulocity.bootstrapuser+json"
            BoundParameters = $PSBoundParameters
        }
    }

    Process {
        foreach ($item in (PSc8y\Expand-Microservice $Id)) {
            if ($item) {
                $appId = if ($item.id) { $item.id } else { $item }
            }

            if ($ClientOptions.ConvertToPS) {
                c8y microservices serviceusers get --id $appId $c8yargs `
                | ConvertFrom-ClientOutput @TypeOptions
            }
            else {
                c8y microservices serviceusers get --id $appId $c8yargs
            }
        }
    }

    End {}
}
Function Get-Session {
<#
.SYNOPSIS
Get the active Cumulocity Session

.DESCRIPTION
Get the details about the active Cumulocity session which is used by all cmdlets

.LINK
c8y sessions get

.EXAMPLE
Get-Session

Get the current Cumulocity session

.EXAMPLE
Get-Session -Show

Print the current session information (if set)

.OUTPUTS
None
#>

    [CmdletBinding()]
    Param(
        # Specifiy alternative Cumulocity session to use when running the cmdlet
        [Parameter()]
        [string]
        $Session,

        # Only print the session information
        [switch]
        $Show
    )

    $c8yArgs = New-Object System.Collections.ArrayList

    if ($Session) {
        $null = $c8yArgs.AddRange(@("--session", $Session))
    }

    if ($Show) {
        c8y sessions get $c8yArgs
        return
    }

    # Convert session to powershell psobject
    $null = $c8yArgs.Add("--json")
    $sessionResponse = c8y sessions get $c8yArgs
    $data = $sessionResponse | ConvertFrom-Json

    if ($env:C8Y_LOGGER_HIDE_SENSITIVE -eq "true") {
        $data | Add-PowershellType "cumulocity/session-hide-sensitive"
    } else {
        $data | Add-PowershellType "cumulocity/session"
    }
}
Function Get-SessionCollection {
<#
.SYNOPSIS
Get a collection of Cumulocity Sessions

.DESCRIPTION
Get a collection of Cumulocity Sessions found in the home folder under .cumulocity

.EXAMPLE
Get-SessionCollection

List all of the Cumulocity sessions in the default home folder

.OUTPUTS
object[]
#>

    [CmdletBinding()]
    Param()
    $HomePath = Get-SessionHomePath

    $Sessions = Get-ChildItem -LiteralPath $HomePath -Filter "*.json" -Recurse | ForEach-Object {
        $Path = $PSItem.FullName
        $data = Get-Content -LiteralPath $Path | ConvertFrom-Json
        $data | Add-Member -MemberType NoteProperty -Name "path" -Value $Path -ErrorAction SilentlyContinue
        $data.path = $Path
        $data
    }

    $Sessions `
        | Select-Object `
        | Add-PowershellType "cumulocity/sessionCollection"
}
Function Get-SessionHomePath {
<#
.SYNOPSIS
Get session home path

.DESCRIPTION
Get the path where all sessions are stored

.Link
c8y settings list

.EXAMPLE
Get-SessionHomePath
#>

    [cmdletbinding()]
    Param()
    c8y settings list --select "session.home" --output csv
}
function Group-ClientRequests {
<#
.SYNOPSIS
Groups the input into array of a given maximum size. It will pass the piped input as array rather than individual items
#>

    [CmdletBinding()]
    param (
        # Input objects to be piped to native c8y binary
        [AllowNull()]
        [AllowEmptyCollection()]
        [Parameter(
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            ValueFromRemainingArguments = $true,
            Mandatory = $true,
            Position = 0
        )]
        [object[]]
        $InputObject,

        [int]
        $Size = 2000,

        [switch]
        $AsPSObject
    )

    begin {
        $Buffer = New-Object System.Collections.ArrayList
    }

    process {
        foreach ($item in $InputObject) {
            if ($AsPSObject -or $item -is [string] -or $item -is [int] -or $item -is [long]) {
                $pipeitem = $item
            } else {
                $pipeitem = ConvertTo-Json -InputObject $item -Depth 100 -Compress
            }
            [void]$Buffer.Add($pipeitem)

            if ($Buffer.Count -eq $Size) {
                $b = $Buffer;
                $Buffer = New-Object System.Collections.ArrayList($Size)
                ,$b
            }
        }
    }

    end {
        if ($Buffer.Count -ne 0) {  
            ,$Buffer
        }
    }
}
Function Install-ClientBinary {
<#
.SYNOPSIS
Install the Cumulocity cli binary (c8y)

.DESCRIPTION
Install the Cumulocity cli binary (c8y) so it is accessible from everywhere in consoles (assuming /usr/local/bin is in the $PATH variable)

.EXAMPLE
Install-ClientBinary

On Linux/MacOS, this installs the cumulocity binary to /usr/local/bin
On Windows this will throw a warning

.EXAMPLE
Install-ClientBinary -InstallPath /usr/bin

Install the Cumulocity binary to /usr/bin

#>

    [cmdletbinding()]
    Param(
        # Cumulocity installation path where the c8y binaries will be installed. Defaults to $env:C8Y_INSTALL_PATH
        [Parameter(
            Position = 0
        )]
        [string] $InstallPath = $env:C8Y_INSTALL_PATH
    )

    $binary = Get-ClientBinary

    if (!$binary -or !(Test-Path $binary)) {
        Write-Error "Could not find c8y binary"
        return
    }

    if ($IsMacOS -or $IsLinux) {
        if (!$InstallPath) {
            $InstallPath = "/usr/local/bin"
        }
        $TargetBinary = "c8y"
        
        Write-Verbose "Changing execution rights for the binary [$binary]"
        & chmod +x $binary

        if ($LASTEXITCODE -ne 0) {
            Write-Warning "Failed to change binary to executable mode. Try running 'chmod +x $InstallPath/$TargetBinary' manually"
        }
    }
    else {
        if (!$InstallPath) {
            if ($env:HOME) {
                $InstallPath = $env:HOME
            }
        }
        $TargetBinary = "c8y.exe"
    }

    if (!$InstallPath) {
        Write-Warning "InstallPath is empty. Please specify a target install path by using the -InstallPath parameter"
        return
    }

    Write-Verbose "Copying binary to [$InstallPath/$TargetBinary]"

    try {
        $AlreadyInstalled = $false
        if (Test-Path "$InstallPath/$TargetBinary") {
            (Get-FileHash -Path $binary -Algorithm SHA256).Hash -eq (Get-FileHash -Path "$InstallPath/$TargetBinary" -Algorithm SHA256).Hash
        }
        if (!$AlreadyInstalled) {
            Copy-Item -Path $binary -Destination "$InstallPath/$TargetBinary" -ErrorAction Stop
        }
    } catch {
        Write-Warning "Failed to copy file. $_"
        Write-Warning "`nPlease run the following command manually `n`n`tsudo cp `"$binary`" `"$InstallPath/$TargetBinary`""
    }

    if ($env:PATH -notlike "*${InstallPath}*") {
        Write-Warning "The Cumulocity binary has been installed in [$InstallPath] however it is not in your `$PATH variable. This means it will not be accessible from any where in the console. Please add [$InstallPath] to your `$PATH variable"
    }
}
function Invoke-ClientIterator {
<#
.SYNOPSIS
Convert the input objects into a format that can be easily piped to the c8y binary directly

.DESCRIPTION
Calling the go c8y directly involves converting powershell objects either into json lines, or
just passing on the id.

The iterator can also also format the input data and fan it out (turning 1 input item into x items) by using the -Format and -Repeat parameters respectively.


.EXAMPLE
Get-DeviceCollection | Invoke-ClientIterator | c8y devices update --data "mytype=myNewTypeValue"
Get a collection of devices and add a fragment "mytype: 'myNewTypeValue'" to each device.

.EXAMPLE
Get-Device myDeviceName | Invoke-ClientIterator -Repeat 5 | c8y measurements create --template example.jsonnet

Lookup a device by its name and then create 5 measurements using a jsonnet template

.EXAMPLE
@(1..20) | Invoke-ClientIterator "device" | c8y devices create --template example.jsonnet

Create 20 devices naming from "device0001" to "device0020" using a jsonnet template file.

.EXAMPLE
@(1..2) | Invoke-ClientIterator "device_{0}-{1}" -Repeat 2 | c8y devices create

Create 4 (Input count x Repeat) devices with the following names.

```powershell
device_1-0
device_1-1
device_2-0
device_2-1
```

.EXAMPLE
@(1..2) | Invoke-ClientIterator "device_{0}-{2}" -Repeat 2 | c8y devices create

Create 4 (Input count x Repeat) devices with the following names (using 1-indexed values when repeating)

```powershell
device_1-1
device_1-2
device_2-1
device_2-2
```

#>

    [CmdletBinding(
        DefaultParameterSetName = "string"
    )]
    param (
        # Input objects to be piped to native c8y binary
        [Parameter(
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            ValueFromRemainingArguments = $true,
            Mandatory = $true,
            Position = 1
        )]
        [object[]]
        $InputObject,

        # Format string to be applied to each value. The format string is $Format -f $item
        # The value will be prefixed to the input objects by default. However the format string
        # can be customized by using a powershell string format (i.e. "{0:00}" )
        #
        # Other format variables (additional )
        # "{0}" is the current input object (i.e. {0:000} for 0 padded numbers)
        # "{1}" is the repeat counter from 0..Repeat-1
        # "{2}" is the repeat counter from 1..Repeat
        [Parameter(
            Position = 0,
            ParameterSetName = "string"
        )]
        [string]
        $Format,

        # Repeat each input x times. Useful when wanting to use the same item in multiple commands.
        # If a value less than 1 is provided, then it will be set to 1 automatically
        [Parameter(
            Position = 2
        )]
        [int]
        $Repeat,

        # Convert the items to json lines
        [Parameter(
            ParameterSetName = "json"
        )]
        [switch]
        $AsJSON
    )

    begin {
        if ($Repeat -lt 1) {
            $Repeat = 1
        }
        $ValueFormatter = "${Format}{0:0000}"
        if ($Format.Contains("{") -and $Format.Contains("}")) {
            $ValueFormatter = $Format
        }
    }

    process {
        if ($PSCmdlet.ParameterSetName -eq "json") {
            foreach ($item in ($InputObject)) {
                
                $OutputItem = if ($item -is [string] -or $item -is [int]) {
                    @{id=$item}
                } else {
                    $item
                }

                for ($i = 0; $i -lt $Repeat; $i++) {
                    Write-Output (ConvertTo-Json $OutputItem -Depth 100 -Compress)
                }
            }
        } else {
            foreach ($item in (Expand-Id $InputObject)) {
                for ($i = 0; $i -lt $Repeat; $i++) {
                    Write-Output ($ValueFormatter -f $item, $i, ($i+1))
                }
            }
        }
        
    }
}
Function Invoke-ClientLogin {
    [cmdletbinding()]
    Param(
        # Two Factor Authentication code
        [string] $TFACode,

        # Clear existing token (if present)
        [switch] $Clear
    )
    Process {
        $cliArgs = New-Object System.Collections.ArrayList

        $null = $cliArgs.AddRange(@("--shell", "powershell"))

        if ($TFACode) {
            $null = $cliArgs.AddRange(@("--tfaCode", $TFACode))
        }

        if ($Clear) {
            $null = $cliArgs.AddRange(@("--clear"))
        }

        if ($VerbosePreference) {
            $cliArgs.Add("--verbose")
        }

        $result = c8y sessions login $cliArgs

        if ($LASTEXITCODE -ne 0) {
            return
        }

        $result | Out-String | Invoke-Expression
    }
}
Function Invoke-ClientRequest {
    <#
.SYNOPSIS
Send a rest request using the c8y

.DESCRIPTION
Send a custom rest request to Cumulocity using all of the options found on other command lets.
This is useful if you are extending PSc8y and want to send custom microservice requests, or
send requests which are not yet provided in the PSc8y module.

Example:

The following function sends a POST request to predefined microservice endpoint.
It accepts an input Body argument which will be used in the request.

The response is also converted from raw json (string) to Powershell objects so that advanced
filtering can be done on the response (i.e. using `Where-Object`)

```powershell
Function Invoke-MyMicroserviceEndpoint {
    [cmdletbinding()]
    Param(
        [hashtable] $Body
    )

    $options = @{
        Method = "POST"
        Uri = "/service/mymicroservice"
        Data = $Body
    }

    # Send request
    $response = Invoke-ClientRequest @options
    
    # Convert response from json to Powershell objects
    ConvertFrom-Json $response
}
```

.LINK
c8y rest

.EXAMPLE
Invoke-ClientRequest -Uri "/inventory/managedObjects" -Method "post" -Data "name=test"

Create a new managed object with the name "test"

.EXAMPLE
Invoke-ClientRequest -Uri "/alarm/alarms" -QueryParameters @{ pageSize = "100" }

Get a list of alarms with page size of 100

.EXAMPLE
Invoke-ClientRequest -Uri "/alarm/alarms?pageSize=100"

Get a list of alarms with page size of 100

.EXAMPLE
Invoke-ClientRequest -Uri "/inventory/managedObjects" -Method "post" -Data "name=test" -Headers @{ Custom-Value = "myValue"}

Create a new managed object but add a custom accept header value
#>

    [cmdletbinding()]
    Param(
        # Uri (or partial uri). i.e. /application/applications
        [Parameter(
            Mandatory = $true,
            Position = 0)]
        [string] $Uri,

        # Rest Method. Defaults to GET
        [ValidateSet("GET", "POST", "DELETE", "PUT", "HEAD")]
        [Microsoft.PowerShell.Commands.WebRequestMethod] $Method = 'GET',

        # Add custom headers to the rest request
        [hashtable] $Headers,

        # Input file to be uploaded as FormData
        [string] $InFile,

        # Uri query parameters
        [hashtable] $QueryParameters,

        # (Body) Content Type
        [string] $ContentType,

        # Accept header
        [string] $Accept,

        # HostName to use which overrides the given host
        [string] $HostName
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "inventory create" -Exclude @(
            "Uri", "Method", "Headers", "QueryParameters", "InFile", "HostName"
        )
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = if ($Accept) { $Accept } else { "application/json" }
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($Method) {
            $null = $c8yargs.Add($Method)
        }

        if ($null -ne $QueryParameters) {
            $queryparams = New-Object System.Collections.ArrayList
            foreach ($key in $QueryParameters.Keys) {
                $value = $QueryParameters[$key]
                if ($value) {
                    $null = $queryparams.Add("${key}=${value}")
                }
            }

            if ($queryparams.Count -gt 0) {
                $str = $queryparams -join "&"
                if ($Uri.Contains("?")) {
                    # uri already has some query parameters, so just append the new one to it
                    $Uri = $Uri + "&" + $str
                }
                else {
                    $Uri = $Uri + "?" + $str
                }
            }
        }

        $null = $c8yargs.Add($Uri)

        if ($null -ne $Headers) {
            foreach ($key in $Headers.Keys) {
                $null = $c8yargs.AddRange(@("-H=`"{0}: {1}`"" -f $key, $Headers[$key]))
            }
        }

        if ($HostName) {
            $null = $c8yargs.AddRange(@("--host", $HostName))
        }

        if ($InFile) {
            $null = $c8yargs.AddRange(@("--file", $InFile))
        }

        if ($ClientOptions.ConvertToPS) {
            $Name `
            | Group-ClientRequests `
            | c8y rest $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Name `
            | Group-ClientRequests `
            | c8y rest $c8yargs
        }
    }
}
Function Invoke-NativeCumulocityRequest {
    [cmdletbinding(
        SupportsShouldProcess = $true,
        ConfirmImpact = "High"
    )]
    Param(
        [Alias("Url")]
        [Parameter(
            Mandatory = $true,
            Position = 0
        )]
        [string] $Uri,

        [string] $Method,

        [object] $Body,

        [object] $Headers
    )

    Begin {
        $FullUri = $Uri
        if (!$FullUri.StartsWith("http")) {
            $FullUri = @($env:C8Y_URL, $Uri.TrimStart("/")) -join "/"
        }

        $options = @{
            Uri = $FullUri
        }

        if ($PSBoundParameters.ContainsKey("Method")) {
            $options.Method = $Method
        }

        $Allheaders = @{}

        if ($PSBoundParameters.ContainsKey("Headers")) {
            $Allheaders = @{} + $Headers
        }

        if ($Env:C8Y_TOKEN) {
            $AllHeaders.Authorization = "Bearer " + $env:C8Y_TOKEN
        } else {
            $AllHeaders.Authorization = "Basic " + (ConvertTo-Base64String ("{0}/{1}:{2}" -f $env:C8Y_TENANT, $env:C8Y_USERNAME, $env:C8Y_PASSWORD))
        }
    }

    Process {

        if ($PSBoundParameters.ContainsKey("Body")) {
            $options.Body = $Body
        }

        $options.Headers = $Allheaders
        Invoke-RestMethod @options
    }
}
Function Invoke-Template {
    <#
    .SYNOPSIS
    Execute a jsonnet data template
    
    .DESCRIPTION
    Execute a jsonnet data template and show the output of the template. Useful when developing new templates
    
    .LINK
    c8y template execute

    .EXAMPLE
    PS> Invoke-Template -Template ./template.jsonnet
    
    Execute a jsonnet template

    .EXAMPLE
    PS> Invoke-Template -Template ./template.jsonnet -TemplateVars "name=input"
    
    Execute a jsonnet template

    .EXAMPLE
    PS> Invoke-Template -Template ./template.jsonnet -TemplateVars "name=input,type=mytype"
    
    Execute a jsonnet template which has multiple template variables (using a comma separated string)

    .OUTPUTS
    String
    
    #>

    [cmdletbinding(PositionalBinding=$true, HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(    
        # Template (jsonnet) file to use to create the request body.
        [Parameter(
            Mandatory = $true,
            Position = 0
        )]
        [string]
        $Template,
    
        # Variables to be used when evaluating the Template. Accepts a file path, json or json shorthand, i.e. "name=peter"
        [Parameter()]
        [string]
        $TemplateVars,

        # Template input data
        [Parameter(
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true
        )]
        [object[]]
        $Data,
            
        # Output compressed/minified json
        [switch] $Compress
    )
    
    Begin {
        $c8yArgs = New-Object System.Collections.ArrayList

        if ($PSBoundParameters.ContainsKey("Template") -and $Template) {
            $null = $c8yArgs.AddRange(@("--template", $Template))
        }
        if ($PSBoundParameters.ContainsKey("TemplateVars") -and $TemplateVars) {
            $null = $c8yArgs.AddRange(@("--templateVars", $TemplateVars))
        }

        if ($Compress) {
            $null = $c8yArgs.Add("--compact=true")
        }
    }
    
    Process {
        $InputData = @($null)

        if ($null -ne $Data) {
            $InputData = $Data
        }

        foreach ($iData in $InputData) {
            $ic8yArgs = $c8yArgs.Clone()

            if ($iData) {
                $null = $ic8yArgs.AddRange(@("--data", (ConvertTo-JsonArgument $iData)))
            }

            c8y template execute $ic8yArgs
        }
    }
    
    End {}
}
Function New-HostedApplication {
<#
.SYNOPSIS
New hosted (web) application

.DESCRIPTION
Create a new hosted web application by uploading a zip file which contains a web application

.LINK
c8y applications createHostedApplication

.EXAMPLE
New-HostedApplication -Name $App.id -File "myapp.zip"

Upload application zip file containing the web application

#>

    [cmdletbinding(PositionalBinding=$true, HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # File or Folder of the web application. It should contains a index.html file in the root folder/ or zip file (required)
        [Parameter(Mandatory = $false,
            ValueFromPipeline=$true,
            ValueFromPipelineByPropertyName=$true)]
        [Alias("FullName")]
        [Alias("Path")]
        [string]
        $File,

        # File to be uploaded as a binary
        [Parameter(Mandatory = $false)]
        [string]
        $Name,

        # Shared secret of application. Defaults to the application name with a "-application-key" suffix if not provided.
        [Parameter(Mandatory = $false)]
        [string]
        $Key,

        # contextPath of the hosted application. Defaults to the application name if not provided.
        [Parameter(Mandatory = $false)]
        [string]
        $ContextPath,

        # URL to application base directory hosted on an external server. Required when application type is HOSTED
        [Parameter()]
        [string]
        $ResourcesUrl,

        # Access level for other tenants. Possible values are : MARKET, PRIVATE (default)
        [Parameter()]
        [ValidateSet('MARKET','PRIVATE')]
        [string]
        $Availability,

        # Don't uploaded the web app binary. Only the application placeholder will be created
        [Parameter()]
        [switch]
        $SkipUpload,

        # Don't subscribe to the application after it has been created and uploaded
        [Parameter()]
        [switch]
        $SkipActivation
    )

    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $Parameters = @{} + $PSBoundParameters
        $Parameters.Remove("File")

        #
        # Set defaults
        if ($Parameters.ContainsKey("Name")) {
            $Parameters["Name"] = $Name
        }

        if (!$Parameters["Key"]) {
            $Parameters["Key"] = $Name
        }

        if (!$Parameters["ContextPath"]) {
            $Parameters["ContextPath"] = $Name
        }

        $ArgOptions = @{
            Parameters = $Parameters
            Command = "applications createHostedApplication"
        }
        $c8yargs = New-ClientArgument @ArgOptions
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.application+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {
        # Set empty array if no file was provided (so it still uses the loop, but ignores the file)
        if (!$File) {
            $File = @("")
        }

        foreach ($item in $File) {
            $ic8yArgs = New-Object System.Collections.ArrayList
            if ($item) {
                [void]$ic8yArgs.AddRange(@("--file", (Resolve-Path $item).ProviderPath))
            }
            [void]$ic8yArgs.AddRange($c8yargs)

            if ($ClientOptions.ConvertToPS) {
                c8y applications createHostedApplication $ic8yArgs `
                | ConvertFrom-ClientOutput @TypeOptions
            }
            else {
                c8y applications createHostedApplication $ic8yArgs
            }
            
        }
    }

    End {}
}
Function New-Microservice {
<#
.SYNOPSIS
New microservice

.DESCRIPTION
Create a new microservice or upload a new microservice binary to an already running microservice. By default the microservice will
also be subscribed to/enabled.

The zip file needs to follow the Cumulocity Microservice format.

This cmdlet has several operations

.NOTES
This cmdlet does not support template variables

.LINK
c8y microservices create

.EXAMPLE
PS> New-Microservice -File "myapp.zip"

Upload microservice binary. The name of the microservice will be named after the zip file name (without the extension)

If the microservice already exists, then the only the microservice binary will be updated.

.EXAMPLE
PS> New-Microservice -Name "myapp" -File "myapp.zip"

Upload microservice binary with a custom name. Note: If the microservice already exists in the platform

.EXAMPLE
PS> New-Microservice -Name "myapp" -File "./cumulocity.json" -SkipUpload

Create a microservice placeholder named "myapp" for use for local development of a microservice.

The `-File` parameter is provided with the microserivce's manifest file `cumulocity.json` to set the correct required roles of the bootstrap
user which will be automatically created by Cumulocity.

The microservice's bootstrap credentials can be retrieved using `Get-MicroserviceBootstrapUser` cmdlet.

This example is usefuly for local development only, when you want to run the microservice locally (not hosted in Cumulocity).

#>

    [cmdletbinding(PositionalBinding=$true, HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # File to be uploaded as a binary (required)
        [Parameter(Mandatory = $true,
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true)]
        [string]
        $File,

        # Name of the microservice. An id is also accepted however the name have been previously uploaded.
        [Parameter(Mandatory = $false)]
        [string]
        $Name,

        # Shared secret of application. Defaults to application name if not provided.
        [Parameter()]
        [string]
        $Key,

        # Access level for other tenants. Possible values are : MARKET, PRIVATE (default)
        [Parameter()]
        [ValidateSet('MARKET','PRIVATE')]
        [string]
        $Availability,

        # ContextPath of the hosted application. Required when application type is HOSTED
        [Parameter()]
        [string]
        $ContextPath,

        # URL to application base directory hosted on an external server. Required when application type is HOSTED
        [Parameter()]
        [string]
        $ResourcesUrl,

        # Skip the uploading of the microservice binary. This is helpful if you want to run the microservice locally
        # and you only need the microservice place holder in order to create microservice bootstrap credentials.
        [Parameter()]
        [switch]
        $SkipUpload,

        # Don't subscribe to the microservice after it has been created and uploaded
        [Parameter()]
        [switch]
        $SkipSubscription
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create"
    }

    Begin {
        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $Parameters = @{} + $PSBoundParameters
        $Parameters.Remove("File")

        $ArgOptions = @{
            Parameters = $Parameters
            Command = "microservices create"
        }
        $c8yargs = New-ClientArgument @ArgOptions
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.application+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        foreach ($item in $File) {
            $ic8yArgs = New-Object System.Collections.ArrayList
            if ($item) {
                [void]$ic8yArgs.AddRange(@("--file", (Resolve-Path $item).ProviderPath))
            }
            [void]$ic8yArgs.AddRange($c8yargs)

            if ($ClientOptions.ConvertToPS) {
                c8y microservices create $ic8yArgs `
                | ConvertFrom-ClientOutput @TypeOptions
            }
            else {
                c8y microservices create $ic8yArgs
            }
        }
    }

    End {}
}
Function New-RandomPassword {
<#
.SYNOPSIS
Create pseudo random password

.DESCRIPTION
Create a random password which can be used for one-time passwords if the
the password reset functionilty in Cumulocity is not available.

.EXAMPLE
New-RandomPassword

C&3SX6Kn

Generate one password with a length between 8 and 12 chars.

.EXAMPLE
New-RandomPassword -MinPasswordLength 8 -MaxPasswordLength 12 -Count 4

7d&5cnaB
!Bh776T"Fw
9"C"RxKcY
%mtM7#9LQ9h

Generate four passwords, each with a length of between 8 and 12 chars.

.EXAMPLE
New-RandomPassword -InputStrings abc, ABC, 123 -PasswordLength 4

3ABa

Generate a password with a length of 4 containing atleast one char from each InputString

.EXAMPLE
New-RandomPassword -InputStrings abc, ABC, 123 -PasswordLength 4 -FirstChar abcdefghijkmnpqrstuvwxyzABCEFGHJKLMNPQRSTUVWXYZ
3ABa

Generates a password with a length of 4 containing atleast one char from each InputString that will start with a letter from
the string specified with the parameter FirstChar

.OUTPUTS
[String]


.FUNCTIONALITY
Generates random passwords

.LINK
http://blog.simonw.se/powershell-generating-random-password-for-active-directory/

    #>

    [CmdletBinding(
        DefaultParameterSetName = 'FixedLength',
        ConfirmImpact = 'None')]
    [OutputType([String])]
    Param
    (
        # Specifies minimum password length
        [Parameter(Mandatory = $false,
            ParameterSetName = 'RandomLength')]
        [ValidateScript( { $_ -gt 0 })]
        [Alias('Min')] 
        [int]$MinPasswordLength = 12,
        
        # Specifies maximum password length
        [Parameter(Mandatory = $false,
            ParameterSetName = 'RandomLength')]
        [ValidateScript( {
                if ($_ -ge $MinPasswordLength) { $true }
                else { Throw 'Max value cannot be lesser than min value.' } })]
        [Alias('Max')]
        [int]$MaxPasswordLength = 20,

        # Specifies a fixed password length
        [Parameter(Mandatory = $false,
            ParameterSetName = 'FixedLength')]
        [ValidateRange(1, 2147483647)]
        [int]$PasswordLength = 12,
        
        # Specifies an array of strings containing charactergroups from which the password will be generated.
        # At least one char from each group (string) will be used.
        [String[]]$InputStrings = @('abcdefghijkmnpqrstuvwxyz', 'ABCEFGHJKLMNPQRSTUVWXYZ', '123456789', '!#%()[]*+-_;,.'),

        # Specifies a string containing a character group from which the first character in the password will be generated.
        # Useful for systems which requires first char in password to be alphabetic.
        [String] $FirstChar,
        
        # Specifies number of passwords to generate.
        [ValidateRange(1, 2147483647)]
        [int]$Count = 1
    )
    Begin {
        Function Get-Seed {
            # Generate a seed for randomization
            $RandomBytes = New-Object -TypeName 'System.Byte[]' 4
            $Random = New-Object -TypeName 'System.Security.Cryptography.RNGCryptoServiceProvider'
            $Random.GetBytes($RandomBytes)
            [BitConverter]::ToUInt32($RandomBytes, 0)
        }
    }
    Process {
        For ($iteration = 1; $iteration -le $Count; $iteration++) {
            $Password = @{ }
            # Create char arrays containing groups of possible chars
            [char[][]]$CharGroups = $InputStrings

            # Create char array containing all chars
            $AllChars = $CharGroups | ForEach-Object { [Char[]]$_ }

            # Set password length
            if ($PSCmdlet.ParameterSetName -eq 'RandomLength') {
                if ($MinPasswordLength -eq $MaxPasswordLength) {
                    # If password length is set, use set length
                    $PasswordLength = $MinPasswordLength
                }
                else {
                    # Otherwise randomize password length
                    $PasswordLength = ((Get-Seed) % ($MaxPasswordLength + 1 - $MinPasswordLength)) + $MinPasswordLength
                }
            }

            # If FirstChar is defined, randomize first char in password from that string.
            if ($PSBoundParameters.ContainsKey('FirstChar')) {
                $Password.Add(0, $FirstChar[((Get-Seed) % $FirstChar.Length)])
            }
            # Randomize one char from each group
            Foreach ($Group in $CharGroups) {
                if ($Password.Count -lt $PasswordLength) {
                    $Index = Get-Seed
                    While ($Password.ContainsKey($Index)) {
                        $Index = Get-Seed                        
                    }
                    $Password.Add($Index, $Group[((Get-Seed) % $Group.Count)])
                }
            }

            # Fill out with chars from $AllChars
            for ($i = $Password.Count; $i -lt $PasswordLength; $i++) {
                $Index = Get-Seed
                While ($Password.ContainsKey($Index)) {
                    $Index = Get-Seed                        
                }
                $Password.Add($Index, $AllChars[((Get-Seed) % $AllChars.Count)])
            }
            Write-Output -InputObject $( -join ($Password.GetEnumerator() | Sort-Object -Property Name | Select-Object -ExpandProperty Value))
        }
    }
}
Function New-RandomString {
<#
.SYNOPSIS
Create a random string

.DESCRIPTION
Helper utility to quickly create a randomized string which can be used
when adding unique names to devices or another other properties

Note: It should not be used for encryption!

.EXAMPLE
New-RandomString -Prefix "hello_"

Create a random string with the "hello" prefix. i.e `hello_jta6fzwvo7`

.EXAMPLE
New-RandomString -Postfix "_device"

Create a random string which ends with "_device", i.e. `1qs7mc2o3t_device`

#>

    [cmdletbinding()]
    Param(
        # Prefix to be added before the random string
        [string] $Prefix,

        # Postfix to be added after the random string
        [string] $Postfix
    )
    $RandomPart = -join ((48..57) + (97..122) |
        Get-Random -Count 10 |
        ForEach-Object { [char]$_ })

    Write-Output "${Prefix}${RandomPart}${Postfix}"
}
Function New-ServiceUser {
    <#
    .SYNOPSIS
    New service user (via a dummy microservice user)

    .DESCRIPTION
    Create a new microservice application used to provide a service user used for external automation tasks

    .EXAMPLE
    PS> New-ServiceUser -Name "automation01" -RequiredRoles @("ROLE_INVENTORY_READ") -Tenants t123456

    Create a new microservice called automation01 which has permissions to read the inventory, and subscribe the application to tenant t123456

    .LINK
    c8y microservices serviceusers create

    .LINK
    Get-ServiceUser
    #>

    [cmdletbinding(PositionalBinding = $true,
                   HelpUri = '')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Name of the microservice. An id is also accepted however the name have been previously uploaded.
        [Parameter(
            Mandatory = $true,
            Position = 0
        )]
        [string]
        $Name,

        # Roles which should be assigned to the service user, i.e. ROLE_INVENTORY_READ
        [Parameter(Mandatory = $false)]
        [string[]]
        $Roles,

        # Tenants IDs where the application should be subscribed. Useful when using in a multi tenant scenario where the
        # application is created in the management tenant, and a service user can be created via subscribing to the application on each
        # sub tenant
        [Parameter(Mandatory = $false)]
        [string[]]
        $Tenants
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create"
    }

    Begin {

        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "microservices serviceusers create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type            = "application/json"
            ItemType        = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y microservices serviceusers create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y microservices serviceusers create $c8yargs
        }
    }

    End {}
}
Function New-Session {
    <#
.SYNOPSIS
Create a new Cumulocity Session

.DESCRIPTION
Create a new Cumulocity session which can be used by the cmdlets. The new session will be automatically activated.

.LINK
c8y sessions create

.EXAMPLE
New-Session -Name "develop" -Host "my-tenant-name.eu-latest.cumulocity.com"

Create a new Cumulocity session called develop

.EXAMPLE
New-Session -Host "my-tenant-name.eu-latest.cumulocity.com"

Create a new Cumulocity session. It will prompt for the username and password.

.OUTPUTS
None
#>

    [CmdletBinding()]
    Param(
        # Host url, i.e. https://my-tenant-name.eu-latest.cumulocity.com
        [Parameter(Mandatory = $true)]
        [string]
        $Host,
    
        # Tenant id, i.e. t12345
        [Parameter(Mandatory = $false)]
        [string]
        $Tenant,
    
        # Username
        [Parameter()]
        $Username,

        # Password
        [Parameter()]
        $Password,

        # Name of the Cumulocity session
        [Parameter(Mandatory = $false)]
        [string]
        $Name,
    
        # Description
        [Parameter(Mandatory = $false)]
        [string]
        $Description,
    
        # Don't use tenant name as a prefix to the user name when using Basic Authentication
        [Parameter(Mandatory = $false)]
        [switch]
        $NoTenantPrefix
    )

    Begin {
        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }
        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "sessions create"
    }
    
    Process {
        $Path = c8y sessions create $c8yargs
    
        Set-Session -File $Path

        # Test the login
        Invoke-ClientLogin
    }
}
Function New-TemporaryDirectory {
<#
.SYNOPSIS
Create a new temporary directory

.DESCRIPTION
Create a temporary directory in the systems temp directory folder.

.EXAMPLE
New-TemporaryDirectory

Create a new temp directory
#>

    [cmdletbinding()]
    Param()
    $parent = [System.IO.Path]::GetTempPath()
    [string] $name = [System.Guid]::NewGuid()
    New-Item -ItemType Directory -Path (Join-Path $parent $name)
}
Function New-TestAgent {
    <#
    .SYNOPSIS
    Create test agent
    
    .DESCRIPTION
    Create a new test agent with a randomized name. Useful when performing mockups or prototyping.
    
    .EXAMPLE
    New-TestAgent
    
    Create a test agent
    
    .EXAMPLE
    1..10 | Foreach-Object { New-TestAgent -Force }
    
    Create 10 test agents all with unique names
    
    #>

        [cmdletbinding()]
        Param(
            # Agent name prefix which is added before the randomized string
            [Parameter(
                Mandatory = $false,
                ValueFromPipeline = $true,
                ValueFromPipelineByPropertyName = $true,
                Position = 0
            )]
            [string] $Name
        )
        DynamicParam {
            Get-ClientCommonParameters -Type "Create", "TemplateVars"
        }
    
        Begin {
            $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "agents create"
            $ClientOptions = Get-ClientOutputOption $PSBoundParameters
            $TypeOptions = @{
                Type = "application/vnd.com.nsn.cumulocity.customAgent+json"
                ItemType = ""
                BoundParameters = $PSBoundParameters
            }

            $Template = ""
            if (-Not $Template) {
                $Template = (Join-Path $script:Templates "test.agent.jsonnet")
            }

            [void] $c8yargs.AddRange(@(
                "--template",
                $Template
            ))
        }
    
        Process {
            if ($Name) {
                if ($ClientOptions.ConvertToPS) {
                    $Name `
                    | Group-ClientRequests `
                    | c8y agents create $c8yargs `
                    | ConvertFrom-ClientOutput @TypeOptions
                }
                else {
                    $Name `
                    | Group-ClientRequests `
                    | c8y agents create $c8yargs
                }
            } else {
                if ($ClientOptions.ConvertToPS) {
                    c8y agents create $c8yargs `
                    | ConvertFrom-ClientOutput @TypeOptions
                }
                else {
                    c8y agents create $c8yargs
                }
            }
        }
    }
    
Function New-TestAlarm {
<#
.SYNOPSIS
Create a new test alarm

.DESCRIPTION
Create a test alarm for a device.

If the device is not provided then a test device will be created automatically

.EXAMPLE
New-TestAlarm

Create a new test device and then create an alarm on it

.EXAMPLE
New-TestAlarm -Device "myExistingDevice"

Create an alarm on the existing device "myExistingDevice"
#>

    [cmdletbinding()]
    Param(
        # Device id, name or object. If left blank then a randomized device will be created
        [Parameter(
            Mandatory = $false,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0
        )]
        [object] $Device
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "TemplateVars"
    }
    Begin {
        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "alarms create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.customDevice+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
        $Template = ""
        if (-Not $Template) {
            $Template = (Join-Path $script:Templates "test.alarm.jsonnet")
        }
        [void] $c8yargs.AddRange(@(
            "--template",
            $Template
        ))
    }

    Process {
        if ($null -ne $Device) {
            $iDevice = Expand-Device $Device
        } else {
            $iDevice = PSc8y\New-TestDevice -Force:$Force -AsPSObject
        }

        # Fake device (if Dry prevented it from being created)
        if ($Dry -and $null -eq $iDevice) {
            $iDevice = @{ id = "12345" }
        }

        if ($ClientOptions.ConvertToPS) {
            $iDevice.id `
            | c8y alarms create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $iDevice.id `
            | c8y alarms create $c8yargs
        }
    }
}
Function New-TestDevice {
<#
.SYNOPSIS
Create a new test device representation in Cumulocity

.DESCRIPTION
Create a new test device with a randomized name. Useful when performing mockups or prototyping.

The agent will have both the `c8y_IsDevice` fragments set.

.EXAMPLE
New-TestDevice

Create a test device

.EXAMPLE
1..10 | Foreach-Object { New-TestDevice -Force }

Create 10 test devices all with unique names

#>

    [cmdletbinding()]
    Param(
        # Device name prefix which is added before the randomized string
        [Parameter(
            Mandatory = $false,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0
        )]
        [string] $Name
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "TemplateVars"
    }

    Begin {
        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "devices create"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/vnd.com.nsn.cumulocity.customDevice+json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
        $Template = ""
        if (-Not $Template) {
            $Template = (Join-Path $script:Templates "test.device.jsonnet")
        }
        [void] $c8yargs.AddRange(@(
            "--template",
            $Template
        ))
    }

    Process {
        if ($ClientOptions.ConvertToPS) {
            $Name `
            | Group-ClientRequests `
            | c8y devices create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Name `
            | Group-ClientRequests `
            | c8y devices create $c8yargs
        }
    }
}
Function New-TestDeviceGroup {
<#
.SYNOPSIS
Create a new test device group

.DESCRIPTION
Create a new test device group with a randomized name. Useful when performing mockups or prototyping.

.EXAMPLE
New-TestDeviceGroup

Create a test device group

.EXAMPLE
1..10 | Foreach-Object { New-TestDeviceGroup -Force }

Create 10 test device groups all with unique names

.EXAMPLE
New-TestDeviceGroup -TotalDevices 10

Create a test device group with 10 newly created devices
#>

    [cmdletbinding()]
    Param(
        # Device group name prefix which is added before the randomized string
        [Parameter(
            Mandatory = $false,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0
        )]
        [string] $Name = "testgroup",

        # Group type. Only device groups of type `Group` are visible as root folders in the UI
        [ValidateSet("Group", "SubGroup")]
        [string] $Type = "Group",

        # Number of devices to create and assign to the group
        [int]
        $TotalDevices = 0
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Process {
        $options = @{} + $PSBoundParameters
        $options.Remove("Name")
        $options.Remove("Type")
        $options.Remove("TotalDevices")

        
        $TypeName = ""
        switch ($Type) {
            "SubGroup" {
                $TypeName = "c8y_DeviceSubGroup"
                break;
            }
            default {
                $TypeName = "c8y_DeviceGroup"
                break;
            }
        }

        $Data = @{
            c8y_IsDeviceGroup = @{ }
            type = $TypeName
        }

        $GroupName = New-RandomString -Prefix "${Name}_"
        $options["Name"] = $GroupName
        $options["Type"] = $TypeName
        $options["Data"] = $Data
        $Group = PSc8y\New-ManagedObject @options 
        
        if ($TotalDevices -gt 0) {
            for ($i = 0; $i -lt $TotalDevices; $i++) {
                $iDevice = PSc8y\New-TestAgent -Force
                $null = PSc8y\Add-AssetToGroup -Group $Group.id -NewChildDevice $iDevice.id -Force
            }
        }

        Write-Output $Group
    }
}
Function New-TestEvent {
<#
.SYNOPSIS
Create a new test event

.DESCRIPTION
Create a test event for a device.

If the device is not provided then a test device will be created automatically

.EXAMPLE
New-TestEvent

Create a new test device and then create an event on it

.EXAMPLE
New-TestEvent -Device "myExistingDevice"

Create an event on the existing device "myExistingDevice"
#>

    [cmdletbinding()]
    Param(
        # Device id, name or object. If left blank then a randomized device will be created
        [Parameter(
            Mandatory = $false,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0
        )]
        [object] $Device,

        # Time
        [Parameter()]
        [string]
        $Time = "0s",

        # Add a dummy file to the event
        [switch] $WithBinary
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Process {
        $commonOptions = @{} + $PSBoundParameters
        $commonOptions.Remove("Device")
        $commonOptions.Remove("Time")
        $commonOptions.Remove("WithBinary")

        if ($null -ne $Device) {
            $iDevice = Expand-Device $Device
        } else {
            $iDevice = PSc8y\New-TestDevice @commonOptions
        }
        
        # Fake device (if Dry prevented it from being created)
        if ($Dry -and $null -eq $iDevice) {
            $iDevice = @{ id = "12345" }
        }
        
        $options = @{} + $PSBoundParameters
        $options["Device"] = $iDevice.id
        $options.Remove("WithBinary")
        $options["Type"] = "c8y_ci_TestEvent"
        $options["Text"] = "Test CI Event"
        
        $c8yEvent = PSc8y\New-Event @options
        
        if ($WithBinary) {
            if ($Dry -and $null -eq $iDevice) {
                $c8yEvent = @{ id = "12345" }
            }
            
            $tempfile = New-TemporaryFile
            "Cumulocity test content" | Out-File -LiteralPath $tempfile
            $null = PSc8y\New-EventBinary `
                -Id $c8yEvent.id `
                -File $tempfile `
                -Force:$Force
            
            Remove-Item $tempfile
        }
        
        $c8yEvent
    }
}
Function New-TestFile {
<#
.SYNOPSIS
Create a new temp file with default contents

.DESCRIPTION
Create a temporary file with some contents which can be used to uploaded it to Cumulocity
via the Binary api.

.EXAMPLE
New-TestFile

Create a temp file with pre-defined content

.EXAMPLE
"My custom text info" | New-TestFile

Create a temp file with customized content.

.OUTPUTS
System.IO.FileInfo

#>

    [cmdletbinding(
        SupportsShouldProcess = $true,
        ConfirmImpact = "Low"
    )]
    Param(
        # Content which should be written to the temporary file
        [Parameter(
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0
        )]
        [object]
        $InputObject = "example message",

        # Don't prompt for confirmation
        [switch]
        $Force
    )

    if (!$Force -and
        !$WhatIfPreference -and
        !$PSCmdlet.ShouldProcess("Create a temporary file")) {
        return
    }

    $TempFile = New-TemporaryFile
    $InputObject | Out-File -LiteralPath $TempFile.FullName -Encoding utf8

    $TempFile
}
Function New-TestMeasurement {
<#
.SYNOPSIS
Create a new test measurement

.DESCRIPTION
Create a test measurement for a device.

If the device is not provided then a test device will be created automatically

.EXAMPLE
New-TestMeasurement

Create a new test device and then create a measurement on it

.EXAMPLE
New-TestMeasurement -Device "myExistingDevice"

Create a measurement on the existing device "myExistingDevice"
#>

    [cmdletbinding()]
    Param(
        # Device id, name or object. If left blank then a randomized device will be created
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0
        )]
        [object] $Device
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "TemplateVars"
    }
    Begin {
        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Exclude Device -Command "measurements create"
        $Template = ""
        if (-Not $Template) {
            $Template = (Join-Path $script:Templates "test.measurement.jsonnet")
        }
        [void] $c8yargs.AddRange(@("--template", $Template))
    }

    Process {
        if ($ClientOptions.ConvertToPS) {
            $Device `
            | Group-ClientRequests `
            | c8y measurements create $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            $Device `
            | Group-ClientRequests `
            | c8y measurements create $c8yargs
        }
    }
}
Function New-TestOperation {
<#
.SYNOPSIS
Create a new test operation

.DESCRIPTION
Create a test operation for a device.

If the device is not provided then a test device will be created automatically

.EXAMPLE
New-TestOperation

Create a new test device and then create an operation on it

.EXAMPLE
New-TestOperation -Device "myExistingDevice"

Create an operation on the existing device "myExistingDevice"
#>

    [cmdletbinding()]
    Param(
        # Device id, name or object. If left blank then a randomized device will be created
        [Parameter(
            Mandatory = $false,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0
        )]
        [object] $Device
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Process {
        $commonOptions = @{} + $PSBoundParameters
        $commonOptions.Remove("Device")

        if ($null -ne $Device) {
            $iAgent = Expand-Device $Device
        }
        else {
            $iAgent = PSc8y\New-TestAgent @commonOptions
        }

        # Fake device (if Dry prevented it from being created)
        if ($Dry -and $null -eq $iAgent) {
            $iAgent = @{ id = "12345" }
        }

        $options = @{} + $PSBoundParameters
        $options["Device"] = $iAgent.id
        $options["Description"] = "Test operation"

        if ($null -eq $options["Data"]) {
            $options["Data"] = @{}
        }
        $options["Data"].c8y_Restart = @{ parameters = @{ } }

        PSc8y\New-Operation @options
    }
}
Function New-TestUser {
<#
.SYNOPSIS
Create a new test user

.DESCRIPTION
Create a user with a randomized username

.EXAMPLE
New-TestUser

Create a new test user

.EXAMPLE
New-TestUser -Name "myExistingDevice"

Create a new test user with a custom username prefix
#>

    [cmdletbinding()]
    Param(
        # Name of the username. A random postfix will be added to it to make it unique
        [Parameter(
            Mandatory = $false,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0
        )]
        [string] $Name = "testuser"
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "TemplateVars"
    }

    Process {
        $Username = New-RandomString -Prefix "${Name}_"
        $options = @{} + $PSBoundParameters
        $options.Remove("Name")
        $options["UserName"] = $Username
        $options["Password"] = New-RandomString
        
        PSc8y\New-User @options
    }
}
Function New-TestUserGroup {
<#
.SYNOPSIS
Create a test user group

.DESCRIPTION
Create a new test user group using a random name

.EXAMPLE
New-TestUserGroup -Name mygroup

Create a new user group with the prefix "mygroup". A random postfix will be added to it
#>

    [cmdletbinding()]
    Param(
        # Name of the user group. A random postfix will be added to it to make it unique
        [Parameter(
            Mandatory = $false,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0
        )]
        [string] $Name = "testgroup"
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Create", "Template"
    }

    Process {
        $options = @{} + $PSBoundParameters
        $options["Name"] = New-RandomString -Prefix "${Name}_"
        PSc8y\New-UserGroup @options
    }
}
Function Open-Website {
<#
.SYNOPSIS
Open a browser to the cumulocity website

.DESCRIPTION
Opens the default web browser to the Cumulocity application or directly to a device page in the Device Management application

.NOTES
When running on Linux, it relies on xdg-open. If it is not found, then only the URL will be printed to the console.
The user can then try to open the URL by clicking on the link if they are using a modern terminal which supports url links.

.EXAMPLE
Open-Website -Application "cockpit"

Open the cockpit application

.EXAMPLE
Open-Website -Device myDevice01

Open the devicemanagement to the device (default) control page for myDevice01

.EXAMPLE
Open-Website -Device myDevice01 -Page alarms

Open the devicemanagement to the device alarm page for myDevice01

#>

  [cmdletbinding(
    DefaultParameterSetName="Device"
  )]
  Param(
    # Application to open
    [ValidateSet("cockpit", "administration", "devicemanagement", "fieldbus4")]
    [Parameter(
      ParameterSetName="Application",
      Position=0
    )]
    [string] $Application = "cockpit",

    # Name of the device to open in devicemanagement. Only the first matching device will be used to open the c8y website.
    [Parameter(
      ParameterSetName="Device",
      Position=0,
      ValueFromPipelineByPropertyName=$true,
      ValueFromPipeline=$true
    )]
    [object[]] $Device,

    # Device page to open
    [Parameter(
      ParameterSetName="Device",
      Position=1
    )]
    [ValidateSet("device-info", "measurements", "alarms", "control", "events", "service_monitoring", "identity")]
    [string] $Page = "control",

    # Browser to use to open the webpage
    [ValidateSet("chrome", "firefox", "ie", "edge")]
    [string] $Browser = "chrome"
  )
  Process {
    switch ($PSCmdlet.ParameterSetName) {
      "Application" {
        $Url = "/apps/{0}/index.html" -f $Application
        break;
      }

      "Device" {
        if ($null -eq $Device) {
          $Url = "/apps/devicemanagement/index.html"
        } else {
          $DeviceInfo = Expand-Device $Device | Select-Object -First 1
          
          if (!$DeviceInfo) {
            Write-Error "Could not find a matching devices to [$Device]"
            return;
          }
          $Url = "/apps/devicemanagement/index.html#/device/{0}/{1}" -f @($DeviceInfo.id, $Page)
        }
        break;
      }
    }

    $Url = (Get-C8ySessionProperty -Name "host") + $Url

    if ($Url -notmatch "https?://") {
      $Url = "https://$Url"
    }

    # Print a link to the console, so the user can click on it
    Write-Host "Open page: $Url" -ForegroundColor Gray

    switch ($Browser) {
      "ie" {
        # Open the url in the default browser...for the people who use Internet Explorer
        # it is most likely still their default browser so it should work.
        $null = Start-Process $Url -PassThru
      }
      "edge" {
        $null = Start-Process "microsoft-edge:$Url" -PassThru -ErrorAction SilentlyContinue
      }
      Default {
        if ($IsMacOS) {
          $null = Start-Process "open" $Url -PassThru
        } elseif ($IsLinux) {
          if (Get-Command "xdg-open" -ErrorAction SilentlyContinue) {
            $null = Start-Process "xdg-open" $Url -PassThru
          } else {
            Write-Warning "xdg-open is not present on your system. Try clicking on the URL to open it in a browser (if supported by your console)"
          }
        } else {
          $null = Start-Process $Browser $Url -PassThru
        }
      }
    }
  }
}
Function Register-Alias {
<#
.SYNOPSIS
Register aliases for commonly used cmdlets within the PSc8y module

.DESCRIPTION
Registers the aliases for quicker access to the PSc8y cmdlets.

Additional aliases can be created by using the in-built Powershell `New-Alias` cmdlet.

.EXAMPLE
Register-Alias

.LINK
Unregister-Alias
#>

    [cmdletbinding()]
    Param()

    $Aliases = $script:Aliases

    foreach ($Alias in $Aliases.Keys) {
        $Value = $Aliases[$Alias]

        if ($Value -is [string]) {
            Set-Alias -Name $Alias -Value $Aliases[$Alias] -Scope "Global"
        }
    }
}
Function Register-ClientArgumentCompleter {
    <#
.SYNOPSIS
Register PSc8y argument completions for a specific cmdlet

.DESCRIPTION
The cmdlet enables support for argument completion which are used within PSc8y in other modules.

.NOTES
The following argument completions are supports

* `-Session` - Session selection completion
* `-Template` - Template file completion

.EXAMPLE
Register-ClientArgumentCompleter -Name "Get-MyCustomCommand"

Register PSc8y argument completion for supported parameters for a custom function called "Get-MyCustomCommand"

.EXAMPLE
Register-ClientArgumentCompleter -Name "New-CustomManagedObject"

Force the registration of argument completers on a function which uses dynamic parameters
#>

    [cmdletbinding()]
    Param(
        # Command Name
        [Parameter(
            Mandatory = $true,
            Position = 0,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true
        )]
        [object]
        $Command,

        [hashtable]
        $BoundParameters
    )

    Begin {
        $script:CompletionMapping = @{
            "Device" = $script:CompleteDevice
        }
    }

    Process {
        foreach ($name in $BoundParameters.Keys) {
            if ($script:CompletionMapping.ContainsKey($name)) {
                Register-ArgumentCompleter `
                    -CommandName $Command `
                    -ParameterName $name `
                    -Force
                    -ScriptBlock $script:CompletionMapping[$name]
            }
        }
    }
}
Function Set-c8yMode {
    <#
    .SYNOPSIS
    Set cli mode temporarily

    .EXAMPLE
    Set-c8yMode -Mode dev

    Enable development mode (all command enabled) temporarily. The active session file will not be updated
    #>

    [cmdletbinding()]
    Param(
        # Mode
        [Parameter(
            Mandatory = $true,
            Position = 0
        )]
        [ValidateSet("dev", "qual", "prod")]
        [string] $Mode
    )

    c8y settings update --shell powershell mode $Mode | Out-String | Invoke-Expression
    if ($LASTEXITCODE -eq 0) {
        Write-Host "Enabled $Mode mode (temporarily)" -ForegroundColor Green
    }
}
Function Set-ClientConsoleSetting {
<#
.SYNOPSIS
Set console settings to be used by the cli tool

.DESCRIPTION
Sensitive information:
When using -HideSensitive, the following information will be obfuscated when shown on the console
(tenant, username, password, base64 credentials)

.EXAMPLE
Set-ClientConsoleSetting -HideSensitive

Hide any sensitive session information on the console. Settings like (tenant, username, password, base64 credentials)

.EXAMPLE
Set-ClientConsoleSetting -EnableCreateCommands -EnableUpdateCommands

Enable all create and update commands until the session is changed
#>

    [cmdletbinding()]
    Param(
        # Hide all sensitive session information (tenant, username, password, base64 encoded passwords etc.)
        [switch] $HideSensitive,

        # Show sensitive information (excepts clear-text passwords)
        [switch] $ShowSensitive,

        # Enable create commands
        [switch] $EnableCreateCommands,

        # Enable update commands
        [switch] $EnableUpdateCommands,

        # Enable delete commands
        [switch] $EnableDeleteCommands,

        # Disable all create/update/delete commands
        [switch] $DisableCommands,

        # Set the default paging size to use in collection queries
        [int] $DefaultPageSize
    )

    if ($ShowSensitive) {
        Write-Host "Sensitive session information will be visible (except clear-text passwords)" -ForegroundColor Gray
        $env:C8Y_SETTINGS_LOGGER_HIDESENSITIVE = $false
    }

    if ($HideSensitive) {
        Write-Host "Sensitive session information will be hidden" -ForegroundColor Gray
        $env:C8Y_SETTINGS_LOGGER_HIDESENSITIVE = $true
    }

    if ($DisableCommands) {
        Write-Host "Disabling create/update/delete commands" -ForegroundColor Gray
        $env:C8Y_SETTINGS_MODE_ENABLECREATE = ""
        $env:C8Y_SETTINGS_MODE_ENABLEUPDATE = ""
        $env:C8Y_SETTINGS_MODE_ENABLEDELETE = ""
    }

    if ($EnableCreateCommands) {
        Write-Host "Enabling create commands" -ForegroundColor Gray
        $env:C8Y_SETTINGS_MODE_ENABLECREATE = $true
    }

    if ($EnableUpdateCommands) {
        Write-Host "Enabling update commands" -ForegroundColor Gray
        $env:C8Y_SETTINGS_MODE_ENABLEUPDATE = $true
    }
    
    if ($EnableDeleteCommands) {
        Write-Host "Enabling delete commands" -ForegroundColor Gray
        $env:C8Y_SETTINGS_MODE_ENABLEDELETE = $true
    }

    if ($PSBoundParameters.ContainsKey("DefaultPageSize")) {
        if ($DefaultPageSize -gt 0) {
            $env:C8Y_SETTINGS_DEFAULTS_PAGESIZE = "$DefaultPageSize"
        } else {
            $env:C8Y_SETTINGS_DEFAULTS_PAGESIZE = ""
        }
    }
}
Function Set-Session {
    <#
.SYNOPSIS
Set/activate a Cumulocity Session.

.DESCRIPTION
By default the user will be prompted to select from Cumulocity sessions found in their home folder under .cumulocity

Filtering the list is always

"customer dev" will be split in to two search terms, "customer" and "dev", and only results which contain these two search
terms will be includes in the results. The search is applied to the following fields of the session:

* index
* filename (basename only)
* host
* tenant
* username

.NOTES
On MacOS, you need to hold "shift"+Arrow keys to navigate the list of sessions. Otherwise the VIM style "j" (down) and "k" (up) keys can be also used for navigation

.LINK
c8y sessions set

.EXAMPLE
Set-Session

Prompt for a list of Cumulocity sessions to select from

.EXAMPLE
Set-Session customer

Set a session interactively but only include sessions where the details contain "customer" in any of the fields

.EXAMPLE
Set-Session customer, dev

Set a session interactively but only includes session where the details includes "customer" and "dev" in any of the fields

.OUTPUTS
String
#>

    [CmdletBinding(
        DefaultParameterSetName = "ByInteraction"
    )]
    Param(
        # SessionFilter list of sessions. Multiple search terms can be provided. A string "Contains" operation
        # is done to match any of the session fields (except password)
        [Parameter(
            ParameterSetName = "ByInteraction",
            Position = 0
        )]
        [string[]] $SessionFilter,

        # Session
        [Parameter(
            ParameterSetName = "ByFile",
            Position = 0
        )]
        [string] $Session
    )

    Process {
        $c8yargs = New-Object System.Collections.ArrayList
        if ($SessionFilter -gt 0) {
            $SearchTerms = $SessionFilter -join " "
            $null = $c8yargs.AddRange(@("--sessionFilter", "$SearchTerms"))
        }

        if ($Session) {
            [void] $c8yargs.AddRange(@("--session", $Session))
        }

        $envvars = c8y sessions set --noColor=false $c8yargs
        if ($LASTEXITCODE -ne 0) {
            Write-Warning "User cancelled set-session. Current session was not changed"
            return
        }

        $envvars | Out-String | Invoke-Expression
    }
}
Function Test-Json {
<#
.SYNOPSIS
Test if the input object is a valid json string

.DESCRIPTION
Test the given input to check if it is most likely valid json. The cmdlet uses
a quick json sanity check rather than trying to parse the json to save time.

.EXAMPLE
Test-Json '{ "name": "tester" }'

Returns true if the input data is valid json

#>

    [cmdletbinding()]
    [OutputType([bool])]
    Param(
        # Input data
        [Parameter(
            Mandatory = $true,
            Position = 0,
            ValueFromPipeline = $true
        )]
        [object]
        $InputObject
    )

    Process {
        if ($inputObject -isnot [string]) {
            return $false
        }

        if (!(($InputObject -match "^\s*[\[\{]") -and ($InputObject -match "[\]\}]\s*$"))) {
            Write-Information "Only json array or objects are supported"
            return $false
        }

        $IsValid = $false
        try {
            $JSONArgs = @{
                InputObject = $InputObject
                ErrorAction = "Stop"
            }
            $null = ConvertFrom-Json @JSONArgs
            $IsValid = $true
        } catch {
            Write-Information "Invalid json: $_"
        }
        $IsValid
    }
}
Function Unregister-Alias {
<#
.SYNOPSIS
Unregister aliases

.DESCRIPTION
Unregister any aliases which were registered by the Register-Alias cmdlet

.EXAMPLE
Unregister-Alias

.LINK
Register-Alias
#>

    [cmdletbinding()]
    Param()

    $Aliases = $script:Aliases

    foreach ($Alias in $Aliases.Keys) {
        $Value = $Aliases[$Alias]

        if ($Value -is [string]) {
            if (!(Get-Alias -Name $Value -ErrorAction SilentlyContinue)) {
                Remove-Item -Path Alias:$Alias
            }
        }
    }
}
Function Wait-Operation {
<#
.SYNOPSIS
Wait for an operation to be completed (i.e. either in the SUCCESS or FAILED status)

.DESCRIPTION
Wait for an operation to be completed with support for a timeout. Useful when writing scripts
which should only proceed once the operation has finished executing.

.PARAMETER Id
Operation id or object to wait for

.PARAMETER Timeout
Timeout in seconds. Defaults to 30 seconds. i.e. how long should it wait for the operation to be processed

.EXAMPLE
Wait-Operation 1234567

Wait for the operation id

.EXAMPLE
Wait-Operation 1234567 -Timeout 30

Wait for the operation id, and timeout after 30 seconds
#>

    Param(
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0
        )]
        [string] $Id,

        # Timeout in seconds
        [Alias("TimeoutSec")]
        [double] $Timeout = 30
    )
    Process {
        $ExpirationDate = (Get-Date).AddSeconds($Timeout)

        do {
            $op = Get-Operation -Id $id -AsPSObject

            if ($null -eq $op) {
                # Cancel early if the operation does not exist
                Write-Warning "Could not find operation"
                return;
            }
            Start-Sleep -Milliseconds 200
            $HasExpired = (Get-Date) -ge $ExpirationDate
        } while (!$HasExpired -and $op.status -notmatch "(FAILED|SUCCESSFUL)" -and $op.id)

        if ($HasExpired) {
            Write-Warning "Timeout: Operation is still being processed after $Timeout seconds. Operation: $id"
            $op
            return
        }

        switch ($op.status) {
            "FAILED" {
                Write-Warning ("Operation failed [id={0}]. Reason: {1}" -f $op.id, $op.failureReason)
                break;
            }
            "SUCCESSFUL" {
                Write-Verbose "Operation was successful"
                break;
            }
            default {
                throw "Unknown operation status. $($op.status)"
            }
        }
        $op
    }
}
Function Watch-Alarm {
<#
.SYNOPSIS
Watch realtime alarms

.DESCRIPTION
Watch realtime alarms

.LINK
c8y alarms subscribe

.EXAMPLE
PS> Watch-Alarm -Device 12345

Watch all alarms for a device

.EXAMPLE
Watch-Alarm -Device 12345 -DurationSec 600 | Foreach-object {
    $alarm = $_
    $daysOld = ($alarm.time - $alarm.creationTime).TotalDays
    if ($alarm.status -eq "ACTIVE" -and $daysOld -gt 1) {
        $alarm | Update-Alarm -Severity CRITICAL -Force
    }}

Subscribe to realtime alarm notifications for a device, and update the alarm severity to CRITICAL
if the alarm is active and was first created more than 1 day ago.

#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device ID
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object]
        $Device,

        # Start date or date and time of alarm occurrence. (required)
        [Alias("DurationSec")]
        [Parameter()]
        [int]
        $Duration,

        # End date or date and time of alarm occurrence.
        [Parameter()]
        [int]
        $Count
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {
        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "alarms subscribe"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y alarms subscribe $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y alarms subscribe $c8yargs
        }
    }

    End {}
}
Function Watch-Event {
<#
.SYNOPSIS
Watch realtime events

.DESCRIPTION
Watch realtime events

.LINK
c8y events subscribe

.EXAMPLE
PS> Watch-Event -Device 12345
Watch all events for a device

#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device ID
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object]
        $Device,

        # Start date or date and time of event occurrence. (required)
        [Alias("DurationSec")]
        [Parameter()]
        [int]
        $Duration,

        # End date or date and time of event occurrence.
        [Parameter()]
        [int]
        $Count
    )

    Begin {
        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "events subscribe"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y events subscribe $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y events subscribe $c8yargs
        }
    }

    End {}
}
Function Watch-ManagedObject {
<#
.SYNOPSIS
Watch realtime managedObjects

.DESCRIPTION
Watch realtime managedObjects

.LINK
c8y inventory subscribe

.EXAMPLE
PS> Watch-ManagedObject -Device 12345
Watch all managedObjects for a device

#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device ID
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object]
        $Device,

        # Start date or date and time of managedObject occurrence. (required)
        [Alias("DurationSec")]
        [Parameter()]
        [int]
        $Duration,

        # End date or date and time of managedObject occurrence.
        [Parameter()]
        [int]
        $Count
    )

    Begin {
        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "inventory subscribe"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y inventory subscribe $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y inventory subscribe $c8yargs
        }
    }

    End {}
}
Function Watch-Measurement {
<#
.SYNOPSIS
Watch realtime measurements

.DESCRIPTION
Watch realtime measurements

.LINK
c8y measurements subscribe

.EXAMPLE
PS> Watch-Measurement -Device 12345
Watch all measurements for a device

#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device ID
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object]
        $Device,

        # Start date or date and time of measurement occurrence. (required)
        [Alias("DurationSec")]
        [Parameter()]
        [int]
        $Duration,

        # End date or date and time of measurement occurrence.
        [Parameter()]
        [int]
        $Count
    )

    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {
        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "measurements subscribe"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y measurements subscribe $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y measurements subscribe $c8yargs
        }
    }

    End {}
}
Function Watch-Notification {
<#
.SYNOPSIS
Watch realtime notifications

.DESCRIPTION
Watch realtime notifications

.LINK
c8y realtime subscribe

.EXAMPLE
PS> Watch-Notification -Channel "/measurements/*" -DurationSec 90
Watch all measurements for 90 seconds

#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Channel
        [Parameter(
            Mandatory = $true)]
        [string]
        $Channel,

        # Start date or date and time of notification occurrence. (required)
        [Alias("DurationSec")]
        [Parameter()]
        [int]
        $Duration,

        # End date or date and time of notification occurrence.
        [Parameter()]
        [int]
        $Count
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {
        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "realtime subscribe"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y realtime subscribe $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y realtime subscribe $c8yargs
        }
    }

    End {}
}
Function Watch-NotificationChannel {
<#
.SYNOPSIS
Watch realtime device notifications

.DESCRIPTION
Watch realtime device notifications

.LINK
c8y realtime subscribeAll

.EXAMPLE
PS> Function Watch-NotificationChannel -Device 12345 -DurationSec 90
Watch all types of notifications for a device for 90 seconds

#>

    [cmdletbinding(PositionalBinding=$true,
                   HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device ID
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object]
        $Device,

        # Start date or date and time of notification occurrence. (required)
        [Alias("DurationSec")]
        [Parameter()]
        [int]
        $Duration,

        # End date or date and time of notification occurrence.
        [Parameter()]
        [int]
        $Count
    )
    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {
        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "realtime subscribeAll"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y realtime subscribeAll $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y realtime subscribeAll $c8yargs
        }
    }

    End {}
}
Function Watch-Operation {
<#
.SYNOPSIS
Watch realtime operations

.DESCRIPTION
Watch realtime operations

.LINK
c8y operations subscribe

.EXAMPLE
PS> Watch-Operation -Device 12345
Watch all operations for a device

#>

    [cmdletbinding(PositionalBinding=$true, HelpUri='')]
    [Alias()]
    [OutputType([object])]
    Param(
        # Device ID
        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [object]
        $Device,

        # Start date or date and time of operation occurrence. (required)
        [Alias("DurationSec")]
        [Parameter()]
        [int]
        $Duration,

        # End date or date and time of operation occurrence.
        [Parameter()]
        [int]
        $Count
    )

    DynamicParam {
        Get-ClientCommonParameters -Type "Get"
    }

    Begin {
        if ($env:C8Y_DISABLE_INHERITANCE -ne $true) {
            # Inherit preference variables
            Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
        }

        $c8yargs = New-ClientArgument -Parameters $PSBoundParameters -Command "operations subscribe"
        $ClientOptions = Get-ClientOutputOption $PSBoundParameters
        $TypeOptions = @{
            Type = "application/json"
            ItemType = ""
            BoundParameters = $PSBoundParameters
        }
    }

    Process {

        if ($ClientOptions.ConvertToPS) {
            c8y operations subscribe $c8yargs `
            | ConvertFrom-ClientOutput @TypeOptions
        }
        else {
            c8y operations subscribe $c8yargs
        }
    }

    End {}
}

#endregion

#region Enums
Enum c8yExitCode {
    StatusBadRequest400 = 40
    StatusUnauthorized401 = 1
    StatusForbidden403 = 3
    StatusNotFound404 = 4
    StatusMethodNotAllowed405 = 5
    StatusConflict409 = 9
    StatusExecutionTimeout413 = 13
    StatusInvalidData422 = 22
    StatusTooManyRequests429 = 29
    StatusInternalServerError500 = 50
    StatusNotImplemented501 = 51
    StatusBadGateway502 = 52
    StatusServiceUnavailable503 = 53
    
    # Command errors
    SystemError = 100
    UserError = 101
    NoSessionLoaded = 102
    BatchAbortedWithErrors = 103
    BatchCompletedWithErrors = 104
}

#endregion

#region Completions
$script:CompleteAgent = {
    param ($commandName, $parameterName, $wordToComplete)
    if ($wordToComplete -is [array]) {
        $searchFor = $wordToComplete | Select-Object -Last 1
    } else {
        $searchFor = $wordToComplete
    }

    Get-AgentCollection -Name "$searchFor*" -PageSize 100 -WarningAction SilentlyContinue `
    | Where-Object { $_.name -like "$searchFor*" } `
    | Sort-Object { $_.name } `
    | ForEach-Object {
        $details = ("{0} ({1})" -f $_.name, $_.id)
        [System.Management.Automation.CompletionResult]::new(
            $_.id,
            $details,
            'ParameterValue',
            $details
        )
    }
}
$script:CompleteApplication = {
    param ($commandName, $parameterName, $wordToComplete)
    if ($wordToComplete -is [array]) {
        $searchFor = $wordToComplete | Select-Object -Last 1
    } else {
        $searchFor = $wordToComplete
    }

    Get-ApplicationCollection -PageSize 100 -WarningAction SilentlyContinue `
    | Where-Object { $_.id -like "$searchFor*" -or $_.name -like "$searchFor*" } `
    | ForEach-Object {
        $value = $_.name
        $details = ("{0} ({1})" -f $_.id, $_.name)
        [System.Management.Automation.CompletionResult]::new(
            $value,
            $details,
            'ParameterValue',
            $value
        )
    }
}
$script:CompleteDevice = {
    param ($commandName, $parameterName, $wordToComplete)
    if ($wordToComplete -is [array]) {
        $searchFor = $wordToComplete | Select-Object -Last 1
    } else {
        $searchFor = $wordToComplete
    }

    Get-DeviceCollection -Name "$searchFor*" -PageSize 100 -WarningAction SilentlyContinue `
    | Where-Object { $_.name -like "$searchFor*" } `
    | Sort-Object { $_.name } `
    | ForEach-Object {
        $details = ("{0} ({1})" -f $_.name, $_.id)
        [System.Management.Automation.CompletionResult]::new(
            $_.id,
            $details,
            'ParameterValue',
            $details
        )
    }
}
$script:CompleteDeviceGroup = {
    param ($commandName, $parameterName, $wordToComplete)
    if ($wordToComplete -is [array]) {
        $searchFor = $wordToComplete | Select-Object -Last 1
    } else {
        $searchFor = $wordToComplete
    }

    Get-DeviceGroupCollection -Name "$searchFor*" -PageSize 100 -WarningAction SilentlyContinue `
    | Where-Object { $_.name -like "$searchFor*" } `
    | Sort-Object { $_.name } `
    | ForEach-Object {
        $details = ("{0} ({1})" -f $_.name, $_.id)
        [System.Management.Automation.CompletionResult]::new(
            $_.id,
            $details,
            'ParameterValue',
            $details
        )
    }
}
$script:CompleteMeasurementFragmentType = {
    param ($commandName, $parameterName, $wordToComplete, $ast, $fakeBoundParameters)
    if ($wordToComplete -is [array]) {
        $searchFor = $wordToComplete | Select-Object -Last 1
    } else {
        $searchFor = $wordToComplete
    }

    if (!$fakeBoundParameters.ContainsKey("Device")) {
        return
    }

    $device = $fakeBoundParameters["Device"]

    Get-SupportedMeasurements -Device:$device -WarningAction SilentlyContinue `
    | Where-Object { $_ -like "$searchFor*" } `
    | Sort-Object { $_ } `
    | ForEach-Object {
        [System.Management.Automation.CompletionResult]::new(
            $_,
            $_,
            'ParameterValue',
            $_
        )
    }
}

$script:CompleteMeasurementSeries = {
    param ($commandName, $parameterName, $wordToComplete, $ast, $fakeBoundParameters)
    if ($wordToComplete -is [array]) {
        $searchFor = $wordToComplete | Select-Object -Last 1
    } else {
        $searchFor = $wordToComplete
    }

    if (!$fakeBoundParameters.ContainsKey("Device")) {
        return
    }

    $device = $fakeBoundParameters["Device"]
    $valueFragmentType = $fakeBoundParameters["valueFragmentType"]
    
    Get-SupportedSeries -Device:$device -WarningAction SilentlyContinue `
    | Where-Object { $_ -like "$valueFragmentType.*" } `
    | Where-Object { $_ -like "*.$searchFor*" } `
    | ForEach-Object { "$_".Split(".")[-1] } `
    | Sort-Object { $_ } `
    | ForEach-Object {
        [System.Management.Automation.CompletionResult]::new(
            $_,
            $_,
            'ParameterValue',
            $_
        )
    }
}

$script:CompleteMeasurementFullSeries = {
    param ($commandName, $parameterName, $wordToComplete, $ast, $fakeBoundParameters)
    if ($wordToComplete -is [array]) {
        $searchFor = $wordToComplete | Select-Object -Last 1
    } else {
        $searchFor = $wordToComplete
    }

    if (!$fakeBoundParameters.ContainsKey("Device")) {
        return
    }

    $device = $fakeBoundParameters["Device"]
    
    Get-SupportedSeries -Device:$device -WarningAction SilentlyContinue `
    | Where-Object { $_ -like "$searchFor*" } `
    | Sort-Object { $_ } `
    | ForEach-Object {
        [System.Management.Automation.CompletionResult]::new(
            $_,
            $_,
            'ParameterValue',
            $_
        )
    }
}
$script:CompleteMicroservice = {
    param ($commandName, $parameterName, $wordToComplete)
    if ($wordToComplete -is [array]) {
        $searchFor = $wordToComplete | Select-Object -Last 1
    } else {
        $searchFor = $wordToComplete
    }

    Get-ApplicationCollection -PageSize 100 -WarningAction SilentlyContinue `
    | Where-Object { $_.type -eq "MICROSERVICE" } `
    | Where-Object { $_.id -like "$searchFor*" -or $_.name -like "$searchFor*" } `
    | ForEach-Object {
        $details = ("{0} ({1})" -f $_.id, $_.name)
        [System.Management.Automation.CompletionResult]::new(
            $_.id,
            $details,
            'ParameterValue',
            $_.id
        )
    }
}
$script:CompleteRole = {
    param ($commandName, $parameterName, $wordToComplete)
    if ($wordToComplete -is [array]) {
        $searchFor = $wordToComplete | Select-Object -Last 1
    } else {
        $searchFor = $wordToComplete
    }

    Get-RoleCollection -PageSize 100 `
    | Select-Object -ExpandProperty id `
    | Where-Object { $_ -like "$searchFor*" } `
    | ForEach-Object {
        [System.Management.Automation.CompletionResult]::new(
            $_,
            $_,
            'ParameterValue',
            "$_"
        )
    }
}
$script:CompletionSession = {
    param ($commandName, $parameterName, $wordToComplete)
    Get-ChildItem -Path (Get-SessionHomePath) -Filter "$wordToComplete*.*" -ErrorAction SilentlyContinue -WarningAction SilentlyContinue `
    | Where-Object { $_ -match ".(json|yaml|yml|toml|env|properties)$" } `
    | ForEach-Object {
        [System.Management.Automation.CompletionResult]::new($_.BaseName, $_.BaseName, 'ParameterValue', $_.BaseName)
    }
}
$script:CompletionTemplate = {
    param ($commandName, $parameterName, $wordToComplete)

    $settings = Get-ClientSetting
    $c8yTemplateHome = $settings."settings.template.path"
    if (!$c8yTemplateHome) {
        return
    }
    Get-ChildItem -Path $c8yTemplateHome -Recurse -Filter "$wordToComplete*" -ErrorAction SilentlyContinue -WarningAction SilentlyContinue |
    ForEach-Object {
        if ($_.Extension -match "(jsonnet)$") {
            [System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', $_.Name)
        }
    }
}
$script:CompleteTenant = {
    param ($commandName, $parameterName, $wordToComplete)
    if ($wordToComplete -is [array]) {
        $searchFor = $wordToComplete | Select-Object -Last 1
    } else {
        $searchFor = $wordToComplete
    }

    Get-TenantCollection -PageSize 100 -WarningAction SilentlyContinue `
    | Where-Object { $_.id -like "$searchFor*" } `
    | ForEach-Object {
        $id = $_.id
        $details = ("{0} ({1})" -f $_.id, ($_.domain -split "\.")[0])
        [System.Management.Automation.CompletionResult]::new(
            $id,
            $details,
            'ParameterValue',
            $id
        )
    }
}
$script:CompleteTenantOptionCategory = {
    param ($commandName, $parameterName, $wordToComplete)
    if ($wordToComplete -is [array]) {
        $searchFor = $wordToComplete | Select-Object -Last 1
    } else {
        $searchFor = $wordToComplete
    }

    Get-TenantOptionCollection -PageSize 100 -WarningAction SilentlyContinue `
    | Where-Object { $_.category -like "$searchFor*" } `
    | Select-Object -Unique -ExpandProperty category `
    | ForEach-Object {
        [System.Management.Automation.CompletionResult]::new(
            $_,
            $_,
            'ParameterValue',
            $_
        )
    }
}

$script:CompleteTenantOptionKey = {
    param ($commandName, $parameterName, $wordToComplete, $ast, $fakeBoundParameters)
    if ($wordToComplete -is [array]) {
        $searchFor = $wordToComplete | Select-Object -Last 1
    } else {
        $searchFor = $wordToComplete
    }

    $options = Get-TenantOptionForCategory -Category $fakeBoundParameters["category"] -PageSize 100 -WarningAction SilentlyContinue
    
    if ($options -is [hashtable]) {
        $keys = $options.keys
    } else {
        $keys = $options.psobject.Properties.Name
    }
    
    $keys `
    | Where-Object { $_ -like "$searchFor*" } `
    | ForEach-Object {
        [System.Management.Automation.CompletionResult]::new(
            $_,
            $_,
            'ParameterValue',
            $_
        )
    }
}
$script:CompleteUser = {
    param ($commandName, $parameterName, $wordToComplete)
    if ($wordToComplete -is [array]) {
        $searchFor = $wordToComplete | Select-Object -Last 1
    } else {
        $searchFor = $wordToComplete
    }

    Get-UserCollection -PageSize 1000 -WarningAction SilentlyContinue `
    | Where-Object { $_.id -like "$searchFor*" -or $_.email -like "$searchFor*" } `
    | ForEach-Object {
        [System.Management.Automation.CompletionResult]::new(
            $_.id,
            $_.id,
            'ParameterValue',
            $_.id
        )
    }
}
$script:CompleteUserGroup = {
    param ($commandName, $parameterName, $wordToComplete)
    if ($wordToComplete -is [array]) {
        $searchFor = $wordToComplete | Select-Object -Last 1
    } else {
        $searchFor = $wordToComplete
    }

    Get-UserGroupCollection -PageSize 100 -WarningAction SilentlyContinue `
    | Where-Object { $_.id -like "$searchFor*" -or $_.name -like "$searchFor*" } `
    | ForEach-Object {
        $value = $_.name
        $details = ("{0} ({1})" -f $_.id, $_.name)
        [System.Management.Automation.CompletionResult]::new(
            $_.id,
            $details,
            'ParameterValue',
            $_.id
        )
    }
}

#endregion

#region Utilities
$CommandsWithTenantOptionCategory = @(
    "Get-TenantOption",
    "Get-TenantOptionForCategory",
    "New-TenantOption",
    "Remove-TenantOption",
    "Update-TenantOption",
    "Update-TenantOptionBulk",
    "Update-TenantOptionEditable"
)
Register-ArgumentCompleter -CommandName $CommandsWithTenantOptionCategory -ParameterName Category -ScriptBlock $script:CompleteTenantOptionCategory

$CommandsWithTenantOptionKey = @(
    "Get-TenantOption",
    "New-TenantOption",
    "Remove-TenantOption",
    "Update-TenantOption",
    "Update-TenantOptionEditable"
)
Register-ArgumentCompleter -CommandName $CommandsWithTenantOptionKey -ParameterName Key -ScriptBlock $script:CompleteTenantOptionKey

$CommandsWithUserGroupId = @(
    "Get-UserGroup",
    "Get-UserGroupMembershipCollection",
    "Remove-UserGroup",
    "Update-UserGroup"
)
Register-ArgumentCompleter -CommandName $CommandsWithUserGroupId -ParameterName Id -ScriptBlock $script:CompleteUserGroup

$CommandsWithApplicationId = @(
    "Copy-Application",
    "Get-Application",
    "Remove-Application",
    "Update-Application"
)
Register-ArgumentCompleter -CommandName $CommandsWithApplicationId -ParameterName Id -ScriptBlock $script:CompleteApplication

$CommandsWithMicroserviceId = @(
    "Disable-Microservice",
    "Enable-Microservice",
    "Get-Microservice",
    "Remove-Microservice",
    "Update-Microservice"
)
Register-ArgumentCompleter -CommandName $CommandsWithMicroserviceId -ParameterName Id -ScriptBlock $script:CompleteMicroservice

$CommandsWithTenantId = @(
    "Get-Tenant",
    "Remove-Tenant",
    "Update-Tenant"
)
Register-ArgumentCompleter -CommandName $CommandsWithTenantId -ParameterName Id -ScriptBlock $script:CompleteTenant

$CommandsWithUserId = @(
    "Get-User",
    "Remove-User",
    "Update-User"
)
Register-ArgumentCompleter -CommandName $CommandsWithUserId -ParameterName Id -ScriptBlock $script:CompleteUser

$CommandsWithUser = @(
    "Add-RoleToUser",
    "Add-UserToGroup",
    "Get-AuditRecordCollection",
    "Get-RoleReferenceCollectionFromUser",
    "New-AuditRecord",
    "Remove-RoleFromUser",
    "Remove-UserFromGroup"
)
Register-ArgumentCompleter -CommandName $CommandsWithUser -ParameterName User -ScriptBlock $script:CompleteUser

$CommandsWithDeviceGroupId = @(
    "Get-DeviceGroup",
    "Remove-DeviceGroup",
    "Update-DeviceGroup"
)
Register-ArgumentCompleter -CommandName $CommandsWithDeviceGroupId -ParameterName Id -ScriptBlock $script:CompleteDeviceGroup

$CommandsWithMeasurementValueFragmentType = @(
    "Get-MeasurementCollection"
)
Register-ArgumentCompleter -CommandName $CommandsWithMeasurementValueFragmentType -ParameterName ValueFragmentType -ScriptBlock $script:CompleteMeasurementFragmentType

$CommandsWithMeasurementValueFragmentSeries = @(
    "Get-MeasurementCollection"
)
Register-ArgumentCompleter -CommandName $CommandsWithMeasurementValueFragmentSeries -ParameterName ValueFragmentSeries -ScriptBlock $script:CompleteMeasurementSeries

$CommandsWithMeasurementSeries = @(
    "Get-MeasurementSeries"
)
Register-ArgumentCompleter -CommandName $CommandsWithMeasurementSeries -ParameterName Series -ScriptBlock $script:CompleteMeasurementFullSeries

$CommandsWithAddUserToGroupGroup = @(
    "Add-UserToGroup"
)
Register-ArgumentCompleter -CommandName $CommandsWithAddUserToGroupGroup -ParameterName Group -ScriptBlock $script:CompleteUserGroup

$CommandsWithAddRoleToGroupGroup = @(
    "Add-RoleToGroup"
)
Register-ArgumentCompleter -CommandName $CommandsWithAddRoleToGroupGroup -ParameterName Group -ScriptBlock $script:CompleteUserGroup

$CommandsWithAssetToGroupGroup = @(
    "Add-AssetToGroup"
)
Register-ArgumentCompleter -CommandName $CommandsWithAssetToGroupGroup -ParameterName *Group* -ScriptBlock $script:CompleteDeviceGroup

$CommandsWithDevice = @(
    "Add-AssetToGroup",
    "Add-ChildDeviceToDevice",
    "Add-DeviceToGroup",
    "Get-AlarmCollection",
    "Get-ChildAssetCollection",
    "Get-ChildDeviceCollection",
    "Get-ChildDeviceReference",
    "Get-DeviceParent",
    "Get-EventCollection",
    "Get-ExternalIdCollection",
    "Get-MeasurementCollection",
    "Get-MeasurementSeries",
    "Get-OperationCollection",
    "Get-SupportedMeasurements",
    "Get-SupportedSeries",
    "Get-UserCollection",
    "New-Alarm",
    "New-Event",
    "New-ExternalId",
    "New-Measurement",
    "New-Operation",
    "New-TestAlarm",
    "New-TestDeviceGroup",
    "New-TestEvent",
    "New-TestMeasurement",
    "New-TestOperation",
    "Open-Website",
    "Remove-AlarmCollection",
    "Remove-AssetFromGroup",
    "Remove-ChildDeviceFromDevice",
    "Remove-DeviceFromGroup",
    "Remove-EventCollection",
    "Remove-MeasurementCollection",
    "Remove-OperationCollection",
    "Set-DeviceRequiredAvailability",
    "Update-AlarmCollection",
    "Watch-Alarm",
    "Watch-Event",
    "Watch-ManagedObject",
    "Watch-Measurement",
    "Watch-NotificationChannel",
    "Watch-Operation"
)
Register-ArgumentCompleter -CommandName $CommandsWithDevice -ParameterName *Device* -ScriptBlock $CompleteDevice

$CommandsWithAgent = @(
    "Get-DeviceCollection",
    "Get-OperationCollection",
    "New-TestDevice",
    "Remove-OperationCollection"
)
Register-ArgumentCompleter -CommandName $CommandsWithAgent -ParameterName *Agent* -ScriptBlock $CompleteAgent

$CommandsWithTenant = @(
    "Add-RoleToGroup",
    "Add-RoleToUser",
    "Add-UserToGroup",
    "Disable-Application",
    "Disable-Microservice",
    "Enable-Application",
    "Enable-Microservice",
    "Get-ApplicationReferenceCollection",
    "Get-RoleReferenceCollectionFromGroup",
    "Get-RoleReferenceCollectionFromUser",
    "Get-User",
    "Get-UserByName",
    "Get-UserCollection",
    "Get-UserGroup",
    "Get-UserGroupByName",
    "Get-UserGroupCollection",
    "Get-UserGroupMembershipCollection",
    "Get-UserMembershipCollection",
    "New-Session",
    "New-User",
    "New-UserGroup",
    "Remove-RoleFromGroup",
    "Remove-RoleFromUser",
    "Remove-User",
    "Remove-UserFromGroup",
    "Remove-UserGroup",
    "Reset-UserPassword",
    "Update-User",
    "Update-UserGroup"
)
Register-ArgumentCompleter -CommandName $CommandsWithTenant -ParameterName Tenant -ScriptBlock $script:CompleteTenant

$CommandsWithRole = @(
    "Add-RoleToGroup",
    "Add-RoleToUser",
    "Remove-RoleFromGroup",
    "Remove-RoleFromUser"
)
Register-ArgumentCompleter -CommandName $CommandsWithRole -ParameterName Role -ScriptBlock $script:CompleteRole

$CommandsWithRoles = @(
    "New-ServiceUser"
)
Register-ArgumentCompleter -CommandName $CommandsWithRoles -ParameterName Roles -ScriptBlock $script:CompleteRole



#endregion

Export-ModuleMember -Function Add-AssetToGroup,Add-ChildAddition,Add-ChildDeviceToDevice,Add-ChildGroupToGroup,Add-DeviceToGroup,Add-RoleToGroup,Add-RoleToUser,Add-UserToGroup,Approve-DeviceRequest,Copy-Application,Disable-Application,Disable-Microservice,Enable-Application,Enable-Microservice,Find-ByTextManagedObjectCollection,Get-Agent,Get-Alarm,Get-AlarmCollection,Get-AllTenantUsageSummaryStatistics,Get-Application,Get-ApplicationBinaryCollection,Get-ApplicationCollection,Get-ApplicationReferenceCollection,Get-AuditRecord,Get-AuditRecordCollection,Get-Binary,Get-BinaryCollection,Get-BulkOperation,Get-BulkOperationCollection,Get-ChildAdditionCollection,Get-ChildAssetCollection,Get-ChildAssetReference,Get-ChildDeviceCollection,Get-ChildDeviceReference,Get-CurrentApplication,Get-CurrentApplicationSubscription,Get-CurrentTenant,Get-CurrentTenantApplicationCollection,Get-CurrentUser,Get-DataBrokerConnector,Get-DataBrokerConnectorCollection,Get-Device,Get-DeviceChildAssetCollection,Get-DeviceGroup,Get-DeviceGroupChildAssetCollection,Get-DeviceRequest,Get-DeviceRequestCollection,Get-Event,Get-EventBinary,Get-EventCollection,Get-ExternalId,Get-ExternalIdCollection,Get-InventoryRole,Get-InventoryRoleCollection,Get-ManagedObject,Get-ManagedObjectCollection,Get-Measurement,Get-MeasurementCollection,Get-MeasurementSeries,Get-Microservice,Get-MicroserviceBootstrapUser,Get-MicroserviceCollection,Get-Operation,Get-OperationCollection,Get-RetentionRule,Get-RetentionRuleCollection,Get-RoleCollection,Get-RoleReferenceCollectionFromGroup,Get-RoleReferenceCollectionFromUser,Get-SupportedMeasurements,Get-SupportedSeries,Get-SystemOption,Get-SystemOptionCollection,Get-Tenant,Get-TenantCollection,Get-TenantOption,Get-TenantOptionCollection,Get-TenantOptionForCategory,Get-TenantStatisticsCollection,Get-TenantUsageSummaryStatistics,Get-TenantVersion,Get-User,Get-UserByName,Get-UserCollection,Get-UserGroup,Get-UserGroupByName,Get-UserGroupCollection,Get-UserGroupMembershipCollection,Get-UserMembershipCollection,Invoke-UserLogout,New-Agent,New-Alarm,New-Application,New-ApplicationBinary,New-AuditRecord,New-Binary,New-BulkOperation,New-Device,New-DeviceGroup,New-Event,New-EventBinary,New-ExternalId,New-ManagedObject,New-Measurement,New-MicroserviceBinary,New-Operation,New-RetentionRule,New-Tenant,New-TenantOption,New-User,New-UserGroup,Register-Device,Remove-Agent,Remove-AlarmCollection,Remove-Application,Remove-ApplicationBinary,Remove-Asset,Remove-Binary,Remove-BulkOperation,Remove-ChildAddition,Remove-ChildDeviceFromDevice,Remove-Device,Remove-DeviceFromGroup,Remove-DeviceGroup,Remove-DeviceRequest,Remove-Event,Remove-EventBinary,Remove-EventCollection,Remove-ExternalId,Remove-GroupFromGroup,Remove-ManagedObject,Remove-Measurement,Remove-MeasurementCollection,Remove-Microservice,Remove-OperationCollection,Remove-RetentionRule,Remove-RoleFromGroup,Remove-RoleFromUser,Remove-Tenant,Remove-TenantOption,Remove-User,Remove-UserFromGroup,Remove-UserGroup,Request-DeviceCredentials,Reset-UserPassword,Set-DeviceRequiredAvailability,Update-Agent,Update-Alarm,Update-AlarmCollection,Update-Application,Update-Binary,Update-BulkOperation,Update-CurrentApplication,Update-CurrentUser,Update-DataBrokerConnector,Update-Device,Update-DeviceGroup,Update-Event,Update-EventBinary,Update-ManagedObject,Update-Microservice,Update-Operation,Update-RetentionRule,Update-Tenant,Update-TenantOption,Update-TenantOptionBulk,Update-TenantOptionEditable,Update-User,Update-UserGroup,Add-ClientResponseType,Add-PowershellType,Clear-Session,ConvertFrom-Base64String,ConvertFrom-ClientOutput,ConvertFrom-JsonStream,ConvertTo-Base64String,ConvertTo-JsonArgument,ConvertTo-NestedJson,Expand-Application,Expand-Device,Expand-DeviceGroup,Expand-Id,Expand-Microservice,Expand-PaginationObject,Expand-Source,Expand-Tenant,Expand-User,Find-ManagedObjectCollection,Format-Date,Get-AgentCollection,Get-AssetParent,Get-C8ySessionProperty,Get-ClientBinary,Get-ClientBinaryVersion,Get-ClientCommonParameters,Get-ClientSetting,Get-DeviceBootstrapCredential,Get-DeviceCollection,Get-DeviceGroupCollection,Get-DeviceParent,Get-ServiceUser,Get-Session,Get-SessionCollection,Get-SessionHomePath,Group-ClientRequests,Install-ClientBinary,Invoke-ClientIterator,Invoke-ClientLogin,Invoke-ClientRequest,Invoke-NativeCumulocityRequest,Invoke-Template,New-HostedApplication,New-Microservice,New-RandomPassword,New-RandomString,New-ServiceUser,New-Session,New-TemporaryDirectory,New-TestAgent,New-TestAlarm,New-TestDevice,New-TestDeviceGroup,New-TestEvent,New-TestFile,New-TestMeasurement,New-TestOperation,New-TestUser,New-TestUserGroup,Open-Website,Register-Alias,Register-ClientArgumentCompleter,Set-c8yMode,Set-ClientConsoleSetting,Set-Session,Test-Json,Unregister-Alias,Wait-Operation,Watch-Alarm,Watch-Event,Watch-ManagedObject,Watch-Measurement,Watch-Notification,Watch-NotificationChannel,Watch-Operation


#region imports

# Add alias to c8y binary
Set-Alias -Name "c8y" -Value (Get-ClientBinary) -Scope "Global"

#
# Create session folder
#
$HomePath = Get-SessionHomePath

if ($HomePath -and !(Test-Path $HomePath)) {
    Write-Host "Creating home directory [$HomePath]"
    $null = New-Item -Path $HomePath -ItemType Directory
}

# Install binary (and make it executable)
if ($script:IsLinux -or $script:IsMacOS) {
    # silence errors
    if ($env:PSC8Y_INSTALL_ON_IMPORT -match "true|1|on") {
        Install-ClientBinary -ErrorAction SilentlyContinue
    } else {
        # Make c8y executable
        $binary = Get-ClientBinary
        & chmod +x $binary
    }
}

# Load c8y completions for powershell
c8y completion powershell | Out-String | Invoke-Expression

# Session
Register-ArgumentCompleter -CommandName "Set-Session" -ParameterName Session -ScriptBlock $script:CompletionSession

# Set environment variables if a session is set via the C8Y_SESSION env variable
$ExistingSession = Get-Session -WarningAction SilentlyContinue -ErrorAction SilentlyContinue
if ($ExistingSession) {

    # Display current session
    $ConsoleMessage = $ExistingSession | Out-String
    $ConsoleMessage = $ConsoleMessage.TrimEnd()
    Write-Host "Current Cumulocity session"
    Write-Host "${ConsoleMessage}`n"
}

# Enforce UTF8 encoding
$CurrentEncodingName = [Console]::Out.Encoding.EncodingName
$RequiredEncodingName = [System.Text.Encoding]::UTF8.EncodingName

if ($CurrentEncodingName -ne $RequiredEncodingName) {
    if (-not $env:C8Y_DISABLE_ENFORCE_ENCODING) {
        Write-Warning ("Current console encoding is not correct. Changing from [{0}] to [{1}]" -f @(
            $CurrentEncodingName,
            $RequiredEncodingName
        ))
        if ($PROFILE) {
            Write-Warning "You can get rid of this message by adding '[Console]::OutputEncoding = [System.Text.Encoding]::UTF8' to your PowerShell profile ($PROFILE)"
        }
        [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
    } else {
        Write-Verbose "User chose to use non-utf8 encoding (via setting C8Y_DISABLE_ENFORCE_ENCODING env variable). Current console encoding is [$CurrentEncodingName] but PSc8y wants [$RequiredEncodingName]"
    }
}

$script:Aliases = @{
    # collections
    alarms = "Get-AlarmCollection"
    apps = "Get-ApplicationCollection"
    devices = "Get-DeviceCollection"
    events = "Get-EventCollection"
    fmo = "Find-ManagedObjectCollection"
    measurements = "Get-MeasurementCollection"
    ops = "Get-OperationCollection"
    series = "Get-MeasurementSeries"

    # single items
    alarm = "Get-Alarm"
    app = "Get-Application"
    event = "Get-Event"
    m = "Get-Measurement"
    mo = "Get-ManagedObject"
    op = "Get-Operation"

    # References
    childdevices = "Get-ChildDeviceCollection"
    childassets = "Get-ChildAssetCollection"

    # utilities
    json = "ConvertTo-NestedJson"
    tojson = "ConvertTo-NestedJson"
    fromjson = "ConvertFrom-JsonStream"
    rest = "Invoke-ClientRequest"
    base64ToUtf8 = "ConvertFrom-Base64String"
    utf8Tobase64 = "ConvertTo-Base64String"
    iterate = "Invoke-ClientIterator"
    batch = "Group-ClientRequests"

    # session
    session = "Get-Session"
}

Register-Alias
#endregion imports