Скрипт PowerShell для сброса пароля в AD Печать

Скрипт PowerShell, позволяющий обозначить домен и учетные данные для подключения, сбросить пароль учетной записи Active Directory и разблокировать ее, а также отобразить примененную к учетной записи политику паролей PSO в домене.

Function Global:Reset-ADAccountPassword ([parameter(Mandatory=$true)][string]$Name,$DistinguishedNameSearchBase,$Credential,[switch]$ShowPasswordPolicy,$Server) {
# $ShowPasswordPolicy = [bool]$false (можно использовать булево значение вместо переключателя switch)

    Write-Host  
    $error.Clear | Out-Null
    Write-Host 'Original and comments: http://vam.in.ua/index.php/it/25-ms-powershell/145-powershell-ad-account-password-reset-script.html'  
    Write-Host 'Feedback: http://vam.in.ua/index.php/contacts/2-admins/1-aleksey.html'
    Remove-Variable pso,psoError,adAcc,passwd,commonError,newADpass,mess,fdomain,getADuserVar -ErrorAction SilentlyContinue

    #--- Если указаны учетные данные
    if ($Credential) {
        $passwd = Get-Credential -Credential $Credential -ErrorVariable commonError
        if (!$passwd) {Break}
    }

    #--- Если не указано имя учетной записи вызвать исключение
    if (!$name) {        
        Write-Error -Message 'Account name is not defined'
        Remove-Variable passwd,Credential -ErrorAction SilentlyContinue
        Break
    }

    #--- Импортируем модуль AD
    Import-Module -Name ActiveDirectory -ErrorVariable commonError

    #--- Если ошибка то прервать функцию
    if ($commonError) {
        Remove-Variable passwd,Credential -ErrorAction SilentlyContinue
        Break
    }

    #--- Если переменная Server не определена, то подставить ей значение текущего контроллера домена
    if ($Server) {
        if ($Credential) {
            $Server = Get-ADDomainController -Credential $passwd -Server $Server -ErrorVariable commonError
            $Server = $Server.HostName
        } else {
            $Server = Get-ADDomainController -Server $Server -ErrorVariable commonError
            $Server = $Server.HostName
        }
    } else {
        if ($Credential) {
            $Server = Get-ADDomainController -Credential $passwd -ErrorVariable commonError
            $Server = $Server.HostName
        } else {
            $Server = Get-ADDomainController -ErrorVariable commonError            
            $Server = $Server.HostName
        }
    }

    # Если произошла общая ошибка - прервать функцию
    if ($commonError) {
        Remove-Variable passwd,Credential -ErrorAction SilentlyContinue
        Break
    }

    #--- Если переменная DistinguishedNameSearchBase не определена, то подставить ей значение текущего домена
    if (!$DistinguishedNameSearchBase) {
        if ($Credential) {
            $fdomain = Get-ADDomain -Credential $passwd -Server $Server -ErrorVariable commonError
        } else {
            $fdomain = Get-ADDomain -Server $Server -ErrorVariable commonError
        }        
    } else {
        if ($Credential) {
            $fdomain = Get-ADObject -Server $Server -Identity $DistinguishedNameSearchBase -Credential $passwd -ErrorVariable commonError
        } else {
            $fdomain = Get-ADObject -Server $Server -Identity $DistinguishedNameSearchBase -ErrorVariable commonError
        }
    }

    # Если произошла общая ошибка (например неверные учетные данные) - прервать функцию
    if ($commonError) {
        Remove-Variable passwd,Credential -ErrorAction SilentlyContinue
        Break
    }

    #--- Загоняем в переменную adAcc объект пользователя по его логину
    if ($Credential) {
        $adAcc = (Get-ADUser -Server $Server -SearchBase $fdomain -Credential $passwd -Filter {samAccountName -eq $name} -ErrorVariable commonError)
    } else {
        $adAcc = (Get-ADUser -Server $Server -SearchBase $fdomain -Filter {samAccountName -eq $name} -ErrorVariable commonError)
    }

    #--- Если ошибка - прервать функцию
    if ($commonError) {
        Remove-Variable passwd,Credential -ErrorAction SilentlyContinue
        Break
    }

    #--- Если учетная запись не определена - прервать функцию, иначе - блок кода 
    if (!$adAcc) {
        $mess = 'Account "' + $name + '" was not find on ' + $fdomain + ' at server ' + $Server
        Write-Error $mess
        Remove-Variable passwd,Credential -ErrorAction SilentlyContinue
        Break        
    } 
    else {
        Write-Host  
        #--- Выведем на экран информацию об аккаунте, с которым хотим работать
        Write-Host '---=== INFORMATION ABOUT ACCOUNT ===---'
        $adAcc | Format-List
        #--- Проказать примененную к аккаунту политику паролей, если требуется
        if ($ShowPasswordPolicy.IsPresent) {
            if ($Credential) {
                $pso = Get-ADUserResultantPasswordPolicy -Server $Server -Identity $adAcc -ErrorVariable psoError -Credential $passwd
            } else {
                $pso = Get-ADUserResultantPasswordPolicy -Server $Server -Identity $adAcc -ErrorVariable psoError
            }

            Write-Host '---=== PASSWORD POLICY ===---'
            if (($pso) -and (!$psoError)) {
                $pso | Format-List
            } else {
                $mess = 'Password Settings Object is not defined for account "' + $name + '"'
                Write-Host $mess
            }
            Write-Host  
            Pause
            Write-Host  
        }
        #--- Формируем приглашение ввести пароль для учетной записи в переменной
        $mess = 'Please type new password for account   "' + $name + '"'
        #--- Интерактивно предложим ввести новый пароль
        $newADpass = Read-Host $mess -AsSecureString         
        #--- Сбросим пароль учетной записи в AD
        if ($Credential) {
            Set-ADAccountPassword -Server $Server -Credential $passwd -Identity $adAcc -Reset -NewPassword $newADpass -ErrorVariable commonError
        } else {
            Set-ADAccountPassword -Server $Server -Identity $adAcc -Reset -NewPassword $newADpass -ErrorVariable commonError
        }
    
        #--- Если ошибок при сбросе небыло, то разблокировать учетную запись и указать на необходимость сменить пароль
        if (!$commonError) { 
            Write-Host  

            #--- Необходимость изменить пароль при первом входе
            if ($Credential) {
                Set-ADUser $adAcc -ChangePasswordAtLogon $true -Server $Server -Credential $passwd
            } else {
                Set-ADUser $adAcc -ChangePasswordAtLogon $true -Server $Server
            }

            $mess = 'Password was successfully reset for account "' + $name + '"'
            Write-Host $mess

            #--- Разблокируем учетную запись 
            if ($Credential) {
                Unlock-ADAccount $adAcc -ErrorVariable commonError -Server $Server -Credential $passwd
            } else {
                Unlock-ADAccount $adAcc -ErrorVariable commonError -Server $Server
            }

            #--- Если разблокировалась без ошибок - поздравить
            if (!$commonError) {
                Write-Host  
                Write-Host 'Account was successfully unlocked'
                Write-Host  
            }

        }         
    }
    
    Remove-Variable passwd,Credential -ErrorAction SilentlyContinue
}

