Private/Backend/Set-SecretRotationEntraPassword.ps1

function Set-SecretRotationEntraPassword {
    <#
    .SYNOPSIS
        Sets a new password on an Entra ID user via Microsoft Graph's Update-MgUser.
    .DESCRIPTION
        Thin wrapper around the Microsoft Graph PowerShell SDK's Update-MgUser, setting the
        user's passwordProfile. Per Microsoft's own documented example
        (learn.microsoft.com/microsoft-365/enterprise/manage-passwords-with-microsoft-365-powershell),
        PasswordProfile.Password is a plaintext string field in the Graph request body - there is
        no SecureString-accepting overload, which is exactly why this target's
        'passwordRepresentation' must be 'String'.

        The Microsoft.Graph.Users module is checked at call time (Get-Module -ListAvailable), not
        declared as a hard module dependency, so importing Posh-SecretRotation - or using its
        ActiveDirectory/Custom backends - never requires the Graph SDK to be installed. This
        function does not itself call Connect-MgGraph: an already-connected session with
        sufficient permissions (User-PasswordProfile.ReadWrite.All or User.ReadWrite.All) is
        assumed, same as the ActiveDirectory backend assumes an already-usable AD context rather
        than managing authentication itself.

        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 Entra ID user identifier - anything Update-MgUser's -UserId accepts (object ID or
        userPrincipalName).
    .PARAMETER Password
        The new password as a plaintext String. Entra ID backends always use String
        representation
        this function throws if handed anything else.
    .PARAMETER BackendConfig
        The target's merged backendConfig hashtable. Recognized keys:
        'forceChangePasswordNextSignIn' (bool, default $false - a rotation should not additionally
        force the account through an interactive password-change prompt).
    .EXAMPLE
        Set-SecretRotationEntraPassword -Identifier 'svc-account1@corp.onmicrosoft.com' -Password $plainPassword -BackendConfig @{}
    #>

    [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 a plaintext String: Microsoft Graph''s PasswordProfile.Password has no SecureString overload. This function itself still requires a String and throws otherwise (see body).')]
    param(
        [Parameter(Mandatory)]
        [string] $Identifier,

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

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

    if ($Password -isnot [string]) {
        throw "Set-SecretRotationEntraPassword requires a plaintext String password (this target's 'passwordRepresentation' must be 'String' for the EntraID backend)."
    }

    if (-not (Get-Module -Name Microsoft.Graph.Users -ListAvailable)) {
        throw "The Microsoft Graph PowerShell SDK's Microsoft.Graph.Users module is not installed. Install it via 'Install-Module Microsoft.Graph.Users -Scope CurrentUser' and connect with 'Connect-MgGraph -Scopes User-PasswordProfile.ReadWrite.All' (or User.ReadWrite.All) before using the EntraID backend."
    }

    Import-Module -Name Microsoft.Graph.Users -ErrorAction Stop

    $forceChangePasswordNextSignIn = $false
    if ($null -ne $BackendConfig.forceChangePasswordNextSignIn) {
        $forceChangePasswordNextSignIn = [bool]$BackendConfig.forceChangePasswordNextSignIn
    }

    $passwordProfile = @{
        Password                      = $Password
        ForceChangePasswordNextSignIn = $forceChangePasswordNextSignIn
    }

    Update-MgUser -UserId $Identifier -PasswordProfile $passwordProfile -ErrorAction Stop
}