'Removing data from Array once pulled from AD

I'm currently pulling user data from Ad by OU, then updating certain fields, which works fine. I want to modify the script to only update certain users but struggling, to remove any of the entries from the array as it is a fixed size. I converted to ArrayList and can get count of object, and can query then individually etc..

$users = Get-ADUser -Filter * -SearchBase "DN" -Properties GivenName, Surname,mail,UserPrincipalName,SAMAccountName,proxyAddresses | Select GivenName, Surname,mail,UserPrincipalName,SAMAccountName,proxyAddresses 

$WorkingSet =[System.Collections.ArrayList]($users)

$WorkingSet.count gives 47 as result with last element being:

GivenName: Laura
Surname:Willox
mail:WilloxL@domain
UserPrincipalName :Laura.Willox@domain
SAMAccountName : Laura.Willox
proxyAddresses : {smtp:laura.willox@domain, SMTP:WilloxL@domain}

but trying $WorkingSet.IndexOf('Laura.Willox') gives -1 instead of 46 So then I can't do something like $WorkingSet.RemoveAt($WorkingSet.IndexOf('Laura.Willox'))

Is something about this data that I am not understanding,that it can't be queried like this?



Solution 1:[1]

You absolutely do not need to wrap your data in an ArrayList, it'll only complicate your code unnecessarily.

Instead of trying to modify the output from Get-ADUser inline in a list, use PowerShell's Where-Object cmdlet to filter the data:

$users = Get-ADUser -Filter * -SearchBase "DN" -Properties GivenName, Surname,mail,UserPrincipalName,SAMAccountName,proxyAddresses | Select GivenName, Surname,mail,UserPrincipalName,SAMAccountName,proxyAddresses 

# use `Where-Object` to filter the data based on individual property values
$usersSansLaura = $users |Where-Object SAMAccountName -ne 'Laura.Willox'

Here, we pipe any user objects contained in $users to Where-Object SAMAccountName -ne 'Laura.Willox' - the -ne operator is the "not equal" operator, so the output will be any input object that does not have a SAMAccountName property with the exact value Laura.Willox, and then assign those to $usersSansLaura

Solution 2:[2]

Mathias' helpful answer is worth considering:

  • In PowerShell, it is unusual to directly manipulate resizable collections.
  • Instead, collection processing in PowerShell usually involves creating new collections by filtering the original collection, using the Where-Object in the pipeline or, for collections already in memory, the .Where() array method.

If you do need to deal with in-place resizing of a list data type, I suggest using System.Collections.Generic.List`1 instead, whose .FindIndex() method allows you to do what you wanted:

# Note: I'm using [object] as the type parameter for simplicity, but you 
#       could use [Microsoft.ActiveDirectory.Management.ADUser] for strict typing.
$WorkingSet = [System.Collections.Generic.List[object]]::new(
  @(Get-ADUser -Filter * -SearchBase "DN" -Properties GivenName, Surname,mail,UserPrincipalName,SAMAccountName,proxyAddresses | Select GivenName, Surname,mail,UserPrincipalName,SAMAccountName,proxyAddresses)
)

# Find the index of the user with a given SAMAccountName: 
$ndx = $WorkingSet.FindIndex({ $args[0].SAMAccountName -eq 'Laura.Willox' })

# If found, remove the user from the list
# (-1 indicates that no matching element was found)
if ($ndx -ne -1) {
  $WorkingSet.RemoveAt($ndx)
}

Generally, note that both System.Collections.ArrayList and System.Collections.Generic.List`1 have a .Remove() method that allows you to pass the object (element) to remove directly, irrespective of its index.


As for what you tried:

Since your array list is composed of ADUser instances, the .IndexOf() method requires passing such an instance in order to locate it among the elements - you can't just pass a string referring to one of the properties among the elements.

Instead, you need a predicate (a Boolean test) that compares the string to the property of interest (.SamAccountName), which is what the .FindIndex() call above does.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mathias R. Jessen
Solution 2 mklement0