Portion of an A.D. cleanup script was working but is no longer

Welcome Forums General PowerShell Q&A Portion of an A.D. cleanup script was working but is no longer

This topic contains 3 replies, has 3 voices, and was last updated by

 
Participant
1 month ago.

  • Author
    Posts
  • #122448

    Participant
    Points: 26
    Rank: Member

    I have a script that cleans up A.D. and DNS objects after servers are decommissioned. One function in the overall script (below) would go through all GPOs in all of the domains and remove any orphaned SIDs.

       Function Remove-GPOUnknownSIDs {
          param ([parameter(mandatory = $true)][Microsoft.GroupPolicy.Gpo]$GPO)
          $name = $GPO.DisplayName
          $gpoSecurity = $GPO.GetSecurityInfo()
          $UnknownSIDs = $gpoSecurity.Trustee | Where {$_.SidType -Like "Unknown"}
          #$UnknownSIDs | Out-GridView -Wait
    
          foreach($UnknownSID in $UnknownSIDs) {
             $SIDToRemove = $UnknownSID.Sid.Value
             $gpoSecurity.RemoveTrustee($SIDToRemove)
             $GPO.SetSecurityInfo($gpoSecurity)
          }
       }
    

    The thing that I do not understand is that this was working, and suddenly is throwing errors. In the larger script it is called like so:

       $aGPOs = Get-GPO -Domain "mydomain.com" -All
       #$aGPOs | Out-GridView -Wait -Title $aGPOs.Count
    
       foreach ($gpo in $aGPOs) {
          Remove-GPOUnknownSIDs -GPO $gpo
       }
    

    As you can see in the code above, I tested to confirm that $aGPOs has members (130+ in the one domain), and inside the function I have tested that there are indeed GPOs that have unknown SIDs in them (at least a dozen). I have also confirmed the orphaned SID shows a blank line int $GPOSecurity. But when the code attempts to remove them I get the following error:

    Exception calling "SetSecurityInfo" with "1" argument(s): "The request is not supported. (Exception from HRESULT: 0x80070032)"
    At line:19 char:13
    + $GPO.SetSecurityInfo($gpoSecurity)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : COMException

    I am hoping I am missing something stupid simple here, but cannot wrap my head around why it has been working but suddenly is not.

  • #122570

    Participant
    Points: 316
    Helping Hand
    Rank: Contributor

    Adding Verbose messages to step thru your functions comes in very handy to see what GPO and what SID it's having issues with.

    Function Remove-GPOUnknownSIDs {
        [CmdLetBinding()]
        param (
            [parameter(mandatory = $true)]
            [Microsoft.GroupPolicy.Gpo]$GPO
        )
        $name = $GPO.DisplayName
        Write-Verbose -Message ("{0} - Processing Group Policy Object {1}" -f $MyInvocation.MyCommand.Name, $name)
        $gpoSecurity = $GPO.GetSecurityInfo()
        $UnknownSIDs = $gpoSecurity.Trustee | Where {$_.SidType -Like "Unknown"}
        Write-Verbose -Message ("{0} - Found {1} unknown SIDs in Group Policy Object {2}" -f $MyInvocation.MyCommand.Name,$UnknownSIDs.Count, $name)
    
    
        foreach($UnknownSID in $UnknownSIDs) {
            $SIDToRemove = $UnknownSID.Sid.Value
            Write-Verbose -Message ("{0} - Processing unknown SID {1} in Group Policy Object {2}" -f $MyInvocation.MyCommand.Name,$SIDToRemove, $name)
            $gpoSecurity.RemoveTrustee($SIDToRemove)
            $GPO.SetSecurityInfo($gpoSecurity)
        }
    }
    

    Then you can run it silently until you have an issue and simply add the verbose switch to step through the logic.

    ...
    Remove-GPOUnknownSIDs -GPO $gpo -Verbose
    ...
    
  • #122573

    Participant
    Points: 26
    Rank: Member

    Thanks for the suggestion, I have been writing out to the console – I simply removed that for posting. That is what I do not understand, at every point, from the GPO name to the $gpoSecurity to the $UnknownSIDs is populated just how I would expect it to be.

  • #122967

    Participant
    Points: 110
    Helping Hand
    Rank: Participant

    Have you tried debugging in the ISE or VSCode? I think for something like this the ability to play with the actual object, and it's various properties and methods might prove to be helpful. I like using the editors for scripting because they offer syntax guidance and other useful pieces of information.

You must be logged in to reply to this topic.