Search code examples
powershellhashtableparameter-splatting

Powershell Data Malformed with Splatting


I am using a custom function that imports data using an API. The function requires several different parameters, which I am currently defining with one $Params hashtable. From there I am adding other parameters that may or may not be added based on certain conditions. I have noticed that storing all parameters in the hashtable is not working properly, but will only work if particularly specified in the function call.

A basic version of the code that does not currently work is:

$ExtraParam = 'ccc'
$Params = @{
   Par1 = 'aaa'
   Par2 = 'bbb'
}
$Params.Par3 = $ExtraParam
Import-APIData @Params

The API is returning the following error message: {"errorId":"error.request.invalidRepresentation.malformed","errorCode":0,"message":"Invalid parameter value was specified."}

However, if I run the following code it works perfectly fine:

$ExtraParam = 'abc'
$Params = @{
   Par1 = '123'
   Par2 = '456'
}
Import-APIData @Params -Par3 $ExtraParam

I have verified that the parameters coming into the function are all of the correct type. The custom function I am calling is proprietary so I cannot share the entire function, but I was just wondering if there was anything that would reformat the parameters in the hashtable as opposed to explicitly calling it in the function call. Given that the two chunks of code are essentially the same I am hoping someone can point out some fundamental difference that may cause the top portion to not work.

Per a request of a commenter, here is the actual function. The _CallAPI function at the bottom is what actually calls the API. I will not be able to share that, but using the $Params output right above it (commented out in the code) may hopefully be enough to troubleshoot.

function Update-ICUser {
<#
    .SYNOPSIS
        Updates user on a Gensys ICWS server.
    .PARAMETER ICSession
        string ICSession. ICSession to update a user.
    .PARAMETER Id
        string Id. Id of the user to update.
    .PARAMETER InputObject
        object InputObject. Full IC User is needed.
    .PARAMETER Argument
        string Argument. Any query string parameters associated with the Api call.
    .Example
        $ICSession = New-ICSession -ComputerName server1 -Credential $Credential
        Get-ICUser -Id user1 -Full |Update-ICUser -ICSession $ICsession -Extension 1234 
        Example 1: Update a user's extension.
#>
    [CmdletBinding()]
    param (
        [Parameter(Mandatory,
            Position = 0)]
        [ICSession]$ICSession,
        [Parameter(Mandatory,
            ValueFromPipeline,
            ParameterSetName = 'InputObject',
            Position = 1)]
        [object]$InputObject,
        [Parameter(Mandatory,
            ParameterSetName = 'Manual',
            Position = 2)]
        [string]$Id,
        [Parameter(ParameterSetName = 'Manual',
            Position = 3)]
        [Parameter(ParameterSetName = 'InputObject')]
        [string]$DisplayName,
        [Parameter(ParameterSetName = 'Manual',
            Position = 4)]
        [Parameter(ParameterSetName = 'InputObject')]
        [string]$OutboundAni,
        [Parameter(ParameterSetName = 'Manual',
            Position = 5)]
        [Parameter(ParameterSetName = 'InputObject')]
        [string]$Title,
        [Parameter(ParameterSetName = 'Manual',
            Position = 6)]
        [Parameter(ParameterSetName = 'InputObject')]
        [string]$OfficeLocation,
        [Parameter(ParameterSetName = 'Manual',
            Position = 7)]
        [Parameter(ParameterSetName = 'InputObject')]
        [string]$Notes,
        [Parameter(ParameterSetName = 'Manual',
            Position = 8)]
        [Parameter(ParameterSetName = 'InputObject')]
        [int]$Cost = 0,
        [Parameter(ParameterSetName = 'Manual',
            Position = 9)]
        [Parameter(ParameterSetName = 'InputObject')]
        [bool]$AutoAnswerAcdInteractions = $false,
        [Parameter(ParameterSetName = 'Manual',
            Position = 10)]
        [Parameter(ParameterSetName = 'InputObject')]
        [bool]$AutoAnswerNonAcdInteractions = $true,
        [Parameter(ParameterSetName = 'Manual',
            Position = 11)]
        [Parameter(ParameterSetName = 'InputObject')]
        [string]$ApplicationId = 'InteractionDesktop',
        [Parameter(ParameterSetName = 'Manual',
            Position = 12)]
        [Parameter(ParameterSetName = 'InputObject')]
        [bool]$ExcludeFromDirectory = $false,
        [Parameter(ParameterSetName = 'Manual',
            Position = 13)]
        [Parameter(ParameterSetName = 'InputObject')]
        [string]$Extension,
        [Parameter(ParameterSetName = 'Manual',
            Position = 14)]
        [Parameter(ParameterSetName = 'InputObject')]
        [bool]$FaxCapability = $false,
        [Parameter(ParameterSetName = 'Manual',
            Position = 15)]
        [Parameter(ParameterSetName = 'InputObject')]
        [bool]$OutlookIntegrationEnabled = $false,
        [Parameter(ParameterSetName = 'Manual',
            Position = 16)]
        [Parameter(ParameterSetName = 'InputObject')]
        [string]$FirstName,
        [Parameter(ParameterSetName = 'Manual',
            Position = 17)]
        [Parameter(ParameterSetName = 'InputObject')]
        [string]$LastName,
        [Parameter(ParameterSetName = 'Manual',
            Position = 18)]
        [Parameter(ParameterSetName = 'InputObject')]
        [string[]]$WorkgroupList,
        [Parameter(ParameterSetName = 'Manual',
            Position = 19)]
        [Parameter(ParameterSetName = 'InputObject')]
        [string]$DepartmentName,
        [Parameter(ParameterSetName = 'Manual',
            Position = 20)]
        [Parameter(ParameterSetName = 'InputObject')]
        [string]$City,
        [Parameter(ParameterSetName = 'Manual',
            Position = 21)]
        [Parameter(ParameterSetName = 'InputObject')]
        [string]$PostalCode,
        [Parameter(ParameterSetName = 'Manual',
            Position = 22)]
        [Parameter(ParameterSetName = 'InputObject')]
        [string]$State,
        [Parameter(ParameterSetName = 'Manual',
            Position = 23)]
        [Parameter(ParameterSetName = 'InputObject')]
        [string]$StreetAddress,
        [Parameter(ParameterSetName = 'Manual',
            Position = 24)]
        [Parameter(ParameterSetName = 'InputObject')]
        [int]$HomeSite,
        [Parameter(ParameterSetName = 'Manual',
            Position = 25)]
        [Parameter(ParameterSetName = 'InputObject')]
        [string[]]$LicenseList,
        [Parameter(ParameterSetName = 'Manual',
            Position = 26)]
        [Parameter(ParameterSetName = 'InputObject')]
        [string[]]$RoleList
    )
    Try {
        if ($InputObject) {
            $User = $InputObject
            $Id = $InputObject.configurationId.id
        }
        else {
            $User = Get-ICUser -ICSession $ICSession -Id $Id -Full
        }
        'Id','InputObject','ICSession' |Foreach-Object {
            $PSBoundParameters.Remove($PSItem) |Out-Null
        }
        $PSBoundParameters.GetEnumerator() |Foreach-Object {
            if ($PSItem.Key -in ('Title','DepartmentName','City','State','StreetAddress','FirstName','LastName','Notes')) {
                if ($PSItem.Key -in ('State','FirstName','LastName')) {
                    $Key = switch ($PSItem.Key) {
                        'State' {'stateOrProvince'}
                        'FirstName' {'givenName'}
                        'LastName' {'surName'}
                    }
                }
                else {
                    $Key = $PSItem.Key
                }
                $User.personalInformationProperties.$Key = $PSItem.Value
            }
            elseif ($PSItem.Key -in ('WorkgroupList','LicenseList','RoleList')) {
                $Key = $PSItem.Key
                if ($Key = 'WorkgroupList' -and $WorkgroupList) {
                    [array]$Value = Get-ICWorkgroup -ICSession $SessionKey -Id $WorkgroupList
                    $User.Workgroups = $Value
                }
                if ($Key = 'LicenseList' -and $LicenseList) {
                    $Value = @((Get-ICLicenseAllocation -ICSession $SessionKey -Id $LicenseList).configurationId)
                    if ($User.licenseProperties.PSobject.Properties.name -match 'additionalLicenses') {
                        $User.licenseProperties.additionalLicenses = $Value
                    }
                    else {
                        $User.licenseProperties | Add-Member -MemberType NoteProperty -Name 'additionalLicenses' -Value $Value -Force
                    }
                }
                if ($Key = 'RoleList' -and $RoleList) {
                    [array]$Value = Get-ICRole -ICSession $SessionKey -Id $RoleList
                    if ($User.roles.PSobject.Properties.name -match 'actualValue') {
                        $User.Roles.actualValue = $Value
                    }
                    else {
                        $User.roles | Add-Member -MemberType NoteProperty -Name 'actualValue' -Value $Value -Force
                    }
                    
                }
            }
            else {
                $Key = $PSItem.Key
                $Value = $PSItem.Value
                $User |Add-Member -MemberType NoteProperty -Name $Key -Value $Value -Force
            }
        }
        $Body = $User |ConvertTo-Json -Depth 5
        $Params = @{
            Area = $Configuration.Area.Configuration
            Resource = $Configuration.Resource.Users
            ICSession = $ICSession
            Id = $Id
            Method = 'Put'
            ContentType = 'application/json'
            Body = $Body
        }
        # $Params
        _CallApi @Params
    }
    Catch {
        _ExceptionError
    }
}

