使用Powershell编辑/修改GPO

时间:2013-07-08 15:22:15

标签: powershell active-directory powershell-v3.0 gpo

目标:我正在尝试通过Powershell(v3)修改GPO(2008R2 AD)。具体来说,用户配置的价值 - >政策 - > Windows设置 - > FileRedirection - >文件UNC路径。

初步尝试:

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

假设我正在http://technet.microsoft.com/en-us/library/ee461027.aspx正确读取信息,上面的Powershell snippit应该将本地文件夹位置的XML恢复到AD中的GPO。 [[我已确认模板值($ StringToFind)不会出现在GPOBackupFolder目录中的任何其他文件中。]]

但是,本地XML文件中更改的值不会还原到AD。我已经通过在恢复它并将初始(修改的)备份文件(已经恢复)与恢复后备份值(现在包含/ Original / values!)进行比较后对GPO进行额外备份来确认这一点。

有没有其他人尝试过这个和/或可以解释为什么Restore-GPO不会恢复备份文件的内容?

3 个答案:

答案 0 :(得分:2)

更新:我找到了一种直接修改DC上GPO的ini文件的方法。

由于此解决方案不使用任何API,我认为这是一个HACK;然而,到目前为止,这是我遇到的唯一解决方案。

从我能够收集的信息(来自我在该世界的有限工作)中了解AD架构和DC复制,DC的SYSVOL部分将复制到Forrest中的其他DC,就像通过MMC进行更改一样。谁能证实这一点?

注意:据我所知,此脚本必须在与受影响的GPO相同的组织中的DC本地运行。

$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

我已经POC了这个,并且它正常运行&运气好的话,其他人会发现这种方法很有帮助;但是我希望有人找到更好的方法来做到这一点。

干杯!

答案 1 :(得分:1)

我偶然发现了这个帖子并且决定自己接受它而不做黑客攻击。虽然内容实际上在XML文件中,但GPO Restore实际上是在查看registry.pol。我在做机器级策略,所以它在DomainSysvol \ GPO \ Machine \ registry.pol中。

一旦我编辑了该文件(有些模糊 - 请参阅此处查看说明) - https://gallery.technet.microsoft.com/scriptcenter/Read-or-modify-Registrypol-778fed6e

...我能够恢复复制的GPO并使其具有正确的设置。

我需要创建300 GPO,这些GPO看起来有点相似,所以这将节省无数小时的时间。

答案 2 :(得分:0)

#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" }
}