Powershell Foreach中的Foreach(嵌套)
我正在尝试通过一组数组循环所有禁用的用户,以检查这些用户是否在列出的任何组中具有成员资格。我的想法是,对于列表中的每个用户,循环检查他们是否在列出的组中。这需要嵌套Powershell Foreach中的Foreach(嵌套),powershell,Powershell,我正在尝试通过一组数组循环所有禁用的用户,以检查这些用户是否在列出的任何组中具有成员资格。我的想法是,对于列表中的每个用户,循环检查他们是否在列出的组中。这需要嵌套foreach循环,对吗?我得到的输出如下: ... user1 user2 user3 is not a member of group1 $dUsers = 'user1','user2','user3' 我在胡思乱想,因为我觉得有一个简单的解决办法,但我迷路了 更新: 我想将所有禁用的用户放入变量$dUsers。 如果我手
foreach
循环,对吗?我得到的输出如下:
...
user1
user2
user3
is not a member of group1
$dUsers = 'user1','user2','user3'
我在胡思乱想,因为我觉得有一个简单的解决办法,但我迷路了
更新: 我想将所有禁用的用户放入变量
$dUsers
。
如果我手动将用户放入变量中,它实际上是有效的,如下所示:
...
user1
user2
user3
is not a member of group1
$dUsers = 'user1','user2','user3'
这给了我以下输出:
user1 is not a member of group1
user1 is not a member of group2
user2 is not a member of group1
user2 is not a member of group2
...
有人对此作出澄清吗
更新: 这是最后的代码。即使只有两组,跑步也需要很长时间
$dUsers = Get-ADUser -Filter {enabled -eq $false} | Select-Object -Expand SamAccountName
$groups = 'Group1', 'Group2'
Write-host '[+] Checking if any disabled user is member of any SSL groups'
Write-host '[+] This might take a while. Get a coffee!'
write-host '[+] Running...'`n
foreach ($dUser in $dUsers) {
foreach ($group in $groups) {
$members = Get-ADGroupMember -Identity $group -Recursive | Select -ExpandProperty SamAccountName
if($members -contains $dUser) {
Write-Host "$dUser is a member of $group"
} Else {
# Remove or comment out the line below to get a clutterfree list.
# Write-Host "$dUser is not a member of $group"
}
}
}
广告组有两个命令。 首先,我看到您希望残疾用户的成员资格很容易获得
#Get the dissabled users from your AD with all their attributes (properties and select)
$dUsers = Get-ADUser -Filter {Enabled -eq $false} -Properties * | Select *
#Run a loop for each user to get the group membership
Foreach ($User in $dUsers) {
$User = $User.SamAccountName
Get-ADUser $User -Properties * | Select Name, SamAccountName, MemberOf | Format-Table -Wrap # > "D:\test\$user.txt" -HideTableHeaders
}
这一个可以工作,但我不喜欢我们得到的输出。
我更喜欢运行groupmembership命令并检查用户
$GroupMembers = Get-ADGroupMember "groupname"| Select Name, SamAccountName
ForEach ($User in $GroupMembers)
{
$UserProperties = Get-ADUser $User.SamAccountName -Properties * | select *
If ($UserProperties.Enabled -eq $False) {
Write-Host $UserProperties.SamAccountName
}
}
编辑:
让我知道这些是否适合你。
问候。根据您所使用的PowerShell版本,此用例和其他用例都有一个cmdlet 至于 我正在尝试循环所有禁用的用户 只要做
Search-ADAccount -AccountDisabled |
Select-Object -Property Name, Enabled,
@{Name = 'GroupName';Expression = {$_.DistinguishedName.Split(',')[1] -replace 'CN='}}
# Results
Name Enabled GroupName
---- ------- ---------
...
testuser2 NewTest False Users
Guest False Users
或者不同的cmdlet
# Get disabled users and their group membership, display user and group name
ForEach ($TargetUser in (Get-ADUser -Filter {Enabled -eq $false}))
{
"`n" + "-"*12 + " Showing group membership for " + $TargetUser.SamAccountName
Get-ADPrincipalGroupMembership -Identity $TargetUser.SamAccountName | Select Name
}
# Results
...
------------ Showing group membership for testuser1
Domain Users
Users
------------ Showing group membership for testuser2
Domain Users
至于
一组
只需使用普通比较运算符选择或筛选所需组名的DN
至于
不幸的是,我对powershell不太熟悉 …一定要花必要的时间加快进度,限制你将要遇到的误解、困惑、错误等。网络上有大量免费视频和基于文本的培训/演示 例如: 使用可以为您编写代码的工具,稍后可以根据需要进行调整
除了通过提供的大量示例脚本和模块外,您应该尝试检查的第一件事是当您只对直接会员资格或间接会员资格感兴趣时。根据答案,您得到的选项会有一些变化。在处理这个问题时,您可能会遇到这样的问题,如果您不知道(主要是对象的路径),请检查它们是什么 如果只是直接会员,那么使用
memberOf
with就足够了。memberOf
属性包含用户的每个直接组成员身份,以及组的完整可分辨名称
Get-ADUser test -Properties MemberOf | Select-Object -ExpandProperty memberOf
您可以通过各种方式匹配您要查找的组。您可以获得这些组的整个可分辨名称,也可以进行部分匹配。如何进行由你决定
如果您也需要间接成员身份,那么您可能希望拆分代码以使自己更轻松。例如,您可以首先找到用户并保存它们。然后找到这些组的所有组成员(您已经通过Get-ADGroupMember
获得了这些成员),最后比较这两个组
当前,对于每个用户,您将再次构建整个组成员列表。这种方法将节省一些资源,因为您不会重复执行相同的查询
最后,您还可以使用MemberOf
方法,但可以使用LDAP查询获取用户的每个直接和间接成员的列表
$dn = (Get-ADUser example).DistinguishedName
$userGroups = Get-ADGroup -LDAPFilter ("(member:1.2.840.113556.1.4.1941:={0})" -f $dn)
这种方法使用了一种新的方法。它可能相当复杂,您也只能通过稍微修改它来检查其中一个组
最终,即使是你目前的方法也会奏效。问题是您正在将AD对象与SAM AccountName列表进行比较。您还需要检查SAM帐户名
if($members -contains $dUsers.SamAccountName)
if($members -contains $dUsers | Select-Object -ExpandProperty SamAccountName)
如果您也更改了
$dUsers
,则其中一项应该也可以使用。就像现在这样,你最终会得到一根巨大的绳子。您可能可以通过检查$dUsers.length
来检查这一点。只需删除格式表
和输出字符串
您的代码中有两个问题:
Get ADUser
输出创建一个字符串。将该cmdlet的输出通过格式表
(别名ft
),然后通过输出字符串
创建一个字符串,该字符串以表格形式显示包括表头在内的所有匹配帐户名
如果您以使字符串的开头和结尾可见的方式输出$dUsers
,您将看到如下内容(标记开头和结尾的前导和尾随=
):
PS>$dUsers | ForEach对象{“=$\u==”}
==samAccountName
--------------
用户1
用户2
用户3==
由于没有用户名与此字符串匹配的帐户,因此在任何组中都找不到匹配项,您将获得观察到的输出
这种对Format-*
cmdlet的误用是初学者常见的错误。人们得到一个格式良好的字符串输出,然后尝试使用它。仅当您直接向用户呈现数据时才使用Format-*
cmdlet,而不是在需要或打算进一步处理数据时
实际上,您需要的不是一个以表格形式显示用户名的字符串,而是一个用户名字符串数组。您可以通过展开从get ADUser
获取的用户对象的SamAccountName
属性来实现这一点
$dUsers = Get-ADUser ... | Select-Object -Expand SamAccountName
$members-包含$dUsers
将不起作用,因为$members
和$dUsers
都是数组(即在修复第一个问题之后)。-contains
运算符需要一个数组作为第一个操作数,一个值作为第二个操作数
改变
$members -contains $dUsers
到
我记得,每个成人都有一个
.MemberOf
属性。你为什么不抓取所有用户,然后检查有问题的组的成员资格呢
$members -contains $dUser