I will also provide everything on the console. In this example the $AutoAnswerAcd parameter is the one that is failing, but I have gotten it to fail and work by adding/removing other parameters. I have not detected a pattern that makes it fail yet, other than that it always works outside of the splat. You can see this pattern below.

PS C:\> $SessionKey = New-ICSession -ComputerName $server -Credential $Credential
PS C:\> $Params = @{
>>     ICSession = $SessionKey
>>     Id = 'tautomation'
>>     WorkgroupList = "MultiSite-UserSpan"
>>     RoleList = "Business User"
>>     LicenseList = "I3_ACCESS_RECORDER"
>>     DepartmentName = "Infr & Ops"
>>     Title = "Process Automation Engineer"
>>     OfficeLocation = "Remote"
>>     AutoAnswerAcdInteractions = $true
>> }
PS C:\> Update-ICUser @Params
Exception: C:\Repos\ICTools\Code\Private\_ExceptionError.ps1:10
Line |
  10 |          throw "$($Exception)`n$($Exception.Exception.Message)"
     |          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | {"errorId":"error.request.invalidRepresentation.malformed","errorCode":0,"message":"Invalid parameter value was specified."} Response status code does not indicate
     | success: 400 (Bad Request). {"errorId":"error.request.invalidRepresentation.malformed","errorCode":0,"message":"Invalid parameter value was specified."} Response status
     | code does not indicate success: 400 (Bad Request).

PS C:\> $Params = @{
>>     ICSession = $SessionKey
>>     Id = 'tautomation'
>>     WorkgroupList = "MultiSite-UserSpan"
>>     RoleList = "Business User"
>>     LicenseList = "I3_ACCESS_RECORDER"
>>     DepartmentName = "Infr & Ops"
>>     Title = "Process Automation Engineer"
>>     OfficeLocation = "Remote"
>> }
PS C:\> Update-ICUser @Params

id          uri
--          ---
tautomation /configuration/users/tautomation

PS C:\> Update-ICUser @Params -AutoAnswerAcdInteractions $true

id          uri
--          ---
tautomation /configuration/users/tautomation

PS C:\>

Thanks!


