PowerShell FrameworkでActive Directoryのヘルスチェック

Active Directoryヘルスチェックの2部シリーズのパートIIです。この記事で紹介されるPowerShellスクリプトの作成方法に興味がある場合、「アクティブディレクトリヘルスチェックツールの構築[詳細]: パートI」を参照することをお勧めします。

パートIでは、さまざまな重要なテストとその重要性について学びました。それでは、これらをまとめてツールを作成しましょう。このパートでは、パートIで説明したすべてのActive Directoryヘルスチェックをテストフレームワークに変換します。また、PesterやPRTGといったツールに対してさまざまなADヘルスチェックの結果を出力する方法も学びます。

この記事で学ぶツールの完成版を表示するか、この記事で学ぶツールの完成版を表示するか、GitHubからADHealthCheck-NoResult.ps1スクリプトをダウンロードしてください。

出力の定義

共通のオブジェクトタイプと、それを生成する簡単な方法を持っていることは、テスト結果を選択したツールに変換するのを容易にします。

すべての潜在的なツールに対して一貫した出力を作成するために、PowerShellクラスを使用することにしました。必須ではありませんが、ここではこのアプローチを選択しました。重要な点は、すべてのADヘルスチェックが同じタイプの出力を返すことを確認することです。

A PowerShell class is a schema that defines how a PowerShell object should look and what it should do. Each line you see below represents a property the objects return will have. You can see below I’m planning on each AD health check to return ten properties.

Class AdhcResult {
    [string]$Source
    [string]$TestName
    [bool]$Pass
    $Was
    $ShouldBe
    [string]$Category
    [string]$SubCategory
    [string]$Message
    $Data
    [string[]]$Tags
}

このクラスの作成を迅速化するために、New-AdhcResultというヘルパー関数を使用します。この関数はクラスを作成し、必要なすべてのものを用意します。この関数はカスタムの[AdhcResult]型オブジェクトを出力します。

AD Health Checkツールの実行

まず、AD health checkスクリプトをドメインコントローラにダウンロードしてコピーします。PowerShell ISEで開き、実行します。このツールのこの部分では、情報は返されません。

このスクリプトは実行され、各チェックの結果が複数の[AdhcResult]オブジェクトとして$TestResults変数に格納されます。これらのオブジェクトは後でレポートの生成やさまざまなツールへの出力に使用します。このように健康チェック結果を変数に保持することで、別の結果を追加してNew-AdHcResultコマンドを使用することができます。

スクリプトの実行が終了すると、$TestResults変数に完全なAD Health Checkオブジェクトセットが格納されます。コンソールから$TestResultsを実行すると、生の結果が表示されます。

ツールでのAD Health Check結果の表示

すべてのチェックは共通のオブジェクト型であるため、PesterやPRTGなどのツールを使用してより詳細に検査することができます。

このセクションでは、extentというツールを使用してHTMLレポートを作成し、PRTGでレポートを表示する方法を学びます。

Pesterを使用してnUnit XMLファイルを作成する

最初に、ツールが理解できる形式にPowerShellオブジェクトを変換する必要があります。多くのツールはXML、特にnUnit XMLを理解します。これは、結果を表示するためにさまざまなツールにインポートできる形式です。

PowerShellを使用しているため、ADヘルスチェックスクリプトの出力を読み取り、nUnit XMLファイルを生成するためにPesterテストフレームワークを使用します。

まず、最新バージョンのPesterをダウンロードします。管理者権限のPowerShellコンソールでInstall-Moduleを実行してPesterをダウンロードできます。以下のコマンドは、最新のPesterバージョンを強制的にインストールします。Pesterに署名されている発行者証明書はWindows 10に付属しているため、SkipPublisherCheckパラメータを使用する必要があります。

PS51> Install-Module Pester -Force -Verbose -SkipPublisherCheck

Pesterが利用可能になったら、スクリプトを実行して動的にPesterテストのセットを作成できます。

注意:提供されたPowerShellスクリプトを使用せずに、自分でPesterテストを作成することもできます。

以下のPowerShellスクリプトでは、ADHealthCheck-NoResult.ps1スクリプトで定義された$TestResults変数の出力から、Pesterを使用してnUnit XMLファイルを生成します。

Pester.ps1という名前でファイルを保存し、ADヘルスチェックスクリプトと同じフォルダに保存してください。

# ADHealthCheckファイルでドットソースを使用
. $PSScriptRoot\ADHealthCheck-NoResult.ps1
$Grouped = $TestResults | Group-Object Category

