Friday, July 7, 2017

Advanced Group Policy Management is such a control freak...


One of the things I like about my job is that I do lots of different "enterprisy" things with Microsoft Windows.
This week I had to solve an issue how to not have to create change requests every time someone edits a group policy.  Thankfully, Microsoft has a solution that, while isn't perfect, is "good enough" called Advanced Group Policy Managment (AGPM).

The problem in our environment is we have over 600 GPOs that I needed to "import"/"control" into AGPM... and unless the owner and permissions are just right, they cannot be "controlled."  I found a few people through some searches that were tackling either ownership, or permissions... but not both.  So I present to you:  Set-AGPMRights.ps1

Again, I am not a "full time programmer", so your mileage will vary, and I expect you to review my code before you use it on any production environment.


# Set-AGPMRights.ps1
# Created by Bryan Loveless
# 
# Created June 2017
# This script will set the ownership and correct permissions/ownership for AGPM and 
# will also "take control" of it/them.
# Just change the necessary variables, and away you go.

# References for borrowed code are in the script blocks where used, if they were.





# ONLY CHANGE THE ONE LINE BELOW!!!  (After changing the users during initial config)

# It will support Wildcards (*)

$GPOTARGET = "*"



########################now the script parts not to configure########################################



# get list of all GPOs with that name



$allGPOnames = ((Get-Gpo -all | ? {$_.displayName -like $GPOTARGET }).DisplayName)



# cycle through each one

foreach ($gpo in $AllGPOnames){

# if you found this script online, below is where you would change the "AGPM archive account info"

set-gppermissions -name $gpo -TargetName "YOURDOMAN\YOURSERVICEACCOUNT" -TargetType user -PermissionLevel GpoEditDeleteModifySecurity

set-gppermissions -name $gpo -TargetName "YOURDOMAIN\Domain Admins" -TargetType group -PermissionLevel GpoEditDeleteModifySecurity

}



# now set owner





#Script to change stale or existing owner of GPO using AD DACL  modules

# ref: https://gallery.technet.microsoft.com/scriptcenter/Script-to-Edit-Owner-on-bbba3562



$OwnerNew = "YOURSERVICEACCOUNT" #Name of the Object user or group to be updated



$GPOName = $GPOTARGET #GPO to be updated, This field accepts wildcards,  "*" updates all GPO



#Get all GPOs, filter if required



$AllGPO = Get-GPO -All | ?{$_.DisplayName -like $GPOName}

#$AllGPO = Get-GPO -All



""

"GPO Name"+"           "+ "OwnerBefore"+"                      "+ "OwnerAfter"

"--------"+"           "+ "-----------"+"                      "+ "----------"



foreach ($gp in $AllGPO){



  #"GPO Name: " + $gp.DisplayName



    #Get the GUID and add wild*



    #Get-GPO "TestGPO"

    $gpId = "*"+($gp).Id+"*"



    #Store the GPO AD Object in a variable



    $Gpo1 = get-adobject -Filter {Name -like $gpId}



    #Store the new Owner in a  variable as well (Note changes for group and user accounts)

        #$Ownr = New-Object System.Security.Principal.SecurityIdentifier (Get-ADGroup "Domain Admins").SID

        #$Ownr = New-Object System.Security.Principal.SecurityIdentifier (Get-ADUser "USer1").SID



    #Generic Cmdlet to get User or Group

    $Ownr = New-Object System.Security.Principal.SecurityIdentifier (Get-ADObject -Filter {Name -like $OwnerNew} -Properties objectSid).objectSid

    #$Ownr = New-Object System.Security.Principal.SecurityIdentifier (Get-ADObject -Filter {Name -like "User1"} -Properties objectSid).objectSid



    #Copy the DACL for the GPO object to be modified in a variable



    $Acl = Get-ACL -Path "ad:$($Gpo1.DistinguishedName)"



    #Validate the currect owner (- can be skipped in when in a script)

  

    #"Before:"

    $aclBefore = $Acl.GetOwner([System.Security.Principal.NTAccount]).Value



    #Edit Owner on a GPO using Powershell to new Owner

    $Acl.SetOwner($Ownr)



    #Note changes are not yet commited, we have made changes only to the variable data not the actual object

    #"Ready:"

    #$Acl.Owner



    #Commit the changes on the variable to the -Path actual object

    Set-ACL -Path "ad:$($Gpo1.DistinguishedName)" -ACLObject $Acl



    #"After:"

    #Get actual data, not from the old variable to confirm change has been made:

    $aclafter = (Get-ACL -Path "ad:$($Gpo1.DistinguishedName)").Owner



  



$gp.DisplayName+"           "+ $aclBefore+"           "+ $aclafter       



}





#Now add the GPO to the archive

#more on this command at https://technet.microsoft.com/itpro/powershell/mdop/agpm/add-controlledgpo

foreach ($gp in $AllGPO){

Add-ControlledGPO $gp

}





# let person know when script finished, and they need to wait for it to propagate

write-host ""

write-host "this script finshed:"

get-date

write-host ""

write-host "THIS MAY TAKE UP TO 15 MINUTES TO FINISH" -ForegroundColor Red

write-host ""



3 comments:



  1. Its a wonderful post and very helpful, thanks for all this information. You are including better information regarding this topic in an effective way.Thank you so much

    Personal Installment Loans
    Payday Cash Advance loan
    Title Car loan
    Cash Advance Loan

    ReplyDelete
  2. this is very nice blog i always interest to know policy management information .this is veryl important to everyone that changes the human life so safety is first super blog thanks for this kind of information share to us .
    MSBI Training in Chennai

    ReplyDelete