Скрипт для поиска некоторых ошибок в прямых и обратных зонах DNS-сервера от Microsoft.
'********************************************
'* Используется утилита dnscmd.exe
'* из состава support tools дистрибутива
'* Windows 2000 Server
'********************************************
'On error Resume Next ' Ошибки пока не обрабатываем
DNS_Server = "193.125.1.95"
'DNS_Server = "193.125.10.250"
'--- Subroutines and Functions ---
'------------------------------------
Sub Sub_1 (My_String)
'--- Замещаем совокупности подряд расположенных пробелов одним пробелом ---
Do While InStr(1,My_String," ") >= 1 AND InStr(1,My_String," ") <= Len(My_String)
My_String = Replace (My_String," "," ")
Loop
End Sub '--- End of Sub_1 ---
'------------------------------------
Sub Sub_2 (My_String)
'--- Замещаем символ табуляции одним пробелом ---
Do While InStr(1,My_String,vbTab) >= 1 AND InStr(1,My_String,vbTab) <= Len(My_String)
My_String = Replace (My_String,vbTab," ")
Loop
End Sub '--- End of Sub_2 ---
'------------------------------------
Sub Sub_3 (Record_A, Zone_Name, Last_Host)
'--- Формирование строки для записи в файл Forward_Records.txt ---
Dim Str_IP
Dim Str_Host
Dim Str_Zone
Str_Zone = Zone_Name
If Mid(Record_A,1,1) = " " Then
'--- Имени нет ---
Str_IP = Mid (Record_A,InStr(1,Record_A," A ")+3,Len(Record_A)-InStr(1,Record_A," A ")-2 )
Str_Host = Last_Host
Else
'--- Имя есть ---
Str_IP = Mid (Record_A,InStr(1,Record_A," A ")+3,Len(Record_A)-InStr(1,Record_A," A ")-2 )
Str_Host = Mid (Record_A,1,InStr(1,Record_A," ")-1)
End If
Last_Host = Str_Host '--- Запоминаем предыдущее имя ---
Record_A = Str_IP & " " & Str_Host & " " & Str_Zone
End Sub '--- End of Sub_3 ---
'------------------------------------
Sub Sub_4 (Record, Zone_Name, Last_IP)
'--- Формирование строки для записи в файл Reverse_Records.txt ---
Dim Str_IP
Dim Str_Host
Dim Str_Zone
Dim Pos
Str_Zone = Zone_Name
Str_IP = ""
Pos = 0
Do While InStr(Pos+1,Zone_Name,".") >= 1 AND Mid(Zone_Name,InStr(Pos+1,Zone_Name,".")+1,1) <> "a"
Str_IP = Mid(Zone_Name,Pos+1,InStr(Pos+1,Zone_Name,".")-Pos) & Str_IP
Pos = InStr(Pos+1,Zone_Name,".")
Loop
If Mid(Record,1,1) = " " Then
'--- IP нет ---
Str_IP = Last_IP
Str_Host = Mid (Record,InStr(1,Record," PTR ")+5,Len(Record)-InStr(1,Record," PTR ")-4 )
Else
'--- IP есть ---
Str_IP = Str_IP & Mid (Record,1,InStr(1,Record," ")-1)
Str_Host = Mid (Record,InStr(1,Record," PTR ")+5,Len(Record)-InStr(1,Record," PTR ")-4 )
End If
Last_IP = Str_IP '--- Запоминаем предыдущий IP ---
Record = Str_IP & " " & Str_Host & " " & Str_Zone
End Sub '--- End of Sub_4 ---
'------------------------------------
Function Function_5(Str_1,Str_2)
'--- Проверка на совпадение IP в зоне ---
Dim P1_1 '--- Позиция в строке первого пробела
Dim P1_2 '--- Позиция в строке второго пробела
Dim P2_1 '--- Позиция в строке первого пробела
Dim P2_2 '--- Позиция в строке второго пробела
Dim Temp_IP_1
Dim Temp_IP_2
Dim Temp_Name_1
Dim Temp_Name_2
Function_5 = False
P1_1 = InStr(1,Str_1," ")
P1_2 = InStr(InStr(1,Str_1," ")+1,Str_1," ")
P2_1 = InStr(1,Str_2," ")
P2_2 = InStr(InStr(1,Str_2," ")+1,Str_2," ")
Temp_IP_1 = Mid(Str_1,1,P1_1-1)
Temp_IP_2 = Mid(Str_2,1,P2_1-1)
Temp_Name_1 = Mid(Str_1, P1_1 + 1, P1_2 - P1_1 -1)
Temp_Name_2 = Mid(Str_2, P2_1 + 1, P2_2 - P2_1 -1)
If Temp_IP_1 = Temp_IP_2 Then
Function_5 = True
End If
If Temp_Name_1 = "@" OR Temp_Name_2 = "@" Then
Function_5 = False
End If
End Function
'------------------------------------
Function Function_6(Str_1,Str_2)
'--- Проверка на совпадение имен в зоне ---
Dim P1_1 '--- Позиция в строке первого пробела
Dim P1_2 '--- Позиция в строке второго пробела
Dim P2_1 '--- Позиция в строке первого пробела
Dim P2_2 '--- Позиция в строке второго пробела
Dim Temp_IP_1
Dim Temp_IP_2
Dim Temp_Name_1
Dim Temp_Name_2
Function_6 = False
P1_1 = InStr(1,Str_1," ")
P1_2 = InStr(InStr(1,Str_1," ")+1,Str_1," ")
P2_1 = InStr(1,Str_2," ")
P2_2 = InStr(InStr(1,Str_2," ")+1,Str_2," ")
Temp_IP_1 = Mid(Str_1,1,P1_1-1)
Temp_IP_2 = Mid(Str_2,1,P2_1-1)
Temp_Name_1 = Mid(Str_1, P1_1 + 1, P1_2 - P1_1 -1)
Temp_Name_2 = Mid(Str_2, P2_1 + 1, P2_2 - P2_1 -1)
If Temp_Name_1 = Temp_Name_2 Then
Function_6 = True
End If
If Temp_Name_1 = "@" OR Temp_Name_2 = "@" Then
Function_6 = False
End If
End Function
'------------------------------------
Function Function_7(Str_1,Str_2)
'--- Проверка на соответствие между прямой и обратной зонами ---
Dim P1_1 '--- Позиция в строке первого пробела
Dim P1_2 '--- Позиция в строке второго пробела
Dim P2_1 '--- Позиция в строке первого пробела
Dim P2_2 '--- Позиция в строке второго пробела
Dim Temp_IP_1
Dim Temp_IP_2
Dim Temp_Name_1
Dim Temp_Name_2
Function_7 = False
P1_1 = InStr(1,Str_1," ")
P1_2 = InStr(InStr(1,Str_1," ")+1,Str_1," ")
P2_1 = InStr(1,Str_2," ")
P2_2 = InStr(InStr(1,Str_2," ")+1,Str_2," ")
Temp_IP_1 = Mid(Str_1,1,P1_1-1)
Temp_IP_2 = Mid(Str_2,1,P2_1-1)
Temp_Name_1 = Mid(Str_1, P1_1 + 1, P1_2 - P1_1 -1)
Temp_Name_2 = Mid(Str_2, P2_1 + 1, P2_2 - P2_1 -1)
If Temp_IP_1 = Temp_IP_2 AND Temp_Name_1 <> Temp_Name_2 Then
Function_7 = True
End If
If Temp_IP_1 <> Temp_IP_2 AND Temp_Name_1 = Temp_Name_2 Then
Function_7 = True
End If
End Function
'------------------------------------
'--- Используемые переменные ---
Dim Command_String ' Командная строка
Dim Current_Dir ' Текущая директория, где находится данный скрипт
Dim oFileSystem ' Объект типа FileSystem
Dim oFolder ' Объект типа Folder
Dim oShell ' Объект типа Shell
Dim DNS_Server ' IP-адрес проверяемого DNS сервера
Dim oF_In ' Объект типа File
Dim oF_Out ' Объект типа File
Dim Work_String ' Рабочая переменная типа строка
Dim Pos_0 ' Позиция символа в строке
'--- Список констант ---
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
'DNS_Server = "193.125.1.95"
'DNS_Server = "193.125.10.250"
Set oFileSystem = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFileSystem.GetFolder(".\")
Current_Dir = oFolder.Path
Set oShell = WScript.CreateObject("WScript.Shell")
'--- Получаем список команд утилиты dnscmd (просто так) ---
Command_String = "cmd /C "
Command_String =Command_String & Current_Dir & "\" & "dnscmd.exe"
Command_String =Command_String & " > " & Current_Dir & "\" & "Command_List.txt"
Return = oShell.Run (Command_String, 0, True)
'--- Получаем список зон с проверяемого DNS сервера ---
Command_String = "cmd /C "
Command_String =Command_String & Current_Dir & "\" & "dnscmd.exe"
Command_String =Command_String & " " & DNS_Server
Command_String =Command_String & " " & "/EnumZones"
Command_String =Command_String & " > " & Current_Dir & "\" & "EnumZones.txt"
Return = oShell.Run (Command_String, 0, True)
'--- Получаем список Forward зон ---
Set oF_In = oFileSystem.OpenTextFile (".\" & "EnumZones.txt", ForReading, True)
Set oF_Out = oFileSystem.OpenTextFile (".\" & "Forward_Zones.txt", ForWriting, True)
Do While oF_In.AtEndOfStream <> True '--- Перебор строк входного файла
Work_String = oF_In.ReadLine
Pos_0 = InStr(1,Work_String,"DS")
If Pos_0 >= 1 Then
Pos_0 = InStr(1,Work_String,"Rev")
If Pos_0 = 0 Then '--- Это НЕ реверсивная зона ---
'--- Замещаем совокупности подряд расположенных пробелов одним пробелом ---
Call Sub_1(Work_String)
'--- Удаляем если нужно первый пробел ---
If Mid (Work_String,1,1) = " " Then
Work_String = Mid (Work_String,2,Len(Work_String)-1)
End If
'--- Получаем только название зоны ---
Pos_0 = InStr(1,Work_String," ")
Work_String = Mid (Work_String,1,Pos_0-1)
'--- Если название зоны ".", то НЕ пишем ---
Pos_0 = InStr(1,Work_String,".")
If Pos_0 <> 1 Then
oF_Out.Write Work_String & vbCrLf
End If
End If
End If
Loop '--- Конец перебора строк входного файла со списком зон ---
oF_Out.Close
oF_In.Close
'--- Получаем список Reverse зон ---
Set oF_In = oFileSystem.OpenTextFile (".\" & "EnumZones.txt", ForReading, True)
Set oF_Out = oFileSystem.OpenTextFile (".\" & "Reverse_Zones.txt", ForWriting, True)
Do While oF_In.AtEndOfStream <> True '--- Перебор строк входного файла
Work_String = oF_In.ReadLine
Pos_0 = InStr(1,Work_String,"DS")
If Pos_0 >= 1 Then
Pos_0 = InStr(1,Work_String,"Rev")
If Pos_0 >= 1 Then '--- Это реверсивная зона ---
'--- Замещаем совокупности подряд расположенных пробелов одним пробелом ---
Call Sub_1(Work_String)
'--- Удаляем если нужно первый пробел ---
If Mid (Work_String,1,1) = " " Then
Work_String = Mid (Work_String,2,Len(Work_String)-1)
End If
'--- Получаем только название зоны ---
Pos_0 = InStr(1,Work_String," ")
Work_String = Mid (Work_String,1,Pos_0-1)
oF_Out.Write Work_String & vbCrLf
End If
End If
Loop '--- Конец перебора строк входного файла со списком зон ---
oF_Out.Close
oF_In.Close
'--- Получаем все A-записи из прямых зон и пишем их в файл Forward_Records.txt ---
'--- в формате : IP-адрес, пробел, имя хоста, пробел, имя зоны ---
Set oF_In = oFileSystem.OpenTextFile (".\" & "Forward_Zones.txt", ForReading, True)
Set oF_Out = oFileSystem.OpenTextFile (".\" & "Forward_Records.txt", ForWriting, True)
Do While oF_In.AtEndOfStream <> True '--- Перебор строк входного файла
Work_String = oF_In.ReadLine '--- Имя прямой зоны (текущее) ---
'--- Получаем список записей текущей зоны с проверяемого DNS сервера ---
Command_String = "cmd /C "
Command_String =Command_String & Current_Dir & "\" & "dnscmd.exe"
Command_String =Command_String & " " & DNS_Server
Command_String =Command_String & " " & "/EnumRecords"
Command_String =Command_String & " " & Work_String
Command_String =Command_String & " " & "@"
Command_String =Command_String & " > " & Current_Dir & "\" & "Temp_For.txt"
Return = oShell.Run (Command_String, 0, True)
'--- Начинаем разбирать полученный файл (Temp_For.txt) и собирать нужные записи ---
Set oF_In_For = oFileSystem.OpenTextFile (".\" & "Temp_For.txt", ForReading, True)
Temp_String_For = " " '--- Для хранения предыдущей записи --
Do While oF_In_For.AtEndOfStream <> True '--- Перебор строк входного файла
Work_String_For = oF_In_For.ReadLine '--- Текущая запись ---
'--- Замещаем символ табуляции одним пробелом ---
Call Sub_2(Work_String_For)
'--- Замещаем совокупности подряд расположенных пробелов одним пробелом ---
Call sub_1(Work_String_For)
Pos_0 = InStr(1,Work_String_For," A ")
If Pos_0 >= 1 Then '--- Это запись типа А ---
Call Sub_3 (Work_String_For, Work_String, Temp_String_For)
oF_Out.Write Work_String_For & vbCrLf
End If
Loop '--- Конец перебора записей типа А ---
oF_In_For.Close
Loop '--- Конец перебора строк входного файла со списком прямых зон ---
oF_Out.Close
oF_In.Close
'--- Получаем все PTR-записи из обратных зон и пишем их в файл Reverse_Records.txt ---
'--- в формате : IP-адрес, пробел, имя хоста, пробел, имя зоны ---
Set oF_In = oFileSystem.OpenTextFile (".\" & "Reverse_Zones.txt", ForReading, True)
Set oF_Out = oFileSystem.OpenTextFile (".\" & "Reverse_Records.txt", ForWriting, True)
Do While oF_In.AtEndOfStream <> True '--- Перебор строк входного файла
Work_String = oF_In.ReadLine '--- Имя прямой зоны (текущее) ---
'--- Получаем список записей текущей зоны с проверяемого DNS сервера ---
Command_String = "cmd /C "
Command_String =Command_String & Current_Dir & "\" & "dnscmd.exe"
Command_String =Command_String & " " & DNS_Server
Command_String =Command_String & " " & "/EnumRecords"
Command_String =Command_String & " " & Work_String
Command_String =Command_String & " " & "@"
Command_String =Command_String & " > " & Current_Dir & "\" & "Temp_Rev.txt"
Return = oShell.Run (Command_String, 0, True)
'--- Начинаем разбирать полученный файл (Temp_Rev.txt) и собирать нужные записи ---
Set oF_In_Rev = oFileSystem.OpenTextFile (".\" & "Temp_Rev.txt", ForReading, True)
Temp_String_Rev = " " '--- Для хранения предыдущей записи --
Do While oF_In_Rev.AtEndOfStream <> True '--- Перебор строк входного файла
Work_String_Rev = oF_In_Rev.ReadLine '--- Текущая запись ---
'--- Замещаем символ табуляции одним пробелом ---
Call Sub_2(Work_String_Rev)
'--- Замещаем совокупности подряд расположенных пробелов одним пробелом ---
Call Sub_1(Work_String_Rev)
Pos_0 = InStr(1,Work_String_Rev," PTR ")
If Pos_0 >= 1 Then '--- Это запись типа PTR ---
Call Sub_4 (Work_String_Rev, Work_String, Temp_String_Rev)
oF_Out.Write Work_String_Rev & vbCrLf
End If
Loop '--- Конец перебора записей типа PTR ---
oF_In_Rev.Close
Loop '--- Конец перебора строк входного файла со списком обратных зон ---
oF_Out.Close
oF_In.Close
'--- Анализируем файлы с записями зон на наличие различных ошибок (несоответствий) ---
'--- и ошибки пишем в файл ошибок ---
Set oF_Err_Log = oFileSystem.OpenTextFile (".\" & "Error_Log.txt", ForWriting, True)
'--- 1. Ищем дубликаты записей в прямой зоне (зонах) ---
oF_Err_Log.Write "Проверка дубликатов в прямой зоне" & vbCrLf
oF_Err_Log.Write "----------------------" & vbCrLf
Set oF_In_1 = oFileSystem.OpenTextFile (".\" & "Forward_Records.txt", ForReading, True)
Do While oF_In_1.AtEndOfStream <> True '--- Перебор записей ---
Work_String_1 = oF_In_1.ReadLine '--- Текущая запись ---
Set oF_In_2 = oFileSystem.OpenTextFile (".\" & "Forward_Records.txt", ForReading, True)
Do While oF_In_2.AtEndOfStream <> True '--- Перебор записей ---
Work_String_2 = oF_In_2.ReadLine '--- Текущая запись ---
If Work_String_1 <> Work_String_2 Then
If Function_5 (Work_String_1, Work_String_2) Then '--- Проверка по IP ---
oF_Err_Log.Write "Совпадение по IP" & vbCrLf
oF_Err_Log.Write Work_String_1 & vbCrLf
oF_Err_Log.Write Work_String_2 & vbCrLf
oF_Err_Log.Write "-----------------" & vbCrLf
End If '--- Проверка по IP ---
If Function_6 (Work_String_1, Work_String_2) Then '--- Проверка по именам ---
oF_Err_Log.Write "Совпадение по имени" & vbCrLf
oF_Err_Log.Write Work_String_1 & vbCrLf
oF_Err_Log.Write Work_String_2 & vbCrLf
oF_Err_Log.Write "-----------------" & vbCrLf
End If '--- Проверка по имени ---
End If
Loop
oF_In_2.Close
Loop
oF_In_1.Close
'--- 2. Ищем дубликаты записей в обратной зоне (зонах) ---
oF_Err_Log.Write "Проверка дубликатов в обратной зоне (зонах)" & vbCrLf
oF_Err_Log.Write "----------------------" & vbCrLf
Set oF_In_1 = oFileSystem.OpenTextFile (".\" & "Reverse_Records.txt", ForReading, True)
Do While oF_In_1.AtEndOfStream <> True '--- Перебор записей ---
Work_String_1 = oF_In_1.ReadLine '--- Текущая запись ---
Set oF_In_2 = oFileSystem.OpenTextFile (".\" & "Reverse_Records.txt", ForReading, True)
Do While oF_In_2.AtEndOfStream <> True '--- Перебор записей ---
Work_String_2 = oF_In_2.ReadLine '--- Текущая запись ---
If Work_String_1 <> Work_String_2 Then
If Function_5 (Work_String_1, Work_String_2) Then '--- Проверка по IP ---
oF_Err_Log.Write "Совпадение по IP" & vbCrLf
oF_Err_Log.Write Work_String_1 & vbCrLf
oF_Err_Log.Write Work_String_2 & vbCrLf
oF_Err_Log.Write "-----------------" & vbCrLf
End If '--- Проверка по IP ---
If Function_6 (Work_String_1, Work_String_2) Then '--- Проверка по именам ---
oF_Err_Log.Write "Совпадение по имени" & vbCrLf
oF_Err_Log.Write Work_String_1 & vbCrLf
oF_Err_Log.Write Work_String_2 & vbCrLf
oF_Err_Log.Write "-----------------" & vbCrLf
End If '--- Проверка по имени ---
End If
Loop
oF_In_2.Close
Loop
oF_In_1.Close
'--- 3. Ищем несоответствие между прямой и обратной зоной (зонами) ---
oF_Err_Log.Write "Проверка несоответствия между прямой и обратной зонами" & vbCrLf
oF_Err_Log.Write "------------------------------------------------------" & vbCrLf
Set oF_In_1 = oFileSystem.OpenTextFile (".\" & "Forward_Records.txt", ForReading, True)
Do While oF_In_1.AtEndOfStream <> True '--- Перебор записей ---
Work_String_1 = oF_In_1.ReadLine '--- Текущая запись ---
Set oF_In_2 = oFileSystem.OpenTextFile (".\" & "Reverse_Records.txt", ForReading, True)
Do While oF_In_2.AtEndOfStream <> True '--- Перебор записей ---
Work_String_2 = oF_In_2.ReadLine '--- Текущая запись ---
If Function_7 (Work_String_1, Work_String_2) Then '--- Проверка между прямой и обратной зонами ---
oF_Err_Log.Write "Нет соответствия между прямой и обратной зонами" & vbCrLf
oF_Err_Log.Write Work_String_1 & vbCrLf
oF_Err_Log.Write Work_String_2 & vbCrLf
oF_Err_Log.Write "-----------------------------------------------" & vbCrLf
End If '--- Проверка между прямой и обратной зонами ---
Loop
oF_In_2.Close
Loop
oF_In_1.Close
'--- Завершаем работу ---
oF_Err_Log.Close '--- Закрываем журнал ошибок ---
Wscript.Echo "Завершение проверок записей в DNS сервере " & DNS_Server
Wscript.Quit (0) ' Exit from script