Как массово поменять пароль локального администратора в домене

Обновлено 21.05.2021

password-logo

Добрый день! Уважаемые читатели и гости одного из крупнейших IT блогов в рунете Pyatilistnik.org. В минувшей статье я вам подробно осветил методы "как разархивировать файл" в операционных системах Windows или Linux. Сегодня я вам хочу показать очень удобный скрипт на PowerShell. который позволит вам изменить пароль локальной учетной записи на компьютерах в домене Active Directory. Уверен, что данная задача. хоть раз в год у вас и появляется. а по правильному лучше это проделывать хотя бы раз в пол года, в целях повышения безопасности.

Задача по смене пароля локального администратора в домене

Представим простую ситуацию. У вас есть домен Active Directory в котором 50 и более компьютеров. На каждом из них есть локальная учетная запись администратора, используется она чаще всего для второй линии, чтобы производить обслуживание рабочих станций. Вам потребовалось сменить пароль для учетной записи "Администратор", как быть, вы же не будите бегать и ручками все менять.

Ранее во времена Windows Server 2008R2, можно было легко обновить пароль локального администратора с помощью групповых политик, я об этом рассказывал, но в следующих версиях Windows Server 2012 R2 и выше, уже данная опция не доступна, кнопки просто неактивны.

Не активные кнопки сброса пароля учетной записи администратор в групповой политике

Не знаю, с какой целью Microsoft убрала данную возможность, очень странный ход, поэтому пойдем другим путем. Мы напишем простой скрипт на PowerShell, который возьмет список DNS-имен серверов и на каждом из них он поменяет пароль для нужной нам локальной учетной записи.

Скрипт PowerShell по изменению пароля локальной учетной записи на удаленном компьютере

Для того, чтобы наш скрипт нормально отработал нам нужно выполнить некоторые требования:

  1. Иметь права администратора на том компьютере, где будет изменяться пароль для локальной учетной записи, я уверен, что вы все доменные администраторы
  2. Выяснить версию PowerShell, так как я приведу два варианта скрипта по изменению пароля, и тут нужно понимать, какой командлет поддерживает ваша версия.
  3. Подготовить список с именами серверов и сформировать текстовый файл, по идее все.

Как узнать версию powerShell смотрите по ссылке

Подготовка файла со списком серверов

Давайте я покажу формат и структуру файла, в котором будет содержаться список наших серверов. Создайте обычный txt файл и задайте ему имя. у меня пусть будет comps.txt. Далее скопируйте в него список ваших FQDN имен серверов, ОДНА СТРОКА - ОДНО имя.

Файл со списком имен серверов для скрипта PowerShell

Скрипт для массовой смены пароля у локального администратора для PowerShell 5.1 и ниже

Хочу напомнить, что если вы скачаете готовый скрипт у меня в виде ps1 файла. то вам нужно разрешить запуск неподписанных скриптов в powerShell, если будите запускать из под PowerShell ISE. то ничего дополнительного делать не нужно

Я уверен, что на серверах из списка вы администратор. Я для примера буду производить смену пароля у локальной учетной записи "Администратор", хотя по хорошему вы ее должны переименовать или отключить вообще, создав другую. Откройте PowerShell ISE и скопируйте скрипт.

# Задаем месторасположение нашего файла со списком серверов

$computer = "C:\Temp\comps.txt"
foreach($computerName in (Get-Content $computer)) {

#Устанавливаем новый пароль
$adminPassword = "123456A@"

#задаем какую учетную запись мы будим изменять
$adminUser = [ADSI] "WinNT://$computerName/Администратор"
$adminUser.SetPassword($adminPassword)
}

Скрипт для массовой смены пароля у локального администратора для PowerShell 5.1 и ниже

Можно использовать еще вот такой вариант для списка:

$computer = "C:\Temp\comps.txt"
foreach ($computerName in (Get-Content $computer))
{
Write-Host "Tryimg to process computer $computerName"

If (Test-Connection -ComputerName $computerName -Count 2 -Quiet)
{
Write-Host "Компьютер отвечает на Ping";

$credential = Get-Credential -UserName "Администратор" -Message "Вводим новый пароль";

If ($credential -eq $null)
{
Write-Warning "The username and/or the password is empty! I quit.";
Exit;
}

$user = [adsi]"WinNT://$computer/$($credential.GetNetworkCredential().Username),user";
$user.SetPassword($credential.GetNetworkCredential().Password);
$user.SetInfo();
}
Else
{
Write-Warning "Компьютер не отвечает.";
}
}

