PDA

Показать полную графическую версию : [решено] Заполнение "Описание" для компа в АД именем залогиненного юзера


HOLY DIVER
02-12-2010, 08:28
Доброго времени суток.
Стоит такая задача: в поле "описание" для компьютеров в домене прописать имя залогиненного на данном компьютере пользователя в виде "Фамилия Имя Отчество".
Нашел скрипт, который пишет в виде "domain\username".
Есть идеи как писать туда именно ФИО данного пользователя?


Option Explicit
Dim rootDSE,strDomainDN,objConnection
Dim strSubContainer,objCommand,objRecordSet
Dim strMsg, arrDescription, strAccountProp, objComputer, strLoggedOnUser
'определяем константы
'символ-разделитель, используемый для формирования строки отчета
Const SPLITER = ","
'констатны, определяющие глубину поиска
Const ADS_SCOPE_SUBTREE = 2
Const ADS_SCOPE_ONELEVEL = 1
'константа, выделяющая бит Enable|Disable из мультибитового атрибута userAccountControl
Const ADS_UF_ACCOUNTDISABLE = 2
'зададим контейнер AD, начиная с которого будем осуществлять поиск
strSubContainer="OU=WorkStations,OU=ORG,"
'получим DN домена
Set rootDSE = GetObject("LDAP://rootDSE")
strDomainDN = rootDSE.Get("defaultNamingContext")
'Выполняем подготовку обращения к AD при помощи ADODB
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
'формируем SELECT-запрос к AD
objCommand.CommandText = "Select Name, " &_
"operatingSystem, operatingSystemServicePack, Description, userAccountControl, distinguishedName " &_
"from 'LDAP://"&strSubContainer&strDomainDN&"' " &_
"Where objectClass='computer'"
'определим максимальное количество объектов, возвращаемых в результирующем наборе записей
objCommand.Properties("Page Size") = 1000
'будем производить поиск по всему поддереву, начиная с заданного каталога
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 'ADS_SCOPE_ONELEVEL 'ADS_SCOPE_SUBTREE
'выполняем сформированный запрос, результатом которого является набор записей objRecordSet
Set objRecordSet = objCommand.Execute
If objRecordSet.RecordCount<1 Then
WScript.Echo "No computer accounts found in "&strContainer&strDomainDN
WScript.Quit
End If
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
''Выбираем только компьютеры, у которых Account установлен в Enabled
''If ((InStr(objRecordSet.Fields("operatingSystem"),"XP")>0) And (InStr(objRecordSet.Fields("operatingSystemServicePack"),"2")>0)) Then
If (objRecordSet.Fields("userAccountControl").Value And ADS_UF_ACCOUNTDISABLE)=0 Then
'формируем строку отчета
strMsg = objRecordSet.Fields("Name").Value & _
SPLITER & objRecordSet.Fields("operatingSystem").Value & _
SPLITER & strAccountProp
arrDescription = objRecordSet.Fields("Description").Value
If Not IsNull (arrDescription) Then
strMsg = strMsg & SPLITER & arrDescription(0)
End If
WScript.Echo strMsg
'Вызываем функцию, возвращающую имя залогоненного пользователя на компьютере,
'имя компьютера передается в функцию в качестве параметра
strLoggedOnUser = fnGetUserName (objRecordSet.Fields("Name").Value)
WScript.Echo "LoggedonUser :" & strLoggedOnUser
'если имя залогонненого пользователя не пусто...
If (Not IsEmpty(strLoggedOnUser)) And (Not IsNull (strLoggedOnUser)) Then
'...записываем его в атрибут Description
Set objComputer = GetObject("LDAP://"&objRecordSet.Fields("distinguishedName").Value)
objComputer.Put "Description" , strLoggedOnUser
objComputer.SetInfo
End If
End If
objRecordSet.MoveNext
Loop
'
'Эта функция опрашивает компьютер, чье имя передано ей в качестве параметра и
'возвращает имя залогоненного на опрашиваемом компьютере пользователя
Function fnGetUserName (strComputer)
On Error Resume Next
Dim objWMIService, colItems, objItem
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_ComputerSystem", "WQL", _
wbemFlagReturnImmediately + wbemFlagForwardOnly)

For Each objItem In colItems
fnGetUserName = objItem.UserName
Next
On Error GoTo 0
End Function


