从 AD 中提取后从数组中删除数据

Removing data from Array once pulled from AD

我目前正在按 OU 从广告中提取用户数据,然后更新某些字段,效果很好。 我想修改脚本以仅更新某些用户但努力从数组中删除任何条目,因为它是固定大小的。我转换为 ArrayList 并且可以获得对象的计数,然后可以单独查询等。

$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 结果为 47,最后一个元素为:

名字:Laura
姓氏:Willox
mail:WilloxL@domain
UserPrincipalName:Laura.Willox@domain
SAMAccountName : Laura.Willox
代理地址:{smtp:laura.willox@domain, SMTP:WilloxL@domain}

但尝试 $WorkingSet.IndexOf('Laura.Willox') 给出 -1 而不是 46 所以我不能做像 $WorkingSet.RemoveAt($WorkingSet.IndexOf('Laura.Willox'))

这样的事情

这个数据是不是有些地方我不理解,不能这样查询?

您绝对不需要将数据包装在 ArrayList 中,它只会使您的代码不必要地复杂化。

与其尝试修改列表中 Get-ADUser 的内联输出,不如使用 PowerShell 的 Where-Object cmdlet 过滤 数据:

$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'

在这里,我们将 $users 中包含的任何用户对象通过管道传输到 Where-Object SAMAccountName -ne 'Laura.Willox' - -ne 运算符是“not equal" 运算符,因此输出将是任何 不具有具有确切值 Laura.WilloxSAMAccountName 属性 的任何输入对象,然后将它们分配给 $usersSansLaura

值得考虑:

  • 在 PowerShell 中,直接操作可调整大小的集合是不常见的。
  • 相反,PowerShell 中的集合处理通常涉及通过使用 Where-Object in the pipeline or, for collections already in memory, the .Where() array method 过滤 原始集合来创建 集合。

如果您确实需要处理 in-place 调整列表数据类型的大小,我建议改用 System.Collections.Generic.List`1,其 .FindIndex() 方法允许您做您想做的事:

# 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)
}

通常,请注意 System.Collections.ArrayListSystem.Collections.Generic.List`1 都有一个 .Remove() 方法,允许您将 object(元素)传递给直接删除,不管它的索引。


至于你试过的

由于您的数组列表由 ADUser 个实例组成,.IndexOf() 方法需要传递 这样一个实例 以便在元素中找到它 -你不能只传递一个 string 来引用元素中的 properties 之一。

相反,您需要一个 predicate(布尔测试)将字符串与感兴趣的 属性 (.SamAccountName) 进行比较,这就是上面的 .FindIndex() 调用确实如此。