Solution

  • Ok, so think I've found what's happening.

    Firstly, here's an instrumented version of your code that gives some log output as it runs - that'll help see where it's going wrong...

    function Update-ICUser {
        [CmdletBinding()]
        param (
            [Parameter(Mandatory,
                Position = 0)]
            [string]$ICSession,
            [Parameter(Mandatory,
                ValueFromPipeline,
                ParameterSetName = 'InputObject',
                Position = 1)]
            [object]$InputObject,
            [Parameter(Mandatory,
                ParameterSetName = 'Manual',
                Position = 2)]
            [string]$Id,
            [Parameter(ParameterSetName = 'Manual',
                Position = 3)]
            [Parameter(ParameterSetName = 'InputObject')]
            [string]$DisplayName,
            [Parameter(ParameterSetName = 'Manual',
                Position = 4)]
            [Parameter(ParameterSetName = 'InputObject')]
            [string]$OutboundAni,
            [Parameter(ParameterSetName = 'Manual',
                Position = 5)]
            [Parameter(ParameterSetName = 'InputObject')]
            [string]$Title,
            [Parameter(ParameterSetName = 'Manual',
                Position = 6)]
            [Parameter(ParameterSetName = 'InputObject')]
            [string]$OfficeLocation,
            [Parameter(ParameterSetName = 'Manual',
                Position = 7)]
            [Parameter(ParameterSetName = 'InputObject')]
            [string]$Notes,
            [Parameter(ParameterSetName = 'Manual',
                Position = 8)]
            [Parameter(ParameterSetName = 'InputObject')]
            [int]$Cost = 0,
            [Parameter(ParameterSetName = 'Manual',
                Position = 9)]
            [Parameter(ParameterSetName = 'InputObject')]
            [bool]$AutoAnswerAcdInteractions = $false,
            [Parameter(ParameterSetName = 'Manual',
                Position = 10)]
            [Parameter(ParameterSetName = 'InputObject')]
            [bool]$AutoAnswerNonAcdInteractions = $true,
            [Parameter(ParameterSetName = 'Manual',
                Position = 11)]
            [Parameter(ParameterSetName = 'InputObject')]
            [string]$ApplicationId = 'InteractionDesktop',
            [Parameter(ParameterSetName = 'Manual',
                Position = 12)]
            [Parameter(ParameterSetName = 'InputObject')]
            [bool]$ExcludeFromDirectory = $false,
            [Parameter(ParameterSetName = 'Manual',
                Position = 13)]
            [Parameter(ParameterSetName = 'InputObject')]
            [string]$Extension,
            [Parameter(ParameterSetName = 'Manual',
                Position = 14)]
            [Parameter(ParameterSetName = 'InputObject')]
            [bool]$FaxCapability = $false,
            [Parameter(ParameterSetName = 'Manual',
                Position = 15)]
            [Parameter(ParameterSetName = 'InputObject')]
            [bool]$OutlookIntegrationEnabled = $false,
            [Parameter(ParameterSetName = 'Manual',
                Position = 16)]
            [Parameter(ParameterSetName = 'InputObject')]
            [string]$FirstName,
            [Parameter(ParameterSetName = 'Manual',
                Position = 17)]
            [Parameter(ParameterSetName = 'InputObject')]
            [string]$LastName,
            [Parameter(ParameterSetName = 'Manual',
                Position = 18)]
            [Parameter(ParameterSetName = 'InputObject')]
            [string[]]$WorkgroupList,
            [Parameter(ParameterSetName = 'Manual',
                Position = 19)]
            [Parameter(ParameterSetName = 'InputObject')]
            [string]$DepartmentName,
            [Parameter(ParameterSetName = 'Manual',
                Position = 20)]
            [Parameter(ParameterSetName = 'InputObject')]
            [string]$City,
            [Parameter(ParameterSetName = 'Manual',
                Position = 21)]
            [Parameter(ParameterSetName = 'InputObject')]
            [string]$PostalCode,
            [Parameter(ParameterSetName = 'Manual',
                Position = 22)]
            [Parameter(ParameterSetName = 'InputObject')]
            [string]$State,
            [Parameter(ParameterSetName = 'Manual',
                Position = 23)]
            [Parameter(ParameterSetName = 'InputObject')]
            [string]$StreetAddress,
            [Parameter(ParameterSetName = 'Manual',
                Position = 24)]
            [Parameter(ParameterSetName = 'InputObject')]
            [int]$HomeSite,
            [Parameter(ParameterSetName = 'Manual',
                Position = 25)]
            [Parameter(ParameterSetName = 'InputObject')]
            [string[]]$LicenseList,
            [Parameter(ParameterSetName = 'Manual',
                Position = 26)]
            [Parameter(ParameterSetName = 'InputObject')]
            [string[]]$RoleList
        )
    
        if ($InputObject) {
            $User = $InputObject
            $Id = $InputObject.configurationId.id
        }
        else {
            $User = [pscustomobject] @{
                personalInformationProperties = [pscustomobject] @{
                    DepartmentName = $null
                    Title          = $null
                }
                licenseProperties = [pscustomobject] @{}
                roles             = [pscustomobject] @{}
                Workgroups        = $null
            }
            #Get-ICUser -ICSession $ICSession -Id $Id -Full
        }
    
        #write-host "user = '$($User |ConvertTo-Json -Depth 5)'"
    
        'Id','InputObject','ICSession' |Foreach-Object {
            $PSBoundParameters.Remove($PSItem) |Out-Null
        }
    
        $PSBoundParameters.GetEnumerator() |Foreach-Object {
            write-host "processing key '$($PSItem.Key)'"
    
            if ($PSItem.Key -in ('Title','DepartmentName','City','State','StreetAddress','FirstName','LastName','Notes')) {
                if ($PSItem.Key -in ('State','FirstName','LastName')) {
                    $Key = switch ($PSItem.Key) {
                        'State' {'stateOrProvince'}
                        'FirstName' {'givenName'}
                        'LastName' {'surName'}
                    }
                }
                else {
                    $Key = $PSItem.Key
                }
                $User.personalInformationProperties.$Key = $PSItem.Value
            }
            elseif ($PSItem.Key -in ('WorkgroupList','LicenseList','RoleList')) {
                $Key = $PSItem.Key
                if ($Key = 'WorkgroupList' -and $WorkgroupList) {
                    write-host "    WorkgroupList - casting to array"
                    #$Value = @( Get-ICWorkgroup -ICSession $SessionKey -Id $WorkgroupList )
                    [array] $Value = @()
                    #$User.Workgroups = $Value
                }
                if ($Key = 'LicenseList' -and $LicenseList) {
                    write-host "    LicenseList - casting to array"
                    #$Value = @((Get-ICLicenseAllocation -ICSession $SessionKey -Id $LicenseList).configurationId)
                    $Value = @()
                    if ($User.licenseProperties.PSobject.Properties.name -match 'additionalLicenses') {
                        $User.licenseProperties.additionalLicenses = $Value
                    }
                    else {
                        $User.licenseProperties | Add-Member -MemberType NoteProperty -Name 'additionalLicenses' -Value $Value -Force
                    }
                }
                if ($Key = 'RoleList' -and $RoleList) {
                    write-host "    RoleList - casting to array"
                    #[array]$Value = Get-ICRole -ICSession $SessionKey -Id $RoleList
                    [array]$Value = @()
                    if ($User.roles.PSobject.Properties.name -match 'actualValue') {
                        $User.Roles.actualValue = $Value
                    }
                    else {
                        $User.roles | Add-Member -MemberType NoteProperty -Name 'actualValue' -Value $Value -Force
                    }
                    
                }
            }
            else {
                write-host "adding key '$($PSItem.Key)' with value '$($PSItem.Value)'"
                write-host "    value before is '$($Value.GetType().FullName)'"
                $Key = $PSItem.Key
                write-host "    value after is '$($Value.GetType().FullName)'"
                $Value = $PSItem.Value
                #write-host ($PSItem.Key | convertto-json)
                #write-host ($PSItem.Value | convertto-json)
                #write-host $PSItem.Key.GetType().FullNane
                #write-host $PSItem.Value.GetType().FullNane
                #write-host "user before = '$($User |ConvertTo-Json -Depth 5)'"
                $User |Add-Member -MemberType NoteProperty -Name $Key -Value $Value -Force
                #write-host "user after = '$($User |ConvertTo-Json -Depth 5)'"
            }
    
    
        }
        $Body = $User |ConvertTo-Json -Depth 5
    
        write-host $Body
    
    }
    

    and when you call it with, e.g. this:

    $Params = @{
        ICSession = "aaa"
        Id = 'tautomation'
        WorkgroupList = "MultiSite-UserSpan"
        RoleList = "Business User"
        LicenseList = "I3_ACCESS_RECORDER"
        DepartmentName = "Infr & Ops"
        Title = "Process Automation Engineer"
        OfficeLocation = "Remote"
        AutoAnswerAcdInteractions = $true
    }
    
    Update-ICUser @Params
    

    you get this output:

    processing key 'DepartmentName'
    processing key 'OfficeLocation'
    adding key 'OfficeLocation' with value 'Remote'
    processing key 'Title'
    processing key 'WorkgroupList'
        WorkgroupList - casting to array
        LicenseList - casting to array
        RoleList - casting to array
    processing key 'AutoAnswerAcdInteractions'
    adding key 'AutoAnswerAcdInteractions' with value 'True'
        value before is 'System.Object[]'
        value after is 'System.Object[]'
    processing key 'RoleList'
        WorkgroupList - casting to array
        LicenseList - casting to array
        RoleList - casting to array
    processing key 'LicenseList'
        WorkgroupList - casting to array
        LicenseList - casting to array
        RoleList - casting to array
    {
      "personalInformationProperties": {
        "DepartmentName": "Infr & Ops",
        "Title": "Process Automation Engineer"
      },
      "licenseProperties": {
        "additionalLicenses": []
      },
      "roles": {
        "actualValue": []
      },
      "Workgroups": null,
      "OfficeLocation": "Remote",
      "AutoAnswerAcdInteractions": [
        true
      ]
    }
    

    So there's a few things to note:

    • casting to array

      casting to array seems to be getting logged for three parameters (WorkgroupList, RoleList and LicenseList) when processing each of them.

      If you look, your code is doing this: if ($Key = 'WorkgroupList' -and $WorkgroupList) but = is an assignment operator, not a comparison operator, so what you really want is if ($Key -eq 'WorkgroupList' -and $WorkgroupList)

      It's the same for if ($Key = 'LicenseList' -and $LicenseList) and if ($Key = 'RoleList' -and $RoleList) - change those to -eq as well and that's one bug stomped...

    • adding key 'AutoAnswerAcdInteractions' with value 'True'

      The $Value variable is of type System.Object[] before and after assigning the parameter value. If you look at the previous parameter in the logs you'll see WorkgroupList - casting to array - this is changing the type of $Value to be an array. Any future attempts to assign values will automatically convert the value to an array, so $true becomes [ $true ], which is where your problem is coming from.

      Note the same cast is happening in RoleList, but not LicenseList.

      Since the order of keys is not guaranteed in a hashtable or $PSBoundParameters, your issue only happens if:

      • $WorkgroupList or $RoleList are specified in the function call
      • They happen to be enumerated before $AutoAnswerAcdInteractions

      To fix this, refactor WorkgroupList and RoleList to be the same as LicenseList - i.e. instead of:

      [array]$Value = <expression>
      

      use the Array subexpression operator:

      $Value = @( <expression> )
      

      This will ensure the value stored in the variable is an array without changing the type of the variable for future parameters.


    Note that the reason the extra parameter appears to work is it changes the order of the items in $PSBoundParameters. For example:

    $Params = @{
        ICSession = "aaa"
        Id = 'tautomation'
        WorkgroupList = "MultiSite-UserSpan"
        RoleList = "Business User"
        LicenseList = "I3_ACCESS_RECORDER"
        DepartmentName = "Infr & Ops"
        Title = "Process Automation Engineer"
        OfficeLocation = "Remote"
    }
    
    Update-ICUser @Params -AutoAnswerAcdInteractions $true
    

    gives this output

    processing key 'AutoAnswerAcdInteractions'
    adding key 'AutoAnswerAcdInteractions' with value 'True'
    processing key 'DepartmentName'
    processing key 'Title'
    processing key 'WorkgroupList'
        WorkgroupList - casting to array
    processing key 'RoleList'
        RoleList - casting to array
    processing key 'LicenseList'
        LicenseList - casting to array
    processing key 'OfficeLocation'
    adding key 'OfficeLocation' with value 'Remote'
        value before is 'System.Object[]'
        value after is 'System.Object[]'
    {
      "personalInformationProperties": {
        "DepartmentName": "Infr & Ops",
        "Title": "Process Automation Engineer"
      },
      "licenseProperties": {
        "additionalLicenses": []
      },
      "roles": {
        "actualValue": []
      },
      "Workgroups": null,
      "AutoAnswerAcdInteractions": true,
      "OfficeLocation": [
        "Remote"
      ]
    }
    

    Note that AutoAnswerAcdInteractions is processed before any of the paths that change the type of $Value to an array.

    Incidentally, the code also works if you omit WorkgroupList and RoleList because $Value never gets changed to an array:

    $Params = @{
        ICSession = "aaa"
        Id = 'tautomation'
        #WorkgroupList = "MultiSite-UserSpan"
        #RoleList = "Business User"
        LicenseList = "I3_ACCESS_RECORDER"
        DepartmentName = "Infr & Ops"
        Title = "Process Automation Engineer"
        OfficeLocation = "Remote"
        AutoAnswerAcdInteractions = $true
    }
    
    Update-ICUser @Params
    

    with the output:

    processing key 'OfficeLocation'
    adding key 'OfficeLocation' with value 'Remote'
    processing key 'Title'
    processing key 'AutoAnswerAcdInteractions'
    adding key 'AutoAnswerAcdInteractions' with value 'True'
        value before is 'System.String'
        value after is 'System.String'
    processing key 'DepartmentName'
    processing key 'LicenseList'
        LicenseList - casting to array
    {
      "personalInformationProperties": {
        "DepartmentName": "Infr & Ops",
        "Title": "Process Automation Engineer"
      },
      "licenseProperties": {
        "additionalLicenses": []
      },
      "roles": {},
      "Workgroups": null,
      "OfficeLocation": "Remote",
      "AutoAnswerAcdInteractions": true
    }