Functions/Set.ps1

function Set-LinaStrategy {
    <#
    .SYNOPSIS
    Changes the configuration of a strategy
    .DESCRIPTION
    Changes the configuration
    Current limitations : two parameters (gateways where encryption is disabled or WAN mode disabled) cannot be modified
    .INPUTS
    Single LinaStrategy Object or Array of parameters
    .OUTPUTS
    LinaStrategy Object
    .PARAMETER Name
    Name of the strategy to modify
    .PARAMETER Tenant
    Optional : Name of the tenant where the strategy to modify is. Needed if multiple strategies have the same name across tenants
    .EXAMPLE
    @{ RPOInMinutes = 1 } | Set-LinaStrategy -Name "MyStrat"
    Modify strategy MyStrat with a RPO of 1 minute
    .EXAMPLE
    Get-LinaStrategy -Name "MyTemplate" | Set-LinaStrategy -Name "MyStrat"
    Clone parameters from strategy MyTemplate to the strategy "MyStrat"
    #>

    [cmdletbinding()]
    Param(
        [Parameter(ValueFromPipeline = $True, ParameterSetName = "ByObject")]
        [pscustomobject]$lina_strategy,
        [Parameter(Mandatory = $true, ParameterSetName = "ByObject", Position = 0)]
        [ValidateNotNullOrEmpty()]
        [string]$Name,
        [Parameter(Mandatory = $false, ParameterSetName = "ByObject", Position = 1)]
        [ValidateNotNullOrEmpty()]
        [string]$Tenant
    )
    BEGIN {
        if ($global:GLOBAL_LINA_CONNECTED -eq $False) { 
            Write-Error "$($global:GLOBAL_DISCONNNECTED_MESSAGE)" 
            return
        }
     }
    PROCESS {
        $current_tenant_id = Get-LinaCurrentTenantID 6>$null
            
        if ($Tenant) {
                
            $domain = LinaTenantShort -Name $Tenant 6>$null
            $domain_id = [int]$domain.ID
            if ( !($domain_id -gt 0) ) {
                Write-Host2 "ERROR : No tenant found with name $Tenant. Please input the exact name of the Tenant"
                Return
            }
            $void = Set-LinaCurrentTenant -ID $domain_id 6>$null
        } 
            
        if ($lina_strategy) {
            if ([string]$lina_strategy.GetType() -like "*PSCustomObject*") {
                $items = $lina_strategy.PSObject.Properties
            }
            else {
                # Get all items in the array
                $items = $lina_strategy.GetEnumerator()
            }

            $strategy_id = (Get-LinaStrategy -Name $Name).ID
             

            if (!$strategy_id -OR $strategy_id -le 0) {
                Write-Host2 "ERROR : No Strategy found with this name ($Name)"
                return 
            }
            elseif ($strategy_id.Count -gt 1) {
                Write-Host2 "ERROR : Multiple strategies are matching this name ($Name). Please select a tenant to identify which one you want to modify."
                return 
            }
                   
        }

        $xml = '<?xml version="1.0" encoding="UTF-8"?><HNConfig><Func>SET</Func><ServiceProfile><ID>' + $strategy_id + '</ID>'

        foreach ($param in $items) {

            if ([string]$lina_strategy.GetType() -like "*PSCustomObject*") {
                $current_key = $($param.Name)
                $current_value = $($param.Value)
            }
            else {
                $current_key = $param.Key
                $current_value = $param.Value
            }     
                                
            switch ($current_key) {
                RPOInMinutes { $current_value = $current_value * 60 }
                AlwaysEncrypt { $current_value = !$current_value }
                AlertAfterDays { $current_value = $current_value * 24 * 3600 }
                QuotaMaxProtSizeMB { $current_value = $current_value * 1024 * 1024 }
                QuotaMaxHistSizeMB { $current_value = $current_value * 1024 * 1024 }
                TenantID { 
                    # Replacing the Tenant with the one provided
                    if ($domain_id -ge 0) { $current_value = $domain_id } 
                }                        
            }
            # Convert Boolean to 0 or 1
            If ($current_value -eq $True -OR $current_value -eq $false) { $current_value = [int]$current_value }
                    
            # Translate Powershell names to XML tags
            $int_trans = $INT_STRATEGIES_MAPPINGS[$current_key]

            if ($current_key -notin "Name", "ID", "InternalName", "ReplicationTarget", "Tenant" ) {
                # Filter out some parameters for creation
                $xml += "<$int_trans>$current_value</$int_trans>"
            }
        }
        $xml += "</ServiceProfile></HNConfig>"
        $body = "data=$xml"
        $request = CallAPI -Path "/mng_serviceprofile.html" -ContentType "application/xml" -Body $body
        if ([string]$request -like "*[0]*") {
            Write-Host2 "Strategy $Name successfully modified."
            $strategy_modified = Get-LinaStrategy -Name $Name
                
            # Setting back the current tenant to what it was before the Set-LinaStrategy command
            if ($Tenant) { Set-LinaCurrentTenant -ID $current_tenant_id 6>$null }
                
            Return $strategy_modified
        }
        else {
            TranslateErrorCode -LinaError $request -FailedAction "modify strategy $Name"
            Return $null
        }
    }
    END { }
}

