3

I need to automate the creation several security groups, then create and apply a GPO that includes OU / Security group specific file permissions and auditing.

I have the OU and group creation done. I can do the permission / auditing as ACLs but need to apply these as a GPO. I can link to the OUs/Groups and I can copy existing GPOs, but I still need to replace certain security groups. I do have the creation of registry keys per security group, but I cannot find any documentation on creating file permission / auditing.

Ex Case: We roll out Virtual web servers that are assigned to specific clients. We've got a PS script that creates the new OUs and security groups for the new server. Rather than have to re-apply a PS script with ACLs if we need to re-deploy the VM, we'd like to automate the GPO creation that contains the ACLs for the default folders so we don't have to touch anything on a re-deploy once the VM is back up.

I have the ACL script, and that works fine, but it's not good for automation in this case.

Zac M.
  • 51
  • 6
  • Why are you not using the deployment tools to role out and configure the web servers? this is trivial rather than manage and maintain a GPO per deployment. – Jim B Mar 26 '15 at 03:07
  • The server image is preset and deployed as a VM by the infrastructure team. The groups are added after the server is deployed when we get a new client. Need to apply the GPO to a new OU for new server / groups. Working on a PS based solution today. – Zac M. Mar 26 '15 at 13:03
  • Just remember that Sid (depending on the environment) can be multiple values. You still might want to use the MDT scripts and editor to run after the infrastructure team is done with theirs, although I'm amazed they aren't doing this as part of the deploy. Its like having 1 guy write the letter, put it in the envelope, write the address, then making another guy run up hill to a well, to wet a sponge to get the stamp glued on. – Jim B Mar 26 '15 at 17:21
  • I am getting the SID in powershell using other confirmed steps. That said, I'm the NFG, and tasked with scripting and coming up w/ better deployment stuff. This is just first step. It's a complicated product to get installed and configured. Trying to attack in chunks without stepping on toes. :-) So far so good. Full self answer coming soon.. :-) – Zac M. Mar 26 '15 at 17:59
  • If you are getting "the SID" just ensure its the right "the SID" the #1 and 2 mistakes I see in scripts for AD user/group objects is the presumption that there is only 1 sid per object and that the SID is unique. Good Luck! – Jim B Mar 26 '15 at 18:44
  • To be clear object SIDs are unique, but there are cases when the other SID from sidhistory isn't. – Jim B Mar 26 '15 at 19:44

2 Answers2

2

So, there is no way to directly set up file permissions in a GPO using Powershell. (Computer/Policies/Windows Settings/Security Settings/File System)

However, I was able to work around this by creating a GPO and manually backing it up (one time thing). In respect to the specific answer I was looking for, there are 3 files that need to be edited in the GPO backup.

  • {SOME_GUID}\Backup.xml
  • {SOME_GUID}\gpreport.xml
  • {SOME_GUID}\DomainSysvol\GPO\Machine\microsoft\windows nt\SecEdit\GptTmpl.inf

You will need to replace the User Group Name(s) and SIDs with placeholders [GROUP_NAME] and [GROUP_SID] (could be USER as well) in all three files. You will also need to update the {Name} tag in gpreport.xml and the {DisplayName} in backup.XML to the new name of the GPO. I did this with another place holder [GPO_NAME].

Now, this was the tricky part that took a while to figure out. You can't just Import-GPO this new object. You actually have to create a new blank GPO, back it up, and output the files that you update from the template into this backup.

Here's the code I used. There are a few placeholders in here. Replace these as needed for you environment. It looks like Stack formatting on Powershell scripts is a little off. It works as pasted.

#root path for script and files.
$scriptPath = "c:\GPO_Deployment"

# Create new GPO 
write-host "Create new GPO"
new-GPO -Name  [GPO_NAME] 

# Backup New GPO to Named folder
$backup = backup-gpo -Name  [GPO_NAME]   -Path $scriptPath

#

# Files that need to be updated:
#  GPO_TEMPLATE_FILES\Backup.xml
#  GPO_TEMPLATE_FILES\gpreport.xml
#  GPO_TEMPLATE_FILES\DomainSysvol\GPO\Machine\microsoft\windows nt\SecEdit\GptTmpl.inf

# Create Output file strucures

