none
How to edit Organizational Unit (OU) GPO via Powershell RRS feed

  • Question

  • Trying to automate GPO editing via Powershell because the OUs, GPOs and Computers are created from csv values.

    Here's how I created the created the OUs:

    PS C:\temp> cat .\OUs.csv
    OUName,Server
    AD-DNS,CO3-G52-AD01
    SolarWinds-App,CO3-G52-NMS1
    SolarWinds-DB,CO3-G52-DB1
    SolarWinds-DB,CO3-G52-DB2
    Utilities-Servers,CO3-G52-WSUS01
    PS C:\temp>
    PS C:\temp>
    PS C:\temp> $OUs = Import-Csv ".\OUs.csv"
    PS C:\temp> foreach ($OU in $OUs){
    >> New-ADOrganizationalUnit -Name $OU.OUName -ProtectedFromAccidentalDeletion $false
    >> }
    New-ADOrganizationalUnit : An attempt was made to add an object to the directory with a name that is already in use
    At line:2 char:1
    + New-ADOrganizationalUnit -Name $OU.OUName -ProtectedFromAccidentalDel ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (OU=SolarWinds-DB,DC=msoc,DC=local:String) [New-ADOrganizationalUnit], ADException
        + FullyQualifiedErrorId : ActiveDirectoryServer:8305,Microsoft.ActiveDirectory.Management.Commands.NewADOrganizationalUnit
    
    PS C:\temp>

    Here's how I moved the respective computer to their OU:

    PS C:\temp> cat .\OUs.csv
    OUName,Server
    AD-DNS,CO3-G52-AD01
    SolarWinds-App,CO3-G52-NMS1
    SolarWinds-DB,CO3-G52-DB1
    SolarWinds-DB,CO3-G52-DB2
    Utilities-Servers,CO3-G52-WSUS01
    PS C:\temp>
    PS C:\temp> $CSVFile = Import-Csv ".\OUs.csv"
    PS C:\temp> foreach ($item in $CSVFile){
    >> $computer = (Get-ADComputer $item.Server).DistinguishedName
    >> $targetOU = Get-ADObject -Filter "Name -eq '$($item.OUName)'"
    >>     Move-ADObject -Identity $computer -TargetPath $targetOU.DistinguishedName -Confirm:$false
    >>     Write-Host "Computer $computer has been moved successfully to $targetOU"
    >> }
    Computer CN=CO3-G52-AD01,CN=Computers,DC=msoc,DC=local has been moved successfully to OU=AD-DNS,DC=msoc,DC=local
    Computer CN=CO3-G52-NMS1,CN=Computers,DC=msoc,DC=local has been moved successfully to OU=SolarWinds-App,DC=msoc,DC=local
    Computer CN=CO3-G52-DB1,CN=Computers,DC=msoc,DC=local has been moved successfully to OU=SolarWinds-DB,DC=msoc,DC=local
    Computer CN=CO3-G52-DB2,CN=Computers,DC=msoc,DC=local has been moved successfully to OU=SolarWinds-DB,DC=msoc,DC=local
    Computer CN=CO3-G52-WSUS01,CN=Computers,DC=msoc,DC=local has been moved successfully to OU=Utilities-Servers,DC=msoc,DC=local
    PS C:\temp>

    Tried searching online on how to edit GPO (not local group policy) but cannot find a way to do it. I also look at these commands:

    PS C:\temp>
    PS C:\temp> Get-Command *GP* -CommandType cmdlet
    
    CommandType     Name                                               Version    Source
    -----------     ----                                               -------    ------
    Cmdlet          Backup-GPO                                         1.0.0.0    GroupPolicy
    Cmdlet          Block-GPInheritance                                1.0.0.0    GroupPolicy
    Cmdlet          Copy-GPO                                           1.0.0.0    GroupPolicy
    Cmdlet          Get-GPInheritance                                  1.0.0.0    GroupPolicy
    Cmdlet          Get-GPO                                            1.0.0.0    GroupPolicy
    Cmdlet          Get-GPOReport                                      1.0.0.0    GroupPolicy
    Cmdlet          Get-GPPermission                                   1.0.0.0    GroupPolicy
    Cmdlet          Get-GPPrefRegistryValue                            1.0.0.0    GroupPolicy
    Cmdlet          Get-GPRegistryValue                                1.0.0.0    GroupPolicy
    Cmdlet          Get-GPResultantSetOfPolicy                         1.0.0.0    GroupPolicy
    Cmdlet          Get-GPStarterGPO                                   1.0.0.0    GroupPolicy
    Cmdlet          Get-TroubleshootingPack                            1.0.0.0    TroubleshootingPack
    Cmdlet          Import-GPO                                         1.0.0.0    GroupPolicy
    Cmdlet          Invoke-GPUpdate                                    1.0.0.0    GroupPolicy
    Cmdlet          Invoke-TroubleshootingPack                         1.0.0.0    TroubleshootingPack
    Cmdlet          New-GPLink                                         1.0.0.0    GroupPolicy
    Cmdlet          New-GPO                                            1.0.0.0    GroupPolicy
    Cmdlet          New-GPStarterGPO                                   1.0.0.0    GroupPolicy
    Cmdlet          Remove-GPLink                                      1.0.0.0    GroupPolicy
    Cmdlet          Remove-GPO                                         1.0.0.0    GroupPolicy
    Cmdlet          Remove-GPPrefRegistryValue                         1.0.0.0    GroupPolicy
    Cmdlet          Remove-GPRegistryValue                             1.0.0.0    GroupPolicy
    Cmdlet          Rename-GPO                                         1.0.0.0    GroupPolicy
    Cmdlet          Restore-GPO                                        1.0.0.0    GroupPolicy
    Cmdlet          Set-GPInheritance                                  1.0.0.0    GroupPolicy
    Cmdlet          Set-GPLink                                         1.0.0.0    GroupPolicy
    Cmdlet          Set-GPPermission                                   1.0.0.0    GroupPolicy
    Cmdlet          Set-GPPrefRegistryValue                            1.0.0.0    GroupPolicy
    Cmdlet          Set-GPRegistryValue                                1.0.0.0    GroupPolicy
    
    
    PS C:\temp>

    But also cannot make sense how they can help.

    Here's the code how I created the GPO for each OU:

    PS C:\temp>
    PS C:\temp> $CSVFile = Import-Csv ".\OUs.csv"
    PS C:\temp> foreach ($item in $CSVFile){
    >> $gpoName = $item.OUName + "-WSUS-GPO"
    >> $targetOU = Get-ADObject -Filter "Name -eq '$($item.OUName)'"
    >> if (!($gpoName)) {
    >> Write-Host "GPO $gpoName already exists, moving on..."
    >> } else {
    >> Write-Host "Creating GPO $gpoName..."
    >> New-GPO -Name $gpoName | New-GPLink -Target $targetOU
    >>     Write-Host "GPO $gpoName has been successfully created for $targetOU"
    >> }
    >> }
    Creating GPO AD-DNS-WSUS-GPO...
    
    
    GpoId       : 32b16a4f-4f01-48d2-9bec-1313e0e325d3
    DisplayName : AD-DNS-WSUS-GPO
    Enabled     : True
    Enforced    : False
    Target      : OU=AD-DNS,DC=msoc,DC=local
    Order       : 1
    
    GPO AD-DNS-WSUS-GPO has been successfully created for OU=AD-DNS,DC=msoc,DC=local
    Creating GPO SolarWinds-App-WSUS-GPO...
    GpoId       : 47631896-c638-40ad-a121-07b71527daa8
    DisplayName : SolarWinds-App-WSUS-GPO
    Enabled     : True
    Enforced    : False
    Target      : OU=SolarWinds-App,DC=msoc,DC=local
    Order       : 1
    
    GPO SolarWinds-App-WSUS-GPO has been successfully created for OU=SolarWinds-App,DC=msoc,DC=local
    Creating GPO SolarWinds-DB-WSUS-GPO...
    GpoId       : d250db2f-8829-4817-9af5-2ca695dbda48
    DisplayName : SolarWinds-DB-WSUS-GPO
    Enabled     : True
    Enforced    : False
    Target      : OU=SolarWinds-DB,DC=msoc,DC=local
    Order       : 1
    
    GPO SolarWinds-DB-WSUS-GPO has been successfully created for OU=SolarWinds-DB,DC=msoc,DC=local
    Creating GPO SolarWinds-DB-WSUS-GPO...
    New-GPO : The command cannot be completed because a "SolarWinds-DB-WSUS-GPO" GPO already exists in the msoc.local domain.
    Parameter name: SolarWinds-DB-WSUS-GPO
    At line:8 char:1
    + New-GPO -Name $gpoName | New-GPLink -Target $targetOU
    + ~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidArgument: (Microsoft.Group...s.NewGpoCommand:NewGpoCommand) [New-GPO], ArgumentException
        + FullyQualifiedErrorId : GpoWithNameAlreadyExists,Microsoft.GroupPolicy.Commands.NewGpoCommand
    
    GPO SolarWinds-DB-WSUS-GPO has been successfully created for OU=SolarWinds-DB,DC=msoc,DC=local
    Creating GPO Utilities-Servers-WSUS-GPO...
    GpoId       : fef5e2e0-19fc-445b-ab4b-ed59755c17b6
    DisplayName : Utilities-Servers-WSUS-GPO
    Enabled     : True
    Enforced    : False
    Target      : OU=Utilities-Servers,DC=msoc,DC=local
    Order       : 1
    
    GPO Utilities-Servers-WSUS-GPO has been successfully created for OU=Utilities-Servers,DC=msoc,DC=local
    
    
    PS C:\temp>

    Basically looking for a code the edit each OU GPO to set the following configurations:

    Computer Configuration > Policies > Administrative Templates > Windows Components > Windows Update 
            > Automatic Updates detection frequency > interval hour(s): 4
            > Configure Automatic Updates > Enabled > Configure automatic updating: 3 - Auto download and notify for install
            > Enable client-side targeting > Enabled > [set-the-respective-group]
            > Specify intranet Microsoft update service location > Enabled > Set the intranet update service for detecting updates: http://wsus-server:8530
                                                                             Set the intranet statistics server: http://wsus-server:8530

    The [set-the-respective-group] should be set to the OUName from the $CSVFile because the Computer Groups in WSUS server was created by this:

    ## create computer groups
    write-host "Creating Computer Groups..."
    $wsusserver = 'localhost'
    [Int32]$portNumber = 8530
    #Load required assemblies
    [void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")
    $wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($wsusserver,$False,$portNumber)
    $wsus.CreateComputerTargetGroup("AD-DNS")
    $wsus.CreateComputerTargetGroup("SolarWinds-App")
    $wsus.CreateComputerTargetGroup("SolarWinds-DB")
    $wsus.CreateComputerTargetGroup("Utilities-Servers")
    if ($?){
        write-host "Computer Groups created successfully!`n" -ForegroundColor Green
        write-host "When you first open WSUS Console, cancel the wizard to go to the console." -foregroundcolor Red
    }

    Then enforce these GPOs.

    OS info:

    PS C:\Users\Administrator>
    PS C:\Users\Administrator> systeminfo |findstr "^OS"
    OS Name:                   Microsoft Windows Server 2019 Standard
    OS Version:                10.0.17763 N/A Build 17763
    OS Manufacturer:           Microsoft Corporation
    OS Configuration:          Primary Domain Controller
    OS Build Type:             Multiprocessor Free
    PS C:\Users\Administrator>
    PS C:\Users\Administrator> $PSVersionTable.PSVersion
    
    Major  Minor  Build  Revision
    -----  -----  -----  --------
    5      1      17763  503
    
    
    PS C:\Users\Administrator>

    Appreciate your help. Thank you!


    • Edited by bad rabbit Monday, June 17, 2019 2:50 AM
    Saturday, June 15, 2019 5:09 AM

All replies

  • Hi,

    I am afraid that editing GPOs with PowerShell is pretty limited. There are not many things you can do and the only cmdlet, which you can use is the

    Set-GPRegistryValue


    And as the name suggest you need to have the registry setting, corresponding to the GPO setting you want to apply. With it you can only edit the GPOs that are under Administrative Templates. There are other GPO related operations, which you can also do (like apply GPOs, report on GPOS, etc.) using PowerShell, but when it comes to editing, there are not many options. 

    Here a couiple of examples:

    Top 10 Group Policy PowerShell Commands

    IF you want to edit Group Policy Preference settings, then you you can use xml files and edit them, like in the last example from this blog post:

    Group Policy editing in Powershell

    #Change GPP Files
    $GPPFPath = $PoliciesPath + "{" + $TGPO + "}\User\Preferences\Files\Files.xml"
    (Get-Content $GPPFPath) | ForEach-Object{$_ -replace "REPLACEME","$CustID"} | Set-Content $GPPFPath
    
    #Change GPP Drive Maps
    $GPPDMPath = $PoliciesPath + "{" + $TGPO + "}\User\Preferences\Drives\Drives.xml"
    (Get-Content $GPPDMPath) | ForEach-Object{$_ -replace "REPLACEME","$CustID"} | Set-Content $GPPDMPath

    Hope I could answer your question. Regards,


    (Please take a moment to "Vote as Helpful" and/or "Mark as Answer" where applicable. This helps the community, keeps the forums tidy, and recognizes useful contributions. Thanks!) Blog: https://blog.pohn.ch/ Twitter: @StoyanChalakov

    Saturday, June 15, 2019 7:23 PM
  • Thank you, Stoyan for your reply.

    I also saw those blogs in my quest to find a solution; will probably take a deeper look into hillside dot no post.

    Anyone from Microsoft Powershell team can shed some light on this? Any roadmap to create cmdlet to achieve this in easy way?


    • Edited by bad rabbit Monday, June 17, 2019 2:55 AM
    Monday, June 17, 2019 2:55 AM
  • Hi,

    Sorry. There are no editing CmdLets.  I agree with Stoyan.

    Maybe you can try post your feedback in uservoice.

    Best regards,

    Lee


    Just do it.

    Tuesday, June 18, 2019 9:09 AM
    Moderator