0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ずんだもん「ギャルも安心シリーズ!2台目のActive Directoryをさくっと昇格&FSMO移譲もできるスクリプトなのだ」

Last updated at Posted at 2025-06-16
Image 1 Image 2

ずんだもん「つむぎ、今日はActive Directoryの続編なのだ!まず2台目のWindows Serverを既存ドメインにメンバーサーバーとして参加させて、さらに追加のドメインコントローラー(DC)に昇格させるスクリプトを解説するのだ。」

つむぎ「おお!前回のAD一発構築の続きね!今度はサーバーをドメインに入れて、さらにDCにしちゃうとか、あーし的にはマジで便利じゃん!でも、ギャルでもできるかな?」

ずんだもん「もちろん大丈夫なのだ!2つのスクリプトに分かれているけど、順番にやれば誰でもできるのだ。」

スクリプトの全体構成

image.png

ずんだもん「今回は2つのスクリプトがセットになっているのだ。」

image.png

実行手順

ずんだもん「実際の実行手順を説明するのだ。」

Image 1 Image 2

ステップ1: ドメイン参加(スクリプト1)

  1. 管理者権限でPowerShellを起動

  2. Join-MemberServer-Interactive.ps1を実行

  3. コンピュータ名の変更(必要に応じて)

  4. 既存DCのIPアドレスを入力

  5. ネットワーク設定の確認・修正

  6. ドメイン管理者資格情報でドメイン参加

  7. 必要に応じて再起動

つむぎ「質問に答えていくだけだから、ギャルでも迷わず進められそう!」

ステップ2: DC昇格(スクリプト2)

  1. ドメイン参加後、同じサーバーで管理者権限PowerShellを起動

  2. Promote-AdditionalDC-Interactive.ps1を実行

  3. Active Directoryモジュールの自動インストール

  4. AD DS役割のインストール(Y/N確認)

  5. DC昇格処理(ドメイン名・DNS・資格情報入力)

  6. 再起動(Y/N確認)

  7. 再起動後、同スクリプトを再実行してFSMO移譲選択

  8. レプリケーション同期の実施

つむぎ「2段階に分かれてるのね!まずドメインに入って、それからDCに昇格するパターン。段階的だからギャルでも安心だわ~!」

ずんだもん「スクリプトは長いからこの記事の最後に書いてあるのだ!」

スクリプト1: メンバーサーバー参加スクリプトの流れと要点

ずんだもん「まずは1つ目のスクリプトから見ていくのだ。」

Image 1 Image 2

1. コンピュータ名の確認・変更

  • 現在のコンピュータ名をチェックして、必要なら新しい名前に変更できるのだ。
  • 変更した場合は再起動が必要で、その場で再起動するかも選択できるのだ。

image.png

つむぎ「ドメイン参加前に名前変えられるの便利!"GAL-DC2"とか付けたいわ~!」

2. ネットワーク構成の詳細チェック

  • 有効なネットワークアダプターを自動検出して一覧表示するのだ。
  • 現在のIP、サブネット、ゲートウェイ、DNSの詳細情報を表示するのだ。
  • DHCPが有効な場合は警告を出して、静的IPへの切り替えを案内するのだ。

image.png

つむぎ「DHCPのままだとドメイン参加で問題出るもんね!自動で教えてくれるの助かる~!」

3. 既存DCへの疎通・ポートチェック

  • 既存ドメインコントローラーのIPアドレスを入力してPing疎通をチェックするのだ。
  • ドメイン参加に必要な主要ポート(DNS、Kerberos、LDAP、SMBなど)の開放状況を自動確認するのだ。
  • ポートが閉じている場合は詳細なエラーメッセージで案内するのだ。

image.png

つむぎ「ポートチェックまでしてくれるとか神!ファイアウォールで詰むパターン多いから、事前に分かるの超ありがたい!」

4. DHCP→静的IP自動切り替え

  • DHCPが有効なアダプターを検出すると、自動で静的IP設定に切り替えられるのだ。
  • 現在のゲートウェイを使うか新規入力するか選択できるのだ。
  • DNSサーバーは必ず既存DCのIPで全NICを上書き設定するのだ。

image.png

つむぎ「DHCPから静的IPに自動で変わるとか、勝手に髪色変わるギャルアプリ並みに便利じゃん!」