Как массово поменять пароль администратора

Или вариант для одного компьютера

$computer = Read-Host -Prompt "Введите имя компьютера";
If (Test-Connection -ComputerName $computer -Count 2 -Quiet) {
Write-Host "The computer responded to our ping request. Connecting...";
$credential = Get-Credential -UserName "Администратор" -Message "Вводим новый пароль";
If ($credential -eq $null) {
Write-Warning "The username and/or the password is empty! I quit.";
Exit;
}
$user = [adsi]"WinNT://$computer/$($credential.GetNetworkCredential().Username),user";
$user.SetPassword($credential.GetNetworkCredential().Password);
$user.SetInfo();
} Else {
Write-Warning "Компьютер не отвечает.";
}

Как поменять пароль локального администратора

Скрипт для массовой смены пароля у локального администратора для PowerShell 5.1 и выше

В Windows 10 build 1607 и выше, новый Powershell 5.1 представил Set-LocalUserкомандлет. Вы можете использовать его для этой задачи вместо адаптера ADSI, но для этого требуется, чтобы на удаленных компьютерах была включена служба удаленного взаимодействия Powershell (которая по умолчанию отключена). Чтобы разрешить прием удаленных команд, вам необходимо запустить run Enable-PSRemotingв терминале Powershell с повышенными привилегиями на удаленном компьютере.

Если удаленное взаимодействие PS включено, измененный сценарий будет выглядеть следующим образом:

  • Для одного компьютера

$computer = Read-Host -Prompt "Введите имя компьютера";
If (Test-Connection -ComputerName $computer -Count 2 -Quiet) {
Write-Host "Пытаюсь проверить компьютер на пакеты ping";
Invoke-Command -ComputerName $computer -ScriptBlock {
$credential = Get-Credential -UserName "Администратор" -Message "Введите новый пароль";
If ($credential -eq $null) {
Write-Warning "The username and/or the password is empty! I quit.";
Exit;
}
Set-LocalUser -Name $credential.UserName -Password $credential.Password;
}
} Else {
Write-Warning "Компьютер не отвечает на Ping.";
}

Скрипт для массовой смены пароля у локального администратора для PowerShell 5.1 и выше

  • Для списка компьютеров

$computer = "C:\Temp\comps.txt"
foreach ($computerName in (Get-Content $computer))
{
If (Test-Connection -ComputerName $computerName -Count 2 -Quiet)
{
Write-Host "Пытаюсь проверить компьютер на пакеты ping";
Invoke-Command -ComputerName $computerName -ScriptBlock {
$credential = Get-Credential -UserName "Администратор" -Message "Введите новый пароль";
If ($credential -eq $null)
{
Write-Warning "The username and/or the password is empty! I quit.";
Exit;
}
Set-LocalUser -Name $credential.UserName -Password $credential.Password;
}
} Else

{
Write-Warning "Компьютер не отвечает на Ping.";
}
}

Массовая замена пароля у локального администратора

На этом у меня все, как говорится нет пределу совершенства. и вы можете написать куда лучше и поделиться со мной и читателями. С вами был Иван Семин. автор и создатель IT портала Pyatilistnik.org.

Автор - Сёмин Иван

