2012年5月28日月曜日

WindowsのDNSサーバのAレコードの消失等を監視するPowerShellスクリプト

このエントリは、ほぼ自分用です。
設定ファイルの仕様など、かなり手抜きなので、コピペでの利用はおすすめしません。

WindowsのDNSサーバに静的に登録したAレコードが、なぜか動的レコードに突然変わったり、気がついたら消えているという現象に悩まされた(NETLOGONサービスが悪さをしている模様?)。
原因は追究できていないのだが、とりあえずレコードの状態を監視しようということでPowerShellスクリプトを書いた。
仕様
  • 監視したいレコードの一覧をテキストファイルで定義。 
  • Aレコードが見つからなかった(消えていた)ら、イベントログにErrorを出力。 
  • Aレコードが動的に変わっていたら、イベントログにWarningを出力。 
レコード一覧ファイルの書式
dnsserver1 ←1行目にDNSサーバ名を記述(FQDNでもよい)
example.com ←2行目はチェック対象とするゾーン名を記述
server1.example.com ←3行目以降にチェック対象レコードを列挙
server2.example.com
....
コード
# CheckDnsRecords.ps1
# 2012.05.16 dsp74118
# Usage: CheckDnsRecords.ps1 <record list file>
# Record list file Format:
#  Line 1: DNS server name
#  Line 2: DNS container(Zone) name
#  Line 3-: Records

$MYPATH = [System.IO.Path]::GetDirectoryName($myInvocation.Mycommand.Definition)

If ($args.length -lt 1) {
 "Usage: CheckDnsRecords.ps1 <record list file>"
 Exit 1
}

$basename = (Get-ChildItem -Path $args | ForEach-Object {$_.basename})
$logfile = "$MYPATH\$basename" + "_log.log"

# Init Log
function InitLog($str) {
 $str | Out-File -FilePath $logfile
}

# Log Writer
function WriteLog($str) {
 $str | Out-File -FilePath $logfile -Append
}

# Warning Log Writer
function WriteWarning($str, $eventId) {
 "Warning: $str" | Out-File -FilePath $logfile -Append
 [Diagnostics.EventLog]::WriteEntry("CheckDnsRecords", $str, "Warning", $eventId)
}

# Error Log Writer
function WriteError($str, $eventId) {
 "Error: $str" | Out-File -FilePath $logfile -Append
 [Diagnostics.EventLog]::WriteEntry("CheckDnsRecords", $str, "Error", $eventId)
}

# Log Initgetialize
InitLog((Get-Date).datetime + " Check Start.")

# Read Record list
$servers = get-content -Path "$args"

$DNSServer = $servers[0]
$Container = $servers[1]

# Get A-Records
$records = Get-WmiObject -class MicrosoftDNS_AType -Namespace "root\MicrosoftDNS" `
 -computerName $DNSServer -Filter "ContainerName='$Container'" | `
 Select-Object -property OwnerName,RecordData,Timestamp

# Get OwnerName(hostname) into array
$ownernames = @()
foreach ($record in $records) {
 $ownernames += $record.OwnerName.ToString()
}

# Check record existence.
for ($i = 2; $i -lt $servers.length; $i++) {
 $server = $servers[$i]
 if (($ownernames -contains $server) -eq $true) {
  WriteLog($server + " のAレコードの存在を確認しました。" )
  $a = $records | where-object {$_.OwnerName -eq $server}
  if ($a.Timestamp -ne 0) {
   WriteWarning "$server のAレコードが動的レコードになっています。" 60002
  }
 } else {
  WriteError "$server のAレコードが存在しません。" 60001
 }
}

# End Of Script
WriteLog((Get-Date).datetime + " Check End.")

0 コメント:

コメントを投稿