5. ドメイン参加処理

  • DNS名前解決テストを実行してドメインの存在確認をするのだ。
  • 既にドメイン参加済みかチェックして、未参加の場合のみ参加処理を実行するのだ。
  • OUパス指定にも対応していて、特定のOUに配置することもできるのだ。

image.png

つむぎ「OUパス指定できるとか、組織的に使うときに便利じゃん!ギャル部門専用OUとか作りたいわ!」


スクリプト2: DC昇格スクリプトの流れと要点

Image 1 Image 2

ずんだもん「続いて2つ目のスクリプトを解説するのだ。これはドメイン参加済みサーバーを追加DCに昇格させるスクリプトなのだ。」

1. Active Directoryモジュールの自動インストール

  • RSAT(Active Directoryモジュール)のインポートを試行するのだ。
  • 見つからない場合は自動でRSAT-AD-PowerShellをインストールするのだ。
  • インストール後に再度インポートを試して、利用可能な状態にするのだ。

image.png

つむぎ「RSATの面倒なインストールも自動でやってくれるとか、マジで親切!手動だと忘れがちなやつよね~。」

2. 前提条件の自動チェック

  • ドメイン参加状態を確認して、未参加なら処理を停止するのだ。
  • OU=Domain Controllersの存在チェックも実行するのだ。(参考用)
  • 各チェックで問題があれば分かりやすいメッセージで案内するのだ。

image.png

3. AD DS役割のインストール

  • 既にインストール済みかチェックして、未インストールの場合のみ処理するのだ。
  • Y/N確認でユーザーの意思を確認してからインストールを実行するのだ。
  • 管理ツールも同時にインストールして、すぐに管理できる状態にするのだ。

image.png

つむぎ「済んでる工程はスキップしてくれるの便利!途中で止まっても再実行できるのは安心だわ~。」

4. ドメインコントローラー昇格

  • 既にDCかどうかをuserAccountControlで判定するのだ。
  • 未昇格の場合は対話式でドメイン名、DNS設定、管理者資格情報を入力するのだ。
  • Install-ADDSDomainControllerで既存ドメインに追加DCとして昇格するのだ。

image.png

image.png
(オレンジ色のエラーが出ますが、消せないので気にしないで下さい)

5. 再起動制御

  • DC昇格後は再起動が必要なので、Y/N確認で再起動タイミングを制御するのだ。
  • 再起動後にFSMO移譲のためスクリプト再実行を案内するのだ。
  • 自動再起動を避けて、ユーザーのタイミングで再起動できるのだ。

image.png

つむぎ「勝手に再起動されないの本当にありがたい!作業中断されると困るもんね。」

6. FSMO役割の移譲(進行状況表示付き)

  • 再起動したらスクリプトを再実行して、5つのFSMO役割(PDC、RID、Infrastructure、Schema、DomainNaming)を順次移譲するのだ。
  • 各役割の移譲進行状況を「[1/5]」形式で表示するのだ。
  • エラーが発生した場合は詳細なメッセージで停止するのだ。

image.png

つむぎ「進行状況見えるのいいね!どこまで進んでるか分からないと不安になっちゃう!」

7. レプリケーション案内

  • FSMO移譲後は他のDCでレプリケーション同期コマンドの実行を案内するのだ。
  • repadmin /syncall /Adeコマンドを具体的に表示するのだ。
  • レプリケーション完了の重要性を分かりやすく説明するのだ。

image.png

便利ポイントまとめ

ポイント ずんだもんの解説 つむぎのギャル語
2段階構成 ドメイン参加→DC昇格で段階的に進められるのだ。 「いきなり全部やるより安心!途中で止まっても大丈夫~」
ネットワーク自動設定 DHCP→静的IP切り替えも自動対応なのだ。 「設定ミスで詰むパターン回避できるの神!」
ポート疎通チェック 必要ポートの開放状況を事前確認するのだ。 「ファイアウォールで止まる前に分かるの助かる!」
FSMO移譲進行表示 5つの役割移譲を進行状況付きで表示するのだ。 「どこまで進んだか見えるから安心して待てる!」
工程スキップ機能 済んでる工程は自動でスキップするのだ。 「途中で止まっても再実行できるの便利!」
再起動制御 自動再起動せず、タイミングを選べるのだ。 「勝手に再起動されると予定狂うからNG!」

注意点とトラブルシューティング

ずんだもん「使う時の注意点も覚えておくのだ。」

