2014-12-05 64 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

相關問題