2014-12-05 34 views
-1

我即将继承此脚本,显然需要14个小时才能完成。我并不是PowerShell的最佳人选,但在我看来,第一步是在AD中搜索已禁用和/或已过期的用户帐户,然后将其从该组和所有组中删除。这是剧本;Power Shell脚本从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} 

在此先感谢您的帮助!

+0

请注意,在Get-ADUser(或大多数,如果不是全部cmdlet)上使用-Filter参数将使提供程序过滤请求并提高性能,有时会显着提高性能。在这种情况下,我认为你会看到显着的性能提升。 – TheMadTechnician 2014-12-05 23:52:09

回答

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文档中的参考信息,因此我将假设这是一个存在于您的组织中的组。对于速度测试,我不打算使用组过滤器,但会显示如何过滤。我的广告中有大约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. 知道​​是自“1601年1月1日12:00”以来计算的100纳秒间隔。稍微更详细的可以发现here
  3. $ldapfilter本身被分成4部分。用户需要成为某个群组的成员,并且该帐户必须至少被禁用或过期。

    • (的memberOf = $ groupDN)匹配,我们正在寻找该组。所得到的用户必须是该组的成员
    • (userAccountControl:1.2.840.113556.1.4.803:= 2)这只是意味着未启用Enabled的UserAccountControll位(想想我的解释是正确的)。
    • (!(accountExpires = 0))(accountExpires < = $ 100NanoSecondIntervals)由设置了到期日期值的帐户解释,并且伴随日期发生在过去.....过期的帐户

显示按下

我不能准确地衡量你的问题的命令我前面提到的原因,但我应该能够得到他们如何叠起来对抗一个好主意彼此之间为用户的主要查询。

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秒钟比作13的第一个拿了。

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

+0

你的其他问题是ldap相关,所以这不应该很难掌握 – Matt 2014-12-06 05:25:43

+0

非常酷!你能评论一下我有这个观察吗?我猜这个脚本运行多长时间的另一个主要原因是由于它检查每个活动用户记录(超过20K)。是否适合在上个星期以来说的WhenChanged = say上的LDAP过滤器,以跳过这些过滤器并仅处理在指定日期之后发生更改的任何用户对象?我假设是,但可以使用LDAP过滤器语法。再次感谢! – MarcGel 2014-12-08 18:57:27

+0

编辑,我会用(whenChanged> = 20080812000000.0Z)。谢谢 – MarcGel 2014-12-08 19:06:53

相关问题