Image 1 Image 2

実行前の準備

  • 管理者権限でのPowerShell実行が必須
  • 既存ドメインコントローラーが稼働していること
  • ネットワーク疎通が取れていること
  • ドメイン管理者アカウントの資格情報が必要

つむぎ「管理者権限忘れると動かないから要注意よ~!」

よくあるエラーパターン

  • ポートが閉じている: ファイアウォール設定を確認

  • DNS名前解決失敗: DNSサーバー設定を確認

  • 資格情報エラー: ドメイン管理者アカウントとパスワードを確認

  • FSMO移譲失敗: 再起動後に実行しているか確認

つむぎ「エラーメッセージが詳しく出るから、原因特定しやすそう!」

推奨環境

  • Windows Server 2022以降(2025 ARM対応)

  • 十分なメモリ(4GB以上推奨)

  • 安定したネットワーク接続

  • バックアップ取得済みの環境(Mac+Parallelsのスナップショットおすすめ)

確認用コマンド

ずんだもん「処理完了後の確認方法も教えるのだ。」

Image 1 Image 2
.ps1
# ドメイン参加状態と詳細情報
Write-Host "===== ドメイン参加状態と詳細情報 =====" -ForegroundColor Cyan
Get-WmiObject Win32_ComputerSystem | Select-Object Name, Domain, DomainRole, PartOfDomain, Workgroup, Model, Manufacturer, UserName | Format-List

# ネットワーク情報
Write-Host "`n===== NetSetupによる詳細情報 =====" -ForegroundColor Cyan
Get-WmiObject -Class Win32_NetworkAdapterConfiguration | Where-Object { $_.IPEnabled } | Select-Object Description, DNSDomain, DNSHostName, DHCPEnabled, IPAddress | Format-List

# ドメインコントローラー情報
Write-Host "`n===== ドメインコントローラー情報(PrimaryDC) =====" -ForegroundColor Cyan
try {
    Get-ADDomainController -Discover -Service "PrimaryDC" | Select-Object Name, HostName, IPv4Address, Site, IsGlobalCatalog | Format-List
} catch {
    Write-Host "Active Directoryモジュールが必要です。または権限が不足しています。" -ForegroundColor Yellow
}

image.png

つむぎ「設定完了後にちゃんと確認できるのも安心!結果が見えないと不安になっちゃうもん。」

ずんだもん「GUIだとこんな感じなのだ!」

image.png

まとめ

ずんだもん「この2つのスクリプトを使えば、Windows Server 2025 ARMでも既存ドメインへの参加から追加DC昇格、FSMO移譲まで多くが自動化できるのだ!」

つむぎ「ドメイン参加とDC昇格が段階的にできるから、ギャルでも安心して進められる!ネットワーク設定のチェックからFSMO移譲まで面倒みてくれてマジ卍!」

ずんだもん「2段階に分かれているから、途中で問題が起きても対処しやすいし、理解しながら進められるのがポイントなのだ」

つむぎ「拡張も設定も、ギャルの自撮りくらい盛大にキメちゃお!みんなも映えサーバー作ってワイワイやろ~☆」

利用キャラクター

  • ずんだもん:VOICEVOX:ずんだもん
  • つむぎ:PIXIV:りょうごさん
    本記事で使用しているキャラクター画像の著作権は、それぞれの権利者に帰属します。
    非商用目的での利用に基づき掲載しています。

スクリプト

スクリプト1: Join-MemberServer-Interactive.ps1

Join-MemberServer-Interactive.ps1
<#
    対話式でパラメータを入力し、Windows Server 2025 ARM上に
    既存Active Directoryドメインのメンバーサーバーとして参加します。
    事前にコンピュータ名・ネットワーク構成(静的IP・DNS)をチェックし、不備があれば案内します。
    DHCPが有効な場合は静的IP+DNSへの切り替えを自動で案内・実施します。
    デフォルトゲートウェイは「現在のものを使うか」選択でき、Nの場合は新規入力できます。
    ドメイン参加済み・ホスト名重複・DNS・時刻同期などの前提条件も自動で確認します。
    既存DCへのPing疎通・必要ポートの開放チェックも自動で行います。
    インストール後は自動再起動せず、ユーザーへ再起動を促します。
    ※管理者権限で実行してください。

    ※このスクリプトは「ドメインへの参加(メンバーサーバー化)」のみを行います。
