PDA

Показать полную графическую версию : [решено] nslookup для парка ПК


HFShak
05-10-2011, 16:59
Добрый день!
Народ, помогите пожалуйста написать скрипт.
Есть файл pc.txt , в котором содержутся имена компьютеров.

Содержание pc.txt:

NAMEPC1
NAMEPC2
NAMEPC3
...


В текстовом файле на каждой строке по одному имени ПК, имена не содержат общих элементов и длинна имен может различаться по кол-ву символов.
Нужно написать скрипт, который для кажного ПК выполняет команду nslookup.
Все собранные данные записываются с один текстовый файл report.txt, желательно в таком порядке:

NAMEPC1 = 10.4.27.7
NAMEPC2 = *** srv.domain.ru не удалось найти NAMEPC2: Non-existent domain
NAMEPC3 = 10.12.16.14
...

Iska
05-10-2011, 18:36
HFShak, попробуйте так:
@echo off
setlocal enableextensions enabledelayedexpansion

set sFileSource=%~1
set sLog=%~2

if defined sFileSource (
if defined sLog (
if exist "%sFileSource%" (
>nul copy nul "%sLog%"

for /f "usebackq tokens=*" %%i in ("%sFileSource%") do (
set sName=
set sAddresses=

for /f "tokens=1,2* delims=,: " %%j in ('nslookup "%%i" 2^>^&1 ^| findstr.exe /r /i /c:"Name: " /c:"Addresses: " /c:"\*\*\* "') do (
if "%%j" equ "***" (
set s%%j=%%k %%l
) else (
set s%%j=%%k
)
)

>>"%sLog%" (
if defined sName (
echo !sName! = !sAddresses!
) else (
echo %%i = !s***!
)
)
)
) else (
echo File with Names list [%sFileSource%] not found
)
) else (
call :Usage
exit /b 1
)
) else (
call :Usage
exit /b 1
)

endlocal
exit /b 0

:Usage
echo Usage: %~nx0 ^<Names list^> ^<Log file^>
exit /b 0

HFShak
06-10-2011, 09:19
sFileSource=%userprofile%\desktop\pc.txt
sLog=%userprofile%\desktop\report.txt

Я правильно задал переменные?, никакие знаки "%" не упустил?

Программа подвисает сильно во время выполнения, в процесса появляется очень много cmd.exe. Завершил задачу, т.к. начали появлятся диалоговые окна с ошибками cmd.
Файл report.txt заполняется так:
PCNAME1 =
PCNAME2 =
PCNAME3 =
...

После равно не появляется ip.

Petya V4sechkin
06-10-2011, 09:24
в процесса появляется очень много cmd.exe
И как же вы назвали CMD-файл? Только не говорите, что nslookup.cmd (или .bat).

HFShak
06-10-2011, 09:25
Блин именно nslookup.cmd )
Переименовал в 123.cmd, скрип отработал, файл почти правильно заполнился, т.е.:

PCNAME1 =
PCNAME2 =
PCNAME3 = srv.domain.ru *Ґ г¤ «®бм * ©вЁ PCNAME3: Non-existent domain
PCNAME4 = srv.domain.ru *Ґ г¤ «®бм * ©вЁ PCNAME4: Non-existent domain
PCNAME5 = srv.domain.ru *Ґ г¤ «®бм * ©вЁ PCNAME5: Non-existent domain
PCNAME6 = srv.domain.ru *Ґ г¤ «®бм * ©вЁ PCNAME6: Non-existent domain
...

Не прописывается ip адрес у тех ПК, которые реализовываются на dns.

Petya V4sechkin
06-10-2011, 09:39
HFShak, попробуйте в скрипте заменить Addresses на Address.

HFShak
06-10-2011, 10:40
В скрипте какая-то ошибка:


C:\>setlocal enableextensions enabledelayedexpansion

C:\>set sFileSource=C:\pc.txt

C:\>set sLog=C:\report.txt

