【PowerShell】ユーザーIDの変更履歴を収集するスクリプト

ユーザー ID の変更履歴を収集する方法

「あるユーザー ID の属性を間違えて変更してしまった!」なんてこと、ありませんか?
Windows Server 2008 からサポートされた「ある種の監査ログ」には、ユーザー ID の変更履歴がしっかりと記載されています。今回は簡単な PowerShell スクリプトを使用して、監査ログに蓄積された ID の変更履歴を取り出す方法をご紹介します。
なお、これからご紹介するスクリプトを使用するには、以下の準備が必要です。

  1. PowerShell を有効にする
  2. ディレクトリ サービスの監査を有効にする
  3. Active Directory オブジェクトの監査設定を変更する

【準備】

1.PowerShell を有効にする

管理者権限で PowerShell コンソールを起動し、以下のコマンドを入力して PowerShell スクリプトを使えるようにしてください。

Set-ExecutionPolicy RemoteSigned

2.ディレクトリサービスの監査を有効にする

ユーザーIDの変更を追跡するには、Active Directory の監査のうち、「ディレクトリサービスの監査」を有効にする必要があります。有効にする手順は以下の通りです。

「サーバーマネージャー」を起動し、[機能] - [グループポリシーの管理] - [フォレスト] - [ドメイン] - [<ドメイン名>] - [Domain Controllers] を開く。

[Default Domain Controllers Policy] を右クリックして[編集]を選択する。

[Default Domain Controllers Policy] - [コンピューターの構成] - [ポリシー] - [Windows の設定] - [セキュリティの設定] - [ローカル ポリシー] から [監査ポリシー]を選択する。

右ペインのポリシー一覧で、「ディレクトリサービスのアクセス監査] の [成功] を有効にする

image 

再起動する

3.Active Directory オブジェクトの監査設定を変更する

監査ログを取得するには、変更を追跡するオブジェクトの監査を有効にする必要があります。

ここでは、Users 配下のユーザー全体を監査するものとします。

[管理ツール] - [ADSI エディター] を起動する。

[ADSI エディター] を右クリックして [接続] を選択する。

image

[既定の名前付けコンテキストを選択する] がチェックされていることを確認して、[OK]をクリック。

image

[CN=Users] を右クリックして [プロパティ] を選択。

image

[セキュリティ] タブを選択し、[詳細設定] をクリックして [監査] タブを開く。

image

[追加] をクリックして [Everyone] に対して [すべてのプロパティの書き込み] の [成功] をチェックする。このとき、監査の設定はUsers配下のすべてのユーザーに対して適用するため、 「このオブジェクトとすべての子オブジェクト」 が選択されていることを確認してください。

image 

以上で準備完了です。

試しに、Users 配下の適当なユーザーの属性を変更してみてください。

image

セキュリティイベントログに、イベントID 5136 が以下のように報告されているはずです。既存の値を書き換えた場合には、「値が削除されました」と「値が追加されました」という2つのイベントが発生します。これにより、変更前と変更後の値を把握することができます。からっぽの属性に値を設定した場合には、「値が追加されました」のみが出力されます。

 imageimage 

【変更を追跡するスクリプト】

出力されたイベントID 5136 を追跡するためのスクリプトは以下の通りです。以下のスクリプトを拡張子 .ps1 で保存してください。たったこれだけのスクリプトで、属性の履歴を追跡することができます。

$UserID = $Args[0] $ev = Get-EventLog -LogName "Security" -Message "*$UserID*" | Where-Object {$_.EventID -eq 5136}

$ev | ForEach-Object -process{     $timeGenerated = $_.TimeGenerated.ToString()     $n = ($_.message).Split("`n")     $strUserID =  ($n[13].Trim()).Split(":")     $strProperty = ($n[18].Trim()).Split(":")     $strValue = ($n[20].Trim()).Split(":")     $strOperationID = ($n[23].Trim()).Split(":")     $strOperation = Switch ($strOperationID[1].Trim())                               {"%%14674" {"追加"} "%%14675" {"削除"} default {"不明"}}     $outString = $timeGenerated + "," +                  ($strUserID[1].Trim()).Replace(",","\") + "," +                  $strProperty[1].Trim() + "," +                  $strValue[1].Trim() + "," +                   $strOperation.Trim()     $outString     }

スクリプトの書式は以下の通りです。
※スクリプトを EventID5136.ps1 という名前で保存したものとします。

.\EventID5136.ps1 [ユーザーID]

[ユーザーID]には、追跡したいユーザーのユーザーIDをを指定してください。指定しなければ、すべての 5136 イベントを出力しますが、その場合はユーザー属性の変更履歴以外のイベントも出力されます。

実行すると以下のように出力されます。

image

出力行は以下の形式で保存されています。

[イベントの発生日時],[変更されたユーザーのDN],[変更された属性],[値],[操作の種類]

出力ファイルはCSVファイルに保存することを想定し、DNの区切り文字を「\」に変換していますので注意して下さい。

今回ご紹介したスクリプトは高機能ではありませんが、「うっかりやってしまったとき」に大変便利です。ぜひとも皆様でカスタマイズしてよりよいものにしてください。