As most environments grow they end up having many group polices enforcing a variety of different settings. At a certain point they become unmanageable and are in need of a cleanup. Merging GPOs is a pain as there isn’t really a good way of doing it – without PowerShell anyway. We faced this exactly scenario recently and lucky for us we came across this blog post by Ashley McGlone on TechNet. His script takes advantage of the Get-GPRegistryValue function to capture all of the settings and then copies them to a destination policy.
#--------------------------------------------------------------------
# Copy GPO Registry Settings
# Ashley McGlone, Microsoft PFE
# http://blogs.technet.com/b/ashleymcglone
# January 2011
#
# Parameters:
# dom FQDN of the domain where the GPOs reside
# src string name of the GPO to copy settings from
# dest string name of the GPO to copy settings to
# newDest switch to create dest GPO if it does not exist
# copymode part of GPO to copy: all, user, computer
#--------------------------------------------------------------------
Param (
$dom,
$src,
$dest,
[switch]$newDest,
$copymode
)
# We must continue on errors due to the way we enumerate GPO registry
# paths and values in the function CopyValues.
$ErrorActionPreference = "SilentlyContinue"
$error.PSBase.Clear()
Import-Module ActiveDirectory
Import-Module GroupPolicy
#--------------------------------------------------------------------
# Help
#--------------------------------------------------------------------
if ($dom -eq $null -and `
$src -eq $null -and `
$dest -eq $null -and `
$copymode -eq $null) {
""
"Copy-GPORegistryValue by Ashley McGlone, Microsoft PFE"
"For more info: http://blogs.technet.com/b/ashleymcglone"
""
"This script copies registry-based GPO settings from one GPO into another."
"Use this script to copy and/or merge policy settings."
"NOTE: This version does not copy GPO preferences."
""
"Syntax:"
".\Copy-GPRegistryValue.ps1 [-dom DomainFQDN] -src `"Source GPO`""
" -dest `"Destination GPO`" [-newDest]"
" [-copymode all/user/computer]"
""
"The -dom switch will default to the current domain if blank."
"The -copymode will default to all if blank."
"The -newDest switch will create a new destination GPO of the specified"
"name. If the GPO already exists, then the copy will proceed."
""
Return
}
#--------------------------------------------------------------------
# Validate parameters
#--------------------------------------------------------------------
if ($dom -eq $null) {
$dom = (Get-ADDomain).DNSRoot
} else {
$dom = (Get-ADDomain -Identity $dom).DNSRoot
If ($error.Count -ne 0) {
"Domain name does not exist. Please specify a valid domain FQDN."
$error
Return
}
}
if ($src -eq $null) {
"Source GPO name cannot be blank."
Return
} else {
$src = Get-GPO -Name $src
If ($error.Count -ne 0) {
"Source GPO does not exist. Be sure to use quotes around the name."
Return
}
}
if ($dest -eq $null) {
"Destination GPO name cannot be blank."
Return
} else {
if ($newDest -eq $true) {
$desttemp = $dest
$dest = New-GPO -Name $desttemp
If ($error.Count -ne 0) {
"The new destination GPO already exists."
"Do you want to merge into this GPO (y/n)?"
$choice = Read-Host
if ($choice -eq "y") {
$dest = Get-GPO -Name $desttemp
} else {
Return
}
}
} else {
$dest = Get-GPO -Name $dest
If ($error.Count -ne 0) {
"Destination GPO does not exist. Be sure to use quotes around the name."
Return
}
}
}
if ($copymode -eq $null) {
$copymode = "all"
} else {
if ($copymode -ne "all" -and `
$copymode -ne "user" -and `
$copymode -ne "computer") {
"copymode must be one of the following values:"
"all, user, computer"
Return
}
}
#--------------------------------------------------------------------
#--------------------------------------------------------------------
# Echo parameters for this run
#--------------------------------------------------------------------
""
"Domain: $dom"
"Source GPO: $($src.DisplayName)"
"Destination GPO: $($dest.DisplayName)"
"New Destination: $newDest"
"CopyMode: $copymode"
""
#--------------------------------------------------------------------
#--------------------------------------------------------------------
# Copy GPO registry values recursively beginning at a specified root.
#--------------------------------------------------------------------
# THIS IS THE HEART OF THE SCRIPT.
# Essentially this routine does a get from the source and a set on
# the destination. Of course nothing is ever that simple, so we have
# to account for the policystate "delete" which disables a setting;
# this is like a "negative set".
# We recurse down each registry path until we find a value to
# get/set.
# If we try to get a value from a path (non-leaf level), then we get
# an error and continue to dig down the path. If we get a value and
# no error, then we do the set.
# User values have a single root: HKCU\Software.
# Computer values have two roots: HKLM\System & HKLM\Software.
# You can find these roots yourself by analyzing ADM and ADMX files.
# It is normal to see an error in the output, because all of these
# roots are not used in all policies.
#--------------------------------------------------------------------
Function CopyValues ($Key) {
$Key
$error.PSBase.Clear()
$path = Get-GPRegistryValue -GUID $src.ID -Key $Key
$path
If ($error.Count -eq 0) {
ForEach ($keypath in $path) {
$keypath
$keypath | ForEach-Object {Write-Host $_}
If ($keypath.HasValue) {
$keypath.PolicyState
$keypath.Valuename
$keypath.Type
$keypath.Value
If ($keypath.PolicyState -eq "Delete") { # PolicyState = "Delete"
Set-GPRegistryValue -Disable -Domain $dom -GUID $dest.ID `
-Key $keypath.FullKeyPath -ValueName $keypath.Valuename
} Else { # PolicyState = "Set"
$keypath | Set-GPRegistryValue -Domain $dom -GUID $dest.ID
}
} Else {
CopyValues $keypath.FullKeyPath
}
}
} Else {
$error
}
}
#--------------------------------------------------------------------
#--------------------------------------------------------------------
# Call the main copy routine for the specified scope of $copymode
#--------------------------------------------------------------------
Function Copy-GPRegistryValue {
# Copy user settings
If (($copymode -eq "user") -or ($copymode -eq "all")) {
CopyValues "HKCU\Software"
}
# Copy computer settings
If (($copymode -eq "computer") -or ($copymode -eq "all")) {
CopyValues "HKLM\System"
CopyValues "HKLM\Software"
}
}
#--------------------------------------------------------------------
# Start the copy
Copy-GPRegistryValue
# ><>
Thursday, October 6, 2011
Steve Jobs 1955 - 2011
Like him or not, Steve Jobs was one of the greatest innovators of our time. His creative vision saved Apple from the brink in the late nineties and turned it into a consumer electronics powerhouse. Just look at how the iPod, iPad and the iPhone has changed our lives. With his health failing he passed the torch one final time to now CEO and Chairman of the board Tim Cook this past August. It will be interesting to see how Apple fairs in the coming years without the innovation and creativity of Jobs. He touched a lot of people and his loss will be felt throughout the world.
"The world rarely sees someone who has had the profound impact Steve has had, the effects of which will be felt for many generations to come. For those of us lucky enough to get to work with him, it’s been an insanely great honor. I will miss Steve immensely."
- Bill Gates
"The world rarely sees someone who has had the profound impact Steve has had, the effects of which will be felt for many generations to come. For those of us lucky enough to get to work with him, it’s been an insanely great honor. I will miss Steve immensely."
- Bill Gates
Labels:
Apple
Subscribe to:
Posts (Atom)