$newXMLpath = New-Item -Path ("{" + $backup.Id + "}") -ItemType Directory -Force
$newGPOinfPath = New-Item -ItemType Directory -Path ("{" + $backup.Id + "}\\DomainSysvol\\GPO\\Machine\\microsoft\\windows nt\\SecEdit") -Force

#get the Group SIDS for the groups we created above
$GROUP_SID =  (New-Object System.Security.Principal.NTAccount("DOMAIN", [GROUP_NAME])).Translate([System.Security.Principal.SecurityIdentifier])

write-host "Applying tranforms to template files"

# read inf_template file, replace sids, and write out
$inf_template = join-path -Path ($scriptPath + "\GPO_TEMPLATE_FILES\DomainSysvol\GPO\Machine\microsoft\windows nt\SecEdit") -ChildPath "GptTmpl.inf"
$inf_outfile = Join-Path -Path $newGPOinfPath -ChildPath "GptTmpl.inf"

(Get-Content $inf_template) | ForEach-Object {
    $_ -replace '\[GROUP_SID\]', $GROUP_SID
} | Set-Content $inf_outfile


# read Backup XML template file, replace sids, and write out
$backup_template = join-path -Path ($scriptPath + "\GPO_TEMPLATE_FILES") -ChildPath "Backup.xml"
$backup_outfile = Join-Path -Path $newXMLpath -ChildPath "Backup.xml"

(Get-Content $backup_template) | ForEach-Object {
    $_ -replace '\[GROUP_SID\]', $GROUP_SID `
        -replace '\[GPO_NAME\]', $hostedclient
} | Set-Content $backup_outfile


# read GPO Report XML template file, replace sids, and write out
$gporeport_template = join-path -Path ($scriptPath + "\GPO_TEMPLATE_FILES") -ChildPath "gpreport.xml"
$gporeport_outfile = Join-Path -Path $newXMLpath -ChildPath "gpreport.xml"

(Get-Content $gporeport_template) | ForEach-Object {
    $_ -replace '\[GROUP_SID\]', $GROUP_SID `
        -replace '\[GPO_NAME\]', $hostedclient
} | Set-Content $gporeport_outfile


Write-Host "Saving updated GPO, linking it to the new OU and moving traget web server to new OU."

# Import GPO
import-gpo -BackupId $backup.Id  -Path $scriptPath -TargetName [GPO_NAME]  -CreateIfNeeded 

$updatedGPO = get-gpo  -Name [GPO_NAME]
# Link GPO to OU 
## NOTE:  If you are updating an existing GPO Link, use Set-GPLink here
New-GPLink -Guid $updatedGPO.Id -Target ("OU=[YOUR_OU],DC=domain,DC=local") -LinkEnabled Yes

# Move web server to OU
get-adcomputer [YOUR_SERVER] | Move-ADObject -TargetPath ("OU=[YOUR_OU],DC=domain,DC=local")


# Add another wait for GPO to settle before forcing update.
Write-Host "Pausing again to allow DC to catch-up again."
start-sleep -seconds 15

write-host "Forcing a GP Update on target webserver."

Invoke-GPUpdate -Computer [YOUR_SERVER] 
Zac M.
  • 51
  • 6
1

You have to do in the computer configuration. Go to:

Computer Configuration\Policies\Windows Settings\Security Settings\File System

Right-click in the empty space in the right pane and choose "Add File". If whatever system you are on doesn't have the folder you want, you can create it in this file browser. After selecting the folder, assign the NTFS permissions.

Todd Wilcox
  • 2,851
  • 2
  • 20
  • 32
  • That is a manual process. There has to be a way to do this in Powershell. Adding better case in original q.. – Zac M. Mar 25 '15 at 21:06
  • Do you need the permissions to be dynamic? I suppose so or else you wokld – Todd Wilcox Mar 25 '15 at 21:13
  • This article makes me think if it's not registry based then you can't do it with powershell: https://technet.microsoft.com/en-us/library/ee461027.aspx – Todd Wilcox Mar 25 '15 at 21:16
  • Yep.. Read all of that one.. I'm thinking that I'll export a template XML, do some [GROUP_SID] find/replace in Powershell, then re-import the GPO and link to new OU. I'll post solution tomorrow if I get it to work. – Zac M. Mar 25 '15 at 21:18