Curious, if below is the most efficient way to do this. I am looking to cycle thru a list of users (from a txt file) and loop thru a set of groups (contained in several OUs and a text file) to see if they are members. If they are, I would like to remove the user from the group. Initially, there is about 300 users in the text file to evaluate. There are about 275 groups. During an initial run, it took a about 2 1/2 hours to evaluate all users/groups (with the Remove-ADGroupMember commented out. I suspect that it may take a little longer with the command in place. Now, going forward, this will be drastically lower counts of users. Would arrays be beneficial here? Or continue with looping thru like I am?

Also, what would be a valid error trapping for this? I guess to confirm if deletion is successful from each user/group and log it as well.

function Get-TimeStamp {
    return "[{0:MM/dd/yy} {0:HH:mm:ss}]" -f (Get-Date)

$LogFile = ".\AccessRemovalLog.txt"
$OUs = "OU=Level2,VDI,OU=Application,OU=Group,DC=GENPT,DC=NET",

$OUGroups = $OUs | foreach-object{(Get-ADGroup -Filter * -SearchBase $_).SamAccountName}
$FileGroups = Get-Content ".\Groups2.txt"
$AllGroups = $OUGroups + $FileGroups | sort

$Users = Get-Content ".\TestRun.txt"

Foreach ($User in $Users) {
    Write-Host "$User"
    #Check for USer in AD
        $UserExists = $(try {Get-ADUser $User} catch {$null})
        If ($UserExists -ne $Null) {
            Write-Host "   $User Exists in AD"
            # If Exists, Loop thru VDI groups and remove access
            ForEach ($Group in $Groups) {
                $members = Get-ADGroupMember -Identity $Group| Select -ExpandProperty SamAccountName
                If ($members -contains $User) {
                    Write-Host "     $Group"
                    Write-output "$(Get-TimeStamp) - $User - $Group " >> $LogFile
                    # Command to remove account for group
                    Remove-ADGroupMember -Identity $Group -Members $User

                else {

        } else {
            Write-Host "   $User not found in AD."
            Write-output "$(Get-TimeStamp) - $User does not exist in AD" >> $LogFile

        #End of CheckUser

    Write-host " "

Reading this objective and wihtout digging too deep into your code this task is actually pretty easy. With the cmdlet …

… you can remove a given user account from multiple groups at once. So if you don’t need a logging which user you removed from which group you simply run a loop iterating over all users imported from your input file piped to the cmdlet ’ Remove-ADPrincipalGroupMembership’.

Something like this should do it actually:

Foreach ($User in $Users) {
    Remove-ADPrincipalGroupMembership -Identity $User -MemberOf $AllGroups -ErrorAction SilentlyContinue


And BTW: if you’re looking for speed you should avoid all unnecessary output to the console. So remove all Write-Host commands and suppress all console output from other cmdlets. You may add some logging if needed but displaying pixels on the screen takes up a lot of time.

1 Like