NTFS AGDLP group nesting between two domains via powershell

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.

 

Was this article helpful?
YesNo
0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments