=========================================================

PART 1

=========================================================

Scenario:

PowerShell Active Directory Delegation.

I wrote this script long ago and I use it when there are changes in Active Directory to apply delegation on the new Organizational Units. I thought that you might find it interesting, so I decided to write this post. We will go through the script and by the end of the series, you will be able to understand what the script is doing. We will divide the script smaller parts and discuss them accordingly.

General Permissions

Microsoft provide us with the ability to perform delegation in Active Directory, through Active Directory User and Computers. Have you ever tried to apply delegation using the GUI? I have tried to do it and it was a nightmare. As you will see later on, the delegation that I had to apply was really detailed and deep that default roles provide by Microsoft were not applicable. To better understand what we are trying to do with this script, we will set our requirements down. First of all we will create our groups based on the permissions that they will have. The groups  are the below:

Each of the above groups will have different permissions. Each group provides additional permissions, so an administrator needs to be member of all groups to have full access. I will not go through the entire list as we will need  a lot of space to list all permissions here. All groups are able to read all properties of all objects. In general the Service Desk group will be able to unlock and reset the password only for user accounts. Computer administrators will be able to do the same with services desk and additionally create, delete,write properties of computer objects in Active Directory. User administrators, additionally, will be ale to create user objects, and write/ modify some properties of the user objects. Active Directory administrators, will be able to perform all of the above and also manage servers and services accounts. Active Directory Engineers will have full control on servers, computers, users and services accounts.

Gather information from Active Directory

Imagine changing all those properties of all current Organizational Units in Active Directory. Also for any new Organizational Unit, you will need also to perform those changes, so the administrators will be able have the same permissions. First we will need to gather some information from our Active Directory.


$rootdse = Get-ADRootDSE

The above command will provide us with the root of a Directory Server information tree. As per Microsoft:

The Get-ADRootDSE cmdlet gets the conceptual object representing the root of the directory information tree of a directory server. This tree provides information about the configuration and capabilities of the directory server, such as the distinguished name for the configuration container, the current time on the directory server, and the functional levels of the directory server and the domain.

After that we will need to create a hash table to store the GUID value of each schema class and attribute. Those values will be used later, to apply the permissions. By using the command below, we declare our hash table and then we fill it accordingly. We keep the LDAP display name and schema GUID number for each value. 


$guidmap = @{}
Get-ADObject -SearchBase ($rootdse.SchemaNamingContext) -LDAPFilter `
"(schemaidguid=*)" -Properties lDAPDisplayName,schemaIDGUID |
% {$guidmap[$_.lDAPDisplayName]=[System.GUID]$_.schemaIDGUID}

Then we have to create another hash table to keep the display name and GUID value for each extended permission right the is included in the forest. The following command will retrieve the information that we need and fill our hash table.

$extendedrightsmap = @{}
Get-ADObject -SearchBase ($rootdse.ConfigurationNamingContext) -LDAPFilter `
"(&(objectclass=controlAccessRight)(rightsguid=*))" -Properties displayName,rightsGuid |
% {$extendedrightsmap[$_.displayName]=[System.GUID]$_.rightsGuid}
Create our arrays

The next part is based on your Organizational Unit structure in Active Directory. The difference is the search base that you search to find the organizational units. By using the below commands we will be able to get the domain and a list of the Organizational Units under that one. The we will create our arrays that we will use to perform the delegation and apply the correct permissions.

$domain = Get-ADDomain
$AllOUs = Get-ADOrganizationalUnit -Properties DistinguishedName -SearchBase ("OU=Offices,"+$domain.DistinguishedName) -Filter *

After we have gathered all Organizational Units that we want, we will proceed with filtering of that variable. The below is a sample on how we are able to do so. We are using the main array that holds all organizational units that we have gathered before. We create new arrays, by using filtering on it and as you are able to see below, we are creating a list of organizational units that are holding employees under them. For the below example, we have five locations, Cyprus, Greece, Germany, India, United Kingdom, and each one has its own array.

$CyprusEmployeesOUs = ($AllOUs | ? {($_.DistinguishedName -like "*Employees*") -and ($_.DistinguishedName -like "*Cyprus*")}).DistinguishedName
$GreeceEmployeesOUs = ($AllOUs | ? {($_.DistinguishedName -like "*Employees*") -and ($_.DistinguishedName -like "*Greece*")}).DistinguishedName
$GermanyEmployeesOUs = ($AllOUs | ? {($_.DistinguishedName -like "*Employees*") -and ($_.DistinguishedName -like "*Germany*")}).DistinguishedName
$IndiaEmployeesOUs = ($AllOUs | ? {($_.DistinguishedName -like "*Employees*") -and ($_.DistinguishedName -like "*India*")}).DistinguishedName
$UnitedKingdomEmployeesOUs = ($AllOUs | ? {($_.DistinguishedName -like "*Employees*") -and ($_.DistinguishedName -like "*UnitedKingdom*")}).DistinguishedName

In the next part we will go through the permissions in more details and ACLs in active directory and how we will apply the delegated permissions. The process of applying delegated permissions is not an one time job. Every time, that there is a new Organizational Unit we will need to apply delegated permissions again.  We will put all parts together so we will have a full working script that can be reused every time we have to apply delegated permissions to new organizational units.

===============================================================

PART 2

===============================================================

Scenario:

