Pull to refresh

Инвентаризация малой кровью

Reading time 4 min
Views 5.3K
Однажды потребовалось провести «инвентаризацию», то есть узнать за каким компьютером, какой пользователь сидит.

Вариант пройти по рабочим местам посмотреть, поспрашивать, был отброшен, как еретический.
Так как все пользователи заведены в Службе каталогов 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

Ну, вот и все нужные данные получены, причем, даже если они изменятся в дальнейшем получить их, не будет проблемой (если конечно служба каталогов не будет реорганизована). И что самое главное не пришлось бегать, всему предприятию в поисках компов и пользователей.
Tags:
Hubs:
+3
Comments 11
Comments Comments 11

Articles