Public/Update-LinuxServer.ps1

function Update-LinuxServer {
    <#
    .SYNOPSIS
        Updates properties of an existing Linux server entry in Active Directory.
 
    .DESCRIPTION
        Modifies one or more attributes on an existing AD computer object that was
        previously registered with Register-LinuxServer. Supports updating the IP
        address, operating system, description, and managed-by fields.
 
    .PARAMETER Name
        The hostname of the Linux server to update. Accepts pipeline input.
 
    .PARAMETER IPAddress
        New IPv4 address for the server.
 
    .PARAMETER OperatingSystem
        Updated operating system name.
 
    .PARAMETER OperatingSystemVersion
        Updated OS version string.
 
    .PARAMETER Description
        Updated description.
 
    .PARAMETER ManagedBy
        Distinguished name or SAMAccountName of the new manager.
 
    .PARAMETER OrganizationalUnit
        OU where the server resides. Used to scope the lookup. Defaults to
        "OU=Linux Servers" under the domain root.
 
    .EXAMPLE
        Update-LinuxServer -Name "web-prod-01" -IPAddress "10.1.2.51" -Description "Migrated to new VLAN"
 
        Updates the IP and description for an existing server.
 
    .EXAMPLE
        Update-LinuxServer -Name "db-prod-01" -OperatingSystem "RHEL 9.3" -OperatingSystemVersion "9.3"
 
        Updates the OS details after a distro upgrade.
 
    .EXAMPLE
        "web-prod-01","web-prod-02" | Update-LinuxServer -Description "Patched 2026-02-15"
 
        Pipeline update of description on multiple servers.
 
    .NOTES
        Requires: ActiveDirectory module (RSAT).
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
    param(
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [string]$Name,

        [ValidatePattern('^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$')]
        [string]$IPAddress,

        [string]$OperatingSystem,

        [string]$OperatingSystemVersion,

        [string]$Description,

        [string]$ManagedBy,

        [string]$OrganizationalUnit
    )

    begin {
        Import-Module ActiveDirectory -ErrorAction Stop

        if (-not $OrganizationalUnit) {
            $domainDN = (Get-ADDomain).DistinguishedName
            $OrganizationalUnit = "OU=Linux Servers,$domainDN"
        }
    }

    process {
        $computerName = $Name.ToUpper()

        # Verify the computer exists
        try {
            $existing = Get-ADComputer -Identity $computerName -Properties `
                OperatingSystem, OperatingSystemVersion, Description, ManagedBy, IPv4Address `
                -ErrorAction Stop
        }
        catch {
            Write-Error "Computer object '$computerName' not found in AD: $_"
            return
        }

        # Build the replacement attribute hash
        $replaceHash = @{}

        if ($PSBoundParameters.ContainsKey('IPAddress'))              { $replaceHash['IPv4Address']            = $IPAddress }
        if ($PSBoundParameters.ContainsKey('OperatingSystem'))        { $replaceHash['OperatingSystem']        = $OperatingSystem }
        if ($PSBoundParameters.ContainsKey('OperatingSystemVersion')) { $replaceHash['OperatingSystemVersion'] = $OperatingSystemVersion }
        if ($PSBoundParameters.ContainsKey('Description'))            { $replaceHash['Description']            = $Description }

        if ($replaceHash.Count -eq 0 -and -not $PSBoundParameters.ContainsKey('ManagedBy')) {
            Write-Warning "No properties specified to update for '$computerName'."
            return
        }

        $changeList = ($replaceHash.Keys + $(if ($PSBoundParameters.ContainsKey('ManagedBy')) { 'ManagedBy' })) -join ', '

        if ($PSCmdlet.ShouldProcess($computerName, "Update properties: $changeList")) {
            try {
                $setParams = @{
                    Identity    = $computerName
                    ErrorAction = 'Stop'
                }

                if ($replaceHash.Count -gt 0) {
                    $setParams['Replace'] = $replaceHash
                }

                if ($PSBoundParameters.ContainsKey('ManagedBy')) {
                    $setParams['ManagedBy'] = $ManagedBy
                }

                Set-ADComputer @setParams
                Write-Verbose "Updated $computerName -- $changeList"

                [PSCustomObject]@{
                    Name    = $computerName
                    Updated = $changeList
                    Status  = 'Updated'
                }
            }
            catch {
                Write-Error "Failed to update '$computerName': $_"
            }
        }
    }
}