C:\>if defined sFileSource (if defined sLog (if exist "C:\pc.txt" (copy nul "C:\report.txt" 1>nul for /F "usebackq tokens=*" %i in ("C:\pc.txt")
do (
set sName=
set sAddress=
for /F "tokens=1,2* delims=,: " %j in ('nslookup "%i" 2>&1 | findstr.exe /r /i /c:"Name: " /c:"Address: " /c:"\*\*\* "')
do (if "%j" EQU "***" (set s%j=%k %l ) else (set s%j=%k ) )
(if defined sName (echo !sName! = !sAddress! ) else (echo %i = !s***! ) ) 1>>"C:\report.txt"))
else (echo File with Names list [C:\pc.txt] not found ) ) else (call :Usage exit /b 1) ) else (call :Usage exit /b 1)





C:\>(
set sName=
set sAddress=
for /F "tokens=1,2* delims=,: " %j in ('nslookup "PCNAME1" 2>&1 | findstr.exe /r /i /c:"Name: " /c:"Address: " /c:"\*\*\* "') do (if "%j" EQU "***"
(set s%j=%k %l ) else (set s%j=%k ) )
(if defined sName (echo !sName! = !sAddress! ) else (echo PCNAME1 = !s***! )) 1>>"C:\report.txt")

C:\>(if "Address" EQU "***" (set sAddress=10.4.27.7 ) else (set sAddress=10.4.27.7 ) )

C:\>(if "Address" EQU "***" (set sAddress=10.1.92.228 ) else (set sAddress=10.1.92.228 ) )

C:\>(
set sName=
set sAddress=
for /F "tokens=1,2* delims=,: " %j in ('nslookup "PCNAME2" 2>&1 | findstr.exe /r /i /c:"Name: " /c:"Address: " /c:"\*\*\* "') do (if "%j" EQU "***"
(set s%j=%k %l ) else (set s%j=%k ) )
(if defined sName (echo !sName! = !sAddress! ) else (echo PCNAME2 = !s***! )) 1>>"C:\report.txt")

C:\>(if "Address" EQU "***" (set sAddress=10.4.27.7 ) else (set sAddress=10.4.27.7 ) )

C:\>(if "Address" EQU "***" (set sAddress=10.1.92.127 ) else (set sAddress=10.1.92.127 ) )

C:\>(
set sName=
set sAddress=
for /F "tokens=1,2* delims=,: " %j in ('nslookup "PCNAME3" 2>&1 | findstr.exe /r /i /c:"Name: " /c:"Address: " /c:"\*\*\* "') do (if "%j" EQU "***"
(set s%j=%k %l ) else (set s%j=%k ) )
(if defined sName (echo !sName! = !sAddress! ) else (echo PCNAME3 = !s***! ) ) 1>>"C:\report.txt")

C:\>(if "***" EQU "***" (set s***=srv.domain.ru не удалось ) else (set s***=srv.domain.ru ) ) main

C:\>(if "Address" EQU "***" (set sAddress=10.4.27.7 ) else (set sAddress=10.4.27.7 ) )

C:\>(
set sName=
set sAddress=
for /F "tokens=1,2* delims=,: " %j in ('nslookup "PCNAME4" 2>&1 | findstr.exe /r /i /c:"Name: " /c:"Address: " /c:"\*\*\* "') do (if "%j" EQU "***"
(set s%j=%k %l ) else (set s%j=%k ) )
(if defined sName (echo !sName! = !sAddress! ) else (echo PCNAME4 = !s***! ) ) 1>>"C:\report.txt")

C:\>(if "***" EQU "***" (set sAddress=10.4.27.7 ) else (set sAddress=10.4.27.7 ) )

C:\>(if "Address" EQU "***" (set sAddress=10.1.92.23 ) else (set sAddress=10.1.92.23 ) )

По факту:
У PCNAME1 ip адрес = 10.1.92.22
У PCNAME2 ip адрес = 10.1.92.127
У PCNAME3 ip адрес = не удалось
У PCNAME4 ip адрес = 10.1.92.23

В файле он записывает так:
PCNAME1 =
PCNAME2 =
PCNAME3 = srv.domain.ru *Ґ г¤*«®бм **©вЁ PCNAME3: Non-existent domain
PCNAME4 = srv.domain.ru *Ґ г¤*«®бм **©вЁ PCNAME4: Non-existent domain

Iska
06-10-2011, 13:00
И как же вы назвали CMD-файл? Только не говорите, что nslookup.cmd (или .bat). »
Моя вина. Сколько раз, сколько раз сам же зарекался обязательно писать расширения у исполняемых файлов… И опять пропустил.