function Set-LinaCurrentTenant {
    <#
.SYNOPSIS
Set the current tenant
.DESCRIPTION
Set the current tenant. When set, all listings and actions will be executed and filtered inside this tenant.
To set the global view (view across all tenants), use the -All switch.
.INPUTS
LinaTenant Object
.OUTPUTS
None
.PARAMETER ID
ID of the tenant to set
.PARAMETER Name
Name of the tenant to set
.PARAMETER All
Switch to set the global view (view across all tenants). Available for superadmin only.
.EXAMPLE
Get-LinaTenant -Name "MyTenant" | Set-LinaCurrentTenant
Set the current tenant to MyTenant
.EXAMPLE
Set-LinaCurrentTenant -All
Enable global view across all tenants (superadmin only)
.EXAMPLE
Set-LinaCurrentTenant -ID 2
Set the current tenant to Tenant with ID 2
#>

    [cmdletbinding(DefaultParameterSetName = "ByID")]
    Param(
        [Parameter(ValueFromPipeline = $True, ParameterSetName = "ByObject")]
        [pscustomobject]$lina_tenant,
        [Parameter(Mandatory = $true, ParameterSetName = "ByID")]
        [ValidateNotNullOrEmpty()]
        [string]$ID,
        [Parameter(Mandatory = $true, ParameterSetName = "ByName")]
        [ValidateNotNullOrEmpty()]
        [string]$Name,
        [Parameter(Mandatory = $true, ParameterSetName = "All")]
        [ValidateNotNullOrEmpty()]
        [switch]$All        
    )

    if ($global:GLOBAL_LINA_CONNECTED -eq $False) { 
        Write-Error "$($global:GLOBAL_DISCONNNECTED_MESSAGE)" 
        return
    }

    if ($Name) {
        LinaTenantShort -Name $Name | Set-LinaCurrentTenant
        Return
    }
    elseif ($ID) {
        LinaTenantShort -ID $ID | Set-LinaCurrentTenant
        Return
    }
    # All tenants is 1 or -1 (no tenant selected, global view)
    if ($All) {
        $ID = -1
        $tenant_name = "Global View / All Tenants"
    }
    elseif ($lina_tenant -AND $lina_tenant.ID -ge 1) {
        $ID = $lina_tenant.ID
        $tenant_name = $lina_tenant.Name
    }
    elseif (!$ID) {
        $ID = -1
        $tenant_name = "Global View / All Tenants"
    }
    Write-Verbose "Setting current tenant to Tenant ID $ID"
    $request = CallAPI -Path "/ADM/domain_set_current.json?domain_id=$ID"
    if ($request.status -eq 0) {
        Write-Verbose "Current tenant has been set to $tenant_name (ID $ID)"
        Return $ID
    }
    else {
        TranslateErrorCode -LinaError $request.status -FailedAction "to set current tenant to tenant ID $ID"
        Return
    }
}

