我正在尝试编写一个脚本,如果用户不在特定的OU中,则会从安全组中删除用户。
我无法将OU中的用户数组与安全组中的用户数组进行比较。
要测试我浏览$testGroup
和$userList
中的内容。两者看起来都与我类似,但很明显他们没有比较,只是输出$userList -contains $user
给了我一堆false
结果,即使它应该是真的。
$userList = @()
$testGroup = @()
#Get current members of group. Using this instead of get-adgroupmember due to speed
$testGroup = Get-AdGroup "testGroup" -properties member | select-object -ExpandProperty member | get-aduser
#Define OUs that we want to get members from
$OUlist = "OU1","OU2"
#Populate $userList with members of each OU
$OUlist | foreach {
$userList += get-aduser -filter {Enabled -eq $True} -SearchBase "OU=$_,DC=dc,DC=dc2,DC=dc3"
}
#Check the group for anyone no longer in one of the approved OUs
$testGroup | foreach {
if($userList -notcontains $user){
#remove the user from $testGroup
}
}
答案 0 :(得分:2)
考虑使用Compare-Object
设置property
值来按专有名称进行比较;即。
compare-object -ReferenceObject $OUList -DifferenceObject $userList -Property 'DistinguishedName' |
?{$_.SideIndicator -eq '=>'} |
select -expand InputObject
完整代码:
(未测试的)
$userList = @()
$testGroup = @()
$groupName = 'testGroup'
#Get current members of group. Using this instead of get-adgroupmember due to speed
$testGroup = Get-AdGroup $groupName -properties member | select-object -ExpandProperty member | get-aduser
#Define OUs that we want to get members from
$OUlist = "OU1","OU2"
#Populate $userList with members of each OU
$OUlist | foreach {
$userList += get-aduser -filter {Enabled -eq $True} -SearchBase "OU=$_,DC=dc,DC=dc2,DC=dc3" | Get-AdUser
}
#Check the group for anyone no longer in one of the approved OUs & remove group group
Remove-ADGroupMember -Identity $groupName -Members (compare-object -ReferenceObject $OUList -DifferenceObject $userList -Property 'DistinguishedName' | ?{$_.SideIndicator -eq '=>'} | select -ExpandProperty InputObject)
答案 1 :(得分:1)
这是一个比较数组的例子:
$a1=@(1,2,3,4,5)
$b1=@(1,2,3,4,5,6)
$result = Compare-Object -ReferenceObject ($a1) -DifferenceObject ($b1) -PassThru
write-host $result
还要看一下这篇文章compare arrays
答案 2 :(得分:1)
有一些问题......在$Variable
中使用$_
代替$Variable | Foreach
,就像提到的MacroPower一样。
你可以像这样压缩整个事情:
# Get-ADGroupMember is easier than Get-ADGroup | Get-ADUser.
# You also only need the SamAccountName.
# $TestGroup will be an array automatially... No need to $TestGroup = @()
$TestGroup = (Get-ADGroupMember 'TestGroup').SamAccountName
#Define OUs using their full paths.
$OUList = @(
'OU=Whatever,DC=example,DC=com',
'OU=Something,DC=example,DC=com'
)
# Easily call the OU's from $OUList using $_.
# Again, we only need SamAccountName
# Again, $UserList will automaticall be an array no '= @()' needed.
$OUList | ForEach-Object {
$UserList += (Get-ADUser -Filter * -SearchBase $_).SamAccountName
}
# A proper foreach construct will let you work with $User instead of $_
foreach ($User in $TestGroup)
{
if ($User -notin $UserList)
{
# Put your action here.
}
}
最后一点,你可以在整个地方切换camelCase,PascalCase和小写。虽然没有PowerShell一致性的官方标准,但代码更易于阅读。由于.NET样式指南,PascalCase也倾向于推荐。
另外,如果您想使用比较而不是foreach ($User in $TestGroup)
:
$Compare = Compare-Object -ReferenceObject ($UserList | Select -Unique) -DifferenceObject $TestGroup
$Compare | ForEach-Object {
if ($_.sideindicator -eq '=>')
{
# Action here.
}
}