AD: скрипт svc-bj сам генерирует пароль и сообщает итог

Пароль — 24 случайных символа (RandomNumberGenerator), показывается один
раз в конце. Итог: создан пользователь (где) или уже был (пароль не
менялся), по каждой группе bj-* — создана (где) или уже есть (DN).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7eREaYwUt1i4fNLZcGnjn
This commit is contained in:
fontvielle
2026-10-22 12:55:35 +03:00
parent 40a7f10d88
commit 8f32f79372
@@ -87,28 +87,62 @@
<p style="margin:0 0 6px">bj читает AD обычной доменной учётной записью: проверяет пароль пользователя и его группы. Прав администратора домена ей не нужно — читать каталог могут все пользователи домена. Создаёт запись администратор домена:</p>
<ol style="margin:0 0 8px;padding-left:20px">
<li>На контроллере домена (или компьютере с RSAT) откройте PowerShell <b>от имени администратора домена</b>.</li>
<li>Скопируйте и выполните скрипт ниже — он спросит пароль для <code>svc-bj</code>.</li>
<li>Скопируйте и выполните скрипт ниже. Он создаст <code>svc-bj</code> со случайным паролем и группы (или сообщит, что они уже есть) и в конце покажет итог и пароль.</li>
<li>Добавьте сотрудников в группы <code>bj-admins</code>, <code>bj-operators</code>, <code>bj-risk</code>, <code>bj-viewers</code> — по ним bj назначит роли (группы можно переназначить после подключения).</li>
<li>Здесь введите <code>svc-bj@<span class="ad-svc-dom">{{with $A.ADDomain}}{{.}}{{else}}ваш-домен{{end}}</span></code> и пароль — «Подключить».</li>
</ol>
<pre class="copyable" id="ad-svc-ps" style="white-space:pre;overflow:auto;font-size:12px"># Bridge&amp;Join: служебная учётная запись для чтения AD и группы ролей
# Запуск: PowerShell от имени администратора домена (контроллер домена или компьютер с RSAT).
Import-Module ActiveDirectory
$dom = Get-ADDomain # домен <span class="ad-svc-dom">{{with $A.ADDomain}}{{.}}{{else}}ваш-домен{{end}}</span>
$name = "svc-bj"
$ou = $dom.UsersContainer # или своё OU, например "OU=Service Accounts,$($dom.DistinguishedName)"
$pwd = Read-Host "Пароль для $name (длинный, случайный)" -AsSecureString
New-ADUser -Name $name -SamAccountName $name -UserPrincipalName "$name@$($dom.DNSRoot)" `
-Path $ou -AccountPassword $pwd -Enabled $true `
-PasswordNeverExpires $true -CannotChangePassword $true `
-Description "Bridge&amp;Join: чтение AD для входа пользователей (без прав администратора)"
# Группы, по которым bj назначает роли
@{ "bj-admins" = "администраторы bj"; "bj-operators" = "операторы депозитария";
"bj-risk" = "риск-менеджеры (НПР)"; "bj-viewers" = "наблюдатели" }.GetEnumerator() | ForEach-Object {
if (-not (Get-ADGroup -Filter "Name -eq '$($_.Key)'")) {
New-ADGroup -Name $_.Key -GroupScope Global -GroupCategory Security -Path $ou -Description "Bridge&amp;Join: $($_.Value)"
$dom = Get-ADDomain # домен <span class="ad-svc-dom">{{with $A.ADDomain}}{{.}}{{else}}ваш-домен{{end}}</span>
$name = "svc-bj"
$ou = $dom.UsersContainer # или своё OU, например "OU=Service Accounts,$($dom.DistinguishedName)"
$report = @()
# пароль — 24 случайных символа (буквы, цифры, знаки)
$chars = [char[]]'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!#%*+-=?@'
$rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
$bytes = New-Object byte[] 24; $rng.GetBytes($bytes)
$plain = -join ($bytes | ForEach-Object { $chars[$_ % $chars.Length] })
$user = Get-ADUser -Filter "SamAccountName -eq '$name'" -ErrorAction SilentlyContinue
if ($user) {
$report += "Пользователь $name уже есть: $($user.DistinguishedName) — пароль НЕ менялся"
$plain = $null
} else {
New-ADUser -Name $name -SamAccountName $name -UserPrincipalName "$name@$($dom.DNSRoot)" `
-Path $ou -AccountPassword (ConvertTo-SecureString $plain -AsPlainText -Force) -Enabled $true `
-PasswordNeverExpires $true -CannotChangePassword $true `
-Description "Bridge&amp;Join: чтение AD для входа пользователей (без прав администратора)"
$report += "Создан пользователь $name@$($dom.DNSRoot) в $ou"
}
# группы, по которым bj назначает роли
$groups = [ordered]@{ "bj-admins" = "администраторы bj"; "bj-operators" = "операторы депозитария";
"bj-risk" = "риск-менеджеры (НПР)"; "bj-viewers" = "наблюдатели" }
foreach ($g in $groups.Keys) {
$ex = Get-ADGroup -Filter "Name -eq '$g'" -ErrorAction SilentlyContinue
if ($ex) {
$report += "Группа $g уже есть: $($ex.DistinguishedName)"
} else {
New-ADGroup -Name $g -GroupScope Global -GroupCategory Security -Path $ou -Description "Bridge&amp;Join: $($groups[$g])"
$report += "Создана группа $g ($($groups[$g])) в $ou"
}
}
Write-Host "Готово. В bj: учётная запись $name@$($dom.DNSRoot)"</pre>
Write-Host ""
Write-Host "===== Bridge&amp;Join: итог =====" -ForegroundColor Cyan
$report | ForEach-Object { Write-Host " - $_" }
Write-Host ""
Write-Host "В bj (Пользователи и вход → Подключить домен):" -ForegroundColor Cyan
Write-Host " учётная запись: $name@$($dom.DNSRoot)"
if ($plain) {
Write-Host " пароль: $plain" -ForegroundColor Yellow
Write-Host " Скопируйте пароль в bj и закройте это окно — больше он нигде не показывается." -ForegroundColor Yellow
} else {
Write-Host " пароль: прежний (запись уже была). Новый: Set-ADAccountPassword $name -Reset"
}
Write-Host "Добавьте сотрудников в группы bj-* — по ним bj назначит роли."</pre>
<p class="muted" style="margin:6px 0 4px">Без модуля ActiveDirectory (cmd от администратора домена, <code>*</code> — запросит пароль):</p>
<pre class="copyable" id="ad-svc-cmd" style="white-space:pre;overflow:auto;font-size:12px">dsadd user "CN=svc-bj,CN=Users,<span class="ad-svc-dn">{{with $A.ADBaseDN}}{{.}}{{else}}DC=corp,DC=example,DC=ru{{end}}</span>" -samid svc-bj -upn svc-bj@<span class="ad-svc-dom">{{with $A.ADDomain}}{{.}}{{else}}ваш-домен{{end}}</span> -pwd * -pwdneverexpires yes -canchpwd no -desc "Bridge&amp;Join: чтение AD"</pre>
<p class="muted" style="margin:6px 0 0">Рекомендуем: запретить этой записи интерактивный вход и вход по RDP (групповая политика «Запретить локальный вход», «Запретить вход через службу удалённых рабочих столов») — она нужна только для чтения каталога. Пароль bj хранит у себя; при смене пароля в AD обновите его здесь.</p>