PowerShell Active Directory Delegation – Part 2

In Part 1 of this series we have discussed about getting the information from Active Directory. We have created our arrays to keep the information that we will need. We created We have also seen sample of the lists, that we can create, to process them later and apply delegation on each Organizational Unit. In this part we will go though the Access Control List in Active Directory and how we will perform our changes to accomplish the delegation in Active Directory. Also, we will see a sample of the attributes that we will provide to local IT administrators.

Active Directory Access Control List

In order to be able to modify the access control list, we need first to retrieve the current list so we will be able to add our delegated access and not to disturb and lose the current setup that we already have. So we need to use the below command to get the current access control list of a specific organizational unit.


$acl = get-acl $currentuserou

The above command will get all access control entries in the current access control list of an organizational unit and will save them in a variable so we will be able to modify it.

Modify the Access Control List

Now we want to modify the access control list that we have saved in the variable. In order to modify it we will have to create and add access control entries in the access control list. Then after the list has been edited with our changes. To create the new access control entries we need to create the objects accordingly. In the access control entries that we will create, we have to define a few variables. These variables will include all the information that we need to provide delegated access to our local IT administrators. As you are able to see below, there are different permissions that we can apply. In general, we have to first provide the group of local IT administrators that we get those permissions. Then we define the right that we want to apply to the group. After that we apply the action and then the objects that will be applied to.

Below are some examples of access control entries. Let's explain them a bit to understand better how you will be able to create you own. On $ace1service, we first define the group that will get the permissions ($servicegroup). Then we define the access, which in this case Read all properties of the organizational unit that will be applied. After that we have to define the access permission which is "Allow" for this one. We apply this, not only to the specific organizational unit but also to any objects under that, which are user objects. As you can see, to define the correct object, we need to define the correct GUID. We have already created in part 1 of the series our GUID hash table and we use it at this point to provide the permissions accordingly. In this specific access control entry we use $guidmap["user"] in order to provide these permissions for user objects.

There are different types of rights that you can provide to local IT administrators, depending on what you are trying to achieve. On $ace3service we have ExtendedRight and we user the other hash table that we have created in part 1 of the series ($extendedrightsmap). Hash tables allow us to use the display names instead of the GUID values for the permissions that we will provide.

In $ace1user we allow our local IT administrators to create child objects under the specific organizational unit. The objects that we allow them to create are users. In $ace2user we allow our local It administrators to write and modify "company" attribute for all user objects under the specific organizational unit.

$ace1service = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $servicegroup,
"ReadProperty",
"Allow",
"Descendents",
$guidmap["user"]
$ace3service = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $servicegroup,
"ExtendedRight",
"Allow",
$extendedrightsmap["Reset Password"],
"Descendents",
$guidmap["user"]
$ace1user = new-object System.DirectoryServices.ActiveDirectoryAccessRule $usergroup,
"CreateChild",
"Allow",
$guidmap["user"]
$ace2user = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $usergroup,
"WriteProperty",
"Allow",
$guidmap["company"],
"Descendents",
$guidmap["user"]
$ace3user = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $usergroup,
"WriteProperty",
"Allow",
$guidmap["department"],
"Descendents",
$guidmap["user"]
$ace4user = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $usergroup,
"WriteProperty",
"Allow",
$guidmap["description"],
"Descendents",
$guidmap["user"]
$ace5user = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $usergroup,
"WriteProperty",
"Allow",
$guidmap["displayName"],
"Descendents",
$guidmap["user"]

The above commands will create access control entries that we need to add in the access control list that we have retrieved before. In order to apply the new access control entries in the access control list, we have to use the below command. After the list is ready with all access control entries in it, we have to set the access control list back to our organizational unit by using the below command.


$acl.AddAccessRule($ace1user)

set-acl -aclobject $acl -Path $currentuserou
Permissions to our local IT administrators

Below are lists with permissions that we will provide to our local IT administrators for user objects, computer objects, group objects. Each group of local IT administrators will get the permissions accordingly based on the groups that we have discussed in Part 1 of this series.

Users Objects
Group Objects
Computer Objects
Applying our knowledge in the script

The below script is a sample and needs to be review and edited accordingly so you will be able to use it. You may give permissions, or remove permissions that you do not want and create issues with your systems. The main point of the above, is that we have to retrieve the access control lists from the organizational units. Then, we create our new access control entries and add them to the current access control list. After we have everything ready will need to apply the access control list to the organizational unit, so the delegated permissions will be applied.

Run the script

As you are able to see below in the script a few loops are used in order to remove some input errors. Another main loop is used so that you will be able to run the script again either for different object or different country without the need to exit the script and run it from the beginning. When the application of the modified access control list is completed, then we receive a green output, that delegation for the specific organizational unit has been applied.

When you run the script will will ask you first to select on which option you want to apply delegation. After you select the object type, the script will ask you to select on which country you want to apply the delegated permissions. At this stage the script will start processing based on your input and will give you the results accordingly. After the script has completed providing the delegated permissions to the specific organizational units it will ask you if you would like to run the script again for another object or country. It accepts only "y" or "n". If your input is yes then the script will start from the beginning and will ask you again to give the options. If your input is no, the script will exit. In order to run the script, you will need to run PowerShell as an administrator with domain admin permissions.

===================================================

Script updated on 12 April 2018

===================================================