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
Tuesday, August 23, 2011
An error occurred when loading the task sequence
Recently I ran into a problem where I was unable to open and edit any of my task sequences. It didn’t matter whether I was accessing ConfigMgr from a remote console or locally on one of my site servers – they would fail to open. The error that I was getting:
"An error occurred when loading the task sequence"
I tried rebooting the problem site server but still no luck. According to KB2468097 this is caused because the BDD_* WMI classes are no longer correctly registered under the \root\SMS\site_ namespace in WMI.
"An error occurred when loading the task sequence"
I tried rebooting the problem site server but still no luck. According to KB2468097 this is caused because the BDD_* WMI classes are no longer correctly registered under the \root\SMS\site_ namespace in WMI.
- Close all of your remote and local SCCM admin console sessions
- Log on to your Configuration Manager server and select Start -> All Programs -> Microsoft Deployment Toolkit -> Configure ConfigMgr Integration
- In the Configure ConfigMgr Integration wizard, select “Remove the ConfigMgr custom action definitions” and then click next to remove all the definitions
- Re-run Configure ConfigMgr Integration again, and select “Install the ConfigMgr extensions”
Labels:
ConfigMgr / SCCM
Friday, July 22, 2011
KB982399 - ConfigMgr site server stops responding while processing status messages
I find that from time to time a ConfigMgr site will stop responding. Some of the first symptoms that are noticed are software distribution will stop, site backups fail and you no longer get site status messages. In the Application event viewer you may notice the following error:
A timeout (30000 milliseconds) was reached while waiting for a transaction response from the SMS_EXECUTIVE service.
Generally restarting the SMS Executive service and the SMS Site Component Manger service or rebooting your site server will resolve the issue. (Temporarily) Microsoft has released a hotfix for ConfigMgr SP2 site servers that resolves this issue http://support.microsoft.com/kb/982399 According to the article the issue is caused by a deadlock situation in the SMS Executive service. I’ve applied the hotfix to one of my problematic site servers and I have not experienced a reoccurrence of this issue.
Labels:
ConfigMgr / SCCM
Monday, July 18, 2011
Windows XP SP3 - update.exe extended error code 0xf00d
Every once in a while an old Windows XP machine will make its way back onto our network – most of the time it’s an old laptop that has been sitting in someone’s desk or in some storage room. Machines are checked out for missing patches or Anti-Virus dat updates prior to the machine being added back onto our domain however once in a while a machine will be missed. For this reason we are still scanning for pre Windows XP SP3 machines and if one is detected SP3 is pushed to it so that the machine can catch up on patches. (We are looking at quarantine solution for rouge machines but that’s another story) The other day a Windows XP SP2 laptop was detected but the SP3 upgrade kept failing. The only sign of a problem in Event Viewer was an entry stating that the update had been cancelled and when I ran the update interactively, same thing. When I checked the install log (C:\Windows\svcpack.log) it had the following entry: update.exe extended error code 0xf00d
After some searching I found that if you browse to C:\Windows\System32 and rename spupdsvc.exe to something like spupdsvc.old and then reapply the update, spupdsvc.exe will get recreated and Service Pack 3 will complete successfully.
Labels:
Windows XP
Subscribe to:
Posts (Atom)