HFShak, пакетный файл весьма критично зависит от формата вывода утилиты. Я ориентировался на вывод «nslookup.exe» из комплекта Windows XP SP3. При разработке использовал перечень общеизвестных доменных имён (не локальных!) и несколько заведомо несуществующих.

Посему проделайте следующее:

1. Подготовьте образец с реальными именами машин:
Содержание pc.txt:
NAMEPC1
NAMEPC2
NAMEPC3
... »
Достаточно будет три-четыре существующих имени, и пары несуществующих/отсутствующих.

2. Вручную проделайте операцию запроса «nslookup.exe» с каждым из подготовленных имён в «pc.txt», каждый раз перенаправляя вывод StdOut и StdErr в файл, наподобие:
>nul copy nul Out.txt
>>Out.txt nslookup.exe PCNAME1 2>&1
>>Out.txt nslookup.exe PCNAME2 2>&1

>>Out.txt nslookup.exe NONEXISTPCNAME 2>&1

3. Обязательно упакуйте файлы «pc.txt» и «Out.txt» в архив, затем отошлите мне его в личку (либо выложите его на обменник, а ссылку, опять же — в личку).

В этом случае я смогу составить представление о формате вывода утилиты в Вашем случае и, возможно, помочь.

Iska
10-10-2011, 23:21
HFShak, я был несколько ошарашен, когда увидел вывод Вашей «nslookup.exe»: в stdout в Ansi, в stderr — в OEM.

Попробуйте очередной вариант:
@echo off
setlocal enableextensions enabledelayedexpansion

set sFileSource=%~1
set sLog=%~2

call :GetTemporaryName
set sStdOut=%TemporaryName%

call :GetTemporaryName
set sStdErr=%TemporaryName%

if defined sFileSource (
if defined sLog (
if exist "%sFileSource%" (
>nul copy nul "%sLog%"

for /f "usebackq tokens=*" %%i in ("%sFileSource%") do (
echo Processing [%%i]...
set sName=
set sAddress=
set bCriticalError=

nslookup.exe "%%i" 1>"%sStdOut%" 2>"%sStdErr%"

<"%sStdErr%" set /p sError=

if defined sError (
if "!sError:~0,3!" equ "***" (
>>"%sLog%" echo %%i = !sError!
set bCriticalError=1
)
)

if not defined bCriticalError (
set /a iCount = 0
for /f "usebackq skip=3 tokens=2 delims=,: " %%j in ("%sStdOut%") do (
set /a iCount += 1

if !iCount! equ 1 set sName=%%j
if !iCount! equ 2 set sAddress=%%j
)
>>"%sLog%" echo !sName! = !sAddress!
)
)
) else (
echo File with Names list [%sFileSource%] not found
)
) else (
call :Usage
exit /b 1
)
) else (
call :Usage
exit /b 1
)

endlocal
exit /b 0
rem ==========================================================================

rem ==========================================================================
:Usage
echo Usage: %~nx0 ^<Names list^> ^<Log file^>
exit /b 0
rem ==========================================================================