#>

Write-Host "==== 既存ADドメインへのサーバー参加スクリプト(WS2025 ARM対応) ====" -ForegroundColor Cyan
Write-Host "このスクリプトは、対話式でパラメータを入力しながら、"
Write-Host "・コンピュータ名/ネットワーク構成(静的IP, DNS)/時刻同期のチェック"
Write-Host "・既存DCへのPing疎通&ADDS必要ポート開放チェック"
Write-Host "・DNSサーバー設定(必ず既存DCのIPで全NICを静的に上書き)"
Write-Host "・ドメイン参加(メンバーサーバー化)を行います。"
Write-Host ""
Write-Host "※管理者権限で実行してください。"
Write-Host ""

try {
    # --- コンピュータ名の確認 ---
    $currentName = (Get-ComputerInfo).CsName
    Write-Host "[現在のコンピュータ名] $currentName"
    $changeName = Read-Host "コンピュータ名を変更しますか? (Y/N)"
    if ($changeName -eq "Y" -or $changeName -eq "y") {
        $newName = Read-Host "新しいコンピュータ名を入力してください(15文字以内、英数字とハイフンのみ)"
        if ($newName -and $newName -ne $currentName) {
            try {
                Rename-Computer -NewName $newName -Force -ErrorAction Stop
                Write-Host "コンピュータ名を [$newName] に変更しました。再起動後に有効になります。" -ForegroundColor Green
                $rebootNow = Read-Host "今すぐ再起動しますか? (Y/N)"
                if ($rebootNow -eq "Y" -or $rebootNow -eq "y") {
                    Restart-Computer
                    exit
                } else {
                    Write-Host "再起動後、再度このスクリプトを実行してください。" -ForegroundColor Yellow
                    exit
                }
            } catch {
                Write-Host "コンピュータ名の変更に失敗しました: $($_.Exception.Message)" -ForegroundColor Red
                exit
            }
        } else {
            Write-Host "無効な名前、または同じ名前が指定されました。変更をスキップします。" -ForegroundColor Yellow
        }
    }

    # --- 現在のネットワーク情報の表示 ---
    Write-Host "`n[現在のネットワーク構成]"
    try {
        $ipconfigs = Get-NetIPConfiguration | Where-Object { $_.IPv4Address -and $_.NetAdapter.Status -eq "Up" }
        foreach ($nic in $ipconfigs) {
            $ip = $nic.IPv4Address.IPAddress
            $prefix = $nic.IPv4Address.PrefixLength
            $gw = if ($nic.IPv4DefaultGateway) { $nic.IPv4DefaultGateway.NextHop } else { "-" }
            $dns = if ($nic.DNSServer.ServerAddresses) { $nic.DNSServer.ServerAddresses -join ", " } else { "-" }
            Write-Host ("  アダプター: {0}`n    IP: {1}/{2}`n    ゲートウェイ: {3}`n    DNS: {4}" -f $nic.InterfaceAlias, $ip, $prefix, $gw, $dns)
        }
        Write-Host ""
    } catch {
        Write-Host "ネットワーク構成情報の取得に失敗しました: $($_.Exception.Message)" -ForegroundColor Red
        exit
    }

    # --- 有効なアダプター一覧取得 ---
    try {
        $adapters = Get-NetAdapter | Where-Object { $_.Status -eq "Up" }
        if (!$adapters -or $adapters.Count -eq 0) {
            Write-Host "有効なネットワークアダプターが見つかりません。ネットワーク接続を確認してください。" -ForegroundColor Red
            exit
        }
        Write-Host "有効なアダプター一覧:"
        $adapters | ForEach-Object { Write-Host "  [$($_.ifIndex)] $($_.Name)" }
    } catch {
        Write-Host "ネットワークアダプター情報の取得に失敗しました: $($_.Exception.Message)" -ForegroundColor Red
        exit
    }

    # --- 既存DCのIP入力と疎通・ポートチェック ---
    $existingDC = Read-Host "既存DC(DNSサーバー)のIPアドレスを入力してください。疎通チェックを行います。"
    $dnsIPs = $existingDC -split ","
    $targetDC = $dnsIPs[0]

    Write-Host "`n[既存DCへのPing疎通チェック]"
    try {
        if (Test-Connection -ComputerName $targetDC -Count 2 -Quiet) {
            Write-Host "Ping疎通成功: $targetDC に到達できます。" -ForegroundColor Green
        } else {
            Write-Host "Ping疎通失敗: $targetDC に到達できません。ネットワークやIPアドレスを確認してください。" -ForegroundColor Red
            exit
        }
    } catch {
        Write-Host "Pingチェック中にエラーが発生しました: $($_.Exception.Message)" -ForegroundColor Red
        exit
    }

    # --- 必要ポート開放チェック(ドメイン参加に必要なポートのみ) ---
    Write-Host "`n[ドメイン参加に必要なポート開放チェック]"
    $requiredPorts = @(
        @{Port=53;   Protocol="TCP"; Name="DNS (TCP)"},
        @{Port=53;   Protocol="UDP"; Name="DNS (UDP)"},
        @{Port=88;   Protocol="TCP"; Name="Kerberos (TCP)"},
        @{Port=88;   Protocol="UDP"; Name="Kerberos (UDP)"},
        @{Port=135;  Protocol="TCP"; Name="RPC Endpoint Mapper"},
        @{Port=389;  Protocol="TCP"; Name="LDAP (TCP)"},
        @{Port=389;  Protocol="UDP"; Name="LDAP (UDP)"},
        @{Port=445;  Protocol="TCP"; Name="SMB (TCP)"}
    )
    $allPortsOK = $true
    foreach ($port in $requiredPorts) {
        try {
            $test = Test-NetConnection -ComputerName $targetDC -Port $port.Port -InformationLevel Quiet -WarningAction SilentlyContinue
            if ($test) {
                Write-Host "[$($port.Name)] $($port.Protocol)/$($port.Port) ... OK" -ForegroundColor Green
            } else {
                Write-Host "[$($port.Name)] $($port.Protocol)/$($port.Port) ... NG" -ForegroundColor Red
                $allPortsOK = $false
            }
        } catch {
            Write-Host "[$($port.Name)] $($port.Protocol)/$($port.Port) ... チェック中にエラー: $($_.Exception.Message)" -ForegroundColor Red
            $allPortsOK = $false
        }
    }
    if (-not $allPortsOK) {
        Write-Host "ドメイン参加に必要なポートが閉じています。ファイアウォールやNW設定を確認してください。" -ForegroundColor Red
        exit
    } else {
        Write-Host "ドメイン参加に必要なポートはすべて開放されています。" -ForegroundColor Green
    }

    # --- DHCP有効かチェックし、静的IP+DNSへ自動切り替え ---
    foreach ($adapter in $adapters) {
        try {
            $ipv4 = Get-NetIPInterface -InterfaceIndex $adapter.ifIndex -AddressFamily IPv4
            if ($ipv4.Dhcp -eq "Enabled") {
                Write-Host "`n[$($adapter.Name)] はDHCP有効です。静的IP+DNSに切り替えます。" -ForegroundColor Yellow
                $curIP = (Get-NetIPAddress -InterfaceIndex $adapter.ifIndex -AddressFamily IPv4 | Where-Object { $_.IPAddress -notlike "169.*" })
                if (!$curIP) {
                    Write-Host "  現在のIPアドレスが取得できません。手動で設定してください。" -ForegroundColor Red
                    exit
                }
                $newIP = Read-Host "  [$($adapter.Name)] 設定するIPv4アドレス(例: $($curIP.IPAddress))"
                $prefix = $curIP.PrefixLength
                $gateway = (Get-NetIPConfiguration -InterfaceIndex $adapter.ifIndex).Ipv4DefaultGateway.NextHop
                $useCurrentGW = Read-Host "  [$($adapter.Name)] 現在のデフォルトゲートウェイ [$gateway] を使いますか? (Y/N)"
                if ($useCurrentGW -eq "Y" -or $useCurrentGW -eq "y" -or [string]::IsNullOrWhiteSpace($useCurrentGW)) {
                    $newGW = $gateway
                } else {
                    $newGW = Read-Host "  [$($adapter.Name)] 新しいデフォルトゲートウェイを入力してください"
                }
                # 既存IP削除
                $allCurIPs = Get-NetIPAddress -InterfaceIndex $adapter.ifIndex -AddressFamily IPv4
                foreach ($ip in $allCurIPs) {
                    Remove-NetIPAddress -InterfaceIndex $adapter.ifIndex -IPAddress $ip.IPAddress -Confirm:$false -ErrorAction SilentlyContinue
                }
                # 静的IP+GW設定
                New-NetIPAddress -InterfaceIndex $adapter.ifIndex -IPAddress $newIP -PrefixLength $prefix -DefaultGateway $newGW -ErrorAction Stop
                Write-Host "  静的IP/GWを設定しました。" -ForegroundColor Green
            } else {
                Write-Host "`n[$($adapter.Name)] は既に静的IPです。" -ForegroundColor Green
            }
            # DNSサーバーを必ず上書き
            Set-DnsClientServerAddress -InterfaceIndex $adapter.ifIndex -ServerAddresses $dnsIPs -ErrorAction Stop
            Write-Host "  [$($adapter.Name)] のDNSサーバーを $($dnsIPs -join ', ') に設定しました。" -ForegroundColor Green
        } catch {
            Write-Host "  [$($adapter.Name)] のネットワーク設定でエラー: $($_.Exception.Message)" -ForegroundColor Red
            exit
        }
    }

    # --- DNS名前解決テスト(Resolve-DnsName推奨) ---
    $domainForTest = Read-Host "この後参加する予定のドメイン名を入力してください(例: example.local)"
    try {
        $resolveResult = Resolve-DnsName $domainForTest -ErrorAction Stop
        if ($resolveResult) {
            Write-Host "DNS名前解決に成功しました。" -ForegroundColor Green
        } else {
            Write-Host "DNS名前解決に失敗しました。DNS設定や既存DCの稼働状況を確認してください。" -ForegroundColor Red
            exit
        }
    } catch {
        Write-Host "DNS名前解決に失敗しました。DNS設定や既存DCの稼働状況を確認してください: $($_.Exception.Message)" -ForegroundColor Red
        exit
    }

    # --- ドメイン参加済みか確認 ---
    try {
        $domainRole = (Get-WmiObject Win32_ComputerSystem).PartOfDomain
    } catch {
        Write-Host "ドメイン参加状態の取得に失敗しました: $($_.Exception.Message)" -ForegroundColor Red
        exit
    }

    if (-not $domainRole) {
        $ouPath = Read-Host "OUパスを指定する場合は入力(例: OU=Servers,DC=example,DC=local、省略可)"
        try {
            $credential = Get-Credential -Message "ドメイン管理者の資格情報を入力してください"
            if ([string]::IsNullOrWhiteSpace($ouPath)) {
                Add-Computer -DomainName $domainForTest -Credential $credential -Force -ErrorAction Stop
            } else {
                Add-Computer -DomainName $domainForTest -Credential $credential -OUPath $ouPath -Force -ErrorAction Stop
            }
            Write-Host "ドメイン参加が完了しました。再起動してください。" -ForegroundColor Yellow
            exit
        } catch {
            Write-Host "ドメイン参加処理中にエラーが発生しました: $($_.Exception.Message)" -ForegroundColor Red
            exit
        }
    } else {
        Write-Host "このサーバーはすでにドメインに参加しています。" -ForegroundColor Green
    }

    Write-Host "すべての処理が完了しました。" -ForegroundColor Green
    Pause
    exit
}
catch {
    Write-Host "スクリプト全体で予期しないエラーが発生しました: $($_.Exception.Message)" -ForegroundColor Red
    Pause
    exit
}

