Однажды потребовалось провести «инвентаризацию», то есть узнать за каким компьютером, какой пользователь сидит.
Вариант пройти по рабочим местам посмотреть, поспрашивать, был отброшен, как еретический.
Так как все пользователи заведены в Службе каталогов Active Directory, так же, как и рабочие места, родилась идея выдрать всю необходимую информацию из AD. Можно, конечно было обратиться к администратору домена и спросить все данные у него, но мы не ищем легких путей.
Итак, для инвентаризации Нужно:
И самое главное условие — это крайнее нежелание ставить на комп каких-либо сторонних приложений, писать приложение на «правильных» языках, тоже было лень. Поэтому для реализации был выбран VBS, так как в нем есть все, что необходимо и ничего дополнительно ставить не нужно и среда для него самая легковесная — notepad.exe.
С сетевыми именами все просто, они есть в службе каталогов. Пример работы с AD из VBS нагуглился довольно быстро. Для получения списка атрибутов объектов использовался скрипт написанный
товарищем Andrew J. Healey listAllProperties
Так что получить имена компьютеров получилось таким нехитрым скриптом.
Далее, нужно получить мак адрес этих компов. Тут все просто, при помощи стандартной утилиты «nbtstat» с параметром "-a" можно получить искомое(есть конечно еще вариант с arp -a, но работает не всегда).
Теперь возникает вопрос: «А где собсно взять список пользователей зарегистрированных на данном компьютере?». Путем непродолжительного гугления было найдено множество способов, которые сводились к удаленному выполнению wmi скрипта. Этот путь мне не подходил, так как в домене запрещено удаленное выполнение скриптов. И тут вспомнилось, что в Windows по умолчанию доступны для чтения по сети, 2 ветки реестра, а именно «HKEY_USERS» и «HKEY_LOCAL_MACHINE».
Значит, получить SID для зарегистрированных пользователей можно получить при помощи утилиты «reg» и в этом нам поможет код, который мы использовали для получения MAC адреса, все, что в нем нужно изменить так это шаблон для регулярки, и текст команды.
Ну, хорошо сиды у нас есть, но они на ФИО не похожи, совсем. Чтобы получить ФИО опять придется обращаться к AD.
У каждого объекта в AD есть поле «objectSID», а значит выбрать инфу о пользователе можно, поэтому самому сиду. Для этого возьмем код, который мы использовали для получения списка компьютеров, и изменим в нем запрос в поле «cmd.commandtext»:
Ну, вот и все нужные данные получены, причем, даже если они изменятся в дальнейшем получить их, не будет проблемой (если конечно служба каталогов не будет реорганизована). И что самое главное не пришлось бегать, всему предприятию в поисках компов и пользователей.
Вариант пройти по рабочим местам посмотреть, поспрашивать, был отброшен, как еретический.
Так как все пользователи заведены в Службе каталогов Active Directory, так же, как и рабочие места, родилась идея выдрать всю необходимую информацию из AD. Можно, конечно было обратиться к администратору домена и спросить все данные у него, но мы не ищем легких путей.
Итак, для инвентаризации Нужно:
- Сетевое имя компьютера.(Все компьтеры под Win разных версий)
- Мак адрес этого компьютера.(Все компьютеры находятся в одной подсети 255.255.0.0)
- ФИО пользователя, который за этим компом закреплен.
И самое главное условие — это крайнее нежелание ставить на комп каких-либо сторонних приложений, писать приложение на «правильных» языках, тоже было лень. Поэтому для реализации был выбран VBS, так как в нем есть все, что необходимо и ничего дополнительно ставить не нужно и среда для него самая легковесная — notepad.exe.
С сетевыми именами все просто, они есть в службе каталогов. Пример работы с AD из VBS нагуглился довольно быстро. Для получения списка атрибутов объектов использовался скрипт написанный
товарищем Andrew J. Healey listAllProperties
Так что получить имена компьютеров получилось таким нехитрым скриптом.
set cn=CreateObject("ADODB.Connection")
set cmd=CreateObject("ADODB.Command")
cn.Provider="ADsDSOObject"
cn.Open "Active Directory Provider"
set cmd.ActiveConnection=cn
используя SQL диалект запросов к Active directory выбираем все обекты класса "Computer"
cmd.CommandText="SELECT * FROM 'LDAP://DC=***,DC=ru' WHERE objectClass='Computer'"
set objRecordSet=cmd.Execute
on error resume next
do while Not objRecordSet.Eof
set objComputer=GetObject(objRecordSet("adspath"))
'путем бесчеловечных экспериментов было выяснено, что если путь содержит данную фразу
'то это демонтированное оборудование, или уволенный работник
if(inSTR(1,objComputer.distinguishedName,"OU=Garbage",vbTextCompare) = 0)then
wscript.echo objComputer.CN 'В данном поле и хранилось заветное сетевое имя
end if
objRecordSet.MoveNext
Loop
Далее, нужно получить мак адрес этих компов. Тут все просто, при помощи стандартной утилиты «nbtstat» с параметром "-a" можно получить искомое(есть конечно еще вариант с arp -a, но работает не всегда).
set oShell=Wscript.CreateObject("wscript.shell")
set re=new regexp
'Регулярка для поиска MAC адреса
re.Pattern = "[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}"
' В данном случае ComputerNetworkName имя компа которое мы взяли из AD
set oExec=oShell.Exec("nbtstat -a" & ComputerNetworkName)
for each obj in re.execute(oExec.StdOut.ReadAll)
GetData=obj.value
next
Теперь возникает вопрос: «А где собсно взять список пользователей зарегистрированных на данном компьютере?». Путем непродолжительного гугления было найдено множество способов, которые сводились к удаленному выполнению wmi скрипта. Этот путь мне не подходил, так как в домене запрещено удаленное выполнение скриптов. И тут вспомнилось, что в Windows по умолчанию доступны для чтения по сети, 2 ветки реестра, а именно «HKEY_USERS» и «HKEY_LOCAL_MACHINE».
Значит, получить SID для зарегистрированных пользователей можно получить при помощи утилиты «reg» и в этом нам поможет код, который мы использовали для получения MAC адреса, все, что в нем нужно изменить так это шаблон для регулярки, и текст команды.
set oShell=Wscript.CreateObject("wscript.shell")
set re=new regexp
'Регулярка для поиска SID в выводе команды reg query
re.Pattern = "S-\d+-\d+-\d+-\d+-\d+-\d+-\d+"
' В данном случае ComputerNetworkName имя компа которое мы взяли из AD
set oExec=oShell.Exec("reg query \\" & iComputerNetworkName&"\HKEY_USERS")
for each obj in re.execute(oExec.StdOut.ReadAll)
GetData=obj.value
next
Ну, хорошо сиды у нас есть, но они на ФИО не похожи, совсем. Чтобы получить ФИО опять придется обращаться к AD.
У каждого объекта в AD есть поле «objectSID», а значит выбрать инфу о пользователе можно, поэтому самому сиду. Для этого возьмем код, который мы использовали для получения списка компьютеров, и изменим в нем запрос в поле «cmd.commandtext»:
dim cn,cmd,objRecordSet
set cn=CreateOBject("ADODB.Connection")
set cmd=CreateObject("ADODB.Command")
cn.Provider="ADsDSOObject"
cn.Open "Active Directory Provider"
set cmd.ActiveConnection=cn
' objSid это сиды которые мы получили из реестра.
cmd.CommandText="SELECT * FROM 'LDAP://DC=***,DC=ru' where objectClass='User' and objectSid='"& objSid &"' "
set objRecordSet=cmd.Execute
'Вдруг пользователя с таким сидом нет
if( not objRecordSet.Eof) then
set objUser=GetObject(objRecordSet("adspath"))
if(inSTR(1,objUser.distinguishedName,"OU=Garbage",vbTextCompare) = 0)then
' Если он всетаки есть, и еще и не в мусоре, выводим его данные.
Wscript.Echo objUser.FirstName &" "& objUser.LastName &" "& objUser.Patronim
end if
end if
Ну, вот и все нужные данные получены, причем, даже если они изменятся в дальнейшем получить их, не будет проблемой (если конечно служба каталогов не будет реорганизована). И что самое главное не пришлось бегать, всему предприятию в поисках компов и пользователей.