rem ==========================================================================
rem Функция GetTemporaryName()
rem
rem Серый форум / CMD/BAT: генерация пути для временного файла или папки
rem (http://forum.script-coding.com/viewtopic.php?id=6259)
rem ==========================================================================
:GetTemporaryName
setlocal enableextensions enabledelayedexpansion

:NextName
set sTempName=%temp%\temp%random%.tmp

if exist "%sTempName%" goto :NextName

set sProcName=%~0

endlocal & set %sProcName:~4%=%sTempName%
exit /b 0
rem ==========================================================================

Iska
11-10-2011, 00:22
Учусь PowerShell'у:
$sMachineList = "E:\Песочница\0084\1\pc.txt"
$sLog = "E:\Песочница\0084\1\out.txt"

Clear-Content -Path $sLog -ErrorAction SilentlyContinue

Get-Content -Path $sMachineList |`
ForEach-Object {
$sHost = $_

try {
$aIPAddress = [System.Net.Dns]::GetHostAddresses($sHost)
$OutLine = $sHost + " = " + $aIPAddress[0].IPAddressToString
} catch {
$OutLine = $sHost + " = (" + $_.Exception.InnerException.Message + ")"
}

Write-Host $OutLine

Add-Content -Path $sLog -Value $OutLine
}

HFShak
11-10-2011, 09:24
HFShak, я был несколько ошарашен, когда увидел вывод Вашей «nslookup.exe»: в stdout в Ansi, в stderr — в OEM. »
Спасибо! Есть небольшая проблема...
Все записывает правильно, до того момента пока не находит ПК в домене. После этого он всегда пишет "ПК не найден в домене"....

Т.е.:

pc.txt:
NAMEPC1
NAMEPC2
NAMEPC3
NAMEPC1
...


Out.txt:
NAMEPC1 = 10.1.1.15
NAMEPC2 = 10.1.1.23
NAMEPC3 = Не найден
NAMEPC1 = Не найден
...


В чем причина?

Iska
11-10-2011, 10:05
HFShak, погляжу вечером.

Iska
11-10-2011, 21:05
HFShak, посмотрел.

Попробуйте добавить:
>nul copy nul "%sStdOut%"
>nul copy nul "%sStdErr%"
перед:
nslookup.exe "%%i" 1>"%sStdOut%" 2>"%sStdErr%"

HFShak
12-10-2011, 09:27
Не помогло, тоже самое...
Переменный задал такие:

set sFileSource=%userprofile%\desktop\pc.txt
set sLog=%userprofile%\desktop\Out.txt

call :GetTemporaryName
set sStdOut=%userprofile%\desktop\StdOut.txt

call :GetTemporaryName
set sStdErr=%userprofile%\desktop\StdErr.txt

Созданные текстовые файлы текстовые отправил через ЛС.

Iska
19-10-2011, 12:04
HFShak, добрался до домена, посмотрел. Проблему подтверждаю.

Добавил принудительное обнуление переменной окружения «sError». Попробуйте теперь так:
@echo off
setlocal enableextensions enabledelayedexpansion

set sFileSource=%~1
set sLog=%~2

call :GetTemporaryName
set sStdOut=%TemporaryName%

call :GetTemporaryName
set sStdErr=%TemporaryName%

if defined sFileSource (
if defined sLog (
if exist "%sFileSource%" (
>nul copy nul "%sLog%"

for /f "usebackq tokens=*" %%i in ("%sFileSource%") do (
echo Processing [%%i]...
set sName=
set sAddress=
set sError=
set bCriticalError=

>nul copy nul "%sStdOut%"
>nul copy nul "%sStdErr%"

nslookup.exe "%%i" 1>"%sStdOut%" 2>"%sStdErr%"

<"%sStdErr%" set /p sError=

if defined sError (
if "!sError:~0,3!" equ "***" (
>>"%sLog%" echo %%i = !sError!
set bCriticalError=1
)
)

if not defined bCriticalError (
set /a iCount = 0
for /f "usebackq skip=3 tokens=2 delims=,: " %%j in ("%sStdOut%") do (
set /a iCount += 1

if !iCount! equ 1 set sName=%%j
if !iCount! equ 2 set sAddress=%%j
)
>>"%sLog%" echo !sName! = !sAddress!
)
)

if exist "%sStdOut%" del /f /q "%sStdOut%"
if exist "%sStdErr%" del /f /q "%sStdErr%"
) else (
echo File with Names list [%sFileSource%] not found
)
) else (
call :Usage
exit /b 1
)
) else (
call :Usage
exit /b 1
)

endlocal
exit /b 0
rem ==========================================================================

rem ==========================================================================
:Usage
echo Usage: %~nx0 ^<Names list^> ^<Log file^>
exit /b 0
rem ==========================================================================

rem ==========================================================================
rem Функция GetTemporaryName()
rem
rem Серый форум / CMD/BAT: генерация пути для временного файла или папки
rem (http://forum.script-coding.com/viewtopic.php?id=6259)
rem ==========================================================================
:GetTemporaryName
setlocal enableextensions enabledelayedexpansion

:NextName
set sTempName=%temp%\temp%random%.tmp

if exist "%sTempName%" goto :NextName

set sProcName=%~0

endlocal & set %sProcName:~4%=%sTempName%
exit /b 0
rem ==========================================================================

HFShak
19-10-2011, 12:18
Спасибо! Все работает.




© OSzone.net 2001-2012