スクリプト2: Promote-AdditionalDC-Interactive.ps1

Promote-AdditionalDC-Interactive.ps1
<#
    ドメイン参加済みサーバー向け
    Windows Server専用
    AD DS役割インストール~DC昇格~再起動~FSMO移譲フルセットアップスクリプト
    ・RSAT(Active Directoryモジュール)自動インストール
    ・OU=Domain Controllers存在チェック
    ・各処理ごとにY/Nで確認(済みの工程は自動スキップ)
    ・FSMO移譲は役割ごとに進行状況を表示
    ・再起動制御付き
    ※管理者権限で実行してください
#>

function Write-Section {
    param([string]$title)
    Write-Host ""
    Write-Host ("".PadRight(60,"=")) -ForegroundColor Cyan
    Write-Host ("【" + $title + "】") -ForegroundColor Cyan
    Write-Host ("".PadRight(60,"=")) -ForegroundColor Cyan
    Write-Host ""
}

function Confirm-YN {
    param([string]$message)
    do {
        $ans = Read-Host "$message (Y/N)"
    } while ($ans -ne "Y" -and $ans -ne "y" -and $ans -ne "N" -and $ans -ne "n")
    return ($ans -eq "Y" -or $ans -eq "y")
}

Write-Host ""
Write-Host "==== AD DS役割インストール~DC昇格~再起動~FSMO移譲フルスクリプト(Windows Server専用) ====" -ForegroundColor Cyan
Write-Host "各処理ごとにY/Nで確認します(済みの工程は自動スキップ)。" -ForegroundColor Yellow
Write-Host ""

# --- 0. RSAT(Active Directoryモジュール)のインポートと自動インストール ---
Write-Section "Active Directoryモジュールのインポートと自動インストール"
$adModuleLoaded = $false

try {
    Import-Module ActiveDirectory -ErrorAction Stop
    $adModuleLoaded = $true
    Write-Host "Active Directoryモジュールをインポートしました。" -ForegroundColor Green
} catch {
    Write-Host "Active Directoryモジュールが見つかりません。自動インストールを試みます..." -ForegroundColor Yellow
    try {
        Install-WindowsFeature RSAT-AD-PowerShell -ErrorAction Stop
        Write-Host "RSAT-AD-PowerShell をインストールしました。" -ForegroundColor Green
        Import-Module ActiveDirectory -ErrorAction Stop
        $adModuleLoaded = $true
        Write-Host "Active Directoryモジュールをインポートしました。" -ForegroundColor Green
    } catch {
        Write-Host "Active Directoryモジュールのインストールまたはインポートに失敗しました。RSATがインストールされているか確認してください。" -ForegroundColor Red
        Pause
        exit
    }
}

if (-not $adModuleLoaded) {
    Write-Host "Active Directoryモジュールの利用準備ができません。スクリプトを終了します。" -ForegroundColor Red
    Pause
    exit
}

