none
nslookup и кириллические имена компютеров RRS feed

  • Вопрос

  • AD на Windows 2003, но режим 2000

    DNS так же на серверах Windows 2003

    в домене появляются компьютеры с русскими именами, и команда "nslookup имя_компьютера", где "имя_компьютера" написана русскими буквам, уже не помогает определить его IP адрес. Причём "ping имя_компьютера" работает нормально. Как из командой строки (например "nslookup") определять IP адреса кириллических компьютеров?

    Можно предложить вариант определения адресов из vbscript.

Ответы

  • http://www.vbscriptexperts.com/general/Q_25436613-VBS-script-ping-IP's-and-get-hostnames.jsp

    Function ResolveIP(computerName)
       Dim objShell  :  Set objShell = CreateObject("WScript.Shell")
       Dim objExec   :  Set objExec = objShell.Exec("ping " & computerName & " -n 1")
       Dim strOutput : strOutput = objExec.StdOut.ReadAll
       Dim RegEx     :  Set RegEx = New RegExp
       RegEx.Pattern = "\[(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\]"
       RegEx.Global = True
       If RegEx.Test(strOutput) Then
           ResolveIP = RegEx.Execute(strOutput)(0).Submatches(0)
       Else
           ResolveIP = "IP Address could not be resolved."
       End If
    End Function
    
    sHost = "привет"
    
    sIP = ResolveIP(sHost)
    
    WScript.Echo sIP

    Вывод:

    PS > cscript //nologo ping.vbs
    192.168.200.100

    • Помечено в качестве ответа СГГ 1 июля 2013 г. 11:07
    1 июля 2013 г. 10:19
    Отвечающий
  • СГГ, раз Вы пользуетесь сценарием, то можно вообще обойтись без утилит. Пример:

    Option Explicit
    
    Dim objWMI, objCollection, objItem, objRoot, objServers
    Dim objDictDNS, objDictComputers, strDomain, strDomainDNS, strDNS, strComputer
    Dim objFS, objFile, objWShell, strLog, strTranslator, blnIsConsole, arrTemp(), strTemp, i
    
    Set objFS = CreateObject("Scripting.FileSystemObject")
    strTranslator = objFS.GetBaseName(WScript.FullName)
    If StrComp(strTranslator, "cscript", vbTextCompare) = 0 Then
        blnIsConsole = True
    Else
        blnIsConsole = False
    End If
    strLog = objFS.BuildPath(objFS.GetParentFolderName(WScript.ScriptFullName), _
                            objFS.GetBaseName(WScript.ScriptName) & ".log")
    Set objRoot = GetObject("LDAP://rootDSE")
    strTemp = objRoot.Get("defaultNamingContext")
    strDomain = Mid(Split(strTemp, ",dc=", -1, vbTextCompare)(0), 4)
    strDomainDNS = Replace(Replace(strTemp, "dc=", ".", 1, -1, vbTextCompare), ",", "")
    '--- Формирование массива имён контроллеров домена
    If blnIsConsole Then WScript.Echo "Поиск контроллеров домена..."
    Set objServers = GetObject(GetObject("LDAP://" & objRoot.Get("serverName")).Parent)
    i = -1
    For Each objItem In objServers
        strTemp = objItem.cn
        If Available(strTemp, blnIsConsole) Then
            i = i + 1
            ReDim Preserve arrTemp(i)
            arrTemp(i) = strTemp
            If blnIsConsole Then WScript.Echo strTemp & " -> отвечает"
        Else
            If blnIsConsole Then WScript.Echo strTemp & " -> не отвечает"
        End If
    Next
    Set objServers = Nothing
    Set objRoot = Nothing
    '------
    If i >= 0 Then
        '--- Поиск DNS-сервера среди ответивших контроллеров
        If blnIsConsole Then WScript.Echo "Поиск DNS-сервера..."
        strDNS = Find_DNS(arrTemp)
        '------
        If Len(strDNS) > 0 Then
             If blnIsConsole Then WScript.Echo strDNS & " -> является DNS-сервером"
            '--- Формирование списка всех компьютеров домена
            If blnIsConsole Then WScript.Echo "Формирование списка компьютеров домена..."
            Set objDictComputers = CreateObject("Scripting.Dictionary")
            objDictComputers.CompareMode = 1
            Set objCollection = GetObject("WinNT://" & strDomain & ",domain")
            objCollection.Filter = Array("computer")
            i = 0
            For Each objItem In objCollection
                strTemp = objItem.Name & strDomainDNS
                objDictComputers.Add strTemp, vbNullString
                If blnIsConsole Then
                    i = i + 1
                    WScript.StdOut.Write vbCr & "Обнаружено: " & i
                End If
            Next
            '------
            Set objFile = objFS.CreateTextFile(strLog, True)
            '--- Формирование таблицы соответствий IP-адресов и DNS-имён
            If blnIsConsole Then WScript.Echo vbNewLine & "Формирование таблицы соответствий IP-адресов и DNS-имён компьютеров домена..."
            Set objDictDNS = CreateObject("Scripting.Dictionary")
            objDictDNS.CompareMode = 1
            Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strDNS & "\root\MicrosoftDNS")
            Set objCollection = objWMI.ExecQuery("SELECT * FROM MicrosoftDNS_AType")
            For Each objItem In objCollection
                strComputer = UCase(objItem.OwnerName)
                If objDictComputers.Exists(strComputer) Then
                    strTemp = objItem.IPAddress
                    If objDictDNS.Exists(strTemp) Then
                        objFile.WriteLine strComputer & " -> " & strTemp & " (запись-дубликат)"
                        If blnIsConsole Then WScript.Echo strComputer & " -> " & strTemp & " (запись-дубликат)"
                    Else
                        objDictDNS.Add strTemp, strComputer
                        objFile.WriteLine strComputer & " -> " & strTemp
                        If blnIsConsole Then WScript.Echo strComputer & " -> " & strTemp
                    End If
                End If
            Next
            '------
            objFile.Close
            Set objItem = Nothing: Set objCollection = Nothing: Set objWMI = Nothing
            Set objDictComputers = Nothing: Set objDictDNS = Nothing
            Set objFile = Nothing
            If blnIsConsole Then
                WScript.Echo "======" & vbNewLine & "Путь к файлу отчёта: " & UCase(strLog)
            Else
                Set objWShell = CreateObject("WScript.Shell")
                objWShell.Run "notepad.exe " & strLog, 1
                Set objWShell = Nothing
            End If
        Else
            WScript.Echo "DNS-сервер не обнаружен."
        End If
    Else
        WScript.Echo "Не ответил ни один контроллер домена."
    End If
    Set objFS = Nothing
    WScript.Quit 0
    
    '======
    
    Function Find_DNS(arrDCs()) 'Поиск DNS-сервера в массиве контроллеров домена
    Dim objWMI, strTemp, i
    
    On Error Resume Next
    For i = 0 To UBound(arrDCs)
        Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & arrDCs(i) & "\root\MicrosoftDNS")
        If Err.Number <> 0 Then
            Err.Clear
        Else
            Set objWMI = Nothing
            strTemp = arrDCs(i)
            Exit For
        End If
    Next
    On Error GoTo 0
    Find_DNS = strTemp
    End Function
    
    '======
    
    Function Available(strName, blnIsCon) 'Проверка доступности узла
    If blnIsCon Then
            Dim objExec, objOutStream, strTemp
            Set objExec = CreateObject("WScript.Shell").Exec("ping -n 1 -w 130 " & strName)
            Set objOutStream = objExec.StdOut
            While Not objOutStream.AtEndOfStream
                strTemp = strTemp & Trim(objOutStream.ReadLine)
            Wend
            Set objOutStream = Nothing
            Set objExec = Nothing
            If InStr(1, strTemp, "TTL", vbTextCompare) > 0 Then
                Available = True
            Else
                Available = False
            End If
    Else
        Dim objWMI, objItem
        On Error Resume Next
        Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery("SELECT StatusCode FROM Win32_PingStatus WHERE Address='" & strName & "'")
        If Err.Number = 0 Then
            For Each objItem In objWMI
                If IsNull(objItem.StatusCode) Then
                    Available = False
                Else
                    Available = (objItem.StatusCode = 0)
                End If
            Next
        Else
            Err.Clear
            Available = False
        End If
        Set objItem = Nothing
        Set objWMI = Nothing
        On Error GoTo 0
    End If
    End Function

    • Помечено в качестве ответа СГГ 2 июля 2013 г. 6:19
  • ... Вижу хорошо пользуетесь WMI. Можете посоветовать хорошие ссылки ?

    Если речь о ресурсах, сторонних по отношению к ресурсам MS, то неплохой материал для начинающих можно найти, например, здесь: Разработка скриптов от "Серого форума".
    • Помечено в качестве ответа СГГ 2 июля 2013 г. 8:54

