Имя пользователя:
Пароль:
 | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » VBS/WSH/JS - objUser.AccountDisabled - не разберусь с этим атрибутом

Ответить
Настройки темы
VBS/WSH/JS - objUser.AccountDisabled - не разберусь с этим атрибутом

Пользователь


Сообщения: 100
Благодарности: 0

Профиль | Отправить PM | Цитировать


Всем добрый день!

По наследству в организации, где работаю досталась настройка создания пользователей в AD (ws2019) из 1С через скрипт. Скрипт помещен в "Планировщик заданий" на DC и стартует каждые 30 мин.
Сам знакомлюсь с vbs только одну неделю) Насколько я разобрался, логика скрипта такая: скрипт парсит некий xml от вэб-сервера 1С на предмет поиска поля "Login" учетки и поступает следующими способами:
1. Если в xml есть логин учетки, которой нет в AD, то создает ее в OU=Users
2. Если в xml нет логина учетки, которая есть в AD, то отключает ее, в каком бы OU она не находилась при условии, что эта учетка не находится в группе безопасности "dontoff".
3. Если в xml нет логина учетки, которая есть в AD, то игнорирует ее, в каком бы OU она не находилась при условии, что эта учетка находится в группе безопасности "dontoff".
Работа скрипта логируется в "Журнале Приложений Windows DC". Если я не ошибаюсь, то сам скрипт "затыкается" в самом низу в блоке

Цитата:
objUser.AccountDisabled = True
Код: Выделить весь код
Const ADS_UF_SCRIPT = &H1
Const ADS_UF_ACCOUNTDISABLE = &H2
Const ADS_UF_HOMEDIR_REQUIRED = &H8
Const ADS_UF_LOCKOUT = &H10
Const ADS_UF_PASSWD_NOTREQD = &H20
Const ADS_UF_PASSWD_CANT_CHANGE = &H40
Const ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = &H80
Const ADS_UF_TEMP_DUPLICATE_ACCOUNT = &H100
Const ADS_UF_NORMAL_ACCOUNT = &H200
Const ADS_UF_INTERDOMAIN_TRUST_ACCOUNT = &H800
Const ADS_UF_WORKSTATION_TRUST_ACCOUNT = &H1000
Const ADS_UF_SERVER_TRUST_ACCOUNT = &H2000
Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000
Const ADS_UF_MNS_LOGON_ACCOUNT = &H20000
Const ADS_UF_SMARTCARD_REQUIRED = &H40000
Const ADS_UF_TRUSTED_FOR_DELEGATION = &H80000
Const ADS_UF_NOT_DELEGATED = &H100000
Const ADS_UF_USE_DES_KEY_ONLY = &H200000
Const ADS_UF_DONT_REQUIRE_PREAUTH = &H400000
Const ADS_UF_PASSWORD_EXPIRED = &H800000
Const ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = &H1000000

Sub recursive(objUnit, objDict)
    itemExists = False
    For Each objMember in objUnit
        If InStr(1, objMember.objectCategory, "CN=Person", vbTextCompare) > 0 Then
            itemExists = objDict.Exists(objMember.sAMAccountName)
            If itemExists = False Then
                               objDict.Add objMember.sAMAccountName, objMember.distinguishedName
            End If
        Else
            recursive objMember, objDict
        End If
    Next
End Sub

On Error Resume Next

Set objShell = CreateObject("WScript.Shell")
objShell.LogEvent 0, "Script started"

Set objDictionary = CreateObject("Scripting.Dictionary")
objDictionary.CompareMode = vbTextCompare

' Bind to the rootDSE object.
Set objRootDSE = GetObject("LDAP://rootDSE")
If (Err.Number <> 0) Then
    objShell.LogEvent 1, "Error getting rootDSE: " & Err.Number & " - " & Err.Description
    WScript.Quit
End If
    
' Bind to the root container in the domain.
Set objUsers = GetObject("LDAP://" & objRootDSE.Get("defaultNamingContext"))
If (Err.Number <> 0) Then
    objShell.LogEvent 1, "Error getting root container: " & Err.Number & " - " & Err.Description
    WScript.Quit
End If

recursive objUsers, objDictionary





Set xmlHttp = CreateObject("MSXML2.ServerXMLHTTP")
xmlHttp.SetOption(2) = (xmlHttp.GetOption(2) - SXH_SERVER_CERT_IGNORE_ALL_SERVER_ERRORS)
xmlHttp.Open "GET", "https://1c.contora.ru/Person", False, "login", "password"
xmlHttp.send ("")

