In order to maintain best practices in a multi domain forest, we occasionally have to create file and application access groups to secure sensitive resources we manage. Creating a 3 groups to do this is a lot of hassle, but it needs to be done, however you don’t need to do it manually.
I created a script to take care of this day to day task for me. The script basically does 3 thing:
- It checks if a security group with that name already exists and if so it aborts.
- It creates 3 security groups: a “Domain Local” group for rights assignment, a “Global” group to put my users in, and a “Universal” group to link the Global and Domain Local groups, as well as to link groups from other domains in our forest.
- It asks the user what folder to add rights to and what rights to add (Read, Write and/or Modify) and then sets those rights on the appropriate folder.
The script uses Quest Active Roles AD Management snapin for Powershell (available here)
I’ve added logging using the transcript functionality, and if you check out line 19 and 114 you see that I’m starting and stopping logging to a specific file using the “Start-Transcript” and “Stop-Transcript” cmdlets. This means that the script will throw and error in ISE since it doesn’t support transcripting, but running it in a normal powershell windows will ensure that everything happing between line 15 to 113 get’s logged!
Without further ado, heres the script:
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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
######################################################################################################## # This scripts creates groups based on best practise and the current naming convention at <company> # 3 groups will be created, on Global for user memberships, one Universal for cross domain # memberships and a Domain Local group for rights assignement. # # When executing the script, you will be asked for a group name. Only write the name of the resource # you like to secure . The string "FILE_" will be added in front, and "_G", "_U" and "_DL" will be # added to each of the 3 groups respectivly based on their type . # Interlinking group memberships are added automatically, but users will need to be added to the # group ending with "_G" (Global). # # No rights are assigned on resources. Assign the requested rights on the group ending with "_DL". As # a result of the interlinking group memberships, the members of the "_G" group and groups made a # member of the "_U" group will also gain or be denied access to the resource based on the rights # assigned to the "_DL" group. ######################################################################################################## # Add Quest ADmanager Snapin Start-Transcript -Path 'C:PowershellAD_File_Group_Creationaction.log' Add-PSSnapin Quest.Activeroles.ADManagement # Nulling out variables to avoid left over values being used in script run $inputname = $null $domain = $null $name = $null $domain = $null $G = $null $U = $null $DL = $null $counter = $null $acl = $null $ar = $null $folder = $null $rights = $null $sign = $null # Get information on group name and format group name to current naming convention $folder = Read-Host 'Please type or copy in the full and correct path to the share and folder the groups will assign rights to. This will be used for the description fields and rights assignement' $rights = Read-Host 'Enter R for Read, W for Write and/or M for Modify to rights on the target folder' $inputname = Read-Host 'Name of security group' $inputname = $inputname.ToUpper() $name = "FILE_" $name = $name+$inputname $domain = "nordic" $G = $name+"_G" $U = $name+"_U" $DL= $name+"_DL" # Check if the group already exists $GroupExists = Get-QADGroup $name IF ( $GroupExists -eq $null ) { # Add groups Write-Host "Creating new groups" New-QADGroup -Name $G -SamAccountName $G -GroupScope 'Global' -ParentContainer 'OU=Organizational Unit,DC=domain,DC=com' -Description "Users have access to $folder" New-QADGroup -Name $U -SamAccountName $U -GroupScope 'Universal' -ParentContainer 'OU=Organizational Unit,DC=domain,DC=com' -Description "Users have access to $folder" New-QADGroup -Name $DL -SamAccountName $DL -GroupScope 'DomainLocal' -ParentContainer 'OU=Organizational Unit,DC=domain,DC=com' -Description "Users have access to $folder" sleep 2 cls # Assign standard group memberships Write-Host "Assigning interlinking group memberships" Add-QADGroupMember $domain$DL $domain$U Add-QADGroupMember $domain$U $domain$G sleep 2 # Add rights on the folder # Read IF ($rights -like "*R*" ) { $rule = New-Object system.security.accesscontrol.filesystemaccessrule($DL,"Read","ContainerInherit,ObjectInherit","None","Allow") $acl = Get-Acl $folder $acl.AddAccessRule($rule) Set-Acl $folder $acl } # Write IF ( $rights -like "*W*" ) { $rule = New-Object system.security.accesscontrol.filesystemaccessrule($DL,"Write","ContainerInherit,ObjectInherit","None","Allow") $acl = Get-Acl $folder $acl.AddAccessRule($rule) Set-Acl $folder $acl } # Modify IF ( $rights -like "*M*" ) { $rule = New-Object system.security.accesscontrol.filesystemaccessrule($DL,"Modify","ContainerInherit,ObjectInherit","None","Allow") $acl = Get-Acl $folder $acl.AddAccessRule($rule) Set-Acl $folder $acl } cls $sign = "." $signs = "." $counter = 0 while ( $counter -lt 10 ) { cls write-host "All done$signs" $signs = $sign+$signs $counter = $counter+1 sleep 1 } } ELSE { $counter = 11 while ( $counter -gt 0 ) { $counter = $counter-1 CLS Write-Host "The groups beginning with" $name "already exists. Please select another group name" $counter Sleep 1 } } Stop-Transcript |
I still consider myself a novice at Powershell, however and advanced one at that, and I’d love to get feedback on better approaches to my scripting, both in the sense of optimizing the script for performance, and simplifying the script itself. I’d also be happy to answer any questions regarding the script 🙂