Foreach($Category in $Grouped) {
    Describe -Name $Category.Name -Tags ($Category.Group.Tags | Select -Unique) {
        Foreach($Result in $Category.Group){
            Context "$($Result.Source) - $($Result.TestName)" {
                It -Name "Should've passed" {
                    $Result.Pass | Should -Be -ExpectedValue $True -Because $Result.data
                }
            }
        }
    }
}

最後に、以下のコードInvoke-Pesterを実行して、Pester.ps1ファイルを呼び出し、結果をNUnitXml形式で保存します。

PS51 > Invoke-Pester -Script @{Path = '.\Pester.ps1'} -OutputFile .\NunitReport.xml -OutputFormat NUnitXml

Extentツールを使用してHTMLレポートを作成する

NUnit XMLファイルを使用してHTMLに変換できるツールを使用します。そのうちの1つがextentと呼ばれるツールです。ExtentはNunit XMLファイルからHTMLレポートを作成するのに便利なツールです。

まず、extentを以前に作成したNunitReport.xmlファイルと同じディレクトリにダウンロードします。その後、PowerShellセッションで以下のコマンドを実行します。これにより、HTMLファイルを保存するディレクトリが作成され、extent.exeが変換を行います。

# レポートディレクトリを作成
PS51> mkdir .\HTMLReports

# レポートを作成
PS51> .\extent.exe -i .\NunitReport.xml -o .\HTMLReports\

完了すると、HTMLReportsディレクトリに2つのHTMLファイルが見つかります。これらのファイルをWebブラウザで開くと、以下のスクリーンショットのように表示されます。

HTML report for Pester test output
HTML report for Pester test output

PRTGへのADヘルスチェック結果の取り込み

PRTGは、Paesslerが開発した人気のあるモニタリングツールで、インフラストラクチャやサービスを監視するために使用することができます。このセクションでは、ヘルスチェックスクリプトの実行後にヘルスチェック結果をPRTGに送信する方法について学びます。

結果をPRTGに送信するには、ツールが情報を取得するのではなく、より多くの作業が必要ですが、時間をかけてセットアップを行う価値があることがわかります。

前提条件

この記事で作成されたADヘルスチェックスクリプトを監視ツールとして設定するために、以下の条件を満たしてください:

  • PRTGがインストールおよび設定されていること
  • PRTGにすべてのドメインコントローラが設定されていること
  • GitHubからダウンロードしたSend-AdhcResultToPrtg.ps1 PowerShellスクリプト
  • あなたのPRTGセンサーのURLとポート

上記の前提条件を満たしている場合は、以下のステップバイステップの手順に従ってADヘルスチェックの結果をPRTGに送信する方法をおすすめします。

  1. PRTGでドメインまたは好きな名前のデバイスを作成します。
  2. Advanced HTTP pushセンサーIdentityTokenとしてdirectory-adhealthcheckという名前で作成します。なお、これは大文字と小文字を区別します!
  3. PRTGの各ドメインコントローラデバイスについて、Advanced HTTP pushセンサーを1つ作成します。各IdentityTokenについて、-adhealthcheckをセンサーに追加します。たとえば、dc01-adhealthcheckなどです。
  4. Send-AdhcResultToPrtg.ps1の内容をADHealthCheck-NoResult.ps1のPowerShellスクリプトの末尾に追加します。
  5. $PRTGUrl変数をPRTGセンサーのURLとポートに変更します。
  6. スクリプトを実行します。

完了したら、ADヘルスチェックスクリプトが完了したら、以下のようにステータスをPRTGセンサーにプッシュするはずです。

PRTG sensors showing AD health

Active Directoryヘルスチェックスクリプトのスケジュール

ADのヘルスチェックは継続的なプロセスです。アドホックなインスタンスではなく、常にテストを実行する必要があります。頻繁な間隔でActive Directoryヘルスチェックスクリプトをスケジュール実行しましょう。

これらのチェックを自動化する最も簡単な方法は、スクリプトをタスクスケジューラに追加し、ADユーザーアカウントまたはグループ管理サービスアカウントの下で実行させることです。

グループ管理サービスアカウント(gMSA)を使用すると、指定されたコンピューターアカウントのみがADからパスワードを取得できるため、スケジュールされたタスクを自律的に実行することができます。ただし、一部の組織ではこの利点を持っていない場合もあります。

ADユーザーアカウントの作成