# --- 1. ドメイン参加状態の確認 ---
Write-Section "ドメイン参加状態の確認"
$domainRole = (Get-WmiObject Win32_ComputerSystem).PartOfDomain
if (-not $domainRole) {
    Write-Host "このサーバーはドメインに参加していません。事前にドメイン参加してください。" -ForegroundColor Red
    Pause
    exit
} else {
    Write-Host "ドメイン参加済みです。" -ForegroundColor Green
}

# --- 2. OU=Domain Controllers存在チェック(参考用。削除しても可) ---
Write-Section "OU=Domain Controllers存在チェック"
$DomainDN = $null
try {
    $DomainDN = (Get-ADDomain).DistinguishedName
    $DCouObj = Get-ADOrganizationalUnit -LDAPFilter '(ou=Domain Controllers)' -SearchBase $DomainDN -ErrorAction Stop
    $DCou = $DCouObj.DistinguishedName
    Write-Host "OU=Domain Controllersが存在します。" -ForegroundColor Green
} catch {
    Write-Host "OU=Domain Controllersがドメイン内に存在しません。新規ドメインの場合はこのエラーは無視して進めてください。" -ForegroundColor Yellow
}

# --- 3. AD DS役割のインストール ---
Write-Section "AD DS役割のインストール"
if ((Get-WindowsFeature -Name AD-Domain-Services).Installed) {
    Write-Host "AD DS役割は既にインストールされています。" -ForegroundColor Green
} else {
    if (Confirm-YN "AD DS役割をインストールしますか?") {
        Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools
        Write-Host "AD DS役割をインストールしました。" -ForegroundColor Green
    } else {
        Write-Host "AD DS役割インストールをスキップしました。" -ForegroundColor Yellow
    }
}

# --- 4. ドメインコントローラー昇格 ---
Write-Section "ドメインコントローラー昇格"
$isDC = $false
try {
    $ComputerObj = Get-ADComputer $env:COMPUTERNAME -Property userAccountControl
    if ($ComputerObj.userAccountControl -band 0x2000) { $isDC = $true }
} catch {
    $isDC = $false
}

