none
Нужен скрипт для проверки списка пользователей и их удаление из AD RRS feed

  • Вопрос

  • Есть список пользователей, которые нужно удалить из 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, vbs 
    22 июля 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;
    }
    ////////////////////////////////////////////////////////////////// // Фукнкция отправке сообщения об удаления пользователя // ////////////////////////////////////////////////////////////////// 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); } }
    Извините, лень переводить свои скрипты на VBS :)
    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.com
    23 июля 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;
    }
    ////////////////////////////////////////////////////////////////// // Фукнкция отправке сообщения об удаления пользователя // ////////////////////////////////////////////////////////////////// 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); } }
    Извините, лень переводить свои скрипты на VBS :)
    Andrew Mishechkin
    • Предложено в качестве ответа Vasily GusevModerator 15 августа 2009 г. 8:37
    • Помечено в качестве ответа Vasily GusevModerator 17 сентября 2009 г. 17:45
    15 августа 2009 г. 7:35
  • Чет, вставка кода в форумах глючит. <br/> в моем коде не было


    Andrew Mishechkin
    15 августа 2009 г. 7:37