コマンド集 / Windows Server / AD

Windows Server / AD コマンド集

Windows Server 2025 のドメインコントローラーで、複製・FSMO・DNS・GPO・アカウント・Kerberos・時刻同期・DSRM・LAPS/gMSA を確認・操作するコマンドを、日本語ロケール特有の罠つきで引ける。

Proxmox 上の Windows Server 2025 評価版で建てたフォレスト ad.lab.example.jp(DC 2 台、dc01 / dc02)向け。DC は日本語ロケールなので、英語の出力文字列で判定せず終了コードかオブジェクトで見るのがこの環境の大前提。

DC の健全性を見る#

dcdiag#

DC の総合診断。成功は終了コード 0。

dcdiag
dcdiag /test:advertising; $LASTEXITCODE
dcdiag /test:dns

⚠️ passed test Advertising の文字列で照合すると、日本語ロケールでは正常なのに「失敗」と報告する。$LASTEXITCODE を見る

複製の要約#

失敗数と最終成功時刻を DC ごとに出す。締める・止める・再起動の前後で必ず取る。

repadmin /replsummary
repadmin /showrepl

⚠️ repadmin /showrepl /csv | ConvertFrom-Csv は列名が日本語になって空を返す。機械判定にはコマンドレットを使う。

複製の失敗をオブジェクトで取る#

プロパティ名は言語に依存しないので、スクリプトからはこちら。

Get-ADReplicationFailure -Target <DC名>
Get-ADReplicationPartnerMetadata -Target <DC名> | Select-Object Partner,LastReplicationSuccess,LastReplicationResult

サービスが本当に上がっているか#

「昇格したのに LDAP が開かない」の真因が「再起動していなかった」だった実例あり。症状より先にここを見る。

Get-Service NTDS,DNS,Netlogon,KDC,himds | Select-Object Name,Status,StartType
Get-ADDomainController -Discover | Select-Object HostName,Site

⚠️ Install-ADDSForest 完了後も再起動するまで DC ではない(DomainRole=3 のまま)。DNS が SOA を返すことを DC 化の根拠にしない。

FSMO#

保持者を見る#

netdom query fsmo
Get-ADForest | Select-Object SchemaMaster,DomainNamingMaster
Get-ADDomain | Select-Object PDCEmulator,RIDMaster,InfrastructureMaster

役割を移す#

DC を退役させるときは降格の前に移す。VM を消しただけだと seize とメタデータクリーンアップが要り、複製が壊れる。

Move-ADDirectoryServerOperationMasterRole -Identity <移行先DC> -OperationMasterRole PDCEmulator,RIDMaster,InfrastructureMaster,SchemaMaster,DomainNamingMaster

⚠️ PDC を移したら 時刻源(w32tm)の設定も一緒に移す。設定はサーバーに紐づくので、役割だけ移すと新 PDC が Local CMOS Clock に戻る。

DC 上の DNS#

フォワーダーと委任#

DC の DNS は上流(このラボでは Technitium)へ転送し、親ゾーン側からは ad の NS 委任で受ける。条件付き転送は使わない。

Get-DnsServerForwarder
Set-DnsServerForwarder -IPAddress <DNS1のIP>,<DNS2のIP>
Get-DnsServerZone
Get-DnsServerResourceRecord -ZoneName ad.lab.example.jp -RRType SRV | Select-Object -First 10

引けるか確かめる#

Resolve-DnsName -Name _ldap._tcp.dc._msdcs.ad.lab.example.jp -Type SRV
Resolve-DnsName -Name <外部の名前> -Server <DNSサーバーのIP>
nslookup -type=SOA ad.lab.example.jp

GPO#

適用と結果#

gpupdate /force
gpresult /r
gpresult /h C:\Windows\Temp\gpresult.html

⚠️ gpupdate /force と結果の読み取りは別の実行に分ける。1 回のスクリプトを長くするとゲストエージェントが詰まる。