If Not xmlHttp.status = 200 Then
    objShell.LogEvent 1, "Error receiving xml: " & xmlHttp.status & " - " & xmlHttp.statusText
    WScrit.Quit
End If





Set xmlParser = CreateObject("MSXML2.DOMDocument")
xmlParser.async = False
xmlParser.loadXML(xmlHttp.responseText)
Set xmlHttp = Nothing

If xmlParser.parseError.errorCode Then
    objShell.LogEvent 1, "Error parsing xml: " & xmlParser.parseError.errorCode & " - " & xmlParser.parseError.reason
    WScript.Quit
End If





' Bind to the Users folder in the domain.
Set objUsers = GetObject("LDAP://CN=Users," & objRootDSE.Get("defaultNamingContext"))
If (Err.Number <> 0) Then
    objShell.LogEvent 1, "Error getting Users container: " & Err.Number & " - " & Err.Description
    WScript.Quit
End If

Set nodes = xmlParser.getElementsByTagName("Person")
For Each node In nodes
Do

    strLogin = Trim(node.getAttribute("Login"))
    If IsNull(strLogin) Or Len(strLogin) = 0 Then
        Exit Do
    End If

    Set objUser = Nothing
    If objDictionary.Exists(strLogin) Then
        Set objUser = GetObject("LDAP://" & objDictionary(strLogin))
        objDictionary.Remove(strLogin)
    End If

    strFullName = Trim(node.getAttribute("FullName"))
    If IsNull(strFullName) Or Len(strFullName) = 0 Then
        Exit Do
    End If
    
    IsNewUser = False
    
    If objUser Is Nothing Then
        Err.Clear
	Set objUser = objUsers.Create("user", "CN=" & strFullName)
        If (Err.Number <> 0) Then
	    objShell.LogEvent 1, "Error creating user" & strLogin & ": " & Err.Number & " - " & Err.Description
            Exit Do
        End If
        IsNewUser = True
    Else
        objShell.LogEvent 0, "Found user " & strLogin
    End If

    strFirstName = Trim(node.getAttribute("FirstName"))
    If IsNull(strFirstName) Then
        strFirstName = ""
    End If
    
    strMiddleName = Trim(node.getAttribute("MiddleName"))
    If IsNull(strMiddleName) Then
        strMiddleName = ""
    End If
    
    strLastName = Trim(node.getAttribute("LastName"))
    If IsNull(strLastName) Then
        strLastName = ""
    End If
    
    Err.Clear
    objUser.sAMAccountName    = strLogin
    objUser.displayName       = strFullName
    objUser.givenName         = strFirstName
    objUser.initials          = Left(strMiddleName, 1)
    objUser.sn                = strLastName
    objUser.userPrincipalName = strLogin & "@contora.ru"
    
    objUser.SetInfo
    If (Err.Number <> 0) Then
        objShell.LogEvent 1, "Error commiting user " & strLogin & ": " & Err.Number & " - " & Err.Description
        Exit Do
    End If
    
    If Not IsNewUser Then
        Exit Do
    End If
    
    objShell.LogEvent 1, "Setting password for user " & strLogin
    Err.Clear
    objUser.SetPassword "Qq12345"
    If (Err.Number <> 0) Then
        objShell.LogEvent 1, "Error setting password for user " & strLogin & ": " & Err.Number & " - " & Err.Description
        Exit Do
    End If
    
    Err.Clear
    objUser.pwdLastSet = 0
    If (Err.Number <> 0) Then
        objShell.LogEvent 1, "Error setting pwdLastSet for user " & strLogin & ": " & Err.Number & " - " & Err.Description
        Exit Do
    End If
    
    Err.Clear
    userActCtrl = objUser.Get("userAccountControl")
    userActCtrl = userActCtrl And Not (ADS_UF_ACCOUNTDISABLE + ADS_UF_PASSWD_NOTREQD + ADS_UF_DONT_EXPIRE_PASSWD)
    objUser.userAccountControl = userActCtrl
    If (Err.Number <> 0) Then
        objShell.LogEvent 1, "Error setting userAccountControlfor user " & strLogin & ": " & Err.Number & " - " & Err.Description
        Exit Do
    End If
    
    Err.Clear
    objUser.SetInfo
    If (Err.Number <> 0) Then
        objShell.LogEvent 1, "Error second commiting user " & strLogin & ": " & Err.Number & " - " & Err.Description
        Exit Do
    End If

