Private/Backend/Set-SecretRotationADPassword.ps1

function Set-SecretRotationADPassword {
    <#
    .SYNOPSIS
        Sets a new password on an Active Directory account via Set-ADAccountPassword.
    .DESCRIPTION
        Thin wrapper around the RSAT ActiveDirectory module's Set-ADAccountPassword, with
        -Reset (administrative override - no old password needed) so the rotation cmdlet can
        set a brand-new random password without knowing the account's current one.

        The ActiveDirectory module is checked at call time (Get-Module -ListAvailable), not
        declared as a hard module dependency, so importing Posh-SecretRotation - or using its
        EntraID/Custom backends - never requires RSAT to be installed. Throws a clear,
        actionable error naming the missing module rather than letting command-not-found
        surface from deep inside Set-ADAccountPassword's auto-load attempt.

        Throws (does not return a status value) on any failure - the caller
        (Set-SecretRotationBackendPassword / Update-SecretRotationAccountPassword) relies on
        this to guarantee a password is never split unless it was actually applied.
    .PARAMETER Identifier
        The AD account identity (SamAccountName, DN, SID, or GUID - anything
        Set-ADAccountPassword's -Identity accepts).
    .PARAMETER Password
        The new password as a SecureString. Active Directory backends always use SecureString
        representation
        this function throws if handed anything else.
    .PARAMETER BackendConfig
        The target's merged backendConfig hashtable. Recognized keys: 'forest' (passed as
        Set-ADAccountPassword's -Server, so the change targets a specific domain/DC when given).
    .EXAMPLE
        Set-SecretRotationADPassword -Identifier 'svc-account1' -Password $securePassword -BackendConfig @{ forest = 'corp.local' }
    #>

    [CmdletBinding()]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'ShouldProcess confirmation happens once at the public cmdlet boundary (Update-SecretRotationAccountPassword); this private helper is only ever called after that confirmation already succeeded and must not prompt again.')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword', 'Password', Justification = 'Deliberately untyped: some backends (EntraID/Graph) require a plaintext string per passwordRepresentation, not just SecureString. This function itself still requires SecureString and throws otherwise (see body).')]
    param(
        [Parameter(Mandatory)]
        [string] $Identifier,

        [Parameter(Mandatory)]
        [AllowNull()]
        $Password,

        [Parameter(Mandatory)]
        [hashtable] $BackendConfig
    )

    if ($Password -isnot [System.Security.SecureString]) {
        throw "Set-SecretRotationADPassword requires a SecureString password (this target's 'passwordRepresentation' must be 'SecureString' for the ActiveDirectory backend)."
    }

    if (-not (Get-Module -Name ActiveDirectory -ListAvailable)) {
        throw "The ActiveDirectory module (RSAT: Active Directory module for Windows PowerShell) is not installed. Install it via 'Install-WindowsFeature RSAT-AD-PowerShell' (Windows Server) or 'Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0' (Windows client) before using the ActiveDirectory backend."
    }

    Import-Module -Name ActiveDirectory -ErrorAction Stop

    $setParams = @{
        Identity    = $Identifier
        NewPassword = $Password
        Reset       = $true
        ErrorAction = 'Stop'
    }
    if ($BackendConfig.forest) { $setParams.Server = $BackendConfig.forest }

    Set-ADAccountPassword @setParams
}