Powershell: GPO script


I have backed up a GPO from one of the domains, and copied it to the network share.

I need help with creating a script to do the following in all the domains in the forest: (I am trying to avoid creating this manually in all the domains in a few forests)

a) Create a GPO called "MyGPO"
b) Import the settings from the network share the backed up gpo is
c) Link the GPO to an OU

Really appreciate your assistance with this.

Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Jeremy WeisingerSenior Network Consultant / EngineerCommented:
I haven't tested it but something like this should do it. If you want a prompt for the relevant info (like OU to link to, backup GPO name, etc) we could do that too.

Import-GPO -BackupGpoName 'Backed up GPO name' -TargetName MyGPO -path \\servername\backupLocation -CreateIfNeeded |New-GPLink -target "ou=MyOU,dc=contoso,dc=com" -LinkEnabled Yes

Open in new window

Parity123Author Commented:
Thanks. Could you please assist with prompt for location of backup, OU to link to and also create gpo.
Jeremy WeisingerSenior Network Consultant / EngineerCommented:
Sure but what do you mean by:
...and also create gpo
Cloud as a Security Delivery Platform for MSSPs

Every Managed Security Service Provider (MSSP) needs a platform to deliver effective and efficient security-as-a-service to their customers. Scale, elasticity and profitability are a few of the many features that a Cloud platform offers. View our on-demand webinar to learn more!

Parity123Author Commented:
Never mind I did not see the createifneeded switch.
Parity123Author Commented:
Hello Jeremy,

I want to run this script for all the domains in the forest. Is there any error handling you could assist with that I could log

Jeremy WeisingerSenior Network Consultant / EngineerCommented:
Here's the prompts
$GPOScrName = Read-Host 'Enter the name of the source GPO'
$GPOBackupPath = Read-Host 'Enter the location of the GPO backup where the source GPO is'
function Check-OUtarget {
    $OUName = Read-Host 'Enter the name of the OU you want to link the GPO to'
    $OUNameFilter = '*'+$OUName+'*'
    $global:OUobj = Get-ADOrganizationalUnit -Filter {Name -like $OUNameFilter} -Properties *
    If($OUobj.Count -gt 1){
        Write-host "`n`nThere are more than one OU that matches that name.`nPlease type in a more specific name to match the list below:`n`n" -ForegroundColor Cyan
        $OUobj.CanonicalName | Write-Host -ForegroundColor Yellow 
        Write-host "`n" 
    $global:OUDN = $OUobj.DistinguishedName


Import-GPO -BackupGpoName $GPOScrName -TargetName MyGPO -path $GPOBackupPath -CreateIfNeeded |New-GPLink -target $OUDN -LinkEnabled Yes

Open in new window

Jeremy WeisingerSenior Network Consultant / EngineerCommented:
There are several ways to handle errors.

Try Catch Finally https://technet.microsoft.com/en-us/library/hh847793.aspx
Trap https://technet.microsoft.com/en-us/library/hh847742.aspx
ErrorVariable with If statements https://technet.microsoft.com/en-us/library/hh847884.aspx

and probably many others.

What are you looking for specifically?
Parity123Author Commented:
This is what I have so far:
$domains = (get-adforest).domains
foreach($domain $domains {

Try {Import-Gpo -BackupGPOName $backupgponame -TargetName $targetgponame -Path $path -domain $domain -CreateIfNeeded | New-GpLink -target $LinkOU -domain $domain}

        Catch {
                  Write-Log "ERROR: Failed to create/import gpo! for $domain"                  
            Write-log "Created/Imported $targetgponame and linked to $LinkOU"


I want to be able to handle error:
a) If GPLink already exists it should say it already exists and skip
b) if any error in importing gpo  or linking gpo it should exit

Thanks very much for your help
Parity123Author Commented:
Is it possible to also remove authenticated users group and another group called group1
Jeremy WeisingerSenior Network Consultant / EngineerCommented:
You ask much! But I had a bit of time so I worked through it a bit. See if this is what you need.

The main weak point of it is the OU to link to. If the OU has the same name and same location in each domain hierarchy then this script, with a slight modification, should work. But if the location in the hierarchy is different or the name of the OU is different then we'll need to design how to handle that.

Change the variables at the top to match your environment.
$backupPath = 'C:\GPObak'
$groupname = 'root\UniGroup1'
$linkOU="test" #This is the relative OU name. It will have the "OU=" prepended to the front and the domain DN appended to the end. 

$domains = (get-adforest).domains

:worker foreach($domain in $domains) {
        $OUDN = 'OU='+$linkOU+','+(Get-ADDomain $domain).DistinguishedName
        Try {Import-Gpo -BackupGPOName $backupgponame -TargetName $targetgponame -Path $backuppath -domain $domain -CreateIfNeeded | Out-Null}
        Catch {Write-error "There was an error importing GPO. Exiting."; Break :worker}
        Write-Host "Created/Imported $targetgponame in $domain" -ForegroundColor Green
        $GPLinks = Get-GPInheritance -Target $OUDN
        $LinkExists = If($GPLinks.GpoLinks.count -gt 0){$GPLinks.GpoLinks.Displayname.Contains($targetgponame)}else{$false}
            New-GpLink -target $OUDN -domain $domain -Name $targetgponame | Out-Null
            Write-Host "Linked $targetgponame to $OUDN" -ForegroundColor Green
            } else {
            Write-Host "Link $targetgponame to $OUDN already existed. Not creating link" -ForegroundColor Yellow
        Set-GPPermission -Name $targetgponame -TargetName $groupname -TargetType Group -PermissionLevel GpoApply -Domain $domain | Out-Null
        Set-GPPermission -Name $targetgponame -TargetName "Authenticated Users" -TargetType Group -PermissionLevel None -Domain $domain | Out-Null
        Write-Host "Set permissions on $targetgponame for $groupname`n" -ForegroundColor Green

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Parity123Author Commented:
The OU location is the same in every domain
Parity123Author Commented:
Thanks. This is exactly what I needed.
Jeremy WeisingerSenior Network Consultant / EngineerCommented:
Glad to help!
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.