1

我对 Powershell 脚本非常陌生,甚至对 AD 的 powershell 脚本也很陌生。我试图基本上将 memberOf 从一个 AD 用户复制到另一个我已经获得了一个复制脚本来工作,但在部门转移等情况下,我还想删除用户不再需要的任何访问权限。我已经尝试了下面包含的脚本。它运行(如不抛出错误),但不进行任何更改。

$Source = Get-ADUser *ShortName* -prop MemberOf
$Destination = Get-ADUser *ShortName* -prop MemberOf
$Source.MemberOf | Where{($Destination.MemberOf -contains $_) -and ($Source.MemberOf -notcontains $_)} | Remove-ADGroupMember $Destination

我看过一些关于 Compare-object 命令的文档,但对它的理解还不够好,无法看到使用该命令的实现方法。任何帮助或提示将不胜感激

4

2 回答 2

1

检查代码并让我知道它是否对您有意义,我添加了注释以向您提供有关逻辑的提示。

当然,这不是这样做的唯一方法,但我使用经典编码,因此您更容易阅读和理解。

# Get the membership of sourceUser
$sourceUser = Get-ADUser sourceUser -Properties MemberOf

# Get the membership of destUser
$destUser = Get-ADUser destUser -Properties MemberOf

# You want to compare if the the membership of destUser is different from
# the membership of sourceUser, hence we use destUser's membership to loop

foreach($group in $destUser.MemberOf)
{
    # If this group is not in the membership of sourceUser ->
    # remove thisUser from thisGroup
    
    # Option 1:
    if(-not $sourceUser.MemberOf.Contains($group)) # This is harder to read but more efficient
    {
        Remove-ADGroupMember -Identity $group -Members $destUser.distinguishedName
    }

    # Option 2:
    if($group -notin $sourceUser.MemberOf) # This is easier to read but less efficient
    {
        Remove-ADGroupMember -Identity $group -Members $destUser.distinguishedName
    }
}

编辑:添加 oneliners 以供参考。

# This is how the oneliner you were attempting should look
# I honestly don't like this for people new to Powershell

# Option 1:
$destUser.MemberOf|where{-not $sourceUser.MemberOf.Contains($_)}|Remove-ADGroupMember -Members $destUser.distinguishedName

# Option 2:
$destUser.MemberOf|where{$_ -notin $sourceUser.MemberOf}|Remove-ADGroupMember -Members $destUser.distinguishedName

# Option 3:
$destUser.MemberOf|where{-not $sourceUser.MemberOf.Contains($_)}|foreach{
    Remove-ADGroupMember -Identity $_ -Members $destUser.distinguishedName
}

# Option 4:
$destUser.MemberOf|where{$_ -notin $sourceUser.MemberOf}|foreach{
    Remove-ADGroupMember -Identity $_ -Members $destUser.distinguishedName
}
于 2021-04-08T21:07:07.823 回答
1

为了修改圣地亚哥的好答案,我想分享一些我在类似任务中的经验。我已经完成了大量的团体成员核对工作。我发现最简洁和最快的方法是利用Compare-Objectcmdlet。适合此处的典型场景是权威源,在这种情况下,源用户确定要对目标进行哪些更改,在这种情况下,目标用户。

我的大部分工作都来自小组,这意味着使用add/Remove-ADGroupMember这种情况可以更直接地为用户工作。这是一个很好的用例Add/Remove-ADPrincipalGroupMembership。不幸的是,MSDocs 帮助链接Get/Add/Remove-ADPrincipalGroupMembership目前似乎已损坏。SS64 似乎有帮助信息here

所以这没有经过测试,但这样的方法可能看起来像这样:

# Get the membership of sourceUser
$sourceUser = Get-ADUser sourceUser -Properties memberOf

# Get the membership of destUser
$destUser = Get-ADUser destUser -Properties memberOf

$Compare = Compare-Object $sourceUser.memberOf $destUser.memberOf

$Adds    = ($Compare | Where-Object{$_.SideIndicator -eq '<=' }).InputObject
$Removes = ($Compare | Where-Object{$_.SideIndicator -eq '=>' }).InputObject

If( $adds ) { Add-ADPrincipalGroupMembership -Identity -MemberOf $Adds }
If( $Removes ) { Remove-ADPrincipalGroupMembership -Identity -MemberOf $Removes -Confirm:$false }

-memberOf参数采用一个数组,因此您可以通过单次执行 cmdlet 来影响更改。一切都没有循环。

您可能会使用.Where()来分析通过Compare-Object锻炼比较返回的对象:

$Adds    = $Compare.Where( {$_.SideIndicator -eq '<=' }).InputObject
$Removes = $Compare.Where( {$_.SideIndicator -eq '=>' }).InputObject

注意:显然,如果您不需要删除,则不必实施。为了完整起见,它包含在示例中。

更新:MS Docs 链接实际上是通过谷歌打破的。直接在 MS 上搜索并在此处获得工作链接

于 2021-04-09T16:44:59.920 回答