function Set-LinaAgent {
    <#
.SYNOPSIS
Changes the configuration of an agent.
.DESCRIPTION
Changes the configuration of an agent for example its name.
.INPUTS
Array of LinaAgent Objects
.OUTPUTS
The modified LinaAgent Objects
.PARAMETER NewName
New name for the agent. If multiple agent are passed, only the first one will be renamed as names have to be unique.
.PARAMETER Strategy
Change the strategy for this agent
.PARAMETER Protection
Change the protection for this agent
.PARAMETER Tenant
Move the agent to this tenant.
.PARAMETER Group
Move the agent to this agent group.
Note : Agent group has to be in the same tenant as the agent or in its new tenant (if Tenant is provided)
.PARAMETER ActivityStatus
Change the activity status of the agent
Accepted values are : Paused, Archived, OnVacation, Disabled, Active
.PARAMETER Email
Change the email associated with this agent. Can be an empty string "" to unset it.
.PARAMETER Tags
Assign tags to this agent. It must be a complete list of all tags to be associated.
Can be an empty string "" to remove all tags associated.
.EXAMPLE
Get-LinaAgent -Name "AGENT1" | Set-LinaAgent -NewName "TEST2"
Changes the name of the agent from AGENT1 to TEST2
.EXAMPLE
Get-LinaAgent -Name "AGENT1" | Set-LinaAgent -Tenant "MyTenant"
Moves the agent AGENT1 to the Tenant MyTenant
.EXAMPLE
Get-LinaAgent -Name "AGENT1" | Set-LinaAgent -Email "test@test.com"
Changes the email associated with AGENT1 to test@test.com
.EXAMPLE
Get-LinaAgent -Name "AGENT1" | Set-LinaAgent -NewName "TEST2" -Tenant "MyTenant" -Group "MyGroup" -Strategy "MyStrategy" -Protection "MyProtection"
Changes everything at the same time (Name, Tenant, Group, Strategy and Protection)
.EXAMPLE
Get-LinaAgent -Name "AGENT1" | Set-LinaAgent -Tags "MyFirstTag,MySecondTag,My Tag with spaces"
.EXAMPLE
Get-LinaAgent -Name "AGENT1" | Set-LinaAgent -Tags @("MyFirstTag","MySecondTag")
Assign two existing tags to an agent. All previous tags will be removed.
.EXAMPLE
Get-LinaAgent -Name "AGENT1" | Set-LinaAgent -Tags (Get-LinaAgent -Name "AGENT2").Tags
Assign same tags as AGENT2 to AGENT1.
.EXAMPLE
Get-LinaAgent -Name "AGENT1" | Set-LinaAgent -Tags @("")
Removes all tags on AGENT1
.EXAMPLE
$current_tags=(Get-LinaAgent -Name "AGENT1").Tags
$new_tags=$current_tags+"France"
Get-LinaAgent -Name "AGENT1" | Set-LinaAgent -Tags $new_tags
Add a "France" tag to existing tags of AGENT1
.EXAMPLE
Get-LinaAgent -Name "AGENT1" | Set-LinaAgent -ActivityStatus "OnVacation"
Set the activity status of AGENT1 to "On Vacation"
.EXAMPLE
Get-LinaAgent -Name "AGENT1" | Set-LinaAgent -ActivityStatus "Active"
Set the activity status of AGENT1 back to normal ("Active")
#>

    [cmdletbinding(DefaultParameterSetName = 'Update')]
    Param(
        [Parameter(ValueFromPipeline = $True, Mandatory = $true, ParameterSetName = "Update")]
        [pscustomobject[]]$LinaAgents,
        [Parameter(Mandatory = $false, ParameterSetName = "Update")]
        [ValidateNotNullOrEmpty()]
        [string]$NewName,
        [Parameter(Mandatory = $false, ParameterSetName = "Update")]
        [ValidateNotNullOrEmpty()]
        [string]$Tenant,
        [Parameter(Mandatory = $false, ParameterSetName = "Update")]
        [ValidateNotNullOrEmpty()]
        [string]$Group,
        [Parameter(Mandatory = $false, ParameterSetName = "Update")]
        [ValidateNotNullOrEmpty()]
        [string]$Strategy,
        [Parameter(Mandatory = $false, ParameterSetName = "Update")]
        [ValidateSet("Active","Archived","OnVacation","Disabled","Paused")]
        [string]$ActivityStatus,
        [Parameter(Mandatory = $false, ParameterSetName = "Update")]
        [ValidateNotNullOrEmpty()]
        [string]$Protection,
        [Parameter(Mandatory = $false, ParameterSetName = "Update")]
        [ValidateNotNull()]
        [string[]]$Tags,        
        [Parameter(Mandatory = $false, ParameterSetName = "Update")]
        [ValidateNotNull()]
        [string]$Email
    )
    BEGIN {
        if ($global:GLOBAL_LINA_CONNECTED -eq $False) { 
            Write-Error "$($global:GLOBAL_DISCONNNECTED_MESSAGE)" 
            return
        }
        $lina_agents_processed = 0
    }
    PROCESS {

        foreach ($LinaAgent in $LinaAgents) {
            If (!$LinaAgent.ID) { return }
            $agent_name = $LinaAgent.Name
            $agent_id = $LinaAgent.ID
            $agent_tenantname = $LinaAgent.Tenant

            if ($NewName) {
                # Renaming Agent => can only be done on one agent at a time
                if ($lina_agents_processed -ge 1) {
                    Write-Host2 "WARNING : You cannot rename multiple agents with the same name. Agent $agent_name will be ignored."
                    Return
                }
                else {
                    Write-Host2 "Renaming Lina agent named $agent_name to new name $NewName"
                    $body = 'data=<?xml version="1.0" encoding="UTF-8"?><HNConfig><Func>REN</Func><Client><ID>' + $agent_id + '</ID><Name>' + $NewName + '</Name></Client></HNConfig>'
                    
                    if ($global:INT_LINA_API_VERSION -lt 60) {
                        # Lina < 6.0
                        $request = CallAPI -Path "/mng_client.html" -ContentType "application/xml" -Body $body
                    } else {
                        # Lina > 6.0
                        $request = CallAPI -Path "/mng_client.json" -ContentType "application/xml" -Body $body
                    }

                    if ([string]$request -like "*[0]*") {
                        Write-Host2 "Agent $agent_name successfully renamed to $NewName."
                        $agent_name = $NewName
                    }
                    else {
                        TranslateErrorCode -LinaError $request -FailedAction "Renaming agent $agent_name to new name $NewName"
                        Return
                    }
                }
                $lina_agents_processed++
            }

            if ($Tenant) {
                # Moving to new tenant
                $tenant_id = (LinaTenantShort -Name $Tenant).ID
                if ($tenant_id -le 1) { 
                    Write-Error "ERROR : No tenant found with this name."
                    Return
                }
                $body = 'data=<?xml version="1.0" encoding="UTF-8"?><HNConfig><Func>MOV</Func><Client><ID>' + $agent_id + '</ID><DomainID>' + $tenant_id + '</DomainID><Name>@auto</Name></Client></HNConfig>'
                Write-Host2 "Moving Lina agent named $agent_name to Tenant $Tenant"

                if ($global:INT_LINA_API_VERSION -lt 60) {
                    # Lina < 6.0
                    $request = CallAPI -Path "/mng_client.html" -ContentType "application/xml" -Body $body
                } else {
                    # Lina > 6.0
                    $request = CallAPI -Path "/mng_client.json" -ContentType "application/xml" -Body $body
                }

                if ([string]$request -like "*[0]*") {
                    Write-Host2 "Agent $agent_name successfully moved to Tenant $Tenant."
                    $agent_tenantname = $Tenant
                }
                else {
                    TranslateErrorCode -LinaError $request -FailedAction "Moving agent $Name to Tenant $Tenant"
                    Return
                }
            }

            if ($Strategy) {
                # Setting a new strategy
                $strategy_id = (Get-LinaStrategy -Name $Strategy).ID
                if ($strategy_id -lt 1 ) { 
                    Write-Error "ERROR : No Strategy found with this name."
                    Return
                }
                $body = 'data=<?xml version="1.0" encoding="UTF-8"?><HNConfig><Func>SET</Func><Client><ID>' + $agent_id + '</ID><ServiceProfileID>' + $strategy_id + '</ServiceProfileID></Client></HNConfig>'
                Write-Host2 "Assigning strategy $Strategy on Lina agent named $agent_name"

                if ($global:INT_LINA_API_VERSION -lt 60) {
                    # Lina < 6.0
                    $request = CallAPI -Path "/mng_client.html" -ContentType "application/xml" -Body $body
                } else {
                    # Lina > 6.0
                    $request = CallAPI -Path "/mng_client.json" -ContentType "application/xml" -Body $body
                }

                if ([string]$request -like "*[0]*") {
                    Write-Host2 "Strategy $Strategy assigned successfully to Agent $agent_name."
                }
                else {
                    TranslateErrorCode -LinaError $request -FailedAction "Assigning strategy $Strategy to agent $Name"
                    Return
                }
            }

            if ($Protection) {
                # Setting a new strategy
                $protection_id = (Get-LinaProtection -Name $Protection).ID
                if ($protection_id -lt 1) { 
                    Write-Error "ERROR : No Protection found with this name."
                    Return
                }
                $body = 'data=<?xml version="1.0" encoding="UTF-8"?><HNConfig><Func>SET</Func><Client><ID>' + $agent_id + '</ID><DataProfileID>' + $protection_id + '</DataProfileID></Client></HNConfig>'
                Write-Host2 "Assigning protection $Protection on Lina agent named $agent_name"

                if ($global:INT_LINA_API_VERSION -lt 60) {
                    # Lina < 6.0
                    $request = CallAPI -Path "/mng_client.html" -ContentType "application/xml" -Body $body
                } else {
                    # Lina > 6.0
                    $request = CallAPI -Path "/mng_client.json" -ContentType "application/xml" -Body $body
                }

                if ([string]$request -like "*[0]*") {
                    Write-Host2 "Protection $Protection assigned successfully to Agent $agent_name."
                }
                else {
                    TranslateErrorCode -LinaError $request -FailedAction "Assigning protection $Protection to agent $Name"
                    Return
                }
            }

            if ($Group) {
                # Moving to group, filtering to group in the same tenant as the agent to move
                $group_id = (Get-LinaAgentGroup -Name $Group -Tenant $agent_tenantname).ID 
                if ($group_id -le 0) { 
                    Write-Error "ERROR : No group found with this name in the same tenant as the agent."
                    Return
                }

                if ($global:INT_LINA_API_VERSION -lt 60 ) {
                    # Legacy mode
                    $hierarchy_id=1 
                }else {
                    # New agents groups
                    $hierarchy_id=2
                }

                $body = 'data=<?xml version="1.0" encoding="UTF-8"?><HNConfig><Func>SETG</Func><Client><ID>' + $agent_id + '</ID><AttachementArray><Attachement><HierarchyID>'+$hierarchy_id+'</HierarchyID><GroupID>' + $group_id + '</GroupID></Attachement></AttachementArray></Client></HNConfig>'
                Write-Host2 "Moving Lina agent named $agent_name to agent group $Group"
                
                if ($global:INT_LINA_API_VERSION -lt 60) {
                    # Lina < 6.0
                    $request = CallAPI -Path "/mng_client.html" -ContentType "application/xml" -Body $body
                } else {
                    # Lina > 6.0
                    $request = CallAPI -Path "/mng_client.json" -ContentType "application/xml" -Body $body
                }

                if ([string]$request -like "*[0]*") {
                    Write-Host2 "Agent $agent_name successfully moved to agent group $Group in Tenant $agent_tenantname."
                }
                else {
                    TranslateErrorCode -LinaError $request -FailedAction "Moving agent $Name to Group $Group in Tenant $agent_tenantname."
                    Return
                }
            }

            if ($ActivityStatus) {
                # Changing activity status
                switch ($ActivityStatus.ToUpper()) {
                    "ARCHIVED" {    $new_status="Archived"
                                    $act_url="/ADE/blocklist/setArchived.json" }

                    "ONVACATION" {  $new_status="On Vacation"
                                    $act_url="/ADE/blocklist/setVacation.json" }

                    "DISABLED" {    $new_status="Disabled"
                                    $act_url="/ADE/blocklist/setDisabled.json" }

                    "PAUSED" {      $new_status="Paused"
                                    $act_url="/ADE/blocklist/setPaused.json" }

                    "ACTIVE" {      $new_status="Active"
                                    $act_url="/ADE/blocklist/unset.json" }
                    
                    # End Of Life not available in webUI / may be deprecated
                    #"ENDOFLIFE" { $new_status="End Of Life"
                    # $act_url="/ADE/blocklist/setEOL.json" }

                    Default {      Write-Host2 "WARNING : $ActivityStatus is not a valid Activity Status value. Ignoring change."
                                   Return
                            }
                }
                if ($Null -eq $LinaAgent.LastConnection) {
                    Write-Host2 "WARNING : Activity Status cannot be changed on agent $agent_name because it has never been connected. Ignoring change."
                } else {
                    Write-Host2 "Changing activity status of Lina agent named $agent_name to $new_status status"
                    $request = CallAPI -Path "${act_url}?id=${agent_id}" -ContentType "application/json" -Method Get
                    
                    if ([string]$request -like "*ASM_OK*") {
                        Write-Host2 "Agent $agent_name status successfully changed to $new_status"
                    }
                    else {
                        TranslateErrorCode -LinaError $request -FailedAction "Change status of agent $agent_name to new status : $new_status"
                        Return
                    }
                }

            }

            # check if parameter is present because it can be empty (to unset email)
            if ($PSBoundParameters.ContainsKey('Email')) {
                if ($global:INT_LINA_API_VERSION -le 51 ) {
                    Write-Host2 "WARNING : Email modification is not available in Lina 5.1 and previous versions. Email won't be modified."
                    Return
                }
                $body = 'data=<?xml version="1.0" encoding="UTF-8"?><HNConfig><Func>SET</Func><Client><ID>' + $agent_id + '</ID><AdminEmail>1</AdminEmail><Email>' + $Email + '</Email></Client></HNConfig>'
                
                Write-Host2 "Assigning Email $Email on Lina agent named $agent_name"

                if ($global:INT_LINA_API_VERSION -lt 60) {
                    # Lina < 6.0
                    $request = CallAPI -Path "/mng_client.html" -ContentType "application/xml" -Body $body
                } else {
                    # Lina > 6.0
                    $request = CallAPI -Path "/mng_client.json" -ContentType "application/xml" -Body $body
                }

                if ([string]$request -like "*[0]*") {
                    Write-Host2 "Email $Email assigned successfully to Agent $agent_name."
                }
                else {
                    TranslateErrorCode -LinaError $request -FailedAction "Assigning Email $Email to agent $Name"
                    Return
                }
            }
            
            # check if parameter is present because it can be empty (to unset tags)
            if ($PSBoundParameters.ContainsKey('Tags')) {
                if ($global:INT_LINA_API_VERSION -lt 60 ) {
                    Write-Host2 "WARNING : Tags are not available in Lina versions below 6.0."
                    Return
                }

                if ( -not (Compare-Object $Tags @("")) ) {
                    Write-Host2 "Removing all Tags on Lina agent named $agent_name"
                    $tag_ids_params=""
                } else {
                    
                    $tag_ids=@()
                    foreach( $tag in $Tags ) {
                        $current_tagid=(Get-LinaTag -Name "$tag").ID
                        
                        if ($null -eq $current_tagid) {
                            Write-Error "Could not find a tag with name $tag"
                            return
                        }
                        $tag_ids += "$current_tagid"
                    }
                    # To have them separated by colon
                    $tag_ids_params= $tag_ids -join (",")
                    Write-Host2 "Assigning Tags $Tags on Lina agent named $agent_name"
                }

                $params = "agent_id=$agent_id&tag_ids=$tag_ids_params"
                $request = CallAPI -Path "/ADE/tag/link.json?$params" -Method Get


                if ([string]$request -like "*[0]*") {
                    if (-not (Compare-Object $Tags @(""))) {
                        Write-Host2 "All tags have been successfully removed on Lina agent named $agent_name"
                    } else {
                        Write-Host2 "Tags $Tags assigned successfully to Agent $agent_name."
                    }
                }
                else {
                    TranslateErrorCode -LinaError $request.status -FailedAction "Assigning Tags $Tags to agent $Name"
                    Return
                }
            }            
            Return Get-LinaAgent -ID $agent_id

        }
    }
    END { }
}

