Power Shell脚本用于从AD中的allusers组中删除已禁用和已过期的帐户

时间:2014-12-05 23:10:40

标签: powershell

我即将继承此脚本,显然需要14个小时才能完成。我在PowerShell上并不是最好的,但在我看来,第一步是搜索AD以查看已禁用和/或已过期的用户帐户,然后将其从该组中移除,也可以从所有组中删除。这是脚本;

$expired_disabled_users = Get-QADGroupMember -Identity allusers -SizeLimit 0 | ?{$_.AccountIsDisabled -eq $true -or $_.AccountIsExpired -eq $true}
$expired_disabled_users | ?{$_.accountisdisabled -eq $true | select Name,whenChanged}
foreach ($user in $expired_disabled_users) {Remove-QADGroupMember -Identity allusers -Member $user}

所以,我没有Quest AD插件。如何使用Powershell中的常规Module Activedirectory加速此脚本?我最初的改变是这样的,但我没有办法测试这个,因为我还没有域名权利;

$expired_disabled_users = Get-ADUser -Filter * | ?{$_.AccountIsDisabled -eq $true -or $_.AccountIsExpired -eq $true}
$expired_disabled_users | ?{$_.accountisdisabled -eq $true | select Name,whenChanged}
foreach ($user in $expired_disabled_users) {Remove-QADGroupMember -Identity allusers -Member $user}

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

只是按原样转换代码以使用“activedirectory”模块(我没有Quest cmdlet),您将获得以下内容。

$expired_disabled_users = Get-ADGroupMember -Identity "allusers" |  Get-Aduser -properties enabled,AccountExpirationDate |
        Where-Object{$_.Enabled -eq $false -or ($_.AccountExpirationDate -is [datetime] -and $_.AccountExpirationDate -lt (Get-Date))}
$expired_disabled_users | Where-Object {$_.Enabled -eq $false} | select Name
foreach ($user in $expired_disabled_users) {Remove-ADGroupMember -Identity "allusers" -Member $user -WhatIf}

现在..当然,由于您从Active Directory中提取所有用户,然后过滤其帐户状态,因此执行速度仍然非常慢。我无法在Quest文档中找到对 allusers 的引用,因此我假设这是一个存在于您的组织中的组。对于速度测试,我不打算使用组过滤器,但会显示如何过滤。我的AD中有大约600个用户。我也不打算删除用户,而是将代码保留为-WhatIf以帮助模拟处理。大多数失去的时间来自枚举所有用户。解决这个问题,我认为其他一切都会好的。

所以我们可以通过几种方式来解决这个问题。解决这个问题的一个更快的方法是使用LDAPFilter,所以我将重点关注它。

$groupDN = (Get-ADGroup "sslvpn_direct_forwards").DistinguishedName
$SecondsSince = (Get-Date).ToUniversalTime() - (Get-Date "00:00:00 01/01/1601") |
    Select-Object -ExpandProperty TotalSeconds
$100NanoSecondIntervals = ($SecondsSince * [Math]::Pow(10, 7)).ToString("0")

$ldapFilter = "(&(memberof=$groupDN)(|(userAccountControl:1.2.840.113556.1.4.803:=2)(&(!(accountExpires=0))(accountExpires<=$100NanoSecondIntervals))))"

Get-Aduser -LDAPFilter $ldapFilter

一些解释

  1. $groupDN是我们正在使用的群组的distunguishedName。对MemberOf的LDAP查询使用DN,因此我们使用Get-AdGroup来捕获该值。
  2. 知道$100NanoSecondIntervals是自“1601年1月1日12:00”以来的100纳秒间隔的计算。可以找到更多细节here
  3. $ldapfilter本身分为四部分。用户需要是某个组的组成员,并且该帐户必须至少被禁用或过期。

    • (memberof = $ groupDN)匹配我们正在寻找的群组。生成的用户必须是该组的成员
    • (userAccountControl:1.2.840.113556.1.4.803:= 2)这只是意味着没有设置Enabled的UserAccountControll位(想想我有正确的解释)。
    • (!(accountExpires = 0))(accountExpires&lt; = $ 100NanoSecondIntervals)由设置了到期值的帐户解释,并且过去的日期发生在过去.....过期的帐户
  4. 显示

    由于我之前提到的原因,我无法准确地测量您问题中的命令,但我应该能够很好地了解它们如何与用户的主要查询相互叠加。

    1..20 | %{
        Measure-Command{
            Get-Aduser -filter * -properties enabled,AccountExpirationDate  | Where-Object{$_.Enabled -eq $false -or ($_.AccountExpirationDate -is [datetime] -and $_.AccountExpirationDate -lt (Get-Date))} 
        }
    }| Select -Expand TotalSeconds | Measure-Object -Sum 
    
    1..20 | %{
        Measure-Command{
            Get-Aduser -LDAPFilter $ldapFilter -Properties enabled,AccountExpirationDate,memberof | Select Name,AccountExpirationDate,Enabled
        }
    }| Select -Expand TotalSeconds | Measure-Object -Sum 
    

    让我们分别运行这两个命令20次,看看它们合在一起多久。首先获取所有用户并筛选已过期或已禁用的帐户。第二次使用ldap只能获得与前一个匹配的帐户。

    Sum      : 13.0219249
    
    Sum      : 1.6220821
    

    正如您所看到的,第二个查询(ldap)与第一个查询所花费的时间相差不到2秒。

    简而言之,我很累,你应该尝试使用和ldap查询给出你的标准和似乎是一个大的组织。