Remotely remove Domain group(s) from Local group(s)

This topic contains 5 replies, has 3 voices, and was last updated by  postanote 1 month ago.

  • Author
    Posts
  • #89845

    Nate
    Participant

    I'm a new system administrator trying to learn PowerShell for some automation of repetitive tasks. I have pieced together some code I found online to handle what I'm trying to do, though it appears to be an older way.

    What I'm trying to do is remotely remove Domain groups from Local groups. The script reads-in the server to connect to from a text file; reads-in the Domain groups to remove from a text file; sets the Local group on the proper server as variables; and then reports what it did in a log file, along with some output to the console just so I don't have to read the log file.

    The issue I'm having is that the Catch block continues to display, and upon further investigation, the actual error is, "Access is denied." I read a bit about what could cause that error and it seems, to me, that the setting for accidental deletion is set which won't allow for removal. However, when I look for solutions, it appears that the AD Cmdlets are being used to turn off accidental deletion and since I'm using an older way, I'm unsure how to update this script to fix the problem. I'd prefer the script to be updated to use the current PowerShell Cmdlets, as I'm using PowerShell ISE 4 or 5, I believe. I'm also running as an elevated user and I have access to these servers and groups. I am the administrator, after all.

    Again, I'm new with PowerShell and Active Directory, and I've been scouring the web learning and looking for solutions. So any help with this would be much appreciated in helping me learn from this and also get the issue resolved. Thanks.

    # Get List of Servers from Flat TXT file 
    $Servers = Get-Content TestServer.txt
    
    # Get List of Domain Groups from Flat TXT file
    [ADSI]$DomainGroup = Get-Content NDCGroups.txt
     
    # Name the LogFile and Initialize it 
    $LogFile = ".\Logs\test.txt"
    New-Item $LogFile -Type File -Force 
    
    # Loop through each server
    $Servers | ForEach-Object {
    
        $Server = $_
        Write-Output "`n$Server"
        Write-Output "`n-------"
     
        # Get Local Group objects 
        $LGRemoteDesktopUsers = [ADSI]"WinNT://$Server/Remote Desktop Users,group"
        $LGPowerUsers = [ADSI]"WinNT://$Server/POWER USERS,group"
        
        # Remove DomainGroups from LocalRDP
        ForEach ( $DG in $DomainGroup ) {
            Try {
                $LGRemoteDesktopUsers.Remove( $DG.Path ) 
                Write-Output "`nRemoved $( $DG.Path ) from $( $LGRemoteDesktopUsers.Path )"
            }
            Catch {
                Write-Output "`nDid Not Remove $( $DG.Path ) from $( $LGRemoteDesktopUsers.Path )"
                Write-Warning "Did Not Remove $( $DG.Path ) from $( $LGRemoteDesktopUsers.Path )"
            }   
        }
        
        # Remove DomainGroup from PowerUsers
        ForEach ( $DG in $DomainGroup ) {
            Try {
                $LGPowerUsers.Remove( $DG.Path )
                Write-Output "`nRemoved $( $DG.Path ) from $( $LGPowerUsers.Path )"
            }
            Catch {
                Write-Output "`nDid Not Remove $( $DG.Path ) from $( $LGPowerUsers.Path )"
                Write-Warning "Did Not Remove $( $DG.Path ) from $( $LGPowerUsers.Path )"
            }  
        }
    } | Add-Content $LogFile
  • #89848

    Jon
    Participant

    What OS are the servers you are running these commands against?

    You can type "$psversiontable" to find out which version of powershell you are running the ISE from. If everything is 2012 and up, I highly recommend updating to PS 5.1 to take advantage of these cmdlets:

    https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.localaccounts/?view=powershell-5.1

    • #89852

      Nate
      Participant

      I'm running PS 5.1. The servers are mostly Windows Server 2012 R2.

  • #89884

    postanote
    Participant

    As for 'The servers are mostly Windows Server 2012 R2.'

    W2K12-R2 is PoSHv4 by default, you have to install v5 and higher.
    W2K16 is v5 by default.

    If you are saying you are doing this from your admin workstation, and running v5 there, then you need to be sure your code is written to address the LCD (lowest common denominator) in your enterprise, in order to use one code path. Otherwise, you have to have your code check for each servers PoSH version and have branches in your code to run whatever your are planning at that version level, regardless of what you are using on your admin workstation. Which as a new learner, not a thing I'd recommend you do. Yon can use whatever version you choose on your admin workstation, but you must only use cmdlets, code that will work on all resources you plan to target. So, first things first. Do a AD scan for all computers in the enterprise and find out what is the lowest version of PoSH in use, then plan to write for that version for all systems.

    As for your query...

    Point of note,

    This sort of thing...

    Write-Output "`n$Server"
    Write-Output "`n——-"

    .. and this.. does the same thing.
    "`n$Server"
    "`n——-"

    ... and this .. all do the same thing
    "`n$Server`n——-"

    You really only need to use Write-* for specific reasons debug, warning, etc. Output to the screen is the default as per the above. So, that Write-Output and Write-Warning thing are doing the same thing. Also, unless you need to create a custom log file, it's better to use Start-Transcript at the beginning of your script and Stop-Transcript at the end. Look at the help file for a explanation of them.

    If you really must use Write-* to the screen, to have more flexibility, use Write-verbose. This way, screen output will only happen if the user specifies the -Verbose switch, well outside of error messages.

    As for your script, at PoSHv5, it has built local group cmdlets for this sort of things, but this is a v5 only thing. SO, if your target is not v5, then that is moot.

    BTW, here is a pre-built script that does what you are attempting to do. Now, this only targets the local admin group, but can be tweaked for any other group on the machine.

    Remove AD User/Group to Local Administrator Group

    The script can use either a plain text file containing a list of
    computername or a computer name as input and will add the trustee
    (AD user or group) as an administrator to the specified computer(s).
    The script will report back errors if the account not a member.

    'gallery.technet.microsoft.com/scriptcenter/Remove-AD-UserGroup-to-f6e9dbfb'

    As far as the accidental deletion thing. That is not PoSH or cmdlets doing this. This is normally ADDS by default. When you create AD groups, unless you manually uncheck the box, 'Protect Object from accidental deletion' is enabled, but that is a deletion thing from ADDS not servers or workstations local groups. Deleting from a workstation local group should have no impact on the existence of the group in ADDS. You'd only get such an error if you are trying to remove the group from ADDS with the prevent enabled. This also could be set at a domain level GPO. So, unless you are a domain admin with privs to remove this GPO or remove the 'Protect Object from accidental deletion' setting, you are going to get this error when / if you try to delete the group from ADDS.

    BTW, there could also be a GPO at the domain level to prevent removal of groups from local groups as well.

    Do you know what GPO settings are in place on the targets you are trying to work on?

    • #89926

      Nate
      Participant

      Thank you for that information, it is really helpful.

      "Do you know what GPO settings are in place on the targets you are trying to work on?"

      I'm not sure because another admin originally wrote a long script we have to modify inline to do this and handed it off to me to try and condense it down and make it a generic script for anyone to use for automation, without modifying the script itself. I'll have to answer this after they return from the holiday. I'll work on this more in the meantime and report back.

      Thanks for your time.

  • #89959

    postanote
    Participant

    No worries.
    Taking over from a previous admin, dev, etc., is always a challenge.
    Trying to figure what they did, how they did it an why they did it the way they did it, is a constant that has to be dealt with as they pop up.

You must be logged in to reply to this topic.