Добрый день наблюдатели НЛО
Хотел описать, как собирал информацию о пользователях из AD и затем размещал информацию на SharePoint для удобочитаемости и в любой момент посмотреть о том, или ином пользователе нужную для нас информацию.
Опишу просто, так как всё оно было…
Поставлена задача собрать из AD информацию о пользователях что можно выдернуть и определенные свои цели.
Из того что имелось: был выбран VBS для сбора информации о пользователях через LDAP, собираем все в простой текстовый файл (так как сбор происходит в нескольких сегментах разделенных между собой), файлы собираются в одном месте и затем с помощью PowerShell размещаем на подготовленном сайте SharePoint.
On Error Resume Next
Dim oQuery
Dim objConnection
Dim objCommand
Dim objRecordSet
Dim strMember
Dim strAC
Dim arrMember
' сюда сохраним всю информацию о пользователях
logfile = "users-lvs.txt"
Set objFSO = CreateObject("Scripting.FileSystemObject")
oQuery = "<LDAP://dc=my,dc=site>;" & _
"(objectCategory=user)" & _ ";distinguishedName,name,sAMAccountname,mail,memberOf,userAccountControl,description;subtree"
' выше перечислены поля из которых именно нам нужна информация о пользователе
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Open "Provider=ADsDSOObject;"
objCommand.ActiveConnection = objConnection
objCommand.CommandText = oQuery
Set objRecordSet = objCommand.Execute
' если нет файла - создаем, если есть - перезаписываем
if objFSO.FileExists(logfile) then
Set objFile = objFSO.OpenTextFile(logfile, 2)
objFile.Write ""
else
Set objFile = objFSO.CreateTextFile(logfile)
objFile.Close
Set objFile = objFSO.OpenTextFile(logfile, 2)
objFile.Write ""
end if
objFile.Close
' начинаем сбор, пока не закончатся объекты
While Not objRecordSet.EOF
strMember = objRecordSet.Fields("memberOf")
strStr = ""
For i = 0 To UBound(strMember)
' переменная где хранится длина символов до запятой
liluka = InStr(2, strMember(i), ",", vbTextCompare)
' все группы делаем в одну строку
strStr = strStr & Right(Left(strMember(i), liluka - 1), liluka - 4) & ", "
Next
arrOpis = objRecordSet.Fields("description")
strOpis = ""
For i = 0 To UBound(arrOpis)
strOpis = strOpis & arrOpis(i) & ", "
Next
' проверка признака отключен ли пользователь
Select Case objRecordSet.Fields("userAccountControl")
Case 512
strAC = "Нет"
Case 514
strAC = "Да"
Case 66048
strAC = "Нет"
Case 66050
strAC = "Да"
End Select
' запись всей информации в файл
Set objFile = objFSO.OpenTextFile(logfile, 8)
objFile.WriteLine objRecordSet.Fields("sAMAccountname") & ";1" & _
objRecordSet.Fields("name") & ";2" & _
objRecordSet.Fields("mail") & ";3" & _
strStr & ";4" & strAC & ";5" & strOpis & ";6ЛВС"
objFile.Close
objRecordSet.MoveNext
Wend
objConnection.Close
Из кода видно что в конце строки дописывается ";6ЛВС", как уже говорил выше сегментов у нас несколько и это первый из них ЛВС. С признаком отключен ли пользователь не стал долго думать и взял 4 встречающихся у нас значения, если усложнить жизнь и копаться то можно по битам читать переменную…
Что бы скрипт PowerShell понимал где какая информация находится, не придумал ни чего лучше чем как через точку с запятой ставить цифру обозначающую индекс определенной информации.
Не профессионал, а всего лишь любитель кода я, как программировать, так и анализа/разбора.
Собственно сам код PowerShell:
# заполнение страницы на шарепойнт информацией о пользователях из тхт файлов, построчно
write-host open Sharepoint from USERS
# sharepoint
$env:SPpath = "${env:CommonProgramFiles}Microsoft Sharedweb server extensions12"
[System.Reflection.Assembly]::LoadFrom("$env:SPPathISAPIMicrosoft.SharePoint.dll")
write-host open web
# открываем web
$nsite="http://my_site/sites/MonitorUser"
$SpSite = New-Object -TypeName "Microsoft.SharePoint.SPSite" -ArgumentList $nsite;
$spweb=$spsite.OpenWeb();
write-host open Sharepoint list
# открываем список
$nlist="http://my_site/sites/MonitorUser/Lists/List5/AllItems.aspx"
$splist=$spweb.getlist($nlist);
# очистим страницу
write-host clearing list...
$iCnt = $splist.Items.Count;
#$icnt;
for ($jj=1; $jj -le $iCnt; $jj++){
$splist.Items.Delete(0);
}
write-host clearing list Done
# перебираем информацию во всех тхт файлах, какие подходят под маску
write-host Processing log files...
foreach ($file in $(get-childitem 'D:scriptswork' -include users*.txt -recurse))
{
$hostout = $file.FullName + "..."
Write-Host $hostout
$fl = get-content $file.FullName;
# $fl;
for ($i=1; $i -lt $fl.Count; $i++)
{
$st1 =$fl[$i];
# делаем переменные наших признаков определенных данных
$ind1 = $st1.IndexOf(";1")
$ind2 = $st1.IndexOf(";2")
$ind3 = $st1.IndexOf(";3")
$ind4 = $st1.IndexOf(";4")
$ind5 = $st1.IndexOf(";5")
$ind6 = $st1.IndexOf(";6")
$stLogin = $st1.substring(0,$ind1)
$stUserName = $st1.substring($ind1+2,$ind2-$ind1-2)
$stMail = $st1.substring($ind2+2,$ind3-$ind2-2)
$ind7 = $ind4-$ind3
if ($ind7 -eq 2)
{
$stGroup = "Нет групп"
}
else
{
$stGroup = $st1.substring($ind3+2,$ind4-$ind3-4)
}
$ind7 = $ind6-$ind5
if ($ind7 -eq 2)
{
$stOpis = ""
}
else
{
$stOpis = $st1.substring($ind5+2,$ind6-$ind5-4)
}
$stBlock = $st1.substring($ind4+2,$ind5-$ind4-2)
$stSeg = $st1.substring($ind6+2,3)
# создаем запись на странице шарепойнт с нашими данными
$NewItem = $SpList.Items.Add();
$NewItem["Логин"] = $stLogin;
$NewItem["Полное имя"] = $stUserName;
$NewItem["e-mail"] = $stMail;
$NewItem["Группы"] = $stGroup;
$NewItem["Отключен"] = $stBlock;
$NewItem["Сегмент"] = $stSeg;
$NewItem["Описание"] = $stOpis;
$NewItem.Update();
}
}
write-host Processing log files DONE
$spweb.Dispose();
$spsite.Dispose();
write-host Program END
Теперь после того как собрали тхт в одном месте, запускаем батник
cscript users-lvs.vbs
%SystemRoot%system32WindowsPowerShellv1.0powershell.exe "& 'D:scriptsworkusers.ps1'"
%SystemRoot%system32WindowsPowerShellv1.0powershell.exe "& 'D:scripts workpk.ps1'"
Так как наш сайт выполняется в сегменте ЛВС то заодно и обновляется у нас информация по данным пользователям. И как вы могли заметить, рабочий скрипт собирает информацию по компьютерам (ОС, версия, пак, описание, когда включался), но там все по аналогии как с пользователями.
Самое долгое, что занимает во всем, это – очищение страницы с информацией (примерно 2-3 минуты). Если страницы чисты, то сбор и обработка нескольких файлов в общей сложности занимает не более 30 секунд, 700-800 записей.
На самом деле в LDAP много лежит информации и свой рабочий скрипт дополнил тем, что он смотрит когда пользователь заходил последний раз а так же когда менял пароль крайний раз. В WMI есть «directoryLDAP» и там в принципе можно найти много интересной информации.
P.S. На быстро руку набросал, рад буду любой критике, а лучше советам как улучшить, где какие моменты не нравятся и почему, аргументировав это…
Автор: fulse