まず、スケジュールされたタスクを実行するためにADユーザーアカウントのセットアップに必要な手順を見てみましょう。

スケジュールされたタスクをユーザーアカウントとして実行する場合は、自分自身のアカウントでは実行しないでください! この目的のためには常に別のユーザーアカウントを作成してください。

時間を節約するために、以下にPowerShellスクリプトが表示されます。これは、Domain Adminsグループの一部であるADユーザーアカウントを作成するための例のスクリプトです。 これを使用してスケジュールされたタスクを実行するためのアカウントを作成できます。

# サービスアカウントのOUに変更してください
$OU = "OU=Service Accounts,DC=contoso,DC=com"
# アカウントに使用するパスワードに変更してください
$Password = "JägareTvå"
$SecureString = $Password | ConvertTo-SecureString -AsPlainText -Force
New-ADUser -Enabled $True -Path $OU -Name svcADHealthCheck -AccountPassword $SecureString
# アカウントをドメインコントローラーのみに制限します
$DomainControllers = (Get-ADDomainController -Filter *).Name

Set-ADAccount -Identity svcADHealthCheck -LogonWorkstations ($DomainControllers -Join ",")

# ドメイン管理者に設定します(申し訳ありません)
Add-ADGroupMember -Identity "Domain Admins" -Members svcADHealthCheck

グループ管理サービスアカウントの作成

環境で既にgMSAを使用していない場合、ADのヘルスチェックを実行するためにgMSAを使用することは少し複雑ですが、セキュリティ面でははるかに安全です。

KDSルートキーの作成

ADヘルスチェックスクリプトを実行するためのgMSAアカウントを作成するには、まずKDSルートキーを追加します。すでにKDSルートキーがあるかどうかは、ドメインコントローラーでPowerShellコマンドGet-KDSRootKeyを実行して確認できます。

KDSルートキーがない場合は、2012R2以降のドメインコントローラーで、ドメイン管理者ADグループに属するユーザーアカウントでAdd-KDSRootKey -EffectiveImmediately を実行して作成します。

キーは他のドメインコントローラーにレプリケートする必要があります。このプロセスの詳細については、Microsoftのドキュメントを参照してください。

gMSAの作成

KDSルートキーが作成されたら、PowerShellを使用してgMSAアカウントを作成する準備が整います。以下に、ドメインコントローラーからの認証のみを許可されたgMSAアカウントを作成するために使用する例のスクリプトがあります。

# ドメインを変更してください
$Domain = "contoso.com"

$AccountName = "svcadhealthcheck"

# svcadhealthcheck(実際はsvcadhealthcheck$)という名前のGMSAを作成し、パスワードの取得をドメインコントローラーのみに制限します
New-ADServiceAccount $AccountName -DNSHostName "$AccountName.$Domain" –PrincipalsAllowedToRetrieveManagedPassword "Domain Controllers"

# GMSAをDomain Adminsに追加する
# アカウントの真のSamAccountName 'svcadhealthcheck$' で追加していることに注意してください
Add-ADGroupMember -Identity "Domain Admins" -Members "$AccountName`$"

gMSAのインストールとテスト

今、gMSAが作成されたので、最後のステップはすべてのドメインコントローラにインストールしてテストすることです。これを行う方法の一つは、Invoke-Command PowerShellコマンドを使用することです。以下は、gMSAをすべてのDCにインストールし、正常に動作することを確認するためのPowerShellスクリプトです。

# これはすべてのドメインコントローラで実行されます
Invoke-Command -ComputerName (Get-ADDomainController -Filter *).Name -ScriptBlock {
    $Account = Get-ADServiceAccount -Filter { Name -eq 'svcadhealthcheck'}
    Install-ADServiceAccount $Account

    # コンピュータ上でGMSAが動作するかをテストします
    # テストがOKの場合、$Trueを返します
    $Test = Test-ADServiceAccount -Identity $Account.Name
    if($Test){
        Write-Output "GMSA test OK on $env:computername"
    }
    else {
        Write-Output "GMSA test FAILED on $env:computername"
    }

}

gMSAにバッチジョブとして実行する権限を与える

gMSAがインストールされたら、バックグラウンドでスケジュールされたタスクで自律的に実行されるため、このアカウントにバッチジョブとして実行する権限を与える必要があります。