function Set-LinaTenant {
    <#
    .SYNOPSIS
    Changes the configuration of a Tenant.
    .DESCRIPTION
    Changes the configuration of a tenant for example its Comments.
    .INPUTS
    LinaTenant Object
    .PARAMETER isDefault
    Set the tenant as the default one
    .OUTPUTS
    The modified LinaTenant Object
    .EXAMPLE
    Get-LinaTenant -ID 2 | Set-LinaTenant -SetDefault
    Set the Tenant with ID 2 as the default tenant
    .EXAMPLE
    Get-LinaTenant -Name "MyTenant" | Set-LinaTenant
    Unset the Tenant MyTenant as the default tenant
    #>

    [cmdletbinding(DefaultParameterSetName = 'update')]
    Param(
        [Parameter(ValueFromPipeline = $True, Mandatory = $true, ParameterSetName = "update")]
        [pscustomobject[]]$LinaTenants,
        [Parameter(Mandatory = $false, ParameterSetName = "update")]
        [Nullable[boolean]]$IsDefault,
        [Parameter(Mandatory = $false, ParameterSetName = "update")]
        [Nullable[boolean]]$AutoCreateClients,
        [Parameter(Mandatory = $false, ParameterSetName = "update")]
        [ValidateNotNullOrEmpty()]
        [string]$WindowsDefaultProtection,
        [Parameter(Mandatory = $false, ParameterSetName = "update")]
        [ValidateNotNullOrEmpty()]
        [string]$LinuxDefaultProtection,
        [Parameter(Mandatory = $false, ParameterSetName = "update")]
        [ValidateNotNullOrEmpty()]
        [string]$MacDefaultProtection,
        [Parameter(Mandatory = $false, ParameterSetName = "update")]
        [ValidateNotNullOrEmpty()]
        [string]$DefaultStrategy
    )
    BEGIN {
        if ($global:GLOBAL_LINA_CONNECTED -eq $False) { 
            Write-Error "$($global:GLOBAL_DISCONNNECTED_MESSAGE)" 
            return
        }
        $tenants_modified = 0
    }
    PROCESS {

        foreach ($Tenant in $LinaTenants) {
            If (!$Tenant.ID) { return }
            $tenant_name = $Tenant.Name
            $tenant_id = $Tenant.ID

            # Batch all configuration (preferences) modification into a single request
            $config_modif = 0
            $body = 'data=<?xml version="1.0" encoding="UTF-8"?><HNConfig><Func>SET</Func><Globals>'

            if ($Null -ne $AutoCreateClients) {
                $body += '<AutoCreateClients>' + ([int]$AutoCreateClients) + '</AutoCreateClients>'
                $config_modif = 1
            }
            if ($WindowsDefaultProtection -ne "" ) {
                $current_item = $WindowsDefaultProtection
                $item_id = (Get-LinaProtection -Name $current_item).ID
                if ($null -eq $item_id -OR $item_id -le 0) {
                    Write-Host2 "ERROR : No Protection found with name $current_item."
                    Return 
                }
                $body += '<WinDefaultDataProfileID>' + $item_id + '</WinDefaultDataProfileID>' 
                $config_modif = 1
            }
            if ($LinuxDefaultProtection -ne "") {
                $current_item = $LinuxDefaultProtection
                $item_id = (Get-LinaProtection -Name $current_item).ID
                if ($null -eq $item_id -OR $item_id -le 0) {
                    Write-Host2 "ERROR : No Protection found with name $current_item."
                    Return 
                }
                $body += '<LinuxDefaultDataProfileID>' + $item_id + '</LinuxDefaultDataProfileID>' 
                $config_modif = 1
            }
            if ($MacDefaultProtection -ne "") {
                $current_item = $MacDefaultProtection
                $item_id = (Get-LinaProtection -Name $current_item).ID
                if ($null -eq $item_id -OR $item_id -le 0) {
                    Write-Host2 "ERROR : No Protection found with name $current_item."
                    Return 
                }
                $body += '<MacDefaultDataProfileID>' + $item_id + '</MacDefaultDataProfileID>' 
                $config_modif = 1
            }                                 

            if ($DefaultStrategy -ne "") {
                $current_item = $DefaultStrategy
                $item_id = (Get-LinaStrategy -Name $current_item).ID
                if ($null -eq $item_id -OR $item_id -le 0) {
                    Write-Host2 "ERROR : No Strategy found with name $current_item."
                    Return 
                }
                $body += '<WinDefaultServiceProfileID>' + $item_id + '</WinDefaultServiceProfileID>' 
                $config_modif = 1
            }    

            if ($config_modif -eq 1 ) {
                $current_tenant_id = Get-LinaCurrentTenantID 6>$null

                Write-Host2 "Modifying configuration of tenant $tenant_name"
                Set-LinaCurrentTenant -ID $tenant_id 6>$null
                $body += '</Globals></HNConfig>'
                $request = CallAPI -Path "/mng_globals.html" -ContentType "application/xml" -Body $body

                # Setting back the current tenant to what it was before the Set-LinaTenant command
                Set-LinaCurrentTenant -ID $current_tenant_id 6>$null
                if ([string]$request -like "*[0]*") {                    
                    Write-Host2 "Tenant $tenant_name config has been succesfully applied"
                }
                else {
                    TranslateErrorCode -LinaError $request.status -FailedAction "applying config on tenant $tenant_name "
                    Return
                }                    

            }


            # Modifications of default tenant (not the same requests)
            if ($Null -ne $IsDefault) {
                If ($tenants_modified -ge 1) {
                    Write-Host2 "WARNING : Only one tenant can be set as the default one. Only the first one will be set as the default tenant"
                    return
                }
                if ($IsDefault -eq $True) {
                    $request = CallAPI -Path "/ADM/domain_set_default.json?id=$tenant_id" -ContentType "application/json"
                    if ($request.status -eq 0) {
                        Write-Host2 "Tenant $tenant_name is now the default Tenant"
                        $tenants_modified++
                    }
                    else {
                        TranslateErrorCode -LinaError $request.status -FailedAction "set tenant $tenant_name as the default tenant"
                        Return
                    }
                }
                elseif ($IsDefault -eq $False) {
                    if (-NOT (LinaTenantShort -Name $tenant_name).IsDefault) {
                        Write-Host2 "Tenant $tenant_name is not the default => No modification is required"
                    }
                    $request = CallAPI -Path "/ADM/domain_unset_all.json" -ContentType "application/json"
                    if ($request.status -eq 0) {
                        Write-Host2 "Tenant $tenant_name is not the default Tenant anymore and no Tenant is set as default."
                        $tenants_modified++

                    }
                    else {
                        TranslateErrorCode -LinaError $request.status -FailedAction "unset tenant $tenant_name as the default tenant"
                        Return
                    }
                }
            }
            Return Get-LinaTenant -ID $tenant_id
        }
            
    }
    END { }
}

