automacao-identidade-ad/scripts/muda-senha-usuario.ps1

124 lines
6.5 KiB
PowerShell

<#
.SYNOPSIS
Altera a senha de um usuário de forma sincronizada em dois ambientes Active Directory (Cliente e Exchange).
.DESCRIPTION
Versão 1.0. Este script é um componente crítico da "Plataforma Unificada de Trabalho Digital".
Ele primeiro valida a senha antiga do usuário e, se bem-sucedido, aplica a nova senha em ambos os Domain Controllers.
O script foi projetado para tratar falhas parciais (ex: sucesso no primeiro AD, falha no segundo)
gerando logs específicos para alertar sobre a dessincronização.
.NOTES
Autor: Gemini (Especialista NGINX & Automação)
Data: 15 de outubro de 2025
Versão: 1.0
Contexto: Módulo "Alteração de Senha (Self-Service)" do Portal de Autoatendimento.
#>
function Set-UnifiedADUserPassword {
[CmdletBinding()]
param(
# --- Parâmetros de Conexão e Autenticação (Obrigatórios) ---
[Parameter(Mandatory = $true, HelpMessage = "IP ou FQDN do Domain Controller principal (cliente).")]
[string]$ClientADServer,
[Parameter(Mandatory = $true, HelpMessage = "Credencial (usuário e senha) da conta de serviço para autenticar no AD do cliente.")]
[pscredential]$ClientADCredential,
[Parameter(Mandatory = $true, HelpMessage = "IP ou FQDN do Domain Controller do ambiente Exchange.")]
[string]$ExchangeADServer,
[Parameter(Mandatory = $true, HelpMessage = "Credencial (usuário e senha) da conta de serviço para autenticar no AD do Exchange.")]
[pscredential]$ExchangeADCredential,
# --- Parâmetros do Usuário (Obrigatórios) ---
[Parameter(Mandatory = $true, HelpMessage = "O nome de logon do usuário (SamAccountName) cuja senha será alterada.")]
[string]$SamAccountName,
[Parameter(Mandatory = $true, HelpMessage = "A senha ANTIGA do usuário. Deve ser um objeto SecureString.")]
[System.Security.SecureString]$OldPassword,
[Parameter(Mandatory = $true, HelpMessage = "A NOVA senha do usuário. Deve ser um objeto SecureString.")]
[System.Security.SecureString]$NewPassword,
# --- Parâmetros de Logging ---
[Parameter(Mandatory = $false)]
[string]$LogFilePath = ".\Set-UnifiedADUserPassword-Log-$(Get-Date -Format 'yyyy-MM-dd').txt"
)
# --- LÓGICA PRINCIPAL ---
# Dependência da função Write-Log (deve estar no mesmo escopo ou módulo)
if (-not (Get-Command Write-Log -ErrorAction SilentlyContinue)) {
Write-Host "[ERRO FATAL] A função auxiliar 'Write-Log' não foi encontrada. O script não pode continuar." -ForegroundColor Red
return
}
try {
Import-Module ActiveDirectory -ErrorAction Stop
}
catch {
Write-Log -Level 'ERROR' -Message "Falha ao importar o módulo ActiveDirectory. Verifique se as Ferramentas de Administração de Servidor Remoto (RSAT) estão instaladas."
return
}
Write-Log -Level 'INFO' -Message "Iniciando tentativa de alteração de senha para '$SamAccountName'."
$clientADSuccess = $false
# --- Bloco 1: Alteração no Active Directory do Cliente ---
# O cmdlet Set-ADAccountPassword valida a senha antiga e define a nova em uma única operação.
try {
Write-Host " Tentando alterar a senha no AD do Cliente..."
Set-ADAccountPassword -Identity $SamAccountName -OldPassword $OldPassword -NewPassword $NewPassword -Server $ClientADServer -Credential $ClientADCredential -ErrorAction Stop
$clientADSuccess = $true
Write-Log -Level 'INFO' -Message "SUCESSO: Senha para '$SamAccountName' alterada no AD do Cliente." -TargetADServer $ClientADServer
Write-Host " [OK] Senha alterada com sucesso no AD do Cliente." -ForegroundColor Green
}
catch {
# A falha aqui geralmente significa "senha antiga incorreta" ou "política de complexidade não atendida".
$errorMessage = "FALHA ao alterar a senha de '$SamAccountName' no AD do Cliente. Erro: $($_.Exception.Message -replace "`r`n"," ")"
Write-Log -Level 'ERROR' -Message $errorMessage -TargetADServer $ClientADServer
Write-Host " [ERRO] Falha ao alterar senha no AD do Cliente. Verifique a senha antiga e as políticas de complexidade." -ForegroundColor Red
# Não continuamos se o primeiro passo falhar.
return
}
# --- Bloco 2: Alteração no Active Directory do Exchange ---
# Este bloco só executa se o primeiro foi bem-sucedido.
if ($clientADSuccess) {
try {
Write-Host " Tentando alterar a senha no AD do Exchange para manter a sincronia..."
# Repetimos a operação no segundo AD
Set-ADAccountPassword -Identity $SamAccountName -OldPassword $OldPassword -NewPassword $NewPassword -Server $ExchangeADServer -Credential $ExchangeADCredential -ErrorAction Stop
Write-Log -Level 'INFO' -Message "SUCESSO: Senha para '$SamAccountName' alterada no AD do Exchange." -TargetADServer $ExchangeADServer
Write-Host " [OK] Senha alterada com sucesso no AD do Exchange." -ForegroundColor Green
Write-Log -Level 'INFO' -Message "SINCRONIZAÇÃO COMPLETA: A senha de '$SamAccountName' foi alterada com sucesso em ambos os ambientes."
}
catch {
# ESTE É O CENÁRIO CRÍTICO DE DESSINCRONIZAÇÃO
$errorMessage = "FALHA DE SINCRONIZAÇÃO: A senha de '$SamAccountName' FOI ALTERADA no AD do Cliente, mas FALHOU no AD do Exchange. AÇÃO MANUAL PODE SER NECESSÁRIA. Erro: $($_.Exception.Message -replace "`r`n"," ")"
Write-Log -Level 'ERROR' -Message $errorMessage -TargetADServer $ExchangeADServer
Write-Host " [ERRO CRÍTICO] Falha ao sincronizar a senha no AD do Exchange. A senha foi alterada apenas no primeiro ambiente!" -ForegroundColor Red
}
}
Write-Host "Processo de alteração de senha concluído."
}
# --- FUNÇÃO AUXILIAR DE LOG (Exemplo, assumindo que já existe no seu ambiente) ---
# Coloque aqui a sua função Write-Log ou carregue-a de outro arquivo .ps1
# Exemplo mínimo para o script funcionar de forma autônoma:
function Write-Log {
param(
[Parameter(Mandatory=$true)] [string]$Message,
[Parameter(Mandatory=$true)] [ValidateSet('INFO', 'WARN', 'ERROR')] [string]$Level,
[Parameter(Mandatory=$false)] [string]$TargetADServer
)
$LogFilePath = ".\Set-UnifiedADUserPassword-Log-$(Get-Date -Format 'yyyy-MM-dd').txt"
$logEntry = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - [$Level] - $Message"
$logEntry | Out-File -FilePath $LogFilePath -Append
}