Filtering users from a CSV then removing those filtered users from specific security groups with Powershell

52 Views Asked by At

I am trying to write a PowerShell program that will take an imported CSV of active and inactive accounts and then filter those users by a keyword (disabled) which successfully works. I get a filtered CSV with a timestamp for auditing purposes in the file name

This is an example from the imported CSV

Username,Name,Email,Status,Created,Last Login
Test,"Test, Test",[email protected],Active,2018-12-07 21:46:40 UTC,2024-03-18 20:01:50 
Import-Module -Name ActiveDirectory

# Gathers Date information and creates CSV naming convention for Filtered CSV Output
$TimeStamp = Get-date -Format "MMddyy"
$filters = "Disabled"

# User drops file named Removal to Desktop
Get-Content -Path 'c:\Scripts\UsersTest.csv' | Select-String -Pattern $filters | Out-File -FilePath "c:\Logs\$TimeStamp FilteredUsersForRemoval.csv"

This is an example from the CSV output

Test2,"Test2,Test2",[email protected],Disabled,2018-12-07 21:46:40 UTC,2024-03-18 20:01:50

A note that I want to add is that in the exported CSV from filtering, there are no headers in the file, just the data

The next part removes those specific filtered users by matching their UPN in AD with their Email from the CSV

$GroupFilter = 'MFA Offline Access', 'Personal Phone', 'MFAUsers', 'Test Domain 1 users', 'Test Domain 2 Users'
$Users= "c:\Logs\$TimeStamp FilteredUsersForRemoval.csv"

foreach ($User in $Users)
{
    $UPN = $User.Username
    $ADUser = Get-ADUser -Filter 'Email' -like $UPN | Select-Object SamAccountName
    {
        $ExistingGroups = Get-ADPrincipalGroupMembership $ADUser.SamAccountName | Select-Object Name
        if ($ExistingGroups.Name -eq $GroupFilter)
            {
                Remove-ADGroupMember -Identity $GroupFilter-Members $ADUser.SamAccountName -Confirm$false
                Write-Host "Removed $UPN from $Group" - ForeGroundColor Green
            }
        else
            {
                Write-Host "$UPN does not exist in $Group" - ForeGroundColor Yellow
            }
    }
}

This is the part that is constantly failing and giving errors such as a parameter can't be found for -like or -eq.

In our live domain, these specific users are inside mutiple OU's - Example Test> > Users > Terminated and that is where thse disabled users are that I am trying to remove groups from.

The specific groups that are needing to be removed from these users are in the $GroupFilter variable.

Any help would be appreciated as I'm not sure where I'm going wrong with syntax or the CSV imports

    foreach ($User in $Users)
{
    $UPN = $User.Email
    $ADUser = Get-ADUser -Filter {Email -like $UPN} | Select-Object UserPrincipalName 
    {
        $ExistingGroups = Get-ADPrincipalGroupMembership $ADUser.UserPrincipalName  | Select-Object Name
        if ($ExistingGroups[0].Name -eq $GroupFilter)
            {
                Remove-ADGroupMember -Identity $GroupFilter-Members $ADUser.UserPrincipalName
                Write-Host "Removed $UPN from $Group" - ForeGroundColor Green
            }
        else
            {
                Write-Host "$UPN does not exist in $Group" - ForeGroundColor Yellow
            }
    }
}

With the new snippet, $UPN is coming back as undefined. Another issue that i figured out or believe to be correct is that the Email in the CSV is what needs to be compared and not the username so i made those changes and I beleive them to be correct.

Overall the Email in the CSV is needing to be compared to the UPN in AD, not the SAM.

1

There are 1 best solutions below

4
Theo On

The main problem starts where you (mis)treat the input CSV as plain text by using Get-Content instead of Import-Csv and Out-File instead of Export-Csv..

Using a Where-Object clause, you can filter out the disabled users from the original input csv file immediately, so basically there would be no need to store a subset into a new file, except maybe for later reference.

Try

# Gathers Date information and creates CSV naming convention for Filtered CSV Output
$TimeStamp = Get-date -Format "MMddyy"
# read and parse the input csv, collect only user objects that are disabled
$Users     = Import-Csv -Path 'c:\Scripts\UsersTest.csv' | Where-Object {$_.Status -eq 'Disabled'}

# for later reference write the disabled users in a separate output csv
$Users | Export-Csv -Path "c:\Logs\$TimeStamp FilteredUsersForRemoval.csv" -NoTypeInformation

$GroupFilter = 'MFA Offline Access', 'Personal Phone', 'MFAUsers', 'Test Domain 1 users', 'Test Domain 2 Users'

foreach ($User in $Users) {
    $ADUser = Get-ADUser -Filter "EmailAddress -eq '$($User.Email)'" -Properties EmailAddress

    Get-ADPrincipalGroupMembership -Identity $ADUser.DistinguishedName |  # get the groups this user belongs to
    Where-Object {$GroupFilter -contains $_.Name} |                       # filter to get only the groups in $GroupFilter
    ForEach-Object {                                                      # loop over these groups and remove the user
        $_ | Remove-ADGroupMember -Members $ADUser
        Write-Host "Removed $($ADUser.Name) from $($_.Name)" -ForeGroundColor Green
    }
}