As for what you tried:
Given that $List
contains an array of objects, with each element containing an object representing a row of the CSV file, $List.Name
and $List.Computer
similarly return arrays of property (column) values, courtesy of PowerShell's member-access enumeration
Therefore, $using:user
refers to the array of all usernames, across all servers.
While the -Member
parameter of Remove-LocalGroupMember
does accept arrays, there are two problems with your approach:
At least hypothetically you'll run the risk of deleting users you shouldn't from certain servers, or you'll run into users that don't exist on a given server (though you could ignore that with -ErrorAction Ignore
).
Since a given server name can appear multiple times in the CSV, the targeted user(s) will have already been deleted, starting with the second call to that server - this is the problem you saw.
TheStingPilot's helpful answer
provides an effective solution: loop over the objects representing the CSV rows one by one, and call Invoke-Command
for each target server, with only the username at hand.
The downside of this approach - which may or may not matter, depending on how many computers you target - is that forgo the benefits of parallel execution that you get when you pass multiple computer names to Invoke-Command
's -Computer
parameter (by default, up to 32 computers at a time are targeted in parallel; you can modify that number with
-ThrottleLimit
).
To avoid multiple calls to a given server while preserving the benefits of parallel execution:
Build a hashtable from the CSV input that maps server names to user names.
Pass that hashtable to a single Invoke-Command
call, as you tried, and let each remote computer look up the relevant usernames in it and act on them.
# Read the CSV file and create a hashtable (map) that
# maps server (computer) names to usernames to remove.
$serverUserMap = [ordered] @{}
Import-CSV C:\temp\LocalAdmin.CSV |
ForEach-Object {
[array] $serverUserMap[$_.Computer] += $_.Name
}
# * $serverUserMap.Keys now contains all unique server names,
# which can be passed to -ComputerName
# * Inside the script block, accessing the hashtable with the local
# computer name as the key returns only the relevant user(s).
Invoke-Command -ComputerName $serverUserMap.Keys -ScriptBlock {
Remove-LocalGroupMember -Group "Administrators" -Member ($using:serverUserMap)[$env:COMPUTERNAME]
}