АйТи Фреш
Главная / Статьи / Windows и Active Directory
Windows и Active Directory

Три безопасных PowerShell-скрипта для Active Directory: приём, увольнение и аудит учётных записей

Автор: Семёнов Евгений Сергеевич, директор ООО «АйТи-Фреш» · · ~19 мин чтения
Автоматизация Active Directory через PowerShell: приём и увольнение сотрудников в небольшом офисе
Скрипт готовит изменения и проверяет данные, а решение о доступе остаётся за человеком.

Для небольшого домена хватает трёх PowerShell-сценариев: создать пользователя из CSV отключённым, уволить со снимком групп и переносом в карантинную OU, раз в неделю выгружать неактивные записи в отчёт. Ниже — готовые скрипты, защита от ошибок, откат и разбор внедрения в студии на 10 рабочих мест.

Что автоматизировать в Active Directory через PowerShell, а что оставить человеку

Я начинаю не со скрипта, а с границ автоматизации. В небольшой компании не нужен комбайн на тысячи строк. Нужны три предсказуемые операции: подготовить нового пользователя, закрыть доступ уволенному сотруднику и показать забытые учётные записи. Эти действия повторяются, состоят из одинаковых шагов и хорошо проверяются. Именно с них я начинаю, когда делаем аудит Active Directory у небольших клиентов. Автоматизировать переименование домена, массовое удаление объектов или «исправление всего AD» я бы не стал: выполняются они редко, а цена ошибки слишком высока.

Мой принцип простой: скрипт может подготовить изменение, проверить данные и выполнить понятную последовательность команд. Решение об увольнении или блокировке принимает человек. Поэтому приём и увольнение запускаются вручную по заявке, а по расписанию работает только отчёт. Я сознательно не делаю автоматическое отключение по дате последнего входа. Для бизнеса на десять-пятьдесят мест выигрыш составит пару минут, а ошибочно заблокированный директор или бухгалтер остановит работу на полдня.

У каждого изменяющего сценария должны быть WhatIf, остановка при первой ошибке и журнал исходного состояния. Ещё важнее идемпотентность: повторный запуск не должен создавать второго пользователя или повторно менять уже обработанную запись. Полной транзакции у набора команд AD нет. Если создание пользователя прошло, а добавление в группу завершилось ошибкой, объект останется в каталоге. Поэтому я создаю его отключённым и включаю только после финальной проверки.

Не начинайте с массовой команды из интернета. Сначала ограничьте SearchBase одной тестовой OU, запустите сценарий с `-WhatIf` и проверьте получившийся список глазами.

Как подготовить рабочее место: RSAT, права, политика выполнения

В 2026 году модуль ActiveDirectory остаётся штатным средством управления AD DS в Windows Server 2025, 2022, 2019 и 2016. Для проекта ниже я выбрал Windows PowerShell 5.1 на отдельном компьютере администратора. PowerShell 7 тоже работает с модулем на актуальных версиях Windows с установленным RSAT, но переходить на него ради десятка локальных пользователей я смысла не вижу. Чем скучнее административный контур, тем он надёжнее.

Запускать сценарии непосредственно на контроллере домена не требуется. Я ставлю RSAT на сервер управления или выделенный компьютер администратора. Для Windows Server и Windows 11 Pro/Enterprise команды различаются:

# Windows Server
Install-WindowsFeature -Name RSAT-AD-Tools -IncludeAllSubFeature

# Windows 11 Pro или Enterprise
Add-WindowsCapability -Online `
  -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0

Import-Module ActiveDirectory
Get-Command -Module ActiveDirectory | Select-Object -First 5

Рабочая учётная запись не должна постоянно состоять в Domain Admins. Я делегирую ей создание и изменение пользователей только в рабочей OU, перенос объектов в OU отключённых сотрудников и изменение состава конкретных ролевых групп. Первичная настройка делегирования потребует повышенных прав, ежедневные операции — нет. Папку со скриптами разрешаю изменять только локальным администраторам и SYSTEM: иначе пользователь с доступом на запись сможет подменить файл, который позже запустит привилегированная задача.

Политику выполнения я задаю централизованно как RemoteSigned или, если уже развёрнута внутренняя PKI и процесс подписи, AllSigned. Политика выполнения контролирует условия запуска файлов, но не заменяет права NTFS, делегирование и аудит. Постоянный Bypass в задаче планировщика — плохая привычка. Сначала проверяю эффективные настройки командой Get-ExecutionPolicy -List, потому что доменная Group Policy имеет приоритет над локальным Set-ExecutionPolicy.

Отдельно про журнал. Каждый изменяющий сценарий я запускаю внутри Start-Transcript с файлом в защищённой папке журналов и закрываю Stop-Transcript в блоке finally. Транскрипт не заменяет аудит на контроллере домена, но показывает, что именно видел и подтверждал администратор. Для студии на десять мест этого хватает с запасом: когда через месяц спрашивают, кто и зачем убрал человека из группы, ответ находится в одном текстовом файле.

Не сохраняйте пароль администратора в `.ps1`, XML задачи или обычном CSV. Для изменяющих операций используйте текущий токен делегированной учётной записи, а для фонового отчёта — `SYSTEM` либо правильно настроенную gMSA.
Три безопасных PowerShell-скрипта для Active Directory: приём, увольнение и аудит учётных записей — схема
Схема к статье. Открыть схему в полном размере

Разбор из практики: танцевальная студия «Ритм тела», 10 рабочих мест

Танцевальная студия «Ритм тела», 10 рабочих мест: два администратора ресепшн, бухгалтер, управляющий, менеджер по маркетингу и общий компьютер в тренерской, через который тренеры смотрят расписание и отмечают занятия. Особенность студии — текучка: тренеры и администраторы приходят на сезон, часть работает по совместительству. Приём и увольнение здесь случаются почти каждый месяц, и именно на этих операциях ручная работа давала сбои. Домен — Windows Server 2022, функциональный уровень Windows Server 2016, два контроллера: DC01 — виртуальная машина на основном хосте рядом с файловым сервером, DC02 — на отдельном небольшом сервере. Рабочие станции — Windows 11 Pro 24H2. В примерах настоящий суффикс заменён на зарезервированный ritm.example.

В каталоге нашлись 14 пользовательских объектов: 9 личных активных записей, 2 сервисные и 3 записи бывших сотрудников. Одна из трёх старых записей оставалась включённой — тренер, ушедший полгода назад, всё ещё мог зайти на общий компьютер в тренерской. У четырёх действующих пользователей не был заполнен отдел. Пять разрешений на файловом сервере были выданы напрямую пользователям, хотя ролевые группы уже существовали. Ручное оформление новичка занимало от 14 до 21 минуты и зависело от памяти того, кто оформлял.

Я привёл структуру к четырём OU: OU=Employees, OU=Service Accounts, OU=Computers и OU=Disabled Users внутри OU=Ritm,DC=ritm,DC=example. Пользователей включали только в глобальные группы ролей с префиксом GG- (GG-Admins, GG-Trainers, GG-Accounting), а те входили в локальные группы ресурсов DL-. Затем прогнали импорт с -WhatIf, создали одного тестового пользователя, проверили вход, применение GPO и доступ к общей папке. Только после этого обработали действующие записи. Вся подготовка заняла два рабочих дня, из них большая часть — разговор с управляющим о том, кому какой доступ на самом деле нужен.

За первые три месяца через сценарии провели пять приёмов и четыре увольнения — сезон набора групп. Среднее время подготовки новичка снизилось с 17 до 4 минут, отключения сотрудника — примерно с 15 до 3 минут. Аудит нашёл двух кандидатов на отключение, но одного мы не тронули: тренер была в декретном отпуске и собиралась вернуться. Именно поэтому отчёт остался отчётом. Через три месяца у всех действующих записей были заполнены отдел и должность, бывшие сотрудники лежали в карантинной OU, а новых прямых назначений на папки больше не появлялось.

Снимок виртуального контроллера домена я не считаю резервной копией AD. Перед массовыми изменениями должна существовать проверенная резервная копия состояния системы и понятная процедура восстановления.
Цифры и версии: Разбор из практики: танцевальная студия «Ритм тела», 10 рабочих мест — схема
Цифры и версии: Разбор из практики: танцевальная студия «Ритм тела», 10 рабочих мест. Открыть схему в полном размере
Результаты автоматизации AD через PowerShell в студии на 10 рабочих мест: приём 4 минуты, увольнение 3 минуты
Главный выигрыш не в минутах, а в том, что забытых включённых записей больше нет.

Скрипт 1: как создать пользователя AD из CSV через PowerShell

CSV хранит только кадровые атрибуты и имена ролевых групп. Пароля в нём нет. Для одного-двух новых сотрудников это может показаться излишним, зато исчезают опечатки и становится видно, кто запросил доступ. Файл сохраняем в UTF-8 с разделителем ;. В поле Groups перечисляем только подготовленные глобальные группы ролей:

GivenName;Surname;SamAccountName;Department;Title;Groups
Анна;Соколова;a.sokolova;Ресепшн;Администратор;GG-Admins
Илья;Орлов;i.orlov;Тренеры;Тренер;GG-Trainers

Скрипт проверяет формат логина, наличие пользователя и существование каждой группы до записи в каталог. Все операции закреплены за одним контроллером домена, чтобы следующий шаг не упёрся в задержку репликации. Существующую запись сценарий не «чинит» автоматически — пропускает с предупреждением. Я считаю это правильным: совпавший логин может принадлежать другому человеку.

#Requires -Version 5.1
#Requires -Modules ActiveDirectory
[CmdletBinding(SupportsShouldProcess)]
param(
    [Parameter(Mandatory)] [string]$CsvPath,
    [string]$Server = 'dc01.ritm.example',
    [string]$TargetOU = 'OU=Employees,OU=Ritm,DC=ritm,DC=example'
)

$ErrorActionPreference = 'Stop'
Import-Module ActiveDirectory
$rows = Import-Csv -Path $CsvPath -Delimiter ';' -Encoding UTF8

foreach ($row in $rows) {
    $sam = $row.SamAccountName.Trim().ToLowerInvariant()
    if ($sam -notmatch '^[a-z][a-z0-9._-]{2,19}$') {
        throw "Недопустимый SamAccountName: $sam"
    }

    $existing = Get-ADUser -LDAPFilter "(sAMAccountName=$sam)" `
        -Server $Server -ErrorAction SilentlyContinue
    if ($existing) {
        Write-Warning "$sam уже существует — строка пропущена"
        continue
    }

    $groupNames = @(($row.Groups -split ',') |
        ForEach-Object { $_.Trim() } | Where-Object { $_ })
    $groups = foreach ($groupName in $groupNames) {
        if ($groupName -notlike 'GG-*') {
            throw "Группа $groupName не является ролевой GG-группой"
        }
        Get-ADGroup -Identity $groupName -Server $Server
    }

    $displayName = "$($row.GivenName.Trim()) $($row.Surname.Trim())"
    $params = @{
        Name              = $sam
        GivenName         = $row.GivenName.Trim()
        Surname           = $row.Surname.Trim()
        DisplayName       = $displayName
        SamAccountName    = $sam
        UserPrincipalName = "$sam@ritm.example"
        Path              = $TargetOU
        Enabled           = $false
    }
    if ($row.Department) { $params.Department = $row.Department.Trim() }
    if ($row.Title)      { $params.Title = $row.Title.Trim() }

    if ($PSCmdlet.ShouldProcess($sam, 'Создать отключённого пользователя')) {
        New-ADUser @params -Server $Server
        if ($groups.Count -gt 0) {
            Add-ADPrincipalGroupMembership -Identity $sam `
                -MemberOf $groups -Server $Server
        }
        Write-Information "Создан отключённый пользователь $sam" -InformationAction Continue
    }
}

Первый запуск выглядит так: New-RitmUser.ps1 -CsvPath .\new-users.csv -WhatIf. Затем убираем -WhatIf, сверяем свойства пользователя и только после этого задаём пароль. Я ввожу его интерактивно как SecureString; открытый текст не попадает в CSV, историю команд или наш журнал:

$user = Get-ADUser -Identity 'a.sokolova' -Server 'dc01.ritm.example'
$password = Read-Host 'Временный пароль' -AsSecureString
Set-ADAccountPassword -Identity $user -Reset `
    -NewPassword $password -Server 'dc01.ritm.example'
Set-ADUser -Identity $user -ChangePasswordAtLogon $true `
    -Server 'dc01.ritm.example'
Enable-ADAccount -Identity $user -Server 'dc01.ritm.example'

Ещё одна деталь, которую легко пропустить: все команды сценария явно работают с одним контроллером через параметр -Server. Если создать пользователя на DC01, а добавлять в группы через DC02, между шагами может не успеть пройти репликация, и вторая команда не найдёт только что созданный объект. В домене из двух контроллеров на одной площадке это секунды, но именно такие секунды превращаются в плавающую ошибку, которую потом невозможно воспроизвести.

Самая частая поломка здесь — не синтаксис, а грязный CSV: пробел после логина, несуществующая группа или кириллическая буква в латинском имени. Вторая ошибка — сразу создавать Enabled = $true. Если добавление в группы затем упадёт, сотрудник получит рабочий пароль, но неполный доступ. В моей схеме частично созданная запись остаётся отключённой. Это безопасный и заметный сбой.

Временный пароль передавайте сотруднику отдельно от логина и не отправляйте оба значения одним письмом или сообщением. Требование смены при первом входе должно соответствовать вашей доменной парольной политике.
Схема создания пользователя AD через PowerShell: CSV, проверка групп, отключённая запись, пароль, включение
Запись создаётся отключённой, поэтому любой сбой посередине безопасен и заметен.

Скрипт 2: как уволить сотрудника в AD без удаления учётной записи

При увольнении первым действием я отключаю учётную запись. Не переименовываю, не очищаю атрибуты и тем более не удаляю. Затем сохраняю снимок прямого членства в группах, убираю эти группы, записываю номер заявки и переношу объект в карантинную OU. Снимок позволяет понять прежний доступ или восстановить запись, если кадровая заявка оказалась ошибочной.

Сценарий намеренно требует подтверждаемого ручного запуска. Параметр SupportsShouldProcess даёт -WhatIf, а ConfirmImpact='High' напоминает, что операция влияет на доступ. Поле MemberOf содержит прямое членство; основная группа вроде Domain Users туда обычно не входит и этим кодом не удаляется.

#Requires -Version 5.1
#Requires -Modules ActiveDirectory
[CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')]
param(
    [Parameter(Mandatory)] [string]$SamAccountName,
    [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Ticket,
    [string]$Server = 'dc01.ritm.example',
    [string]$DisabledOU = 'OU=Disabled Users,OU=Ritm,DC=ritm,DC=example',
    [string]$SnapshotPath = 'C:\AD-Automation\Snapshots'
)

$ErrorActionPreference = 'Stop'
Import-Module ActiveDirectory
$user = Get-ADUser -Identity $SamAccountName -Server $Server `
    -Properties MemberOf,Department,Title,Description

$groups = @(foreach ($groupDN in $user.MemberOf) {
    Get-ADGroup -Identity $groupDN -Server $Server
})

if ($PSCmdlet.ShouldProcess($user.SamAccountName, 'Отключить и поместить в карантин')) {
    New-Item -Path $SnapshotPath -ItemType Directory -Force | Out-Null
    $stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
    [ordered]@{
        SamAccountName    = $user.SamAccountName
        DistinguishedName = $user.DistinguishedName
        Department        = $user.Department
        Title             = $user.Title
        MemberOf          = @($user.MemberOf)
        Ticket            = $Ticket
        CapturedAt        = (Get-Date).ToString('o')
    } | ConvertTo-Json -Depth 3 |
        Set-Content -Path "$SnapshotPath\$($user.SamAccountName)-$stamp.json" -Encoding UTF8

    Disable-ADAccount -Identity $user -Server $Server
    if ($groups.Count -gt 0) {
        Remove-ADPrincipalGroupMembership -Identity $user `
            -MemberOf $groups -Server $Server -Confirm:$false
    }
    Set-ADUser -Identity $user -Clear manager `
        -Description "Disabled $(Get-Date -Format 'yyyy-MM-dd'); ticket $Ticket" `
        -Server $Server
    Move-ADObject -Identity $user.DistinguishedName `
        -TargetPath $DisabledOU -Server $Server
}

AD — только один слой доступа. Следом я закрываю облачную почту, VPN, CRM, онлайн-кассу и систему записи клиентов, телефонию и внешние кабинеты. Проверяю активные SMB-сеансы на файловом сервере и при необходимости завершаю конкретный сеанс. Автоматически закрывать все соединения пользователя по одному совпавшему имени опасно: можно оборвать копирование данных или задеть одноимённую локальную запись. Удаление объекта я рассматриваю отдельно после согласованного срока хранения, обычно не в день увольнения.

Отключение записи в AD не гарантирует мгновенного завершения уже открытой сессии во всех приложениях. Существующий локальный токен или соединение может жить до повторной проверки полномочий.
Порядок действий: Скрипт 2: как уволить сотрудника в AD без удаления учётной записи — схема
Порядок действий: Скрипт 2: как уволить сотрудника в AD без удаления учётной записи. Открыть схему в полном размере
Чек-лист увольнения сотрудника в Active Directory через PowerShell: WhatIf, снимок групп, отключение, карантинная OU
Снимок групп до изменений превращает ошибочное увольнение в минутный откат.

Скрипт 3: как найти неактивные учётные записи AD и запустить отчёт по расписанию

Для поиска я использую Search-ADAccount -AccountInactive, но отношусь к результату как к подсказке. Свойство LastLogonDate строится на реплицируемом lastLogonTimestamp. Этот атрибут обновляется не при каждом входе: стандартная логика предусматривает интервал и случайный сдвиг, исторически дающий окно примерно 9–14 дней. Кроме того, сервисные сценарии Kerberos и неверное время на контроллере могут искажать картину. Поэтому беру порог 90 дней, исключаю свежесозданные записи и всё равно запрашиваю подтверждение руководителя. Подробно про разницу между lastLogon на разных контроллерах и реплицируемым lastLogonTimestamp я писал в статье про аудит последнего входа в Active Directory — здесь нужен только грубый фильтр.

Отчёт ограничен рабочей OU, не захватывает сервисные записи и ничего не блокирует. Пустой LastLogonDate тоже важен: это может быть забытая заготовка или сотрудник, который так и не вышел на работу.

#Requires -Version 5.1
#Requires -Modules ActiveDirectory
$Server = 'dc01.ritm.example'
$SearchBase = 'OU=Employees,OU=Ritm,DC=ritm,DC=example'
$ReportDir = 'C:\ProgramData\AD-Automation\Reports'
$cutoff = (Get-Date).AddDays(-90)

New-Item -Path $ReportDir -ItemType Directory -Force | Out-Null
$report = foreach ($account in (Search-ADAccount -UsersOnly -AccountInactive `
    -TimeSpan '90.00:00:00' -SearchBase $SearchBase -Server $Server)) {
    $user = Get-ADUser -Identity $account -Server $Server `
        -Properties LastLogonDate,whenCreated,Enabled,Department
    if ($user.Enabled -and $user.whenCreated -lt $cutoff) {
        [pscustomobject]@{
            SamAccountName = $user.SamAccountName
            Name           = $user.Name
            Department     = $user.Department
            LastLogonDate  = $user.LastLogonDate
            Created        = $user.whenCreated
        }
    }
}

$file = Join-Path $ReportDir "inactive-$(Get-Date -Format 'yyyyMMdd').csv"
$report | Sort-Object LastLogonDate |
    Export-Csv -Path $file -NoTypeInformation -Encoding UTF8
Write-Output "Кандидатов: $($report.Count). Отчёт: $file"

Такой read-only сценарий можно запускать от SYSTEM на присоединённом к домену сервере: машинной записи обычно хватает стандартных прав чтения каталога, а пароль хранить не приходится. Я назначаю еженедельный запуск и отдельно защищаю каталог со скриптом от изменения обычными пользователями:

$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument `
  '-NoProfile -NonInteractive -ExecutionPolicy RemoteSigned -File "C:\AD-Automation\Audit-AD.ps1"'
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday -At '07:00'
$principal = New-ScheduledTaskPrincipal -UserId 'SYSTEM' `
  -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask -TaskName 'AD inactive users audit' `
  -Action $action -Trigger $trigger -Principal $principal `
  -Description 'Еженедельный отчёт, без изменений в AD'

Если задаче действительно нужно менять AD по расписанию, я выбираю gMSA, а не обычную сервисную запись с бессрочным паролем. Но для студии на 10 мест это оправдано только при уже подготовленном KDS и делегировании: нужны функциональные уровни домена и леса не ниже Windows Server 2012, корневой ключ KDS и разрешённый узел получения управляемого пароля. Для трёх редких кадровых операций проще и прозрачнее оставить ручной подтверждаемый запуск. В первую очередь внедрите отключение и аудит. Красивую панель, уведомления в мессенджер и универсальный модуль можно спокойно отложить. Общие приёмы работы с планировщиком — триггеры, журнал, перезапуск при сбое — собраны в материале про автоматизацию задач через Task Scheduler.

`lastLogonTimestamp` подходит для поиска давно неиспользуемых записей, но не для точного ответа «когда пользователь входил последний раз». Для расследования проверяют дополнительные источники и журналы контроллеров домена.

Что делать, если скрипт ошибся: откат по снимку и корзина AD

Ошибки случаются даже с проверенными сценариями: кадровик перепутал фамилии, в заявке указали не того тренера, администратор запустил увольнение по старой заявке. Ради этого сценарий увольнения и сохраняет JSON-снимок прямого членства в группах до изменений. Откат занимает минуту: вернуть объект в рабочую OU, восстановить группы из снимка и включить запись. Я держу этот откат отдельным маленьким скриптом рядом с основным, чтобы в стрессовой ситуации не писать код с нуля.

#Requires -Modules ActiveDirectory
param(
    [Parameter(Mandatory)] [string]$SnapshotFile,
    [string]$Server = 'dc01.ritm.example',
    [string]$TargetOU = 'OU=Employees,OU=Ritm,DC=ritm,DC=example'
)
$ErrorActionPreference = 'Stop'
$snap = Get-Content -Path $SnapshotFile -Raw -Encoding UTF8 | ConvertFrom-Json
$user = Get-ADUser -Identity $snap.SamAccountName -Server $Server

Move-ADObject -Identity $user.DistinguishedName -TargetPath $TargetOU -Server $Server
if (@($snap.MemberOf).Count -gt 0) {
    Add-ADPrincipalGroupMembership -Identity $snap.SamAccountName `
        -MemberOf @($snap.MemberOf) -Server $Server
}
Enable-ADAccount -Identity $snap.SamAccountName -Server $Server

Хуже, когда объект удалили руками, не дождавшись срока хранения. Здесь спасает только заранее включённая корзина Active Directory: без неё удалённый пользователь теряет членство в группах и большинство атрибутов, и восстанавливать придётся из резервной копии состояния системы. Корзина включается один раз на лес командой Enable-ADOptionalFeature и выключить её потом нельзя — как это сделать и как восстанавливать объекты, я разбирал в статье про Active Directory Recycle Bin. В «Ритме тела» мы включили её в первый же день, до любых скриптов.

И последнее. Любой сценарий, который меняет каталог, я держу в одном месте с понятной историей изменений — хотя бы в папке с датами в именах файлов, лучше в git. Через полгода вопрос «почему у Анны нет доступа к папке расписаний» решается за пять минут, если видно, какой версией скрипта и по какой заявке её оформляли. Для малого офиса этого достаточно; журнал в SIEM и согласование через тикет-систему нужны уже при большем масштабе. А если однажды захочется расширить набор — отчёты по группам, сброс паролей, инвентаризацию компьютеров, — добавляйте новые сценарии по тем же правилам: WhatIf, остановка при ошибке, снимок до изменений и отдельный тест на пробной OU.

Не удаляйте объекты уволенных сотрудников в день увольнения. Отключённая запись в карантинной OU ничего не стоит, а удалённая без корзины AD восстанавливается только из резервной копии контроллера.
Порядок действий: Что делать, если скрипт ошибся: откат по снимку и корзина AD — схема
Порядок действий: Что делать, если скрипт ошибся: откат по снимку и корзина AD. Открыть схему в полном размере

Частые вопросы

Можно ли запускать эти скрипты с контроллера домена?

Технически можно, но я использую отдельный сервер управления или защищённый компьютер с RSAT. Для работы cmdlet достаточно сетевого доступа к контроллеру и делегированных прав.

Нужна ли учётная запись Domain Admin?

Для ежедневного создания и отключения пользователей — нет. Делегируйте минимальные права на рабочие OU и конкретные группы. Повышенные права понадобятся администратору при первоначальной настройке.

Почему сценарий создания не генерирует пароль автоматически?

Чтобы пароль не оказался в CSV, журнале или консольном выводе. Для малого количества приёмов безопаснее отдельно ввести временный пароль как SecureString и включить обязательную смену при первом входе.

Можно ли автоматически блокировать пользователей после 90 дней без входа?

Я не советую. lastLogonTimestamp обновляется с задержкой и имеет дополнительные ограничения. Формируйте отчёт, сверяйте его с кадровыми данными и только потом отключайте подтверждённые записи.

Что делать, если добавление в группу завершилось ошибкой?

Пользователь останется отключённым. Исправьте имя или права группы, проверьте объект вручную и завершите назначение доступа. Не включайте запись, пока вся проверка не пройдена.

Как откатить ошибочное увольнение?

Сценарий увольнения сохраняет JSON-снимок прямого членства в группах. По нему объект возвращают в рабочую OU, восстанавливают группы через Add-ADPrincipalGroupMembership и включают запись Enable-ADAccount. Если объект уже удалён, поможет только заранее включённая корзина AD или резервная копия.

Столкнулись с похожей задачей? Обращайтесь — решим

Если у вас происходит что-то из описанного в этой статье — или любая другая проблема с ИТ-инфраструктурой, — обращайтесь в любое время. Мои специалисты и я лично разберём ситуацию, найдём настоящую причину и доведём до решения.

Возьмёмся и за разовую задачу, и за постоянное обслуживание. Первичная консультация — бесплатно и без обязательств.

📞 +7 903 729-62-41 💬 MAX: +7 903 729-62-41 ✈ Telegram @ITfresh_Boss

С уважением, Семёнов Евгений Сергеевич, директор «АйТи Фреш» — IT-аутсорсинг для компаний до 50 рабочих мест, 15+ лет практики

Источники

© ООО «АйТи-Фреш» · Москва · Все статьи