Active Directory PowerShell Delegate Permission to Reset User Passwords for a specific Organizational Unit

Is there an easy solution to allow Helpdesk Users to reset passwords for user accounts for a specific Active Directory Organizational Unit (OU) with PowerShell?

Yes, there is! Just use the script/function below to set the necessary Active Directory Delegation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function Set-ResetPasswordDelegation(){
    param(
    [string]$OrganizationalUnit,
    [string]$DelegationGroupName
    )
 
    # Configuration Parameters
    $confADRight = "ExtendedRight"
    $confDelegatedObjectType = "bf967aba-0de6-11d0-a285-00aa003049e2" # User Object Type GUID
    $confExtendedRight = "00299570-246d-11d0-a768-00aa006e0529" # Extended Right PasswordReset GUID
 
    # Collect and prepare Objects
    $delegationGroup = Get-ADGroup -Identity $DelegationGroupName
    $delegationGroupSID = [System.Security.Principal.SecurityIdentifier] $delegationGroup.SID
    $delegationGroupACL = Get-Acl -Path "AD:\$OrganizationalUnit"
 
    # Build Access Control Entry (ACE)
    $aceIdentity = [System.Security.Principal.IdentityReference] $delegationGroupSID
    $aceADRight = [System.DirectoryServices.ActiveDirectoryRights] $confADRight
    $aceType = [System.Security.AccessControl.AccessControlType] "Allow"
    $aceInheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] "Descendents"
    $ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($aceIdentity, $aceADRight, $aceType, $confExtendedRight, $aceInheritanceType,$confDelegatedObjectType)
 
    # Apply ACL
    $delegationGroupACL.AddAccessRule($ace)
    Set-Acl -Path "AD:\$OrganizationalUnit" -AclObject $delegationGroupACL
}
 
# Calling the function
Set-ResetPasswordDelegation -OrganizationalUnit "OU=Users,DC=pwsh,DC=ch" -DelegationGroupName "ServiceDesk-PasswordReset-Allow"

Get-ADUser not returning all user attributes [solution]

Using the Active Directory PowerShell command Get-ADUser with the –properties * (asterisk) switch does not return all available user attributes.

Properties like “msDS-UserPasswordExpiryTimeComputed” will not show up like that and have to be explicitly specified to be returned:

1
Get-ADUser –Properties msDS-UserPasswordExpiryTimeComputed

The following code returns all values of the user object:

1
2
$properties = Get-ADObject -SearchBase (Get-ADRootDSE).SchemanamingContext -Filter {name -eq "User"} -Properties MayContain,SystemMayContain | Select-Object @{name="Properties";expression={$_.maycontain+$_.systemmaycontain}} | Select-Object -ExpandProperty Properties
Get-ADUser -Identity username -Properties $properties | fl $properties

In the above example, all available properties of the Active Directory ObjectClass “user” are retrieved and stored in an array, which is then used to specify the wanted properties using the Get-ADUser cmdlet.

PowerShell to get the CIDR Notation by Subnet Mask

The following function provides an easy way to get the CIDR (Classless Inter Domain Routing) notation for any subnet mask using PowerShell.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# Calculate CIDR (Classless Inter Domain Routing) Notation
function getCIDRNotationBySubnetmask([string]$subnetmask){
 
    $cidr = 0
    $subnetmask.split(".") | foreach {
        switch($_){
            255 { $cidr += 8 }
            254 { $cidr += 7 }
            252 { $cidr += 6 }
            248 { $cidr += 5 }
            240 { $cidr += 4 }
            224 { $cidr += 3 }
            192 { $cidr += 2 }
            128 { $cidr += 1 }
            default { $cidr += 0 }
        }
    }
 
    return $cidr
}
 
# Examples how to use it
getCIDRNotationBySubnetmask 0.0.0.0
 