一覧・レポート・リンク#

Get-GPO -All | Select-Object DisplayName,GpoStatus,ModificationTime
Get-GPOReport -Name "<GPO名>" -ReportType Html -Path C:\Windows\Temp\gpo.html
Get-GPInheritance -Target "OU=Domain Controllers,DC=ad,DC=lab,DC=example,DC=jp"

リンクする・外す#

戻すときはまずリンクを外す。スナップショットは最後の手段(AD は巻き戻すと複製の整合性に影響しうる)。

New-GPLink -Name "<GPO名>" -Target "<OUのDN>" -Order 1
Remove-GPLink -Name "<GPO名>" -Target "<OUのDN>"

⚠️ リンク順の数字が小さいほど強い。名前の番号は読みやすさのためで、優先順位はリンク順。override は必ず上に置く。

ベースラインを取り込む#

Microsoft のベースライン GPO は編集しない。差分は別 GPO に置きリンク順で上書きし、新版は「新しく取り込んで古い版のリンクを外す」。

Import-GPO -BackupGpoName "<バックアップ名>" -Path "<展開したzipのGPOsフォルダ>" -TargetName "<GPO名>" -CreateIfNeeded

⚠️ VM では Credential Guard / VBS 系のベースラインはリンクしない(入れ子仮想化が要り、起動不能もありうる)。同じ役割の GPO(Domain Security など)を 2 つ入れない。

レジストリ値を GPO に書く#

ADMX に無い設定もこれで入る。

Set-GPRegistryValue -Name "<GPO名>" -Key "HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Directory Service" -ValueName MaxSize -Type DWord -Value 134217728

⚠️ Security/System/Application は HKLM\SOFTWARE\Policies\...\EventLog\<log>\MaxSizeKB)、Directory Service などは HKLM\SYSTEM\...\Services\EventLog\<log>\MaxSizeバイト)。場所と単位が違う。

イベントログのサイズを今すぐ効かせる#

イベントログサービスは起動時にしか GPO を読まない。再起動を待たずに反映するには併用する。

wevtutil sl "Security" /ms:536870912
wevtutil sl "Directory Service" /ms:134217728
wevtutil gl "Directory Service"

⚠️ Directory Service の既定は 1 MB で、複製の診断ログがすぐ上書きされる。「設定した」と「効いている」を wevtutil gl で分けて確認する。

GPP(基本設定)が黙って失敗するとき#

CSE は Error suppressed. で握り潰す。gpresult は適用済みと出るのに項目だけ効かないときはトレースを取る。

$k = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{<CSEのGUID>}"
New-Item -Path $k -Force | Out-Null
Set-ItemProperty -Path $k -Name "TraceLevel" -Value 2 -Type DWord
Set-ItemProperty -Path $k -Name "TraceFileMaxSize" -Value 2048 -Type DWord
Set-ItemProperty -Path $k -Name "TraceFilePathMachine" -Value "C:\Windows\Temp\gpp.log" -Type String
Set-ItemProperty -Path $k -Name "LogLevel" -Value 3 -Type DWord

⚠️ トレースのキーは 3 箇所紛らわしく、効くのは HKLM\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{CSE} だけ。「トレースが出ない」を「CSE が処理していない」と誤読しない。

ユーザーとコンピューター#

検索する#

Get-ADUser -Filter * -SearchBase "OU=Users,OU=Example,DC=ad,DC=lab,DC=example,DC=jp" | Select-Object SamAccountName,Enabled
Get-ADComputer -Filter * | Select-Object Name,OperatingSystem,LastLogonDate
dsquery user -samid <アカウント名>
Search-ADAccount -LockedOut

⚠️ Get-ADUser -Identity は対象が無いとき終了エラーを投げる。-ErrorAction SilentlyContinue では抑えられず、try { } catch { } が要る。

作る・消す・ロック解除#

