Лучший отвечающий
Нужен скрипт для проверки списка пользователей и их удаление из AD

Вопрос
-
Есть список пользователей, которые нужно удалить из AD. Но некоторых пользователей, которые есть в списках нет в AD.
Поэтому требуется:
1. Проверка пользователей в AD из списка, сохранение результатов в блокнот, кто есть в базе данных контроллера домена.
Например:
dsquery user "CN=Пупкин В.И,OU=Managers,OU=Sales,OU=Domain Users,DC=example,DC=local"
dsquery user "CN=Сидоров В.И,OU=Managers,OU=Sales,OU=Domain Users,DC=example,DC=local"
Всех пользователей, которые проверены, что есть в AD занести в блокнот, например users.txt.
2. Удаление этих пользователей из проверенных, из блокнота users.txt
Например:
dsrm -subtree -noprompt -c "CN=Пупкин В.И,OU=Managers,OU=Sales,OU=Domain Users,DC=example,DC=local"
dsrm -subtree -noprompt -c "CN=Сидоров В.И,OU=Managers,OU=Sales,OU=Domain Users,DC=example,DC=local"
Требуется либо 2 отдельных скрипта (1 проверяет, второй удаляет), либо все в одном, можно в cmd, vbs22 июля 2009 г. 6:39
Ответы
-
Проверку пользователя средствами WSH и ADSI сделать легко:
Если вы читаете список пользователей из текстовика, то код будет примерно выглядеть так:var objLDAPUser; var objRootDSE = GetObject("LDAP://rootDSE"); var objConnection = WScript.CreateObject("ADODB.Connection"); //объект ADO-соединения var objCommand = WScript.CreateObject("ADODB.Command"); //объект запроса objConnection.Provider = "ADsDSOObject"; objConnection.Open("Active Directory Provider"); objCommand.ActiveConnection = objConnection; objCommand.Properties("Page Size")=1000;
objCommand.CommandText = "SELECT sAMAccountName,distinguishedName from 'LDAP://DC=local,DC=polad,DC=ru' Where objectClass='user' and objectClass<>'computer'"; var objADCRes = objCommand.Execute; objADCRes.MoveFirst; //Переход к первому элементу коллекции выборки учетных записей пользователей
UsrList = fso.OpenTextFile("UsrList.txt",1)
while(!UsrList.AtEndOfStream)
{
var LoginUserName = new String(UsrList.ReadLine());
while(!objADCRes.EOF) //Цикл перебора всех учетных записей пользователей { //Получение LDAP-объекта пользователя if(objADCRes.Fields("sAMAccountName").Value == LoginUserName) { objLDAPUser = GetObject("LDAP://" + objADCRes.Fields("distinguishedName").Value); WScript.Echo("User " + LoginUserName + "is found");
break; } else objADCRes.MoveNext; }
}
UsrList.Close();
У меня несколько другая задача - удаление отключенных пользователей из домена. Удаление выполняет админ с помощью скрипта, но руками после проверки (был уже инцидент, когда грохнули отключенную учетку одной бух-ши, ушедшей в декрет). На всякий случай привожу код скрипта (JScript), может пригодится:////////////////////////////////////////////////////////// // Скрипт удаления отключенных учетных записей // // в OU=DisabledAccounts // // Язык: JScript // // Автор: Андрей Мишечкин // ////////////////////////////////////////////////////////// //Объявление переменных var count1 = 0; //Счетчик общего количества пользователей var count2 = 0; //Счетчик числа увволенных пользователей var delUsersList = ""; //Список удаленных пользователей var objNTUser; //ADSI-объект пользователя (используя NTLM) var input; //переменная ввода символов со стандартного потока //Определение полного пути к орг. единце с отключенными учетными записями var DisabledAccountsOU = LDAP://OU=DisabledAccounts,DC=local,DC=mycompany; try { var objDisabledAccountsOU = GetObject(DisabledAccountsOU); var enumDisabledAccountsOU = new Enumerator(objDisabledAccountsOU); } catch(e) { WScript.Echo("Can't create the OU object and collection" + e.description); } ////////////////////////////////////////////////////////////////////// // Основной цикл перебора элементов коллекции // ////////////////////////////////////////////////////////////////////// for(;!enumDisabledAccountsOU.atEnd();enumDisabledAccountsOU.moveNext()) { objOUMember = enumDisabledAccountsOU.item(); if(objOUMember.Class == "user") { //Вывод на экран информации о пользователе WScript.Echo("Login name: " + GetParam("objOUMember","sAMAccountName")); WScript.Echo("Display name: " + GetParam("objOUMember","displayName")); WScript.Echo("Description: " + GetParam("objOUMember","Description")); WScript.Echo("Last login time: " + GetParam("objNTUser","LastLogin")); if(objOUMember.AccountDisabled == 1) WScript.Echo("Account disabled"); else WScript.Echo("Account is not disabled"); //Выполнение удаления пользователя выполнении условия. WScript.Echo("Delete this account ? Y/N"); for(;;) { input = ""; input = WScript.StdIn.ReadLine(); if((input == "Y")||(input == "y")) { try { objDisabledAccountsOU.Delete("user","cn=" + objOUMember.Get("Name")); } catch(e) { WScript.Echo("Error. Account " + objOUMember.Get("sAMAccountName") + " is not deleted. " + e.description); } WScript.Echo(objOUMember.Get("sAMAccountName") + " is deleted"); delUsersList += GetParam("objOUMember","sAMAccountName") + " / " + GetParam("objOUMember","displayName") + "\n"; count2++; break; } else if((input == "N")||(input == "n")) { WScript.Echo(objOUMember.Get("sAMAccountName") + " is not deleted"); break; } else { WScript.Echo("Invalid option."); WScript.Echo("Delete this account ? Y/N"); } } WScript.Echo("------------------------------------------------------------"); count1++; } } WScript.Echo("Total accounts: " + count1); WScript.Echo("Deleted accounts: " + count2); Information(); ////////////////////////////////////////////////////////////////// // Фукнкция считывания параметров из кэша с обработкой ошибок // ////////////////////////////////////////////////////////////////// function GetParam(object,ParamName) { var result; if(object == "objOUMember") var objUser = objOUMember; else if(object == "objNTUser") var objUser = GetObject("WinNT://POLAD/" + objOUMember.Get("sAMAccountName") + ",user"); try { result = objUser.Get(ParamName); } catch(e) { result = "Undefined"; } return result; }
Извините, лень переводить свои скрипты на VBS :)
////////////////////////////////////////////////////////////////// // Фукнкция отправке сообщения об удаления пользователя // ////////////////////////////////////////////////////////////////// function Information() { var WMIServiceObj = GetObject("Winmgmts:"); var ProcEnumerator = new Enumerator(WMIServiceObj.ExecQuery("Select Handle from Win32_Process WHERE Caption = 'cscript.exe' OR Caption = 'wscript.exe'")); var ProcHandle = ProcEnumerator.item().Handle; var objWMIProcess = GetObject("winmgmts:Win32_Process.Handle='" + ProcHandle + "'"); var wmiOutParams = objWMIProcess.ExecMethod_("GetOwner"); var AdministratorName = wmiOutParams.User; var objCurrentDate = new Date; var CurrentDate = objCurrentDate.getDate(); CurrentDate += "." + (objCurrentDate.getMonth()+1); CurrentDate += "." + objCurrentDate.getYear() + " "; var CurrentHour = objCurrentDate.getHours(); if(CurrentHour < 10) CurrentDate += "0"; CurrentDate += CurrentHour + ":"; var CurrentMinute = objCurrentDate.getMinutes(); if(CurrentMinute < 10) CurrentDate += "0"; CurrentDate += CurrentMinute; var objEmail = WScript.CreateObject("CDO.Message"); objEmail.From = "\"Usrclean script\" script@mycompany.ru"; objEmail.To = "anmi@mycompany.ru"; objEmail.Subject = "Usrclean.js report"; objEmail.Textbody = "Users:\n" + delUsersList + "was deleted by " + AdministratorName + " in " + CurrentDate; objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2; objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "mail.company.ru"; objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25; objEmail.Configuration.Fields.Update(); try { objEmail.Send(); } catch(e) { WScript.Echo("Mail system error: " + e.description); } }
Andrew Mishechkin- Предложено в качестве ответа Vasily GusevModerator 15 августа 2009 г. 8:37
- Помечено в качестве ответа Vasily GusevModerator 17 сентября 2009 г. 17:45
15 августа 2009 г. 7:35
Все ответы
-
А что у вас не получается?
AKA Xaegr, MCSE: Security, Messaging; MCITP: Server\Enterprise Administrator; Блог: http://xaegr.wordpress.com23 июля 2009 г. 18:12Модератор -
Проверку пользователя средствами WSH и ADSI сделать легко:
Если вы читаете список пользователей из текстовика, то код будет примерно выглядеть так:var objLDAPUser; var objRootDSE = GetObject("LDAP://rootDSE"); var objConnection = WScript.CreateObject("ADODB.Connection"); //объект ADO-соединения var objCommand = WScript.CreateObject("ADODB.Command"); //объект запроса objConnection.Provider = "ADsDSOObject"; objConnection.Open("Active Directory Provider"); objCommand.ActiveConnection = objConnection; objCommand.Properties("Page Size")=1000;
objCommand.CommandText = "SELECT sAMAccountName,distinguishedName from 'LDAP://DC=local,DC=polad,DC=ru' Where objectClass='user' and objectClass<>'computer'"; var objADCRes = objCommand.Execute; objADCRes.MoveFirst; //Переход к первому элементу коллекции выборки учетных записей пользователей
UsrList = fso.OpenTextFile("UsrList.txt",1)
while(!UsrList.AtEndOfStream)
{
var LoginUserName = new String(UsrList.ReadLine());
while(!objADCRes.EOF) //Цикл перебора всех учетных записей пользователей { //Получение LDAP-объекта пользователя if(objADCRes.Fields("sAMAccountName").Value == LoginUserName) { objLDAPUser = GetObject("LDAP://" + objADCRes.Fields("distinguishedName").Value); WScript.Echo("User " + LoginUserName + "is found");
break; } else objADCRes.MoveNext; }
}
UsrList.Close();
У меня несколько другая задача - удаление отключенных пользователей из домена. Удаление выполняет админ с помощью скрипта, но руками после проверки (был уже инцидент, когда грохнули отключенную учетку одной бух-ши, ушедшей в декрет). На всякий случай привожу код скрипта (JScript), может пригодится:////////////////////////////////////////////////////////// // Скрипт удаления отключенных учетных записей // // в OU=DisabledAccounts // // Язык: JScript // // Автор: Андрей Мишечкин // ////////////////////////////////////////////////////////// //Объявление переменных var count1 = 0; //Счетчик общего количества пользователей var count2 = 0; //Счетчик числа увволенных пользователей var delUsersList = ""; //Список удаленных пользователей var objNTUser; //ADSI-объект пользователя (используя NTLM) var input; //переменная ввода символов со стандартного потока //Определение полного пути к орг. единце с отключенными учетными записями var DisabledAccountsOU = LDAP://OU=DisabledAccounts,DC=local,DC=mycompany; try { var objDisabledAccountsOU = GetObject(DisabledAccountsOU); var enumDisabledAccountsOU = new Enumerator(objDisabledAccountsOU); } catch(e) { WScript.Echo("Can't create the OU object and collection" + e.description); } ////////////////////////////////////////////////////////////////////// // Основной цикл перебора элементов коллекции // ////////////////////////////////////////////////////////////////////// for(;!enumDisabledAccountsOU.atEnd();enumDisabledAccountsOU.moveNext()) { objOUMember = enumDisabledAccountsOU.item(); if(objOUMember.Class == "user") { //Вывод на экран информации о пользователе WScript.Echo("Login name: " + GetParam("objOUMember","sAMAccountName")); WScript.Echo("Display name: " + GetParam("objOUMember","displayName")); WScript.Echo("Description: " + GetParam("objOUMember","Description")); WScript.Echo("Last login time: " + GetParam("objNTUser","LastLogin")); if(objOUMember.AccountDisabled == 1) WScript.Echo("Account disabled"); else WScript.Echo("Account is not disabled"); //Выполнение удаления пользователя выполнении условия. WScript.Echo("Delete this account ? Y/N"); for(;;) { input = ""; input = WScript.StdIn.ReadLine(); if((input == "Y")||(input == "y")) { try { objDisabledAccountsOU.Delete("user","cn=" + objOUMember.Get("Name")); } catch(e) { WScript.Echo("Error. Account " + objOUMember.Get("sAMAccountName") + " is not deleted. " + e.description); } WScript.Echo(objOUMember.Get("sAMAccountName") + " is deleted"); delUsersList += GetParam("objOUMember","sAMAccountName") + " / " + GetParam("objOUMember","displayName") + "\n"; count2++; break; } else if((input == "N")||(input == "n")) { WScript.Echo(objOUMember.Get("sAMAccountName") + " is not deleted"); break; } else { WScript.Echo("Invalid option."); WScript.Echo("Delete this account ? Y/N"); } } WScript.Echo("------------------------------------------------------------"); count1++; } } WScript.Echo("Total accounts: " + count1); WScript.Echo("Deleted accounts: " + count2); Information(); ////////////////////////////////////////////////////////////////// // Фукнкция считывания параметров из кэша с обработкой ошибок // ////////////////////////////////////////////////////////////////// function GetParam(object,ParamName) { var result; if(object == "objOUMember") var objUser = objOUMember; else if(object == "objNTUser") var objUser = GetObject("WinNT://POLAD/" + objOUMember.Get("sAMAccountName") + ",user"); try { result = objUser.Get(ParamName); } catch(e) { result = "Undefined"; } return result; }
Извините, лень переводить свои скрипты на VBS :)
////////////////////////////////////////////////////////////////// // Фукнкция отправке сообщения об удаления пользователя // ////////////////////////////////////////////////////////////////// function Information() { var WMIServiceObj = GetObject("Winmgmts:"); var ProcEnumerator = new Enumerator(WMIServiceObj.ExecQuery("Select Handle from Win32_Process WHERE Caption = 'cscript.exe' OR Caption = 'wscript.exe'")); var ProcHandle = ProcEnumerator.item().Handle; var objWMIProcess = GetObject("winmgmts:Win32_Process.Handle='" + ProcHandle + "'"); var wmiOutParams = objWMIProcess.ExecMethod_("GetOwner"); var AdministratorName = wmiOutParams.User; var objCurrentDate = new Date; var CurrentDate = objCurrentDate.getDate(); CurrentDate += "." + (objCurrentDate.getMonth()+1); CurrentDate += "." + objCurrentDate.getYear() + " "; var CurrentHour = objCurrentDate.getHours(); if(CurrentHour < 10) CurrentDate += "0"; CurrentDate += CurrentHour + ":"; var CurrentMinute = objCurrentDate.getMinutes(); if(CurrentMinute < 10) CurrentDate += "0"; CurrentDate += CurrentMinute; var objEmail = WScript.CreateObject("CDO.Message"); objEmail.From = "\"Usrclean script\" script@mycompany.ru"; objEmail.To = "anmi@mycompany.ru"; objEmail.Subject = "Usrclean.js report"; objEmail.Textbody = "Users:\n" + delUsersList + "was deleted by " + AdministratorName + " in " + CurrentDate; objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2; objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "mail.company.ru"; objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25; objEmail.Configuration.Fields.Update(); try { objEmail.Send(); } catch(e) { WScript.Echo("Mail system error: " + e.description); } }
Andrew Mishechkin- Предложено в качестве ответа Vasily GusevModerator 15 августа 2009 г. 8:37
- Помечено в качестве ответа Vasily GusevModerator 17 сентября 2009 г. 17:45
15 августа 2009 г. 7:35 -
Чет, вставка кода в форумах глючит. <br/> в моем коде не было
Andrew Mishechkin15 августа 2009 г. 7:37