既存のGPOを使用してこの権限を設定するか、新しいGPOを作成してDomain Controllers OUにリンクすることで、この権限を設定できます。使用するGPOがまだない場合、以下にいくつかの手順があります。

  1. DC上でGroup Policy Editorを起動します。
  2. Domain Controllers OUを右クリックし、Create GPO in this domain and link it hereを選択します。
  3. DC – Logon as batchまたは他の好みの名前に名前を付けます
  4. GPOを右クリックし、Editをクリックします。
  5. Computer Configuration -> Windows Settings -> Security Settings -> User Rights Assignmentに移動します。
  6. バッチジョブとしてログインを左クリックし、プロパティをクリックします。
  7. ユーザーまたはグループを追加をクリックします。
  8. オブジェクトの種類をクリックし、サービスアカウントのみを選択し、OKをクリックします。
  9. 先ほど作成したsvcADHealthCheckサービスアカウントを検索し、選択してOKをクリックします。

これで、以下のように gMSA が AD オブジェクトのリストに表示されるはずです。

gMSA given rights to logon as a batch job

スケジュールタスクの作成

スケジュールタスクを実行するために作成したアカウントがあるので、任意のドメインに参加しているサーバー上でスケジュールタスク自体を作成できます。

GUI を使用してスケジュールタスクを作成することもできますが、クリックが多すぎます!その代わりに、以下に示すコードを使用して PowerShell で作成することをおすすめします。なぜなら、以下のコードを単純にコピーするだけで済むからです。

以下には2つのスクリプトがあります。どちらのスクリプトも似ていますが、1つは AD ユーザーアカウントを想定し、もう1つは gMSA を想定しています。使用するアカウントに基づいて適切なスクリプトを使用してください。

# スクリプトへのパスで置き換えてください
$ScriptPath = "C:\Scripts\ADHealthCheck.ps1"
# タスクを実行するために作成したアカウントのユーザー名で置き換えてください
$UserName = "svdADHealthCheck"

# 上記アカウントに設定したパスワードで置き換えてください
$Password = "JägareTvå!"
# スクリプトを起動するアクションを作成します
$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy bypass -File '$ScriptPath'"
# タスクを開始するトリガーを作成します
$Trigger = New-ScheduledTaskTrigger -Once -At "12:00" -RepetitionInterval (New-TimeSpan -Hours 12)
# スケジュールされたタスクの設定を作成します
$Settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RunOnlyIfNetworkAvailable -DontStopOnIdleEnd
# 可読性のためにスプラットを使用してスケジュールされたタスクを作成します
$Splat = @{
    User = "$env:USERDOMAIN\$UserName"
    Password = $Password
    TaskName = "ADHealthCheck"
    Action = $Action
    Trigger = $Trigger
    RunLevel = "Highest"
    Settings = $Settings
}
Register-ScheduledTask @Splat
# スクリプトへのパスで置き換えてください
$ScriptPath = "C:\Scripts\ADHealthCheck.ps1"
# タスクを実行するために作成したアカウントのユーザー名で置き換えてください
$UserName = "svdADHealthCheck$"
# スクリプトを起動するアクションを作成します
$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy bypass -File '$ScriptPath'"
# タスクを開始するトリガーを作成します
$Trigger = New-ScheduledTaskTrigger -Once -At "12:00" -RepetitionInterval (New-TimeSpan -Hours 12)
# スケジュールされたタスクの設定を作成します
$Settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RunOnlyIfNetworkAvailable -DontStopOnIdleEnd

# GMSA を定義するプリンシパルを作成します
$Principal = New-ScheduledTaskPrincipal -UserID "$env:USERDOMAIN\$UserName" -LogonType Password -RunLevel Highest
# 可読性のためにスプラットを使用してスケジュールされたタスクを作成します
$Splat = @{
    Principal = $Principal
    TaskName = "ADHealthCheck"
    Action = $Action
    Trigger = $Trigger
    RunLevel = "Highest"
    Settings = $Settings
}
Register-ScheduledTask @Splat

完了です!この時点で、スケジュールされたタスクは上記のスクリプトの間隔で実行されます。

概要

フー!もし最初のパートからずっとついてきてくれたなら、ADの健全性について深く知っているはずです。この1つのトピックには非常に多くの要素があり、2つの長いブログ投稿でも十分にカバーすることはできません。

しかし、今では十分な知識と事前に作成されたPowerShellフレームワークがあるので、他のActive Directoryの健全性チェックを必要に応じて組み込むことができるはずです。

さらに読むには

Source:
https://adamtheautomator.com/active-directory-health-check-2/