Все ответы

  • PowerShell :

    PS > [System.Net.Dns]::GetHostEntry("привет")

    HostName                                Aliases                                 AddressList
    --------                                -------                                 -----------
    привет.contoso.com                     {}                                      {192.168.200.100}

    • Предложено в качестве ответа R.LevchenkoMVP 1 июля 2013 г. 9:31
    Отвечающий

  • Resolve-DnsName пока


    Roman Levchenko, MCITP, MCTS http://www.rlevchenko.com


    • Предложено в качестве ответа R.LevchenkoMVP 1 июля 2013 г. 9:31
    • Изменено R.LevchenkoMVP 1 июля 2013 г. 9:34 фывы
  • Можно проще :)

    Resolve-DnsName пока


    Roman Levchenko, MCITP, MCTS http://www.rlevchenko.com


    Можно, но только если система Windows Server 2012,Windows 8 и выше.
    Отвечающий
  • Так точно. Полностью согласен

    Roman Levchenko, MCITP, MCTS http://www.rlevchenko.com

  • Спасибо, всё хорошо, но системы 2003, XP и нужно переделывать vbscript-ы под  PS, и устанавливать PS на Windows 2003. Политика в компании консервативная, ставить что-то новое на рабочие сервера надо долго согласовывать.

    Изначальная задача: На сервере есть ресурс (папка с приложением). Необходимо собрать статистику по использованию этого ресурса в виде: "логин", "с какого компа", "IP адрес компа". Скрипт работает через промежуток времени банальным опросом открытых файлов, какой пользователь с какого компа заходит. IP адрес определяется через nslookup, всё написано на vbscript. Может есть хорошая альтернатива?

    Статистика в реальном времени не требуется (по крайней мере с данным приложением)

  • http://www.vbscriptexperts.com/general/Q_25436613-VBS-script-ping-IP's-and-get-hostnames.jsp

    Function ResolveIP(computerName)
       Dim objShell  :  Set objShell = CreateObject("WScript.Shell")
       Dim objExec   :  Set objExec = objShell.Exec("ping " & computerName & " -n 1")
       Dim strOutput : strOutput = objExec.StdOut.ReadAll
       Dim RegEx     :  Set RegEx = New RegExp
       RegEx.Pattern = "\[(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\]"
       RegEx.Global = True
       If RegEx.Test(strOutput) Then
           ResolveIP = RegEx.Execute(strOutput)(0).Submatches(0)
       Else
           ResolveIP = "IP Address could not be resolved."
       End If
    End Function
    
    sHost = "привет"
    
    sIP = ResolveIP(sHost)
    
    WScript.Echo sIP

    Вывод:

    PS > cscript //nologo ping.vbs
    192.168.200.100

    • Помечено в качестве ответа СГГ 1 июля 2013 г. 11:07
    1 июля 2013 г. 10:19
    Отвечающий
  • да. не мытьём так катанием (не nslookup, так ping) :-)

    С RegExp получается элегантно. Только ping работает медленней nslookup, а когда идёт список более 8000 компов, в итоге получается приличная разница. Если никак не придумается, буду пробовать так. Может как идея: как мне кажется всё дело в кодировке. nslookup выдаёт ответ в UTF-8. Наглядно проверить: в cmd в свойствах окна меняем шрифт на "Lucida Console" далее меняем кодировку на UTF-8 и запрашиваем nslookup IP адрес "русской" машины

    chcp 65001

    nslookup 192.168.200.100

    В ответе будет видно имя "привет"

    т.е. может команде nslookup можно отправить имя компа в UTF-8 кодировке?

    1 июля 2013 г. 11:07
  • СГГ, раз Вы пользуетесь сценарием, то можно вообще обойтись без утилит. Пример:

    Option Explicit
    
    Dim objWMI, objCollection, objItem, objRoot, objServers
    Dim objDictDNS, objDictComputers, strDomain, strDomainDNS, strDNS, strComputer
    Dim objFS, objFile, objWShell, strLog, strTranslator, blnIsConsole, arrTemp(), strTemp, i
    
    Set objFS = CreateObject("Scripting.FileSystemObject")
    strTranslator = objFS.GetBaseName(WScript.FullName)
    If StrComp(strTranslator, "cscript", vbTextCompare) = 0 Then
        blnIsConsole = True
    Else
        blnIsConsole = False
    End If
    strLog = objFS.BuildPath(objFS.GetParentFolderName(WScript.ScriptFullName), _
                            objFS.GetBaseName(WScript.ScriptName) & ".log")
    Set objRoot = GetObject("LDAP://rootDSE")
    strTemp = objRoot.Get("defaultNamingContext")
    strDomain = Mid(Split(strTemp, ",dc=", -1, vbTextCompare)(0), 4)
    strDomainDNS = Replace(Replace(strTemp, "dc=", ".", 1, -1, vbTextCompare), ",", "")
    '--- Формирование массива имён контроллеров домена
    If blnIsConsole Then WScript.Echo "Поиск контроллеров домена..."
    Set objServers = GetObject(GetObject("LDAP://" & objRoot.Get("serverName")).Parent)
    i = -1
    For Each objItem In objServers
        strTemp = objItem.cn
        If Available(strTemp, blnIsConsole) Then
            i = i + 1
            ReDim Preserve arrTemp(i)
            arrTemp(i) = strTemp
            If blnIsConsole Then WScript.Echo strTemp & " -> отвечает"
        Else
            If blnIsConsole Then WScript.Echo strTemp & " -> не отвечает"
        End If
    Next
    Set objServers = Nothing
    Set objRoot = Nothing
    '------
    If i >= 0 Then
        '--- Поиск DNS-сервера среди ответивших контроллеров
        If blnIsConsole Then WScript.Echo "Поиск DNS-сервера..."
        strDNS = Find_DNS(arrTemp)
        '------
        If Len(strDNS) > 0 Then
             If blnIsConsole Then WScript.Echo strDNS & " -> является DNS-сервером"
            '--- Формирование списка всех компьютеров домена
            If blnIsConsole Then WScript.Echo "Формирование списка компьютеров домена..."
            Set objDictComputers = CreateObject("Scripting.Dictionary")
            objDictComputers.CompareMode = 1
            Set objCollection = GetObject("WinNT://" & strDomain & ",domain")
            objCollection.Filter = Array("computer")
            i = 0
            For Each objItem In objCollection
                strTemp = objItem.Name & strDomainDNS
                objDictComputers.Add strTemp, vbNullString
                If blnIsConsole Then
                    i = i + 1
                    WScript.StdOut.Write vbCr & "Обнаружено: " & i
                End If
            Next
            '------
            Set objFile = objFS.CreateTextFile(strLog, True)
            '--- Формирование таблицы соответствий IP-адресов и DNS-имён
            If blnIsConsole Then WScript.Echo vbNewLine & "Формирование таблицы соответствий IP-адресов и DNS-имён компьютеров домена..."
            Set objDictDNS = CreateObject("Scripting.Dictionary")
            objDictDNS.CompareMode = 1
            Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strDNS & "\root\MicrosoftDNS")
            Set objCollection = objWMI.ExecQuery("SELECT * FROM MicrosoftDNS_AType")
            For Each objItem In objCollection
                strComputer = UCase(objItem.OwnerName)
                If objDictComputers.Exists(strComputer) Then
                    strTemp = objItem.IPAddress
                    If objDictDNS.Exists(strTemp) Then
                        objFile.WriteLine strComputer & " -> " & strTemp & " (запись-дубликат)"
                        If blnIsConsole Then WScript.Echo strComputer & " -> " & strTemp & " (запись-дубликат)"
                    Else
                        objDictDNS.Add strTemp, strComputer
                        objFile.WriteLine strComputer & " -> " & strTemp
                        If blnIsConsole Then WScript.Echo strComputer & " -> " & strTemp
                    End If
                End If
            Next
            '------
            objFile.Close
            Set objItem = Nothing: Set objCollection = Nothing: Set objWMI = Nothing
            Set objDictComputers = Nothing: Set objDictDNS = Nothing
            Set objFile = Nothing
            If blnIsConsole Then
                WScript.Echo "======" & vbNewLine & "Путь к файлу отчёта: " & UCase(strLog)
            Else
                Set objWShell = CreateObject("WScript.Shell")
                objWShell.Run "notepad.exe " & strLog, 1
                Set objWShell = Nothing
            End If
        Else
            WScript.Echo "DNS-сервер не обнаружен."
        End If
    Else
        WScript.Echo "Не ответил ни один контроллер домена."
    End If
    Set objFS = Nothing
    WScript.Quit 0
    
    '======
    
    Function Find_DNS(arrDCs()) 'Поиск DNS-сервера в массиве контроллеров домена
    Dim objWMI, strTemp, i
    
    On Error Resume Next
    For i = 0 To UBound(arrDCs)
        Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & arrDCs(i) & "\root\MicrosoftDNS")
        If Err.Number <> 0 Then
            Err.Clear
        Else
            Set objWMI = Nothing
            strTemp = arrDCs(i)
            Exit For
        End If
    Next
    On Error GoTo 0
    Find_DNS = strTemp
    End Function
    
    '======
    
    Function Available(strName, blnIsCon) 'Проверка доступности узла
    If blnIsCon Then
            Dim objExec, objOutStream, strTemp
            Set objExec = CreateObject("WScript.Shell").Exec("ping -n 1 -w 130 " & strName)
            Set objOutStream = objExec.StdOut
            While Not objOutStream.AtEndOfStream
                strTemp = strTemp & Trim(objOutStream.ReadLine)
            Wend
            Set objOutStream = Nothing
            Set objExec = Nothing
            If InStr(1, strTemp, "TTL", vbTextCompare) > 0 Then
                Available = True
            Else
                Available = False
            End If
    Else
        Dim objWMI, objItem
        On Error Resume Next
        Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery("SELECT StatusCode FROM Win32_PingStatus WHERE Address='" & strName & "'")
        If Err.Number = 0 Then
            For Each objItem In objWMI
                If IsNull(objItem.StatusCode) Then
                    Available = False
                Else
                    Available = (objItem.StatusCode = 0)
                End If
            Next
        Else
            Err.Clear
            Available = False
        End If
        Set objItem = Nothing
        Set objWMI = Nothing
        On Error GoTo 0
    End If
    End Function

    • Помечено в качестве ответа СГГ 2 июля 2013 г. 6:19
  • Неплохо, даже очень. Проверю как будет работать с русскими именами. Скрипт практически написан под мою задачу. Спасибо.

    Вижу хорошо пользуетесь WMI. Можете посоветовать хорошие ссылки ?

  • ... Вижу хорошо пользуетесь WMI. Можете посоветовать хорошие ссылки ?

    Если речь о ресурсах, сторонних по отношению к ресурсам MS, то неплохой материал для начинающих можно найти, например, здесь: Разработка скриптов от "Серого форума".
    • Помечено в качестве ответа СГГ 2 июля 2013 г. 8:54