Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Заполнение "Описание" для компа в АД именем залогиненного юзера (http://forum.oszone.net/showthread.php?t=192818)

HOLY DIVER 02-12-2010 08:28 1556388

Заполнение "Описание" для компа в АД именем залогиненного юзера
 
Доброго времени суток.
Стоит такая задача: в поле "описание" для компьютеров в домене прописать имя залогиненного на данном компьютере пользователя в виде "Фамилия Имя Отчество".
Нашел скрипт, который пишет в виде "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



Взято отсюда

Petya V4sechkin 02-12-2010 12:19 1556525

CMD/BAT - заполнить "описание компьютера"

HOLY DIVER 03-12-2010 08:22 1557241

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



Есть решение на CMD (спасибо smaharbA ), но малогибкое:

Код:

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 1564568

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

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

Код:

@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 2011941

HOLY DIVER, а не проще использовать переменную текущего пользователя %username% !?

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

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

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

DmitriiV 25-10-2012 16:05 2012024

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 2012353

Цитата:

Цитата DmitriiV
sea707, такая задача несложно решается на клиентах без всяких утилит. »

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

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

sea707 26-10-2012 06:09 2012364

ПопробЫвал переконвентировать с помошью программы ExeScript в файл exe, но всё равно пишет запрещено....

DmitriiV 26-10-2012 08:41 2012395

Цитата:

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

Если запрет накладывается пользовательской групповой политикой, то единственный легальный способ - запуск сценария от имени "учётки", на которую запрет не распространяется.
Впрочем, попробуйте выполнить этот код в составе макроса для какого-нибудь приложения из комплекта MS Office.


Время: 01:31.

Время: 01:31.
© OSzone.net 2001-