if ($isDC) {
    Write-Host "このサーバーは既にドメインコントローラーです。" -ForegroundColor Green
} else {
    $dcPromote = Confirm-YN "このサーバーをドメインコントローラーに昇格しますか?"
    if ($dcPromote) {
        Import-Module ADDSDeployment
        $DomainName = Read-Host "昇格先ドメイン名を入力してください(例: example.local)"
        $InstallDNS = Read-Host "このDCにDNSサーバーもインストールしますか? (Y/N)"
        $InstallDNSFlag = if ($InstallDNS -eq "Y" -or $InstallDNS -eq "y") { $true } else { $false }
        $DomainAdminUser = Read-Host "ドメイン管理者アカウント(例: example\\Administrator)"
        $DSRMPassword = Read-Host "DSRMパスワードを入力してください" -AsSecureString

        Write-Host "このあと資格情報入力ウィンドウが開きます。" -ForegroundColor Yellow
        $credential = Get-Credential -UserName $DomainAdminUser -Message "ドメイン管理者資格情報"

        try {
            Install-ADDSDomainController `
                -DomainName $DomainName `
                -InstallDns:$InstallDNSFlag `
                -Credential $credential `
                -SafeModeAdministratorPassword $DSRMPassword `
                -NoRebootOnCompletion:$true
            Write-Host "ドメインコントローラーへの昇格が完了しました。" -ForegroundColor Green
            Write-Host "※DNS委任警告が出た場合、内部運用のみなら無視して問題ありません。" -ForegroundColor Yellow
        } catch {
            Write-Host "昇格処理でエラーが発生しました: $_" -ForegroundColor Red
            Pause
            exit
        }

        # --- 5. 再起動 ---
        Write-Section "再起動"
        if (Confirm-YN "ドメインコントローラー昇格後、再起動しますか?(FSMO移譲のため必須)") {
            Write-Host "再起動します。再起動後、このスクリプトを再度実行し、FSMO移譲を選択してください。" -ForegroundColor Yellow
            Pause
            Restart-Computer -Force
            exit
        } else {
            Write-Host "再起動をスキップしました。FSMO移譲は再起動後に実行してください。" -ForegroundColor Yellow
            exit
        }
    }
}

# --- 6. FSMO役割の移譲(進行状況表示付き) ---
Write-Section "FSMO役割の移譲"
$didFSMO = $false
if (Confirm-YN "FSMO全役割をこのサーバーに移譲しますか?(DC昇格・再起動済みが前提)") {
    $NewDCName = $env:COMPUTERNAME
    $roles = @(
        @{Name="PDCEmulator";Num=0},
        @{Name="RIDMaster";Num=1},
        @{Name="InfrastructureMaster";Num=2},
        @{Name="SchemaMaster";Num=3},
        @{Name="DomainNamingMaster";Num=4}
    )
    foreach ($idx in 0..($roles.Count-1)) {
        $role = $roles[$idx]
        Write-Host ("[" + ($idx+1) + "/5] " + $role.Name + " を移譲中...") -ForegroundColor Cyan
        try {
            Move-ADDirectoryServerOperationMasterRole `
                -Identity $NewDCName `
                -OperationMasterRole $role.Num `
                -Confirm:$false
            Write-Host ("[" + ($idx+1) + "/5] " + $role.Name + " の移譲が完了しました。") -ForegroundColor Green
        } catch {
            Write-Host ("[" + ($idx+1) + "/5] " + $role.Name + " の移譲でエラー: $_") -ForegroundColor Red
            Pause
            exit
        }
    }
    Write-Host "全FSMO役割の移譲が完了しました。" -ForegroundColor Green
    $didFSMO = $true
} else {
    Write-Host "FSMO移譲はスキップしました。" -ForegroundColor Yellow
}

# --- 7. FSMO役割の確認 ---
Write-Section "FSMO役割の現在の所有者"
Get-ADDomain | fl PDCEmulator,RIDMaster,InfrastructureMaster
Get-ADForest | fl SchemaMaster,DomainNamingMaster

# --- 8. レプリケーション即時実行の案内メッセージ ---
if ($didFSMO) {
    Write-Host ""
    Write-Host "【重要】FSMO移譲後は、DC1など他のドメインコントローラーで" -ForegroundColor Yellow
    Write-Host "  repadmin /syncall /Ade" -ForegroundColor Cyan
    Write-Host "を実行し、ADレプリケーションを即時反映させてください。" -ForegroundColor Yellow
    Write-Host "レプリケーションが完了すると、すべてのDCでFSMO所有者情報が最新になります。" -ForegroundColor Yellow
    Write-Host ""
}

Write-Host "すべての処理が完了しました。" -ForegroundColor Green
Pause
exit

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?