[CmdletBinding()] param( [parameter(helpmessage="samaccountname of group owner",mandatory=$true)]$owner, #defaults to current user's domain if not specified [parameter(helpmessage="netbios domain name")]$domain=$env:userdomain, [parameter(parametersetname='pipe', valuefrompipeline=$true)] [Microsoft.ActiveDirectory.Management.ADGroup]$group, [parameter(parametersetname='normal',valuefrompipeline=$false, helpmessage="AD group name")]$identity, #for cross domain? needs testing and what if the group and owner are in different domains? [parameter(helpmessage="domain controller to do object lookups")]$server ) begin{ import-module activedirectory if ($server -eq $null) { $server = (get-addomaincontroller -Discover -Writable).hostname} } process { #allow for both a single group name to be passed as $identity, or take pipeline get-adgroup output if ($pscmdlet.parametersetname -eq 'normal') { try { [array]$group = get-adgroup $identity -property managedby -ea stop -server $server } catch { throw "Unable to find AD group" } } #cast the group as an array for the foreach loop if (!($group -is [array])) { $group = [array]$group} #hardcode guid for the write members permission $guid =[guid]'bf9679c0-0de6-11d0-a285-00aa003049e2' #get the group owner's sid - this could be replaced with get-aduser $user = New-Object System.Security.Principal.NTAccount("$domain\$owner") $sid =$user.translate([System.Security.Principal.SecurityIdentifier]) $ctrl =[System.Security.AccessControl.AccessControlType]::Allow $rights =[System.DirectoryServices.ActiveDirectoryRights]::WriteProperty $intype =[System.DirectoryServices.ActiveDirectorySecurityInheritance]::None try { try { $aduserobj = get-aduser $owner -server $server } catch { #if no user was found try looking for a group owner $aduserobj = get-aduser $owner -server $server } } catch { throw "Unable to find owner's account" } foreach ($groupobj in $group) { $acl = Get-Acl ad:"$($groupobj.distinguishedname)" #if the group was passed without the managedby property, look it up again if (($groupobj |gm |where {$_.name -eq "managedby"}) -eq $null) { #if there was a previous manager listed that doesn't match the one being passed to this script # remove any existing rights for that user $groupobj = get-adgroup $groupobj.distinguishedname -property managedby -server $server } if ($groupobj.managedby -ne $null) { try { $previousownersid = (get-aduser $groupobj.managedby -property sid -server $server).sid } catch { $previousownersid = (get-adgroup $groupobj.managedby -property sid -server $server).sid if ($previousownersid.value -ne $sid.value) { #$prevownerID = new-object system.security.principal.securityidentifier($previousownersid) $previousownerID = $previousownersid.Translate([System.security.principal.ntaccount]).Value $acl.access | where {$_.identityreference -eq $previousownerID} | % { $acl.RemoveAccessRule($_) } } } #set the ManagedBy property to the new owner set-adgroup $groupobj -managedby $aduserobj -server $server #add new owner's right to manage members $rule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($sid,$rights,$ctrl,$guid) $acl.AddAccessRule($rule) Set-Acl -acl $acl -path ad:"$($groupobj.distinguishedname)" } }
Wednesday, May 8, 2019
AD groups - setting group owner and delegating permission with powershell
Given that permissions delegation is only a simple checkbox in the AD users and computers tool under the manager's name, it would be nice if set-adgroup had a similar functionality. There are several steps involved in delegating rights, and if the owner is being changed, typically the old owner's rights should be removed. With this script below, it should accomplish this at least on a single domain environment. If the owner and group are in multiple domains, it can get a bit more complicated and some adjustments would be needed. This script takes either get-adgroup pipeline input, or a single group name that would work as an "identity" value in get-adgroup.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment