Reputation: 759
Objective: I'm attempting to modify a GPO (2008R2 AD) via Powershell (v3). Specifically the value of the User Configuration -> Policies -> Windows Settings -> FileRedirection -> Documents UNC path.
Initial attempt:
import-module grouppolicy;
$StringToFind = "\\this\is\a\template\path";
$StringToRepalce="\\server123\%CustomerID%\%username%\Documents\";
$GPOBackupFolder = "C:\src\psh\gpoBackupEditRestore\backups";
$GPO = copy-gpo -SourceName "Customer GPO Template v1.4" -targetName "Customer $CustomerID" -CopyACL;
$GPOBackup = $Backup-GPO -guid $gpo.id -path $GPOBackupFolder;
$GPOBackupXMLPath="$GPOBackupFolder\$($GpoBackup.ID)\Backup.xml";
$GPOGPReportXMLPath="$GPOBackupFolder\$($GpoBackup.ID)\GPReport.xml";
$NewBackupXMLPath="$GPOBackupFolder\$($GpoBackup.ID)\nBackup.xml";
$NewGPReportXMLPath="$GPOBackupFolder\$($GpoBackup.ID)\nGPReport.xml";
$GPOBackup=gc $GPOBackupXMLPath;
$GPOGPReport= gc $GPOGPReportXMLPath;
foreach($line in $GPOBackup){ac $NewBackupXMLPath $line.Replace($StringToFind,$StringToReplace);}
foreach($line in $GPOGPReport){ac $NewGPReportXMLPath $line.Replace($StringToFind,$StringToReplace);}
remove-item -force $GPOBackupXMLPath;
remove-item -force $GPOGPReportXMLPath;
move-item -force $NewBackupXMLPath $GPOBackupXMLPath
move-item -force $NewGPReportXMLPath $GPOGPReportXMLPath
Remove-GPO -ID $GPO.ID #remove GPO before restore. deleting/commenting this line does not change outcome.
Restore-GPO -BackupID $GPOBackup.ID -Path $GPOBackupFolder
Assuming I'm reading the information correctly at http://technet.microsoft.com/en-us/library/ee461027.aspx, the above Powershell snippit should restore the XML at the local folder location to the GPO in AD. [[I've confirmed that the template values ($StringToFind) do not occur within any other file in the GPOBackupFolder directory.]]
However, the changed values from the local XML files are NOT being restored to AD. I have confirmed this by doing an additional backup of the GPO after restoring it and comparing the initial (modified) backup files (which have been restored) to the post-restore backup value (now containing the /Original/ values!).
Has anyone else attempted this and/or can explain this behaviour as to why Restore-GPO would not be restoring the content of the backup files?
Upvotes: 2
Views: 19492
Reputation: 1
#Full name of GPO
$GPOedits = "Name1", "Name2"
#Local path to back GPO up to
$Pathbkp = "C:\Location"
#Names of old paths
$Pathstoedit = @("Stuff")
#Names of new paths -in same order as old paths
$Pathseditted = @("NewStuff")
foreach ($GPOedit in $GPOedits)
{Backup-GPO -Name $GPOedit -Path $Pathbkp}
$configFiles = Get-ChildItem $Pathbkp *.xml -rec
foreach ($file in $configFiles)
{
Write-Host "Editting $file."
$n = 0
foreach ($Pathtoedit in $Pathstoedit)
{
$Patheditted = $Pathseditted[$n]
$Pathtoedit = $Pathtoedit.Replace(".domain", "")
$Patheditted = $Patheditted.Replace(".domain", "")
[regex]$addfqdn = "\\"
$Patheditted = $addfqdn.replace($Patheditted, ".dir.ad.dla.mil\", 1)
Write-Host "Changing $Pathtoedit to $Patheditted"
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace [Regex]::Escape($Pathtoedit), $Patheditted } |
Set-Content $file.PSPath
[regex]$addfqdn = "\\"
$Pathtoedit = $addfqdn.replace($Pathtoedit, ".domain\", 1)
Write-Host "Changing $Pathtoedit to $Patheditted"
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace [Regex]::Escape($Pathtoedit), $Patheditted } |
Set-Content $file.PSPath
$n = $n + 1
}
}
Write-Host "Check you work, we are about to import policy changes!"
Pause
foreach ($GPOedit in $GPOedits)
{
Write-Host "Restoring $GPOEdit"
Restore-GPO -Name $GPOedit -Path $Pathbkp
Write-Host "Checking GUID"
$GUID = Get-GPO -Name "$GPOedit" | select -ExpandProperty "ID"
$GUID = "{$GUID}"
Write-Host "Checking GPT.ini for $GUID"
$GPT = Get-ChildItem -Path "\\domain\SYSVOL\Domain\Policies\$GUID" -File | select -ExpandProperty "Name"
If ($GPT -like "*gpt.ini*") { Write-Host "GPT.ini located" }
else { Write-Host "GPT.ini NOT FOUND" }
}
Upvotes: 0
Reputation: 13
I stumbled upon this post and decided to take it on myself without doing hacks. While the content was actually in the XML file, the GPO Restore is actually looking at registry.pol instead. I was doing Machine-level policies, so it was in DomainSysvol\GPO\Machine\registry.pol.
Once I edited that file (which is somewhat obfuscated - see here for directions) - https://gallery.technet.microsoft.com/scriptcenter/Read-or-modify-Registrypol-778fed6e
...I was able to restore the copied GPO and have it have the correct settings.
I have 300 GPO's I need to create which all look somewhat similar, so this will save countless hours of time.
Upvotes: 1
Reputation: 759
UPDATE: I found a way to directly modify the GPO's ini file on the DC.
As this solution does NOT use any API, I consider this a HACK; however, thus far it's the only solution I've encountered.
From what I've been able to glean (from my limited workings in that world) about AD Architecture & DC Replication, The SYSVOL section of the DC will be replicated to other DC's in the Forrest, same as if the changes were made via MMC. Can anyone confirm this?
Note: As far as I can tell, this script must be run locally from a DC in the same org as the GPO being affected.
$GPO = copy-gpo -SourceName "$GPOTemplateName" -TargetName "$NewGPOName" -CopyACL
#Found post referencing how to Manually Edit GPO's: http://blogg.husbanken.no/it/2013/04/13/manually-edit-gpo-settings/
$adGPO=[ADSI]"LDAP://$($GPO.path)";
$GPOFilePath = $adGPO.psbase.properties.gPCFileSysPath;
#Specifically the path to the GPO section affecting Folder Redirection
$GPOFolderRedirectionINIPath = "$GPOFilePath\User\Documents & Settings\fdeploy.ini";
#Functions for importing/exporting an INI file with Powershell in a very standard way: http://blogs.technet.com/b/heyscriptingguy/archive/2011/08/20/use-powershell-to-work-with-any-ini-file.aspx
. ".\get-inicontent.ps1"; # From: http://gallery.technet.microsoft.com/scriptcenter/ea40c1ef-c856-434b-b8fb-ebd7a76e8d91
. ".\out-inifile.ps1"; # From: http://gallery.technet.microsoft.com/scriptcenter/7d7c867f-026e-4620-bf32-eca99b4e42f4
$GPOFolderRedirectionINI = get-iniContent $GPOFolderRedirectionINIPath;
$GPOFolderRedirectionINI["My Documents"]["s-1-1-0"]="\\New\Path\To\CustomerFolder\%USERNAME%\"
$GPOFolderRedirectionINI | out-iniFile $GPOFolderRedirectionINIPath -Force
I've POC'd this, and it functions properly & With any luck someone else will find this method helpful; however I'm hopeful someone finds a better way to do this.
Cheers!
Upvotes: 2