Взято отсюда (http://shss.wordpress.com/2010/01/21/set-logged-on-user-name-as-value-of-description-attribute-of-computer-object-in-ad/)

Petya V4sechkin
02-12-2010, 12:19
CMD/BAT - заполнить "описание компьютера" (http://forum.oszone.net/thread-189534.html)

HOLY DIVER
03-12-2010, 08:22
Petya V4sechkin, эту (пункт "Описание" в свойствах Моего компьютера на каждой юзерской машине) задачу решил. Мне же надо "Описание" у компьютера в оснастке Active Directory - Пользователи и Компьютеры:

http://i038.radikal.ru/1012/9d/86dfa3f038fb.png

Есть решение на CMD (спасибо smaharbA (http://forum.script-coding.info/profile.php?id=2911) ), но малогибкое:


echo off
setlocal ENABLEDELAYEDEXPANSION
set exclude=proxy;pavel igor,ws013
for %%i in (%exclude%) do (
set "regexclude=!regexclude! \<%%i\>"
)
set domain=
set user=
for /f "delims=\ " %%i in ('net view ^| find "\\"') do (
set comp=%%~i
ping -n 1 -w 10 !comp! > nul 2>&1 && dsquery server -o rdn | find /v /i "!comp!" > nul && echo !comp! | findstr /i /v /r "%regexclude%" > nul && (
for /f "tokens=2,3 delims==\" %%d in ('wmic /failfast:on /output:STDOUT /node:"!comp!" ComputerSystem get username /format:value 2^> nul ^| find "="') do (
set user=%%~e
set domain=%%~d
set domain=!domain:~0!
if /i "%userdomain%"=="!domain!" (
set user=!user:~0,-1!
net user "!user!" /domain > nul 2>&1 && (
for /f "delims=" %%u in ('dsquery user -samid "!user!" -scope subtree -o dn ^| dsget user -fn -mi -ln -display -L 2^> nul ^| find ": "') do (
set name=%%~u
set name=set !name:: ==!
!name!
)
set fullname=!fn! !mi! !ln!
set fullname=!fullname:"='!
set display=!display:"='!
dsquery computer domainroot -name "!comp!" -scope subtree -o dn | dsmod computer -desc "!fullname! (!display!)" 2> nul && echo !comp! - !fullname! (!display!^)
)
)
)
)
)

HOLY DIVER
13-12-2010, 07:08
Собственно, сделал предложенным способом, только немного модифицировал: скрипт не пробегает по всему домену, а запускается от каждого пользователя, причем с проверкой - если в дескрипшине у компьютера в АД уже есть такая же информация, которую он потенциально может записать, то ничего не делает. Если там что-то другое - то пишет.
Да, кстати, информацию по пользователю берет не из АД, а из реестра (правда, получается, что имя прошлого залогиненного пользователя).

Собственно, вот скрипт:


@echo off
setlocal ENABLEDELAYEDEXPANSION

FOR /F "tokens=2* delims= " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName') DO SET LastLogonUsername=%%B
ECHO Last Logon Username=%LastLogonUsername%

set domain=
set user=
set comp=%computername%
for /f "tokens=2,3 delims==\" %%d in ('wmic /failfast:on /output:STDOUT /node:"!comp!" ComputerSystem get username /format:value 2^> nul ^| find "="') do (
set user=%%~e
set domain=%%~d
set domain=!domain:~0!
if /i "%userdomain%"=="!domain!" (
set user=!LastLogonUsername!
net user "!user!" /domain > nul 2>&1 && (
for /f "delims=" %%u in ('dsquery user -samid "!user!" -scope subtree -o dn ^| dsget user -fn -mi -ln -display -L 2^> nul ^| find ": "') do (
set name=%%~u
set name=set !name:: ==!
!name!
)
set fullname=!fn! !mi! !ln!
set fullname=!fullname:"='!
set display=!display:"='!
dsquery computer -name "!comp!" | dsget computer -desc > c:\windows\temp\availabilty.txt
for /F "eol=d tokens=1,2,3 delims= " %%i in (c:\windows\temp\availabilty.txt) do set availabilty=%%i %%j %%k && echo "!availabilty!" && echo "!display! "
if "!availabilty!" NEQ "!display! " (
dsquery computer domainroot -name "!comp!" -scope subtree -o dn | dsmod computer -desc "!display!" 2> nul && echo !comp! - !fullname! (!display!^)
) else (
echo Equal
)
)
)
)

sea707
25-10-2012, 14:11
HOLY DIVER, а не проще использовать переменную текущего пользователя %username% !?

В реестре всё равно не храниться полная информация о предыдущем пользователе... правильно!?

Из ветки реестра (параметр DefaultUserName из HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon) берёться логин пользователя, далее в домене ищёться инфо о пользователе (ФИО пользователя) и записываеться в AD

Ещё вопрос, батчик выполняеться на клиентских машинах, а на них нет доменских утилит по работе с доменом (dsquery, dsget, dsmod) - как решал эту проблему!? Утилиты лежали вместо батчиком в одной папке или как!?

DmitriiV
25-10-2012, 16:05
sea707, такая задача несложно решается на клиентах без всяких утилит.
Простой пример на VBS:
Dim strUser, objComputer
strUser = GetObject("LDAP://" & CreateObject("ADSystemInfo").UserName).FullName
Set objComputer = GetObject("LDAP://" & CreateObject("ADSystemInfo").ComputerName)
On Error Resume Next
objComputer.Put "Description" , strUser
objComputer.SetInfo
If Err.Number <> 0 Then Err.Clear
Set objComputer = Nothing
WScript.Quit 0

Главное, чтобы "учётке", от имени которой вносятся изменения в атрибут AD, хватало для этого полномочий.

sea707
26-10-2012, 04:17
sea707, такая задача несложно решается на клиентах без всяких утилит. »

Работает, но у нас запрещено выполнение скриптов VBS, можно как-нибудь выполнить при существующем запрете!?

Снять запрет не предлагать )))

sea707
26-10-2012, 06:09
Попробывал переконвентировать с помошью программы ExeScript в файл exe, но всё равно пишет запрещено....

DmitriiV
26-10-2012, 08:41
... можно как-нибудь выполнить при существующем запрете!?Если запрет накладывается пользовательской групповой политикой, то единственный легальный способ - запуск сценария от имени "учётки", на которую запрет не распространяется.
Впрочем, попробуйте выполнить этот код в составе макроса для какого-нибудь приложения из комплекта MS Office.




© OSzone.net 2001-2012