Loop While False
Next
Set xmlParser = Nothing





Err.Clear
Set objDontOff = GetObject("LDAP://CN=dontoff,CN=Users," & objRootDSE.Get("defaultNamingContext"))
If (Err.Number <> 0) Then
    objShell.LogEvent 1, "Error getting dontoff container: " & Err.Number & " - " & Err.Description
    WScript.Quit
End If

For Each objMember In objDontOff.members
    If objDictionary.Exists(objMember.sAMAccountName) Then
        objDictionary.Remove(objMember.sAMAccountName)
    End If
Next





For Each strLogin In objDictionary
Do

    Set objUser = Nothing
    Set objUser = GetObject("LDAP://" & objDictionary(strLogin))
    
    If IsNull(objUser) Or objUser Is Nothing Then
        Exit Do
    ElseIf InStr(1, objUser.memberOf, "CN=dontoff,CN=Users", vbTextCompare) > 0 Then
        Exit Do
    End If
    
    Err.Clear
    objUser.AccountDisabled = True
    objUser.SetInfo
    If (Err.Number <> 0) Then
        objShell.LogEvent 1, "Error disabling user " & strLogin & ": " & Err.Number & " - " & Err.Description
        Exit Do
    Else
        objShell.LogEvent 0, "Disabled user " & strLogin
    End If
    
Loop While False    
Next





objShell.LogEvent 0, "Script finished"
с ошибкой в "Журнале Приложений Windows DC"
Цитата:
Error disabling user : -2147463155 - Свойства службы каталогов не могут быть найдены в кэше.
Собственно и вопрос) В скрипте есть строка 236: objUser.AccountDisabled = True, которая как-то должна отсылаться на атрибуты пользователя, чья учетка проверяется на предмет отключена она или нет. Понимаю, что наверно вопрос больше по AD, но тем не менее, правильно ли задан данный атрибут при условии, что строка 242: objShell.LogEvent 0, "Disabled user " в "Журнале Приложений Windows DC" логируется правильно как
Цитата:
Disabled user Ivanov
Те проблема в каком-то пользователе, где останавливается скрипт с ошибкой или это неверный параметр AccountDisabled, которого в явном виде нет в атрибутах пользователя?

Спасибо заранее!

Отправлено: 12:49, 20-03-2022

 

Deadooshka


Сообщения: 2566
Благодарности: 698

Профиль | Отправить PM | Цитировать


strLogin пустой что-ли (должен быть в тексте ошибки перед двоеточием)? Может быть надо проверять, что не пустой в начале итерации по objDictionary?

Отправлено: 14:22, 20-03-2022 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Пользователь


Сообщения: 100
Благодарности: 0

Профиль | Отправить PM | Цитировать


Изображения
Тип файла: jpg WSH.JPG
(45.7 Kb, 12 просмотров)

Цитата:
strLogin пустой что-ли (должен быть в тексте ошибки перед двоеточием)?
Да, пустой. Нет логина на котором останавливается скрипт.

Цитата:
Может быть надо проверять, что не пустой в начале итерации по objDictionary?
Учетку же нельзя создать без логина.

Последний раз редактировалось AlexWhite, 20-03-2022 в 15:28.


Отправлено: 15:01, 20-03-2022 | #3


Deadooshka


Сообщения: 2566
Благодарности: 698

Профиль | Отправить PM | Цитировать


Ключ в словаре objDictionary это атрибут sAMAccountName. Словарь заполняется в recursive(), где objDict.Add. Этот атрибут sAMAccountName видимо где-то пустой. Можно добавить "objDictionary(strLogin)" в строку лога, чтобы понять, какая строка запроса LDAP://... приводит к ошибке. Это где objShell.LogEvent 1, "Error disabling user " & strLogin &.... ну как-нибудь .... & "LDAP://" & objDictionary(strLogin) (& - конкатенация строк).
Это сообщение посчитали полезным следующие участники:

Отправлено: 18:05, 20-03-2022 | #4


Пользователь


Сообщения: 100
Благодарности: 0

Профиль | Отправить PM | Цитировать


Цитата:
ну как-нибудь .... & "LDAP://" & objDictionary(strLogin) (& - конкатенация строк).
спасибо большое за совет, теперь вижу "проблемное место". Последний блок поправил и получилось так.