2 Responses to Как массово поменять пароль локального администратора в домене

  1. Виктор Викторович:

    Ранее настройки групповой политики (GPP) часто использовались для изменения паролей локальных администраторов на компьютерах, присоединённых к домену. Однако позже в GPP была обнаружена серьёзная уязвимость, позволяющая любому пользователю домена расшифровать пароль, хранящийся в текстовом файле в каталоге SYSVOL на контроллерах домена AD. В мае 2014 года Microsoft выпустила обновление безопасности (MS14-025 — KB 2962486), которое полностью отключило возможность установки пароля локального пользователя с помощью GPP.

    При использовании скриптов:
    — не забудьте защитить атрибут объекта, в котором пароль будете хранить, а то обычные поля компьютерных объектов по умолчанию весь домен может читать. А после этого сделать какой-то тул для просмотра этого атрибута, потому что в ADUC его видно не будет.
    — еще что-то придумать для клиентов, которые не постоянно онлайн, чтобы не пропускали время запуска скрипта.
    — не забудьте открыть везде порты, чтобы COM-RPC работал с сервера, на котором скрипт запускается, к клиентам — а то по умолчанию, например, клиенты общаются с контроллером домена только в режиме pull.
    — и как следует защитить учетную запись, от которой запускается скрипт — прав у нее в сети будет немало.

    Или можно вместо всей этой головной боли использовать LAPS, официальное и поддерживаемое (бесплатное) решение от Microsoft.

  2. Сергей:

    Немного допилил. Можно еще чуть оптимизировать, но суть такая:

    $date= Get-Date -Format yyyy-M-dd-hh-mm
    #Список компьютеров, которые необходимо пропинговать и поменять на них пароль
    $File1=»comps.txt»
    #Список компьютеров, до которых в сети достучаться не удалось(они будут просканированы при следующем старте, ПК с измененным паролем сканироваться не будут)
    $file2=»no_answer.txt»
    #В файл формата Result + дата + время записываются ПК, пинг до которых успешен и они при повторном старте из шедалера этого скрипта опрашиваться не будут
    $file3 = «result» + $date +».txt»
    # обнуление переменных
    $result=$null
    $noanswer=$null
    #выгрузка всех имен ПК из ОУ вашего домена
    $user_Out=Get-ADComputer -SearchBase ‘OU=Users, OU=Branch,DC=test,DC=local’ -Filter * | Where-Object {$_.enabled -eq $True} | Sort-Object name |ft name

    # проверка — если скрипт запускается впервые и файла со списком ПК не существует, то берутся все компы из домена выгруженные ранее

    if (Test-Path -path $File1) {1} Else {$user_out | Out-File $File1}
    # проверка, если существует файл, в котором есть ПК, которые не были просканированы в прошлый раз, то файл со списком, который будет сканироваться подменяется этим файлом. То есть сканироваться будут только те ПК, которые не отвечали на запросы при прошлых сканированиях.
    if (Test-Path -path $File2) {get-content -Path $file2 | Out-File $File1}

    # Задаем месторасположение нашего файла со списком серверов
    $computer = $File1
    foreach($computerName in (Get-Content $computer)) {
    #убираем все лишние пробелы из имени ПК, которые присутствуют при выгрузке из АД
    $computerName = $computerName.TrimEnd()

    Write-Host «Tryimg to process computer $computerName»
    If (Test-Connection -ComputerName $computerName -Count 2 -Quiet)
    {
    #Write-Host «Компьютер отвечает на Ping»;

    #Устанавливаем новый пароль
    $adminPassword = «Password123@»
    #Формируем список ПК с удчано установленными паролями
    $result += $computername.tostring().trim() + «`r`n»

    #задаем какую учетную запись мы будим изменять, обычно на разных компах это разные учетки, что бы не определять делаем скрипт на все возможные варианты, критической ошибкой это не будет, скрипт не остановиться. К примеру:

    $adminUser = [ADSI] «WinNT://$computerName/Администратор»
    $adminUser.SetPassword($adminPassword)
    $adminUser = [ADSI] «WinNT://$computerName/Administrator»
    $adminUser.SetPassword($adminPassword)
    }

    Else
    {
    Write-Warning «Компьютер $computerName не отвечает.»;
    #Формируем список компов, которые не ответили на пинги и которые будут проверяться при следующем старте скрипта
    $noanswer += $computername.tostring().trim() + «`r`n»

    }
    }
    #Сохраняем результаты работы. Файл No_Answer.txt при следующем старте подменит сomps.txt и сканирование и смена паролей будет выполнена только на тех компах, которые не были в сети.
    Set-Content $file2 $noanswer
    # создает файл результата только в том случае, если были ПК отозвавшиеся на пинги
    if ($result -Ne $null) {Set-Content $file3 $result}

    #встраиваем скрипт в шедаллер с произвольным повторением — раз в 2 -3 часа будет достаточно.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *