Function Set-User {
    <#
    .SYNOPSIS
        Sets a property on a user account in DRA.

    .DESCRIPTION
        Sets a single property value on one or more user accounts in the DRA
        environment. Use this for attributes such as HomeDrive, HomeDirectory,
        Description, etc.

    .PARAMETER UserName
        The name(s) of the user(s) to modify.

    .PARAMETER Property
        The name of the attribute to set (e.g. "HomeDrive", "Description").

    .PARAMETER Value
        The value to assign to the property.

    .PARAMETER DraServer
        The FQDN of the DRA server. Defaults to "mcguire.dra.us.af.mil".

    .EXAMPLE
        Set-User -UserName 'Doe.John' -Property 'Description' -Value 'New description'
        Sets the Description attribute on the user.

    .EXAMPLE
        Set-User -UserName 'Doe.John', 'Smith.Jane' -Property 'HomeDrive' -Value 'U:' -Verbose
        Sets the HomeDrive attribute on multiple users and shows verbose output.
    #>
    [CmdletBinding(SupportsShouldProcess=$true)]
    param(
        [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
        [string[]]$UserName,

        [Parameter(Mandatory=$true, Position=1)]
        [string[]]$Property,

        [Parameter(Mandatory=$true, Position=2)]
        [string[]]$Value,

        [Parameter(Position=3)]
        [string]$DraServer = "mcguire.dra.us.af.mil"
    )

    Begin {
        $UserName = @(Split-ToolArgumentList -Value $UserName)
        $Property = @(Split-ToolArgumentList -Value $Property)
        $Value = @(ConvertTo-ToolArray -Value $Value)

        if ($Property.Count -ne $Value.Count) {
            throw "Set-User requires the same number of Property and Value entries."
        }

        $i = 1
        $total = [Math]::Max(1, ($UserName.Count * $Property.Count))
    }

    Process {
        foreach ($user in $UserName) {
            foreach ($propertyName in $Property) {
                $propertyIndex = [Array]::IndexOf($Property, $propertyName)
                $propertyValue = [string]$Value[$propertyIndex]
                $percentComplete = ($i / $total) * 100
                Show-ProgressBar -Activity "Setting $propertyName on $user to '$propertyValue'" -PercentComplete $percentComplete

                try {
                    # Resolve the user's canonical name via AD
                    $adUser = Get-ToolADUser -Identity $user -ErrorAction Stop
                    $displayName = $adUser.Name
                    Write-Verbose "Resolved '$user' to '$displayName'"

                    if ($pscmdlet.ShouldProcess($displayName, "Set $propertyName = '$propertyValue'")) {
                        if ($script:SimulationMode) {
                            Set-ToolADUserProperty -Identity $user -Property $propertyName -Value $propertyValue -ErrorAction Stop | Out-Null
                            Write-Verbose "Simulation: set $propertyName = '$propertyValue' on user: $displayName"
                        } else {
                            Set-DRAUser -ErrorAction Stop `
                                -Domain "AREA52.afnoapps.usaf.mil" `
                                -DRARestServer $DraServer `
                                -DRARestPort 8755 `
                                -DRAHostServer $DraServer `
                                -DRAHostPort 11192 `
                                -Identifier $displayName `
                                -Properties @{$propertyName=$propertyValue}

                            Write-Verbose "Successfully set $propertyName = '$propertyValue' on user: $displayName"
                        }
                    }
                }
                catch {
                    Write-Warning "Could not set '$propertyName' on user '$user'. Error: $($_.Exception.Message)"
                }
                $i++
            }
        }
    }

    End {
        Show-ProgressBar -Activity "Operation Complete" -PercentComplete 100
    }
}
