Public/Users/Set-UKGUser.ps1

function Set-UKGUser {
    <#
    .SYNOPSIS
        Updates an existing user in the UKG HR Service Delivery system.

    .DESCRIPTION
        Updates user properties using either PUT (full replacement) or PATCH (partial update).

    .PARAMETER Id
        The unique identifier of the user to update.

    .PARAMETER Email
        The user's email address.

    .PARAMETER FirstName
        The user's first name.

    .PARAMETER LastName
        The user's last name.

    .PARAMETER RoleId
        The ID of the role to assign to the user.

    .PARAMETER OrganizationIds
        Array of organization IDs the user has access to.

    .PARAMETER Active
        Whether the user account is active.

    .PARAMETER Properties
        Hashtable of properties to update.

    .PARAMETER InputObject
        A hashtable or PSCustomObject containing the properties to update.

    .PARAMETER Replace
        Use PUT method for full replacement instead of PATCH.

    .EXAMPLE
        Set-UKGUser -Id "user123" -RoleId "newrole456"

    .EXAMPLE
        Set-UKGUser -Id "user123" -Active $false

    .OUTPUTS
        UKG.User object representing the updated user.
    #>

    [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Properties')]
    [OutputType([PSCustomObject])]
    param(
        [Parameter(Mandatory, ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [Alias('UserId')]
        [string]$Id,

        [Parameter(ParameterSetName = 'Properties')]
        [string]$Email,

        [Parameter(ParameterSetName = 'Properties')]
        [string]$FirstName,

        [Parameter(ParameterSetName = 'Properties')]
        [string]$LastName,

        [Parameter(ParameterSetName = 'Properties')]
        [string]$RoleId,

        [Parameter(ParameterSetName = 'Properties')]
        [string[]]$OrganizationIds,

        [Parameter(ParameterSetName = 'Properties')]
        [bool]$Active,

        [Parameter(ParameterSetName = 'Properties')]
        [hashtable]$Properties,

        [Parameter(Mandatory, ParameterSetName = 'InputObject')]
        [object]$InputObject,

        [Parameter()]
        [switch]$Replace
    )

    process {
        $body = @{}

        if ($InputObject) {
            if ($InputObject -is [hashtable]) {
                $body = $InputObject.Clone()
            }
            else {
                foreach ($prop in $InputObject.PSObject.Properties) {
                    if ($prop.Name -notin @('id', 'created_at', 'updated_at', 'PSTypeName')) {
                        $body[$prop.Name] = $prop.Value
                    }
                }
            }
        }
        else {
            if ($Email) { $body['email'] = $Email }
            if ($FirstName) { $body['first_name'] = $FirstName }
            if ($LastName) { $body['last_name'] = $LastName }
            if ($RoleId) { $body['role_id'] = $RoleId }
            if ($OrganizationIds) { $body['organization_ids'] = $OrganizationIds }
            if ($PSBoundParameters.ContainsKey('Active')) { $body['active'] = $Active }

            if ($Properties) {
                foreach ($key in $Properties.Keys) {
                    $body[$key] = $Properties[$key]
                }
            }
        }

        if ($body.Count -eq 0) {
            Write-Warning "No properties specified to update."
            return
        }

        $method = if ($Replace) { 'PUT' } else { 'PATCH' }

        if ($PSCmdlet.ShouldProcess($Id, "Update User ($method)")) {
            $response = Invoke-UKGRequest -Endpoint "/users/$Id" -Method $method -Body $body

            if ($response) {
                $response.PSObject.TypeNames.Insert(0, 'UKG.User')
            }

            return $response
        }
    }
}