从 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.Willox
的 SAMAccountName
属性 的任何输入对象,然后将它们分配给 $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.ArrayList
和 System.Collections.Generic.List`1
都有一个 .Remove()
方法,允许您将 object(元素)传递给直接删除,不管它的索引。
至于你试过的:
由于您的数组列表由 ADUser
个实例组成,.IndexOf()
方法需要传递 这样一个实例 以便在元素中找到它 -你不能只传递一个 string 来引用元素中的 properties 之一。
相反,您需要一个 predicate(布尔测试)将字符串与感兴趣的 属性 (.SamAccountName
) 进行比较,这就是上面的 .FindIndex()
调用确实如此。
我目前正在按 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.Willox
的 SAMAccountName
属性 的任何输入对象,然后将它们分配给 $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.ArrayList
和 System.Collections.Generic.List`1
都有一个 .Remove()
方法,允许您将 object(元素)传递给直接删除,不管它的索引。
至于你试过的:
由于您的数组列表由 ADUser
个实例组成,.IndexOf()
方法需要传递 这样一个实例 以便在元素中找到它 -你不能只传递一个 string 来引用元素中的 properties 之一。
相反,您需要一个 predicate(布尔测试)将字符串与感兴趣的 属性 (.SamAccountName
) 进行比较,这就是上面的 .FindIndex()
调用确实如此。