New-ADUser -Name "<名前>" -SamAccountName "<アカウント名>" -AccountPassword $sec -Enabled $true
Remove-ADUser -Identity "<アカウント名>" -Confirm:$false
Unlock-ADAccount -Identity "<アカウント名>"

⚠️ ロックアウトしきい値を入れる前に、使わない break-glass 管理者を別に作り、自動化用アカウントを Administrator から分ける。自動化の認証失敗で管理者が固まる。

Kerberos とイベントログ#

チケットを見る・消す#

klist
klist purge

⚠️ Kerberos は5 分の時刻ずれで止まる。認証が一斉に落ちたら先に時刻を疑う。

ログオン失敗・ロックアウト・複製#

Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625} -MaxEvents 20
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4740} -MaxEvents 20
Get-WinEvent -LogName "Directory Service" -MaxEvents 50
Get-WinEvent -FilterHashtable @{LogName='System'; Id=7034} -MaxEvents 20

⚠️ 7034(サービスの異常終了)は再起動直後のレースで出る。MSA / gMSA で動くサービスは遅延自動起動+回復動作をセットで確認する。

時刻同期(w32tm)#

状態を見る#

PDC の「ソース」が Local CMOS Clock なら、VM の仮想クロック任せで補正されない。

w32tm /query /status
w32tm /query /source
w32tm /stripchart /computer:time.cloudflare.com /samples:3

PDC を外部 NTP に向ける#

PDC はドメイン全体の時刻の源なので、上位を持たせる。/reliable:yes は「信頼できる時刻源」の宣言。

w32tm /config /manualpeerlist:"time.windows.com,0x8 time.cloudflare.com,0x8" /syncfromflags:manual /reliable:yes /update
Restart-Service w32time -Force
w32tm /resync /rediscover

⚠️ 追加 DC は NT5DS(ドメイン階層)のままにする。UDP 123 が届かない NTP サーバーは /stripchart がタイムアウト(0x800705B4)になる。

DSRM パスワード#

非対話で変える#

reset password on server null は対話入力しか受けず、自動化すると 0x57 で落ちる。ドメインアカウントから同期する形なら通る。

New-ADUser -Name "svc-dsrm" -SamAccountName "svc-dsrm" -AccountPassword $sec -Enabled $true
cmd.exe /c "ntdsutil ""set dsrm password"" ""sync from domain account svc-dsrm"" q q"
Remove-ADUser -Identity "svc-dsrm" -Confirm:$false

⚠️ 同期はその時点の値を写すだけなので、直後にアカウントを消しても DSRM は新しい値のまま。DSRM はドメイン認証には使えない。

LAPS / gMSA#

Windows LAPS#

Server 2025 に標準搭載。ローカル管理者パスワードの使い回しを消せる。

Update-LapsADSchema
Set-LapsADComputerSelfPermission -Identity "<OUのDN>"
Get-LapsADPassword -Identity <コンピューター名> -AsPlainText

gMSA / MSA#

サービスアカウントの作成と、対象機での検証。

New-ADServiceAccount -Name <名前> -DNSHostName <名前>.ad.lab.example.jp -PrincipalsAllowedToRetrieveManagedPassword <コンピューター名>$
Install-ADServiceAccount -Identity <名前>
Test-ADServiceAccount -Identity <名前>

MSA で動くサービスの回復動作#

起動直後のドメイン認証レースで落ちたまま誰も起こさない、を防ぐ。

sc.exe failure <サービス名> reset= 86400 actions= restart/60000/restart/60000/restart/60000
sc.exe config <サービス名> start= delayed-auto

そのほか#

OpenSSH サーバー#

Server 2022 では手動で入れる。2025 以降は既定で導入済み。

Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Set-Service -Name sshd -StartupType Automatic; Start-Service sshd
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 -Profile Any

⚠️ 自動生成のルール名は OpenSSH-Server-In-TCP、手動は指定名。締めるとき取り違えない。