function Set-LinaUser {
    <#
.SYNOPSIS
Changes the configuration of a user.
.DESCRIPTION
Changes the configuration of a user : Enable/Disable, Password, UserGroup
.INPUTS
Array of LinaUser Objects
.OUTPUTS
The modified LinaUser Objects
.PARAMETER Password
Optional : New password for the user(s)
.PARAMETER Disabled
Optional : New status of the user(s). Can be $True (Disabled) or $False (Enabled)
.PARAMETER UserGroup
Optional : New user group (and user profile) for the user(s)
Note : User group has to be in the same tenant as the user
.EXAMPLE
Get-LinaUser -Name "MyUser" | Set-LinaUser -Disabled $False
Enables the user MyUser
.EXAMPLE
Get-LinaUser -Name "MyUser*" | Set-LinaUser -Password "bioubiou" -Disabled $False -UserGroup "Groupe d'utilisateurs par défaut"
Changes users "MyUser*" password, user group and enable them
#>

    [cmdletbinding(DefaultParameterSetName = 'Update')]
    Param(
        [Parameter(ValueFromPipeline = $True, Mandatory = $true, ParameterSetName = "Update")]
        [pscustomobject[]]$LinaObjects,
        [Parameter(Mandatory = $false, ParameterSetName = "Update")]
        [ValidateNotNullOrEmpty()]
        [string]$Password,
        [Parameter(Mandatory = $false, ParameterSetName = "Update")]
        [ValidateNotNullOrEmpty()]
        [string]$UserGroup,
        [Parameter(Mandatory = $false, ParameterSetName = "Update")]
        [ValidateNotNullOrEmpty()]
        [Nullable[Boolean]]$Disabled
    )
    BEGIN {
        if ($global:GLOBAL_LINA_CONNECTED -eq $False) { 
            Write-Error "$($global:GLOBAL_DISCONNNECTED_MESSAGE)" 
            return
        }
    }
    PROCESS {

        foreach ($LinaObject in $LinaObjects) {
            If (!$LinaObject.ID) { return }
            $user_name = $LinaObject.Name
            $user_id = $LinaObject.ID
            $user_groupid = $LinaObject.UserGroupID
            $user_tenantname = $LinaObject.Tenant
            $user_tenantid = $LinaObject.TenantID
            $user_disabled = $LinaObject.Disabled

            if ($Password) {
                Write-Host2 "Changing password for user named $user_name in Tenant $user_tenantname"
                $pass_enc=[System.Web.HttpUtility]::UrlEncode($Password)
                $request = CallAPI -Path "/ADM/user_set_pass.json?user_id=$user_id&pass=$pass_enc" -ContentType "application/json"
                if ($request.status -eq 0) {
                    Write-Host2 "Successfully changed password for user named $user_name in Tenant $user_tenantname"
                } else {
                    TranslateErrorCode -LinaError $request -FailedAction "Changing password for user named $user_name in Tenant $user_tenantname"
                    Return
                }
            }

            if ($UserGroup) {
                $UserGroupObject = Get-LinaUserGroup -Name $UserGroup | Where-Object {$_.TenantID -eq $user_tenantid}
                $new_user_groupid = $UserGroupObject.ID

                if (!$new_user_groupid) { 
                    Write-Error "ERROR : No user group found with this name ($UserGroup) in Tenant $user_tenantname."
                    Return
                }
                Write-Host2 "Changing user group for user named $user_name in Tenant $user_tenantname to user group $UserGroup"

                $request = CallAPI -Path "/ADM/move_user_to_ug.json?user_id=$user_id&from_ug_id=$user_groupid&ug_id=$new_user_groupid" -ContentType "application/json"
                if ($request.status -eq 0) {
                    Write-Host2 "Succesfully changed user group to $UserGroup for user named $user_name in Tenant $user_tenantname."
                }
                else {
                    TranslateErrorCode -LinaError $request -FailedAction "changing user group to $UserGroup for user named $user_name in Tenant $user_tenantname"
                    Return
                }
            }

            if ($Null -ne $Disabled) {
                if ($Disabled -eq $True) {
                    if ($user_disabled -eq $True) {
                        Write-Host2 "Nothing to do : user $user_name in Tenant $user_tenantname is already disabled"
                        Return
                    }
                    Write-Host2 "Disabling user $user_name in Tenant $user_tenantname"
                    $request = CallAPI -Path "/ADM/user_disable.json?user_id=$user_id" -ContentType "application/json"
                    if ($request.status -eq 0) {
                        Write-Host2 "Successfully disabled user $user_name in Tenant $user_tenantname"
                    }else {
                        TranslateErrorCode -LinaError $request -FailedAction "disabling user $user_name in Tenant $user_tenantname"
                        Return
                    }
                } elseif ($Disabled -eq $False) {
                    if ($user_disabled -eq $False) {
                        Write-Host2 "Nothing to do : user $user_name in Tenant $user_tenantname is already enabled"
                        Return
                    }
                    Write-Host2 "Enabling user $user_name in Tenant $user_tenantname"
                    $request = CallAPI -Path "/ADM/user_enable.json?user_id=$user_id" -ContentType "application/json"
                    if ($request.status -eq 0) {
                        Write-Host2 "Successfully enabled user $user_name in Tenant $user_tenantname"
                    }else {
                        TranslateErrorCode -LinaError $request -FailedAction "enabling user $user_name in Tenant $user_tenantname"
                        Return
                    }
                }
            }
            Return Get-LinaUser -ID $user_id
        }
    }
    END { }
}

