リストにあるActiveDirectoryサーバから特定ユーザの失敗の監査ログを取得するツールを作りたい
ファイルサーバのアクセス権限管理にActiveDirectoryを利用しているが、よくアカウントロックされる人たちがいる。
パスワード変更を資格情報マネージャに反映するのを漏らしたり、RDPしたときにサインアウトせず「☓」で閉じてしまう人たちが、Kerberos事前認証とかでパスワードポリシー違反を起こしているようだ。
で、被疑となる認証元の調査をする度にADサーバにログインしてイベントログを見に行くのが面倒なので、自端末からリモートセッションを張って引っ張るようにする。
搭載機能
- リストにあるActiveDirectoryサーバ全てで指定ユーザの失敗の監査ログを取得する。仕様として、ADサーバリストはCSVとする。(ファイル名:ADList.csv で指定)ADサーバリストは予め指定の場所(スクリプトと同じ階層の同フォルダ内)においておく方式とする。第一要素にHostName、第二要素をIPaddressとする。
- 指定ユーザーはテキストボックスに入力して指定する方式とする。
- ADサーバへのリモートセッションには、同じユーザーの認証情報が利用できることとする(ドメインのAdministratorなど)
- 結果はCSVで出力する。ファイル名はSearchADFailAud_ユーザーID_yyyymmdd_時分秒.csvとする
- 後からエラーなどを追えるように実行ログを別ファイルとして吐き出す。※別途関数にしたほうが良かった気がする。要改善
コード
絶対改善余地があるけどこんな感じ。
#
# ActiveDirectoryから特定ユーザーの失敗の監査のみ取得するスクリプト
#
# ファイル名:Search-AD-FailureAudit.ps1
# 調査対象ADサーバ情報の初期化
$ADList = $null
# 調査対象ユーザIDの初期化
$SearchUser = ""
# 日付の取得
$date = Get-Date -Format "yyyyMMdd";
# 時間の取得
$time = Get-Date -Format "HHmmss";
# 調査結果を出力するフォルダ
$scriptPath = $MyInvocation.MyCommand.Path
$scriptPath_split = Split-Path -Parent $scriptPath
$ResultFolder = ($scriptPath_split+"\結果")
# 調査結果出力結果フォルダがなかったら作成
if( -not (Test-Path $ResultFolder) ) {
New-Item $ResultFolder -Type Directory
}
# 実行結果出力ファイル名
$ExecuteLogFile = ( "\ExecuteLog_"+$date+"_"+$time+".log" )
#実行結果出力フォルダとファイル名のマージ
$ExecuteLog = Join-Path $ResultFolder $ExecuteLogFile
# アセンブリ読み込み
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# フォーム作成
$Form = New-Object System.Windows.Forms.Form
$Form.Size = New-Object System.Drawing.Size(400,130)
$Form.Text = "AD失敗の監査調査ツール"
# ラベル作成
$LabelSearchAD = New-Object System.Windows.Forms.Label
$LabelSearchAD.Location = New-Object System.Drawing.Point(20,10)
$LabelSearchAD.Size = New-Object System.Drawing.Size(300,20)
$LabelSearchAD.Text = "調査対象ユーザIDを入力してください"
$Form.Controls.Add($LabelSearchAD)
# 入力用テキストボックス
$TextBoxSearchAD = New-Object System.Windows.Forms.TextBox
$TextBoxSearchAD.Location = New-Object System.Drawing.Point(20,30)
$TextBoxSearchAD.Size = New-Object System.Drawing.Size(300,20)
$Form.Controls.Add($TextBoxSearchAD)
# OKボタン
$ButtonOK = New-Object System.Windows.Forms.Button
$ButtonOK.Location = New-Object System.Drawing.Point(230,60)
$ButtonOK.Size = New-Object System.Drawing.Size(60,20)
$ButtonOK.Text = "OK"
$Form.Controls.Add($ButtonOK)
# Cancelボタン
$ButtonCancel = New-Object System.Windows.Forms.Button
$ButtonCancel.Location = New-Object System.Drawing.Point(300,60)
$ButtonCancel.Size = New-Object System.Drawing.Size(60,20)
$ButtonCancel.Text = "キャンセル"
$ButtonCancel.DialogResult = "Cancel"
$Form.Controls.Add($ButtonCancel)
# OKボタンをクリック時の動作
$ButtonOK.add_click{
#ユーザIDが入力されていないときは背景を黄色にする
if($TextBoxSearchAD.text -eq ""){
$TextBoxSearchAD.BackColor = "yellow"
}else{
$Form.DialogResult = "OK"
}
}
Start-Transcript $ExecuteLog
# フォームを表示し処理が完了したらユーザIDを返す
$FormResult = $Form.ShowDialog()
if($FormResult -eq "OK"){
$SearchUser = $TextBoxSearchAD.text
# 調査対象ADサーバ情報の取得
$ADList = ($scriptPath_split+"\ADList.csv")
echo $SearchUser"を調査します。この処理は数分ほどかかります。調査中にPowershellのウィンドウのサイズ変更をしないでください。"
# 調査結果出力ファイル名
$ResultFile = ( "\SearchADFailAud_"+$SearchUser+"_"+$date+"_"+$time+".csv" )
# 調査結果出力フォルダとファイル名のマージ
$Result = Join-Path $ResultFolder $ResultFile
echo "認証情報取得のためパスワードを入力してください。"
# ドメインのAdministratorの認証情報を取得する
$AdminCred = Get-Credential -Credential [ドメイン]\Administrator
###進捗表示用###
echo "サーバ数取得中"
$GetADList = Import-CSV $ADList
$ServerCount = $GetADList.Length
$counter = 0
echo ("サーバ数="+$ServerCount)
echo "調査開始"
echo ""
$denominator = "/"+[string]$ServerCount
ForEach($a in $GetADList){
$counter ++;
Write-Progress -activity "進捗状況" -status $counter$denominator -percentComplete ($counter / $ServerCount * 100)
if( $a.IPaddress -eq ""){
} else {
if( Test-NetConnection $a.IPaddress -port 5985 -InformationLevel Quiet ){
# 対象AD向けの新規セッションを作成
$ADsession = New-PSSession $a.IPaddress -Credential $AdminCred
# リモートセッション上へ調査対象ユーザ情報を渡す
Invoke-Command -Session $ADSession -ScriptBlock { $UserID = $args[0] } -ArgumentList $SearchUser
# 対象ADのイベントログ(セキュリティ)から調査対象ユーザーの失敗の監査イベントのみを抽出し、CSVへエクスポートする
Invoke-Command -Session $ADSession -ScriptBlock { Get-EventLog Security -EntryType FailureAudit | Where-Object {$_.Message -match $UserID } } | Export-CSV -Path $Result -Encoding UTF8 -NoTypeInformation -Append
# 作成したセッションを閉じる
Remove-PSSession $ADSession
} else {
Write-Host $a.HostName"は存在しないか、Powershell用ポート(5985)が空いていません。(SKIP)"
}
}
}
# 調査結果ファイルを開く
Invoke-item $Result
}
else {
echo "操作はキャンセルされました"
}
Stop-Transcript
実行イメージ
そのうちつける。
注意点と補足
・PowerShellが実行可能な環境である必要があります。
・共有フォルダなどで利用する場合は認証済みである必要があります。
改版履歴
2020/09/14 初版公開
コメント