The estimated reading time 7 minutes
NTFS AGDLP group nesting between two domains via powershell
the last two years I was involved in some small project migrating domains to a new forest. There are lots of consideration you have to think about. One piece of this considerations should be your fileserver. Lots of fileservers don’t have a proper ntfs acls following the AGDLP principle. There for I created a small powershell script to generate a new folderstructure with the appropriated NTFS permissions also implementing AGDLP automatically between two domains.
scenario:
So my setup should look like this after executing the script.
In my demolab there are two domaincontroller hosting separated forest.
First one is called demo01.it-koehler.com and the second just simple demo02.it-koehler.com .
One domaincontroller is Windows Server 2016 and the other is Windows Server 2019 17763 Core Edition.
I configured a two way trust so that I can test both directions.
share02 is located on dc01-70.demo01.it-koehler.com. I use the Windows Admin Center to show it. Have a look, its pretty cool!
On dc01-70 I created a shot txt file (can also be an csv file) with my new folderstructure. (c:\temp\folders.txt)
Another prerequisit is to install the ntfs powershell module created by Andree Raimund.
https://gallery.technet.microsoft.com/scriptcenter/1abd77a5-9c0b-4a2b-acef-90dbb2b84e85
https://www.powershellgallery.com/packages/NTFSSecurity/4.2.4
On my machine I already installed the module and imported it to my environment.
NTFS permission on the share have also been modified. Only administrative permission are set on this folder.
In my active directory I created some OUs to store the new ad groups for the folders. Of course they are empty at the beginning.
Now we’re ready to do some cool stuff with these two forests.
No more kidding here is the script I created to do the task.
NTFS-Permissions Script
#domain 1 informations $folderstructure = Get-Content -Path c:\temp\folders.txt -Encoding UTF8 $dir = "\\dc01-70.demo01.it-koehler.com\share02" $dc = "dc01-70.demo01.it-koehler.com" $ouglobaldemo01 = "OU=groups,OU=DEMO,DC=demo01,DC=it-koehler,DC=com" $outlocaldemo01 = "OU=groups,OU=DEMO,DC=demo01,DC=it-koehler,DC=com" $domainadmin = "demo01\domain admins" #groupnames $grouplocal = "loc_dc01-70_share02-" $groupglobal = "glo_dc01-70_share02-" #domain 2 only creating global groups and put them into local group of domain 1 $dcdemo02 = "dc0280.demo02.it-koehler.com" $ouglobaldemo02 = "OU=groups,OU=DEMO02,DC=demo02,DC=it-koehler,DC=com" #loading modules $ADModule='ActiveDirectory' if (Get-Module -Name $ADModule) { write-host 'Module' $ADModule 'already loaded' } else { Import-Module $ADModule -force write-host 'Module' $ADModule 'loaded successfully' } $NTFSModule='NTFSSecurity' if (Get-Module -Name $NTFSModule) { write-host 'Module' $NTFSModule 'already loaded' } else { Import-Module $NTFSModule -force write-host 'Module' $NTFSModule 'loaded successfully' } #credentials already available or not if ($credentialdemo02 -eq $null){ #getting credentials for second domain $credentialdemo02 = Get-Credential -Message "user for connecting to $dcdemo02" -UserName demo02\administrator } else{ Write-Host "Credentials already available." } #go through textfile and generate folders and groups in both domains foreach($newfolder in $folderstructure){ #generate path to folders $folderpath = "$dir\$NewFolder" #generate groupnames $groupnamelocalread = ("$grouplocal-"+$newfolder+"_r").ToLower() $groupnameglobalread = ("$groupglobal-"+$newfolder+"_r").ToLower() $groupnamelocalwrite = ("$grouplocal-"+$newfolder+"_w").ToLower() $groupnameglobalwrite = ("$groupglobal-"+$newfolder+"_w").ToLower() if( -Not (Test-Path -Path "$folderpath" ) ) { #generate folder New-Item -ItemType directory -Path "$folderpath".Tolower() | Out-Null Write-Host "folder $folderpath created" #group creation write in domain 1 New-ADGroup -server "$dc" -GroupScope global -Name "$groupnameglobalwrite" -Path "$ouglobaldemo01" -Description "global permission to write on $folderpath" New-ADGroup -server "$dc" -GroupScope domainlocal -Name "$groupnamelocalwrite" -Path "$ouglobaldemo01" -Description "local permission to write on $folderpath" #group creation write in domain 2 New-ADGroup -server "$dcdemo02" -Credential $credentialdemo02 -GroupScope global -Name ("$groupnameglobalwrite").tolower() -Path "$ouglobaldemo02" -Description "global permission to write on $folderpath " #group nesting $tempreadgroupdemo01 = get-adgroup -server $dc -Identity ("$groupnameglobalwrite") $tempreadgroupdemo02 = get-adgroup -server $dcdemo02 -Credential $credentialdemo02 -Identity ("$groupnameglobalwrite") # group nesting domain 1 Add-ADGroupMember -Identity ("$groupnamelocalwrite") -Members $tempreadgroupdemo01 -Server $dc #group nesting domain 2 Add-ADGroupMember -Identity ("$groupnamelocalwrite") -Members $tempreadgroupdemo02 -Server $dc #generate folder #group creation read in domain 1 New-ADGroup -server "$dc" -GroupScope global -Name "$groupnameglobalread" -Path "$ouglobaldemo01" -Description "global permission to write on $folderpath" New-ADGroup -server "$dc" -GroupScope domainlocal -Name "$groupnamelocalread" -Path "$ouglobaldemo01" -Description "local permission to write on $folderpath" #group creation read in domain 2 New-ADGroup -server "$dcdemo02" -Credential $credentialdemo02 -GroupScope global -Name ("$groupnameglobalread").tolower() -Path "$ouglobaldemo02" -Description "global permission to write on $folderpath " #group nesting $tempreadgroupdemo01 = get-adgroup -server $dc -Identity ("$groupnameglobalread") $tempreadgroupdemo02 = get-adgroup -server $dcdemo02 -Credential $credentialdemo02 -Identity ("$groupnameglobalread") # group nesting domain 1 Add-ADGroupMember -Identity ("$groupnamelocalread") -Members $tempreadgroupdemo01 -Server $dc #group nesting domain 2 Add-ADGroupMember -Identity ("$groupnamelocalread") -Members $tempreadgroupdemo02 -Server $dc Write-Host "Adding NTFS Permissions" #setting owner $folderpath | Set-NTFSOwner -Account "$domainadmin" Write-Host "New Owner on $NewFolder is $domainadmin " Write-Host "Addin other NTFS Permissions on $NewFolder " #write permission Add-NTFSAccess -Path "$folderpath" -Account ("$groupnamelocalwrite") -AccessRights ReadData,CreateFiles,Createdirectories,ReadExtendedAttributes,WriteExtendedAttributes,DeleteSubdirectoriesandFiles,ReadAttributes,WriteAttributes,ReadPermissions,ExecuteFile -AppliesTo ThisFolderSubfoldersAndFiles #read permission Add-NTFSAccess -Path "$folderpath" -Account ("$groupnamelocalread") -AccessRights Read,ReadAndExecute,ListDirectory -AppliesTo ThisFolderSubfoldersAndFiles Write-Host "NTFS Permissions set!" #show all NTFS permissions on folder Get-NTFSAccess -Path "$folderpath" | ft -AutoSize -Wrap } else { Write-Host "$newfolder Ordner existiert bereits, es wird nichts angelegt!" -ForegroundColor Yellow } }
The Script is asking for credentials to the second domain demo02
After typing the credentials it connects to the local and to the remote ad and creates the groups for the folders. It also nests the local with global groups to agdlp principle.
Let’s have a look on the share and the created folders.
The folders receive the administrative permissions from folder “share02” and domainlocal groups give the access rights to users.
Also the script gives you a short overview in the console.
After you finished creating you folders put the appropriated users to the GLOBAL groups and your done.
Also check if the can access the top folder “share02”. In my demo I set “authenticated users” to access the top level of the share.
Some explanation to the script where you can modify for your own needs:
Change all variables for your domain structure.
#domain 1 informations $folderstructure = Get-Content -Path c:\temp\folders.txt -Encoding UTF8 $dir = "\\dc01-70.demo01.it-koehler.com\share02" $dc = "dc01-70.demo01.it-koehler.com" $ouglobaldemo01 = "OU=groups,OU=DEMO,DC=demo01,DC=it-koehler,DC=com" $outlocaldemo01 = "OU=groups,OU=DEMO,DC=demo01,DC=it-koehler,DC=com" $domainadmin = "demo01\domain admins" #groupnames $grouplocal = "loc_dc01-70_share02-" $groupglobal = "glo_dc01-70_share02-" #domain 2 only creating global groups and put them into local group of domain 1 $dcdemo02 = "dc0280.demo02.it-koehler.com" $ouglobaldemo02 = "OU=groups,OU=DEMO02,DC=demo02,DC=it-koehler,DC=com"
Line 50-56 you can define the groupnames
generate path to folders $folderpath = "$dir\$NewFolder" #generate groupnames $groupnamelocalread = ("$grouplocal-"+$newfolder+"_r").ToLower() $groupnameglobalread = ("$groupglobal-"+$newfolder+"_r").ToLower() $groupnamelocalwrite = ("$grouplocal-"+$newfolder+"_w").ToLower() $groupnameglobalwrite = ("$groupglobal-"+$newfolder+"_w").ToLower()
If you want to give additional permissions you can simply modify the add-ntfsaccess line 96-99
#write permission Add-NTFSAccess -Path "$folderpath" -Account ("$groupnamelocalwrite") -AccessRights ReadData,CreateFiles,Createdirectories,ReadExtendedAttributes,WriteExtendedAttributes,DeleteSubdirectoriesandFiles,ReadAttributes,WriteAttributes,ReadPermissions,ExecuteFile -AppliesTo ThisFolderSubfoldersAndFiles #read permission Add-NTFSAccess -Path "$folderpath" -Account ("$groupnamelocalread") -AccessRights Read,ReadAndExecute,ListDirectory -AppliesTo ThisFolderSubfoldersAndFiles
The script does not much error handling. It only checks if the folder already exists.
If there are any questions just leave a comment and if you like this article please klick “helpful”
Have fun.