Hi Guys,
I'm trying to clean all users from Local Group test_group, and next new bunch of users form TXT fiel, by executing the following script as a scheduled task

Import-Module Adaxes
# Remove old users from the group
Get-AdmGroupMember "test_group" -AdaxesService localhost | ForEach-Object {Remove-AdmGroupMember "documents-users" -ErrorAction SilentlyContinue -AdaxesService localhost $_ -Confirm:$false}

# Get list of new members from TXT and add them to the gorup
$web = New-Object Net.WebClient
$web.DownloadString("https://server.contoso.com/users.txt") | Out-File "C:\userlist.txt"
$users = Get-Content "C:\userlist.txt"
foreach ($user in $users) {

Add-AdmGroupMember -Identity "test_group" -Members $user -AdaxesService localhost  
}

Remove-Item ""C:\userlist.txt"

Everything is looks fine, but sometimes I get error message "Requested service not find", also this script is quite slow. In the userlist.txt I have only 600 users. Do you have any idea how to improve this script?

by (510 points)

1 Answer

by (390 points)
Best answer
0 votes

You don't need to iterate through the lists, because the -Members parameter takes an array. I tested this on my system and it worked, so I believe it will work for you. The only part I couldn't test was getting the userlist from a web page, but you should be able to assign that to a variable with Out-String and not need to use the intermediate file. You *might* have to do something like:
$users = $users.trim()
In case there are trailing spaces on the user list.

Note also that the remove could be a single line, but it throws an error if the group is empty:
Remove-AdmGroupMember -AdaxesService $admService -Identity $groupName -Confirm:$false -Members (Get-AdmGroupMember -Identity $groupName -AdaxesService $admService)

Import-Module Adaxes

$groupName = 'test_group'
$admService = 'localhost'

# Remove old users from the group
$members = Get-AdmGroupMember -Identity $groupName -AdaxesService $admService
if ($members) {
    Remove-AdmGroupMember -AdaxesService $admService -Identity $groupName -Confirm:$false  -Members $members
} 

# Get list of new members from TXT and add them to the gorup
$web = New-Object Net.WebClient
$users = $web.DownloadString("https://server.contoso.com/users.txt") | Out-String

# Add users to group
Add-AdmGroupMember -AdaxesService $admService -Identity $groupName -Confirm:$false -Members $users

Best Regards,
Scott Kuntzelman
Electrolux North America

by (216k points)
0

Hello,

Scott is right that Add-AdmGroupMember cmdlet accepts a String[] array for the -Members parameter, the same as Remove-AdmGroupMember, and this fact gives you certain advantages. If you add members to a group in a foreach loop, you add the members one-by-one. However, if you pass an array to the -Members parameter, the cmdlet will add all the members at once, which should give you a certain performance boost.

However, there is a small error in Scott's post. The thing is that when you read your file using the Net.WebClient::DownloadString method, you receive a multi-line string, not an array. Scott's will work as long as you have 1 user in the text file, but won't work if there are multiple users specified, because the Add-AdmGroupMember cmdlet will consider the whole of the string as a single member that you want to add.

So, before passing the new members to the Add-AdmGroupMember cmdlet, you need to convert the multiline string into a String[] array.

Find below a version of the script that does the job.

Import-Module Adaxes

$groupName = 'test_group'
$admService = 'localhost'

# Get new users
$web = New-Object Net.WebClient
$users = $web.DownloadString("https://server.contoso.com/users.txt")

if (-not [System.String]::IsNullOrEmpty($users))
{
    # Remove empty lines
    $users = $users -replace '\s+\r\n+', "`r`n"

    # Convert to a String[] array
    $reader = New-Object System.IO.StringReader($users)
    $newMembers = @()
    while ($True)
    {
        $line = $reader.Readline()
        if (-not ($line))
        {
            break
        }
        $newMembers += $line.Trim()
    }

    # Get current group members
    $group = Get-AdmGroup $groupName -AdaxesService $admService -Properties member
    $members = $group.member
    if ($members)
    {
        # Remove old users from the group
        Remove-AdmGroupMember $group -Members $members -Confirm:$false -AdaxesService $admService
    }

    # Add users to group
    Add-AdmGroupMember $group -Members $newMembers -Confirm:$false -AdaxesService $admService
}
by (390 points)
0

I was afraid of that. ;) I don't have a handy webserver to test downloading the file from the web, so wasn't entirely sure. I'm going to grab your copy of the script for my library.

Related questions

We would like the membership in a distribution group to be based on a particular M365 license a user has (for example, Microsoft Copilot for Microsoft 365 (SKU part number ... the group. Is there way to do that by making it a rule-based group?

asked 2 days ago by RayBilyk (290 points)
0 votes
1 answer

How can I create a script that does these things For internal audit. objective Even removing all groups of a disconnected user, we will still know which groups the ... in the created group (audit)-sAMAccountName-access add the (user)-sAMAccountName in members

asked Jul 2, 2022 by alancardoso (40 points)
0 votes
1 answer

In the de-provisioning process, I need to remove all users from all Office 365 groups (UnifiedGroups). I tried to adapt this script but unsuccessfully. https://www.adaxes.com/script-repositor ... -s360.htm Is there any way to do this?

asked Sep 22, 2019 by flaviodouglas (70 points)
0 votes
1 answer

I am using this script to remove all users from groups when they are terminated. This script doesn't remove users from Azure only groups just on prem. How would I change ... .LogMessage("Can not remove $U from $GN"+$_.Exception.Message, "Information") } }

asked Jun 18, 2024 by mightycabal (1.2k points)
0 votes
1 answer

I would like to have a script that removes the offboarded users from all teams groups

asked Jan 3, 2024 by bodson (20 points)
0 votes
1 answer