function Set-LinaUserGroup {
    <#
.SYNOPSIS
Changes the configuration of a user group.
.DESCRIPTION
Changes the configuration of a user group : Name, UserProfile
.INPUTS
Array of LinaUserGroup Objects
.OUTPUTS
The modified LinaUserGroup Objects
.PARAMETER Name
Optional : New name for the user group
.PARAMETER UserProfile
Optional : New user profile to be assigned
Note : User profile has to be in the same tenant as the user group
.EXAMPLE
Get-LinaUserGroup -Name "MyUserGroup" | Set-LinaUserGroup -NewName "MyUserGroupModified" -UserProfile "Profil administrateur"
Changes the name and user profile of MyUserGroup
.EXAMPLE
Get-LinaUserGroup -Name "MyUserGroup* | Set-LinaUser -UserProfile "Profil administrateur"
Changes the user profile of all user groups MyUserGroup*
#>

    [cmdletbinding(DefaultParameterSetName = 'Update')]
    Param(
        [Parameter(ValueFromPipeline = $True, Mandatory = $true, ParameterSetName = "Update")]
        [pscustomobject[]]$LinaObjects,
        [Parameter(Mandatory = $false, ParameterSetName = "Update")]
        [ValidateNotNullOrEmpty()]
        [string]$NewName,
        [Parameter(Mandatory = $false, ParameterSetName = "Update")]
        [ValidateNotNullOrEmpty()]
        [string]$UserProfile
    )
    BEGIN {
        if ($global:GLOBAL_LINA_CONNECTED -eq $False) { 
            Write-Error "$($global:GLOBAL_DISCONNNECTED_MESSAGE)" 
            return
        }
        if ($global:INT_LINA_API_VERSION -ge 61) {
            Write-Warning "This cmdlet is not yet supported in Lina 6.1+." 
            return
        }
        
    }
    PROCESS {

        foreach ($LinaObject in $LinaObjects) {
            If (!$LinaObject.ID) { return }
            $usergroup_name = $LinaObject.Name
            $usergroup_id = $LinaObject.ID
            $usergroup_profileid = $LinaObject.UserProfileID
            $usergroup_profile = $LinaObject.UserProfile
            $usergroup_tenantname = $LinaObject.Tenant
            $usergroup_tenantid = $LinaObject.TenantID

            if ($UserProfile) {
                $UserProfileObject = Get-LinaUserProfile -Name $UserProfile | Where-Object {$_.TenantID -eq $usergroup_tenantid}
                $new_user_profileid = $UserProfileObject.ID

                if (!$new_user_profileid) { 
                    Write-Error "ERROR : No user profile found with this name ($UserProfile) in Tenant $usergroup_tenantname."
                    Return
                }
                Write-Host2 "Changing user profile for user group named $usergroup_name in Tenant $usergroup_tenantname"

                $request = CallAPI -Path "/ADM/replace_profile.json?from_prof_id=$usergroup_profileid&to_prof_id=$new_user_profileid&ug_id=$usergroup_id" -ContentType "application/json"
                if ($request.status -eq 0) {
                    Write-Host2 "Succesfully changed user profile to $UserProfile for user group named $usergroup_name in Tenant $usergroup_tenantname."
                }
                else {
                    TranslateErrorCode -LinaError $request -FailedAction "changing user profile to $UserProfile for user group named $usergroup_name in Tenant $usergroup_tenantname"
                    Return
                }
            }


            if ($NewName) {
                Write-Host2 "Renaming user group named $usergroup_name in Tenant $user_tenantname"
                $newname_enc=[System.Web.HttpUtility]::UrlEncode($NewName)
                $request = CallAPI -Path "/ADM/rename_user_group.json?id=$usergroup_id&name=$newname_enc" -ContentType "application/json"
                if ($request.status -eq 0) {
                    Write-Host2 "Successfully renamed user group to $NewName in Tenant $usergroup_tenantname"
                } else {
                    TranslateErrorCode -LinaError $request -FailedAction "renaming user group named $usergroup_name to $NewName in Tenant $usergroup_tenantname"
                    Return
                }
            }
            Return Get-LinaUserGroup -ID $usergroup_id
        }
    }
    END { }
}