Применение:

Reset-ADAccountPassword [-Name <string>] [-DistinguishedNameSearchBase <string>] [-Credential <PSCredential>] [-ShowPasswordPolicy ] [-Server <string>]

 

PS C:\> Reset-ADAccountPassword domainuser # сбросит пароль учетной записи domainuser и разблокирует ее. Необходимо чтобы командлет запускался внутри домена от имени пользователя имеющего соответствующие права
PS C:\> Reset-ADAccountPassword -Name domainuser -Server dc1 -DistinguishedNameSearchBase "OU=managers,DC=domain,DC=local" -Credential domain\admin # сбросит пароль и разблокирует учетную запись domainuser, которая находится в подразделении managers домена domain.local на контроллере домена dc1. Для выполнения этой операции будет запрошен пароль доменной учетной записи admin
PS C:\> Reset-ADAccountPassword -Name domainuser -ShowPasswordPolicy # сбросит пароль учетной записи domainuser и разблокирует ее. Перед приглашением ввести новый пароль будет отображена политика паролей PSO для этой учетной записи

 

Добавляем скрипт в профиль и функция Reset-ADAccountPassword будет доступна также как и все остальные командлеты. Как работать с профилями смотрите в моей статье (ссылка).

Для того чтобы скрипт нормально отработал, необходимо чтобы был установлен родной модуль PowerShell ActiveDirectory. Он входит в набор Remote Server Administration Tools (RSAT) [Remote Server Administration Tools/Role Administration Tools/AD DS and AD LDS Tools/Active Directory module for Windows PowerShell] и автоматически ставится на контроллерах домена вместе с Active Directory.