none
Добавление - удаление пользователей в локальной группе RRS feed

  • Вопрос

  • Добрый день! Сам только начинаю работать с PowerShell, поэтому не пинайте сильно :)

    Задача - динамически удалять - добавлять пользователей домена в  локальную группу безопасности на одном из ПК в зависимости от определенных условий. Решение нужно на PowerShell.

    Все вроде уже как сделал, но такая проблема - если пользователь уже существует в группе - при добавлении возникает ошибка, соответственно, если его нет, то при удалении ошибка. Как правильно проверить, существует ли юзер в группе?

    Использую примерно такой код

    $domain = "domain"
    $strComputer = "pc"
    $username = "user"

    $localgroup = "localgroup"

    $computer = [ADSI]("WinNT://" + $strComputer + ",computer")
    $Group = $computer.psbase.children.find($localgroup)

    $Group.Add("WinNT://" + $domain + "/" + $username)

    Соответственно при удалении вызывается

    #$Group.Remove("WinNT://" + $domain + "/" + $username

    29 марта 2010 г. 9:39

Ответы

  • Вот тут:

     

    $domain = "домен"
    $strComputer = "комп"
    $username = "юзернэйм"
    $localgroup = "лок группа"


    #Переменные для проверки состава группы
    $Locpath = "WinNT://"+$strComputer+"/" + $localgroup
    $CheckGroup =[ADSI]"$Locpath"
    $GroupMembers = @($CheckGroup.psbase.Invoke("Members"))

    #1 - есть такой, 0 - еще нет такого пользователя
    $isNew = "0"
    foreach ($Member in $GroupMembers)
    {
       
        $MB = $member.GetType().InvokeMember("Name", 'GetProperty', $null, $member, $null)

        if ($username -eq $mb)
        {
            $isNew = "1"

        }

    }

    #Переменные для работы в локальных группах
    $computer = [ADSI]("WinNT://" + $strComputer + ",computer")
    $Group = $computer.psbase.children.find($localgroup)


    if ( $isNew -eq  "0")
    {
        $Group.Add("WinNT://" + $domain + "/" + $username)
    }


    Если сообщение было информативным, отметьте его как правильный ответ. Сразу видно ответ на вопрос :-)
    29 марта 2010 г. 10:38
  • хорошо. Тогда можете выдрать список member для  группы вот так:

    $group =[ADSI]"WinNT://./Power Users"
    $members = @($group.psbase.Invoke("Members"))
    $members | foreach {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}


    Если сообщение было информативным, отметьте его как правильный ответ. Сразу видно ответ на вопрос :-)
    29 марта 2010 г. 10:05

Все ответы

  • Первое, что пришло на ум - получать всех  пользователей и просто парсить их на совпадения.

     

     

    Не использовать GPP что-то не позволяет ?

    Причем в администрирование в разы легче, чет отлавливать ошибки - проблемы в скриптах.
    Я лично уже давно отказался по большей части от таких скриптов.... Трудозатраты больше, результат тот же.
    Тут описал наш коллега     и еще 

     

     


    Если сообщение было информативным, отметьте его как правильный ответ. Сразу видно ответ на вопрос :-)
    29 марта 2010 г. 9:54
  • Да, не позволяет. Условия добавления-удаления пользователей формируются также на powershell путем запросов к SQL серверу.
    29 марта 2010 г. 10:02
  • хорошо. Тогда можете выдрать список member для  группы вот так:

    $group =[ADSI]"WinNT://./Power Users"
    $members = @($group.psbase.Invoke("Members"))
    $members | foreach {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}


    Если сообщение было информативным, отметьте его как правильный ответ. Сразу видно ответ на вопрос :-)
    29 марта 2010 г. 10:05
  • хорошо. Тогда можете выдрать список member для  группы вот так:

    $group =[ADSI]"WinNT://./Power Users"
    $members = @($group.psbase.Invoke("Members"))
    $members | foreach {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}


    Если сообщение было информативным, отметьте его как правильный ответ. Сразу видно ответ на вопрос :-)
    29 марта 2010 г. 10:05
  • а потом? Если есть список из 300 проверяемых пользователей на членство в данной локальной группе, то брать каждого и прогонять на совпадение с членами локальной группы? То бишь - вложенные циклы... Не получится ли слишком долго?
    29 марта 2010 г. 10:16
  • Тем не менее, проверю
    29 марта 2010 г. 10:17
  • делайте проще. Создайте в Active Directory группу. Включайте ее в члены локальной групп средства restricted groups.

    А ваш скрипт пускай уже работает только с этой группой (которая в Active Directory) . незачем подключаться ко всем компам и там проверять. тем самым вы ускорите процесс.

     

    Есть два типа:

    1. Полностью замещает в членов  в группе
    2. Добавляет  новых  членов в группу
    Restricted Groups
    Для  управления:
    1. Идем в GPO - Computer Configuration - Polices - Security Settings - Restricted Groups
    2. Добавлям новую группу и выбираем ту AD группу или  пользователя, которую нам нем добавить в  локальную  группу. Т.е. к выбираем к примеру G_LocalSubAdmin .
    3. В свойствах есть два типа
    • Members of this group - Замещает всех членов в выбранной  группе
    • This group is member of - Только  добавляет, никого не трогая из уже присутствующих. Именно сюда мы добавляем  нужную  нам группу например  локальных администраторов, имеющих SID S-1-5-32-544.
    Возможно поможет использование  Well-Known SID для добавления пользователей

    Таким  образом мы  добавили глобальную группу G_LocalSubAdmin в члены  локальной  группы  администраторов на  ПК, на которых применится  данная политика.  Теперь в  группу  G_LocalSubAdmin можно  добавлять  необходимых сотрудников, что даст им права локальных администраторов на  нужных ПК.

    Локальных админов замените на вашу необходимую локальную группу.GPO привязываем на OU с компьютерами.
    Если сообщение было информативным, отметьте его как правильный ответ. Сразу видно ответ на вопрос :-)
    29 марта 2010 г. 10:27
  • Вот тут:

     

    $domain = "домен"
    $strComputer = "комп"
    $username = "юзернэйм"
    $localgroup = "лок группа"


    #Переменные для проверки состава группы
    $Locpath = "WinNT://"+$strComputer+"/" + $localgroup
    $CheckGroup =[ADSI]"$Locpath"
    $GroupMembers = @($CheckGroup.psbase.Invoke("Members"))

    #1 - есть такой, 0 - еще нет такого пользователя
    $isNew = "0"
    foreach ($Member in $GroupMembers)
    {
       
        $MB = $member.GetType().InvokeMember("Name", 'GetProperty', $null, $member, $null)

        if ($username -eq $mb)
        {
            $isNew = "1"

        }

    }

    #Переменные для работы в локальных группах
    $computer = [ADSI]("WinNT://" + $strComputer + ",computer")
    $Group = $computer.psbase.children.find($localgroup)


    if ( $isNew -eq  "0")
    {
        $Group.Add("WinNT://" + $domain + "/" + $username)
    }


    Если сообщение было информативным, отметьте его как правильный ответ. Сразу видно ответ на вопрос :-)
    29 марта 2010 г. 10:38
  • Мне так и не удалось использовать SID, а вот если указывать полное имя локальной группы то все работает.
    9 декабря 2010 г. 1:58
  • Доброго времени!

    Подниму старую тему про пользователей. Можете помочь с решением этой проблемы: http://social.technet.microsoft.com/Forums/ru-ru/ws2008r2ru/thread/a4a674cd-ffef-40b9-88a1-713ec1891f05

    Имя компьютера: $computer = Get-Content Env:\COMPUTERNAME

    Получаем имя пользователя на управление компьютером: $user = (Get-ADComputer $computer -Properties *).ManagedBy

    Таким образом осталось при загрузке компьютера выполнять PowerShell скрипт который будет импортировать модуль АД (или добавлять аплет Get-ADComputer на рядовых компьютерах) и удалять из группы Администраторы (Administrators) всех пользователей кроме Администраторы домена (Domain administrators).

    Соответственно если $user = (Get-ADComputer $computer -Properties *).ManagedBy возвращает пустой результат, то в группе остается только группа Администраторов домена.

    26 сентября 2012 г. 19:03
  • Доброго времени!

    Подниму старую тему про пользователей. Можете помочь с решением этой проблемы: http://social.technet.microsoft.com/Forums/ru-ru/ws2008r2ru/thread/a4a674cd-ffef-40b9-88a1-713ec1891f05

    Имя компьютера: $computer = Get-Content Env:\COMPUTERNAME

    Получаем имя пользователя на управление компьютером: $user = (Get-ADComputer $computer -Properties *).ManagedBy

    Таким образом осталось при загрузке компьютера выполнять PowerShell скрипт который будет импортировать модуль АД (или добавлять аплет Get-ADComputer на рядовых компьютерах) и удалять из группы Администраторы (Administrators) всех пользователей кроме Администраторы домена (Domain administrators).

    Соответственно если $user = (Get-ADComputer $computer -Properties *).ManagedBy возвращает пустой результат, то в группе остается только группа Администраторов домена.

    На ошибку внимания можно не обращать,т.к. встроенного администратора удалить нелья:

    $searcher = [adsisearcher]"(&(objectClass=computer)(name=$env:computername))"
    $pc = $searcher.FindOne().GetDirectoryEntry()
    $lsid = "S-1-5-32-544"
    $lgroup = ([Security.Principal.SecurityIdentifier]$lsid).Translate([Security.Principal.NTAccount]).Value.Split("\")[1]
    $dsid = (New-Object Security.Principal.SecurityIdentifier($pc.objectsid[0] , 0)).AccountDomainSid.value+"-512"
    $dgroup = ([Security.Principal.SecurityIdentifier]$dsid).Translate([Security.Principal.NTAccount]).Value.Replace("\","/")
    
    if(!$pc.managedBy)
    {
    	$wla = [ADSI]"WinNT://$env:computername/$lgroup,group"
    	$wla.Members() | foreach {
    		$member = $_.GetType().InvokeMember("AdsPath","GetProperty",$null,$_,$null)
    		$wla.Remove($member)
    	}
    	$wla.Add("WinNT://$dgroup,group")
    }

    • Предложено в качестве ответа Nail Mukhametshin 7 октября 2012 г. 20:26
    27 сентября 2012 г. 10:01
    Отвечающий