getCIDRNotationBySubnetmask 128.0.0.0
getCIDRNotationBySubnetmask 192.0.0.0
getCIDRNotationBySubnetmask 224.0.0.0
getCIDRNotationBySubnetmask 240.0.0.0
getCIDRNotationBySubnetmask 248.0.0.0
getCIDRNotationBySubnetmask 252.0.0.0
getCIDRNotationBySubnetmask 254.0.0.0
getCIDRNotationBySubnetmask 255.0.0.0
 
getCIDRNotationBySubnetmask 255.128.0.0
getCIDRNotationBySubnetmask 255.192.0.0
getCIDRNotationBySubnetmask 255.224.0.0
getCIDRNotationBySubnetmask 255.240.0.0
getCIDRNotationBySubnetmask 255.248.0.0
getCIDRNotationBySubnetmask 255.252.0.0
getCIDRNotationBySubnetmask 255.254.0.0
getCIDRNotationBySubnetmask 255.255.0.0
 
getCIDRNotationBySubnetmask 255.255.128.0
getCIDRNotationBySubnetmask 255.255.192.0
getCIDRNotationBySubnetmask 255.255.224.0
getCIDRNotationBySubnetmask 255.255.240.0
getCIDRNotationBySubnetmask 255.255.248.0
getCIDRNotationBySubnetmask 255.255.252.0
getCIDRNotationBySubnetmask 255.255.254.0
getCIDRNotationBySubnetmask 255.255.255.0
 
getCIDRNotationBySubnetmask 255.255.255.128
getCIDRNotationBySubnetmask 255.255.255.192
getCIDRNotationBySubnetmask 255.255.255.224
getCIDRNotationBySubnetmask 255.255.255.240
getCIDRNotationBySubnetmask 255.255.255.248
getCIDRNotationBySubnetmask 255.255.255.252
getCIDRNotationBySubnetmask 255.255.255.254
 
getCIDRNotationBySubnetmask 255.255.255.255

Delegate Permission on Active Directory Organizational Unit using Powershell

In case you need to delegate permissions on an Active Directory (AD) Organizational Unit (OU) for a security principal such as a User or a Group, you can easily do that with the follwing PowerShell function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function Set-Delegation(){
    param(
    [string]$OrganizationalUnit,
    [string]$DelegationGroupName
    )
 
    # Configuration Parameters
    $confADRight = "GenericAll"
    $confDelegatedObjectType = "00000000-0000-0000-0000-000000000000"
 
    # Collect and prepare Objects
    $delegationGroup = Get-ADGroup -Identity $DelegationGroupName
    $delegationGroupSID = [System.Security.Principal.SecurityIdentifier] $delegationGroup.SID
    $delegationGroupACL = Get-Acl -Path "AD:\$OrganizationalUnit"
 
    # Build Access Control Entry (ACE)
    $aceIdentity = [System.Security.Principal.IdentityReference] $delegationGroupSID
    $aceADRight = [System.DirectoryServices.ActiveDirectoryRights] $confADRight
    $aceType = [System.Security.AccessControl.AccessControlType] "Allow"
    $aceInheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] "Descendent"
    $ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($aceIdentity, $aceADRight, $aceType, $confDelegatedObjectType, $aceInheritanceType)
 
    # Apply ACL
    $delegationGroupACL.AddAccessRule($ace)
    Set-Acl -Path "AD:\$OrganizationalUnit" -AclObject $delegationGroupACL
}
 
# Calling the function
Set-Delegation -OrganizationalUnit "OU=My,OU=Servers,DC=contoso,DC=com" -DelegationGroupName "global-server-admins-full"

Using the function as it is written above would set Full Control for members of the security group “global-server-admins-full” for all descendent objects (00000000-0000-0000-0000-000000000000) of the Organizational Unit “OU=My,OU=Servers,DC=contoso,DC=com” but not for the OU itself. Therefore, Users of the security group “global-server-admins-full” cannot modify or delete the OU itself.