src/Public/Rename-ADUser.ps1

#Requires -RunAsAdministrator

<#
.SYNOPSIS
Renames a user account in Active Directory.
 
.DESCRIPTION
The Rename-User function renames an existing user account in Active Directory. It allows for updating the username and optionally the full name and email address associated with the user account.
It also automatically updates the Home Directory and Profile Folder of the user account to match the new username.
 
.PARAMETER CurrentUsername
The current username of the user account to be renamed. This parameter is mandatory.
 
.PARAMETER NewUsername
The new username for the user account. This parameter is mandatory.
 
.PARAMETER FullName
The full name of the user to update in Active Directory. This parameter is optional.
 
.PARAMETER UpdateEmail
A switch parameter that indicates whether to update the email address associated with the user account to match the new username. This parameter is optional.
 
.EXAMPLE
Rename-User -CurrentUsername 'jdoe' -NewUsername 'john.doe' -FullName 'John Doe' -UpdateEmail
 
This example renames the user account with the username 'jdoe' to 'john.doe', updates the full name to 'John Doe', and updates the email address associated with the user account.
 
.EXAMPLE
Rename-User -CurrentUsername 'jdoe' -NewUsername 'john.doe'
 
This example renames the user account with the username 'jdoe' to 'john.doe' without updating the full name or email address.
 
.NOTES
Requires ActiveDirectory module.
Requires running as Administrator.
 
.LINK
https://docs.microsoft.com/en-us/powershell/module/addsadministration/
 
#>



function Rename-ADUser {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$CurrentUsername,

        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$NewUsername,

        [String]$FullName,

        [Switch]$UpdateEmail
    )

    begin {

        # Check if AD Module is available
        if (-not(Get-Module -ListAvailable -Name ActiveDirectory)) {
            throw "The Active Directory module is not available. Please run this script on an Active Directory Domain Controller."
        }
        #Parameter validation

        #Trim whitespace from the beginning and end of the strings
        $CurrentUsername = $CurrentUsername.Trim()
        $NewUsername = $NewUsername.Trim()

        if ($CurrentUsername -eq $NewUsername) {
            Write-Error "The current and new usernames are the same. Please provide a different username."
            return
        }

        # Check if the current username is alphanumeric
        if (-not($CurrentUsername -match '^[a-zA-Z0-9\s]+$')) {
            Write-Error "The current username is not alphanumeric. Please ensure the username contains only letters and numbers."
            return
        }

        if (-not($NewUsername -match '^[a-zA-Z0-9\s]+$')) {
            Write-Error "The new username is not alphanumeric. Please ensure the username contains only letters and numbers."
            return
        }

        # Check for spaces in the new username and prompt user to confirm
        if ($NewUsername -match '[\s]') {
            Write-Warning "It is recommended to avoid using spaces in usernames. Are you sure you wish to continue?"
            $Continue = Read-Host "Continue? (Y/N)"
            if ($continue -ne "Y" -and $continue -ne "y") {
                Write-Host "Operation cancelled."
                return
            }
        }
    }

    process {

        # Check the device is an Active Directory Domain Controller
        if (-not(Get-Module -ListAvailable -Name ActiveDirectory)) {
            Write-Error "The Active Directory module is not available. Please run this script on an Active Directory Domain Controller."
            return
        }

        try {
            $User = Get-ADUser $CurrentUsername -properties *
        } catch {
            Write-Error "User $CurrentUsername not found in Active Directory."
            return
        }

        # Check if the new username already exists
        try {
            $NewUser = Get-ADUser $NewUsername
            if ($NewUser) {
                Write-Error "User $NewUsername already exists. Please provide a different username."
                return
            }
        } catch {}

        # If the user does not exist, proceed with the update
        Write-Host "Updating username from $CurrentUsername to $NewUsername"

        #Build a splat for updated user properties
        $UserProperties = @{
            SamAccountName    = $NewUsername
            UserPrincipalName = $user.UserPrincipalName -replace $CurrentUsername, $NewUsername
            HomeDirectory     = $user.HomeDirectory -replace $CurrentUsername, $NewUsername
            ProfilePath       = $user.ProfilePath -replace $CurrentUsername, $NewUsername
        }

        if ($FullName) {
            $FirstName = $FullName.Split()[0]
            $LastName = $FullName.Split()[1]
            $UserProperties.Add("DisplayName", ($FirstName.substring(0, 1) + " " + $LastName))
            $UserProperties.Add("GivenName", $FirstName)
            $UserProperties.Add("Surname", $LastName)
        }

        if ($UpdateEmail) {
            $UserProperties.Add("EmailAddress", ($user.EmailAddress -replace $CurrentUsername, $NewUsername))
        }

        #Check if Home and or Profile Path are empty and remove them if they are

        if ($Null -eq $UserProperties.HomeDirectory) {
            $UserProperties.Remove("HomeDirectory")
        }
        if ($Null -eq $UserProperties.ProfilePath) {
            $UserProperties.Remove("ProfilePath")
        }

        # Update the user properties
        try {
            Write-Verbose "Setting the following values:"
            $UserProperties
            Set-ADUser $user @UserProperties -ErrorAction Stop
            if ($FullName) {
                Rename-ADObject -Identity $User.DistinguishedName -NewName $FullName
            } else {
                Rename-ADObject -Identity $User.DistinguishedName -NewName $NewUsername
            }
        } catch {
            Write-Error "Failed to update user properties."
            return
        }

        # Update Home folder
        try {

            if ($User.HomeDirectory) {
                Rename-Item -Path $User.HomeDirectory -NewName $UserProperties.HomeDirectory
                Write-Host "Home Directory updated successfully."
            }
        } catch {
            Write-Error "Failed to update Home Directory. Please do this manually."
        }

    }

    end {

    }
}