Код: Выделить весь код
 Err.Clear
    objUser.AccountDisabled = True
    objUser.SetInfo
    If (Err.Number <> 0) Then
        objShell.LogEvent 1, "Error disabling user " & "LDAP://" & objDictionary(strLogin) & strLogin & ": " & Err.Number & " - " & Err.Description
        Exit Do
    Else
        objShell.LogEvent 0, "Disabled user " & strLogin
    End If

Цитата:
Error disabling user LDAP://CN=Склад,OU=Завод,OU=Контора,DC=ad,DC=contora,DC=ru: -2147463155 - Свойства службы каталогов не могут быть найдены в кэше.
Склад - это оказался контакт, у которого нет логина. Поэтому и была ошибка.

Sham, не подскажите как сделать так, чтобы скрипт игнорировал контакты?

Отправлено: 20:06, 20-03-2022 | #5


Deadooshka


Сообщения: 2566
Благодарности: 698

Профиль | Отправить PM | Цитировать


Сейчас добавляется в словарь по наличию подстроки "CN=Person" в objMember.objectCategory. Видимо, можно попробовать добавить дополнительную проверку к itemExists = False ещё and objMember.objectClass = "user". Проверить не могу.

Отправлено: 03:09, 21-03-2022 | #6


Пользователь


Сообщения: 100
Благодарности: 0

Профиль | Отправить PM | Цитировать


Цитата Sham:
Сейчас добавляется в словарь по наличию подстроки "CN=Person" в objMember.objectCategory. Видимо, можно попробовать добавить дополнительную проверку к itemExists = False ещё and objMember.objectClass = "user". Проверить не могу. »
Сделал, получилось так

Код: Выделить весь код
Sub recursive(objUnit, objDict)
    itemExists = False
    For Each objMember in objUnit
        If InStr(1, objMember.objectCategory, "CN=Person", vbTextCompare) > 0 Then
            itemExists = objDict.Exists(objMember.sAMAccountName)
            If itemExists = False and objMember.objectClass = "user" Then
                               objDict.Add objMember.sAMAccountName, objMember.distinguishedName
            End If
        Else
            recursive objMember, objDict
        End If
    Next
End Sub
Получаю ошибку

Цитата:
Error getting Users container: 13 - Несоответствие типа
Наверно надо что-то еще тут менять

Код: Выделить весь код
' Bind to the Users folder in the domain.
Set objUsers = GetObject("LDAP://CN=Users," & objRootDSE.Get("defaultNamingContext"))
If (Err.Number <> 0) Then
    objShell.LogEvent 1, "Error getting Users container: " & Err.Number & " - " & Err.Description
    WScript.Quit
End If
или я неправильно добавил условие and objMember.objectClass = "user"

Отправлено: 21:42, 26-03-2022 | #7


Deadooshka


Сообщения: 2566
Благодарности: 698

Профиль | Отправить PM | Цитировать


Цитата AlexWhite:
Error getting Users container: 13 - Несоответствие типа »
это видимо Err.Number не 0 остался после "несоответствия типа", и там неверная строка ошибки получается. Какой тип в objectClass?

я бы вывел в консоль, что добавляется в словарь (там где objDict.Add), к примеру: WScript.Echo objMember.sAMAccountName, objMember.distinguishedName, objMember.objectClass
там видны будут критерии. Может и другие атрибуты есть помимо objectClass.

кстати, ошибка
Цитата AlexWhite:
WScrit.Quit »
WScript

Отправлено: 01:30, 28-03-2022 | #8



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » VBS/WSH/JS - objUser.AccountDisabled - не разберусь с этим атрибутом

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
PowerShell - [решено] Выборка пользователей с атрибутом accountExpires < текущей даты АД ejik_off Скриптовые языки администрирования Windows 4 14-09-2017 12:54
CMD/BAT - [решено] Добавление учетных записей компьютеров в домен с атрибутом Silver23 Скриптовые языки администрирования Windows 1 25-05-2015 12:56
2008 R2 - [решено] objUser.memberOf не дает список групп PyroTechnic Windows Server 2008/2008 R2 1 09-06-2014 20:43
Lynksys - Не разберусь с роутером WAP54G Rodion14 Сетевое оборудование 20 19-12-2013 19:45
Блог - Почему Microsoft вас не слушает, и можно ли что-нибудь сделать с этим Vadikan Microsoft Windows 8 и 8.1 0 09-07-2012 08:30




 
Переход