Powershell 获取过去 6 个月内被禁用的 AD 用户的困惑?
Powershell to get the AD user that was disabled in the past 6 months confusion?
我想知道可以使用或自定义哪个命令或脚本来搜索在过去 6 个月内被禁用的 AD 用户帐户?
脚本 1:不确定如何自定义下面的脚本,因为它非常复杂。
# When an account is disabled, the userAccountControl attribute is set to 514.
# Therefore, with Get-ADReplicationAttributeMetadata to find out when that attribute was the last set
$disabledUsers = Get-ADObject -Filter "ObjectClass -eq 'User' -and userAccountControl -eq '514'"
foreach ($disabledUser in $disabledUsers)
{
Get-ADReplicationAttributeMetadata $disabledUser -Server localhost |
Where-Object { $_.AttributeName -eq 'UserAccountControl' } | Select Object, LastOriginatingChangeTime |
Where-Object { $_.LastOriginatingChangeTime -gt (Get-Date).AddDays(-180) }
}
脚本 2:我能够使用此脚本并获得我需要的所有列和过滤,但是,它不显示过去 6 个月内被禁用的 AD 帐户?
Import-Module ActiveDirectory
$domainDN = (Get-ADDomain).DistinguishedName
$excludeOUs = @(
'OU=Shared Mailbox'
'OU=Company Leaver'
) | ForEach-Object { $_ + ',' + $domainDN }
$Past = -180
$Days = (Get-Date).AddDays($Past)
$ResultPath = "C:\TEMP\ADLastLogonPast_$($Past)_Days.csv"
$properties = @('Name', 'mail', 'physicalDeliveryOfficeName', 'DisplayName', 'title', 'SamAccountName', 'CanonicalName', 'lastlogondate')
$filter = { (LastLogonDate -notlike '*' -or LastLogonDate -le $Days) -and (passwordLastSet -le $Days) -and (enabled -eq $True) -and (PasswordNeverExpires -eq $false) -and (whenCreated -le $Days) }
Get-ADUser -properties $properties -Filter $filter -SearchBase $domainDN |
Select-Object DisplayName,
Title,
PhysicalDeliveryOfficeName,
UserPrincipalName,
LastLogonDate,
@{ n = 'LastLogonDaysAgo'; e = { [int]((Get-Date) - $_.LastLogonDate).TotalDays } },
@{ n = 'CN'; e = { Split-Path $_.CanonicalName -Parent } },
@{ n = 'ParentContainer'; e = { $_.DistinguishedName -replace '^CN=.*?(?=CN|OU)' } } | Where-Object {
($_.SamAccountName -notmatch '^(Calendar|Room|Account|Fax|Team|Office|Test|User|SM_|HealthMailbox|SVC)$') -and
($excludeOUs -notcontains $_.ParentContainer)
} |
Export-Csv -NoTypeInformation -Path $ResultPath
假设您要查找在过去 6 个月内从启用更改为禁用的帐户,那么您的第二个脚本不会告诉您。您只是查找已禁用且超过 6 个月未使用的帐户。或者充其量,您可以对其进行修改,为您提供在过去 6 个月内被禁用和最后更新的帐户。但其中一些可能在 6 个多月前就被禁用了。
第一个脚本将为您提供所需的内容,因为使用 Get-ADReplicationAttributeMetadata
可以让您找到特定属性的修改时间。这样就可以查到userAccountControl
属性是什么时候被修改的。但它确实需要一些修改。
首先,这个:
# When an account is disabled, the userAccountControl attribute is set to 514.
这不一定是真的。 userAccountControl
attribute is a bit flag, meaning that every bit in the binary value is a flag that means something different (1
= on, 0
= off). So the decimal value doesn't really have any relevance. To find out if an account is disabled, you want to look at the second bit. To do that, you use the bitwise operator -band
.
该脚本也指向 localhost
,这意味着您必须在域控制器上 运行 它。但是您可以轻松修改它以找到要指向的域控制器。
我还在 Get-ADObject
中添加了一个条件,只查找最近 6 个月内修改过的帐户,因为如果该帐户在不到 6 个月前被禁用,那肯定意味着它被修改的时间少于6 个月前。这减少了您必须调用 Get-ADReplicationAttributeMetadata
的帐户数量,将此脚本花费的时间减少到 运行。 (请注意过滤器周围的单引号,这很重要,因为 PowerShell 如何处理日期。)
$sixMonthsAgo = (Get-Date).AddDays(-180)
$disabledUsers = Get-ADObject -Filter 'ObjectClass -eq "User" -and whenChanged -ge $sixMonthsAgo -and UserAccountControl -band 2'
$server = Get-ADDomainController
foreach ($disabledUser in $disabledUsers)
{
Get-ADReplicationAttributeMetadata $disabledUser -Server $server -Properties UserAccountControl |
Where-Object { $_.AttributeName -eq 'UserAccountControl' } | Select Object, LastOriginatingChangeTime |
Where-Object { $_.LastOriginatingChangeTime -gt $sixMonthsAgo }
}
(出于某种原因,我发现当我在 PowerShell ISE 中 运行 这个脚本时 Get-ADReplicationAttributeMetadata
没有给我任何数据,但是当我 copy/paste 到一个普通的 PowerShell window。不知道为什么,但值得一提)
从技术上讲,这仍然可能无法准确找到帐户被禁用的时间,因为它正在寻找 userAccountControl
中的任何变化。例如,有可能有人在帐户被禁用后将帐户设置为 "don't expire password",这也会更改 userAccountControl
属性,并且此脚本会查看 "don't expire password" 的日期] 更改,而不是禁用日期。但在大多数情况下,这种事情是不会发生的。
我会这样做:
# Midnight 180 days ago
$CutoffDate = [DateTime]::Today.AddDays(-180)
$UsersDisabledAfterCutoff = Search-ADAccount -AccountDisabled -UsersOnly |
Get-ADReplicationAttributeMetadata -Server $DomainController -Properties UserAccountControl |
Where-Object LastOriginatingChangeTime -ge $CutoffDate |
Select-Object -Property Object, LastOriginatingChangeTime
Search-ADAccount
命令使查找帐户类别变得容易,而无需费力地使用位掩码。您肯定想看一看 the documentation for future use,因为它处理了大量此类事情。
Get-ADReplicationAttributeMetadata
命令可让您指定要查找的属性,从而减少每个人的工作量。这个命令也有一个 -Filter
参数,但我发现它的性能有时很糟糕。
我想知道可以使用或自定义哪个命令或脚本来搜索在过去 6 个月内被禁用的 AD 用户帐户?
脚本 1:不确定如何自定义下面的脚本,因为它非常复杂。
# When an account is disabled, the userAccountControl attribute is set to 514.
# Therefore, with Get-ADReplicationAttributeMetadata to find out when that attribute was the last set
$disabledUsers = Get-ADObject -Filter "ObjectClass -eq 'User' -and userAccountControl -eq '514'"
foreach ($disabledUser in $disabledUsers)
{
Get-ADReplicationAttributeMetadata $disabledUser -Server localhost |
Where-Object { $_.AttributeName -eq 'UserAccountControl' } | Select Object, LastOriginatingChangeTime |
Where-Object { $_.LastOriginatingChangeTime -gt (Get-Date).AddDays(-180) }
}
脚本 2:我能够使用此脚本并获得我需要的所有列和过滤,但是,它不显示过去 6 个月内被禁用的 AD 帐户?
Import-Module ActiveDirectory
$domainDN = (Get-ADDomain).DistinguishedName
$excludeOUs = @(
'OU=Shared Mailbox'
'OU=Company Leaver'
) | ForEach-Object { $_ + ',' + $domainDN }
$Past = -180
$Days = (Get-Date).AddDays($Past)
$ResultPath = "C:\TEMP\ADLastLogonPast_$($Past)_Days.csv"
$properties = @('Name', 'mail', 'physicalDeliveryOfficeName', 'DisplayName', 'title', 'SamAccountName', 'CanonicalName', 'lastlogondate')
$filter = { (LastLogonDate -notlike '*' -or LastLogonDate -le $Days) -and (passwordLastSet -le $Days) -and (enabled -eq $True) -and (PasswordNeverExpires -eq $false) -and (whenCreated -le $Days) }
Get-ADUser -properties $properties -Filter $filter -SearchBase $domainDN |
Select-Object DisplayName,
Title,
PhysicalDeliveryOfficeName,
UserPrincipalName,
LastLogonDate,
@{ n = 'LastLogonDaysAgo'; e = { [int]((Get-Date) - $_.LastLogonDate).TotalDays } },
@{ n = 'CN'; e = { Split-Path $_.CanonicalName -Parent } },
@{ n = 'ParentContainer'; e = { $_.DistinguishedName -replace '^CN=.*?(?=CN|OU)' } } | Where-Object {
($_.SamAccountName -notmatch '^(Calendar|Room|Account|Fax|Team|Office|Test|User|SM_|HealthMailbox|SVC)$') -and
($excludeOUs -notcontains $_.ParentContainer)
} |
Export-Csv -NoTypeInformation -Path $ResultPath
假设您要查找在过去 6 个月内从启用更改为禁用的帐户,那么您的第二个脚本不会告诉您。您只是查找已禁用且超过 6 个月未使用的帐户。或者充其量,您可以对其进行修改,为您提供在过去 6 个月内被禁用和最后更新的帐户。但其中一些可能在 6 个多月前就被禁用了。
第一个脚本将为您提供所需的内容,因为使用 Get-ADReplicationAttributeMetadata
可以让您找到特定属性的修改时间。这样就可以查到userAccountControl
属性是什么时候被修改的。但它确实需要一些修改。
首先,这个:
# When an account is disabled, the userAccountControl attribute is set to 514.
这不一定是真的。 userAccountControl
attribute is a bit flag, meaning that every bit in the binary value is a flag that means something different (1
= on, 0
= off). So the decimal value doesn't really have any relevance. To find out if an account is disabled, you want to look at the second bit. To do that, you use the bitwise operator -band
.
该脚本也指向 localhost
,这意味着您必须在域控制器上 运行 它。但是您可以轻松修改它以找到要指向的域控制器。
我还在 Get-ADObject
中添加了一个条件,只查找最近 6 个月内修改过的帐户,因为如果该帐户在不到 6 个月前被禁用,那肯定意味着它被修改的时间少于6 个月前。这减少了您必须调用 Get-ADReplicationAttributeMetadata
的帐户数量,将此脚本花费的时间减少到 运行。 (请注意过滤器周围的单引号,这很重要,因为 PowerShell 如何处理日期。)
$sixMonthsAgo = (Get-Date).AddDays(-180)
$disabledUsers = Get-ADObject -Filter 'ObjectClass -eq "User" -and whenChanged -ge $sixMonthsAgo -and UserAccountControl -band 2'
$server = Get-ADDomainController
foreach ($disabledUser in $disabledUsers)
{
Get-ADReplicationAttributeMetadata $disabledUser -Server $server -Properties UserAccountControl |
Where-Object { $_.AttributeName -eq 'UserAccountControl' } | Select Object, LastOriginatingChangeTime |
Where-Object { $_.LastOriginatingChangeTime -gt $sixMonthsAgo }
}
(出于某种原因,我发现当我在 PowerShell ISE 中 运行 这个脚本时 Get-ADReplicationAttributeMetadata
没有给我任何数据,但是当我 copy/paste 到一个普通的 PowerShell window。不知道为什么,但值得一提)
从技术上讲,这仍然可能无法准确找到帐户被禁用的时间,因为它正在寻找 userAccountControl
中的任何变化。例如,有可能有人在帐户被禁用后将帐户设置为 "don't expire password",这也会更改 userAccountControl
属性,并且此脚本会查看 "don't expire password" 的日期] 更改,而不是禁用日期。但在大多数情况下,这种事情是不会发生的。
我会这样做:
# Midnight 180 days ago
$CutoffDate = [DateTime]::Today.AddDays(-180)
$UsersDisabledAfterCutoff = Search-ADAccount -AccountDisabled -UsersOnly |
Get-ADReplicationAttributeMetadata -Server $DomainController -Properties UserAccountControl |
Where-Object LastOriginatingChangeTime -ge $CutoffDate |
Select-Object -Property Object, LastOriginatingChangeTime
Search-ADAccount
命令使查找帐户类别变得容易,而无需费力地使用位掩码。您肯定想看一看 the documentation for future use,因为它处理了大量此类事情。
Get-ADReplicationAttributeMetadata
命令可让您指定要查找的属性,从而减少每个人的工作量。这个命令也有一个 -Filter
参数,但我发现它的性能有时很糟糕。