Однажды потребовалось провести «инвентаризацию», то есть узнать за каким компьютером, какой пользователь сидит.
Вариант пройти по рабочим местам посмотреть, поспрашивать, был отброшен, как еретический.
Так как все пользователи заведены в Службе каталогов 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
Ну, вот и все нужные данные получены, причем, даже если они изменятся в дальнейшем получить их, не будет проблемой (если конечно служба каталогов не будет реорганизована). И что самое главное не пришлось бегать, всему предприятию в поисках компов и пользователей.
Автор: 0serd0