如何使用PowerShell监视AD组更改

时间:2020-01-09 10:46:44  来源:igfitidea点击:

让我们看看当有人向重要的Active Directory安全组添加新用户时如何创建简单的管理员通知系统。例如,我们要跟踪域管理员组的更改,并且如果向其中添加了新用户,则要获取相应的通知(通过电子邮件或者弹出警报消息)。

有一些方法可以实现它:

  • 我们可以在域控制器上启用事件审核,并跟踪将新用户添加到安全组的事件(EventID 4728);
  • 我们可以将本地文本文件与某个组的用户列表一起存储,并定期将其与域组的当前成员列表进行比较。

将用户添加到域控制器上的组的审核

如果在GPO部分"计算机配置-> Windows设置->安全设置->高级审核配置->帐户管理->审核安全组管理"中启用了审核策略,则事件ID为" 4732"的事件(成员为将新用户添加到任何Active Directory组中后,"添加到启用了安全性的全局组中"将显示在"安全性"日志中。

使用PowerShell,我们可以在安全日志中跟踪此事件。例如,让我们在过去24小时内在域控制器上显示具有此ID的所有事件。为了方便起见,请很好地显示已更改的AD组的名称,添加的帐户的名称以及将该用户添加到该组的管理员。该脚本类似于文章"如何获取最近24小时内创建的所有Active Directory用户"中给出的脚本。

$CurrTime = (get-date) - (new-timespan -hour 24)
Get-WinEvent -FilterHashtable @{LogName="Security";ID=4732;StartTime=$CurrTime}| Foreach {
$event = [xml]$_.ToXml()
if($event)
{
$CurrTime = Get-Date $_.TimeCreated -UFormat "%Y-%d-%m %H:%M:%S"
$New_GrpUser = $event.Event.EventData.Data[0]."#text"
$AD_Group = $event.Event.EventData.Data[2]."#text"
$AdminWhoAdded = $event.Event.EventData.Data[6]."#text"
$dc = $event.Event.System.computer
$dc + "|" + $CurrTime + "|" + "|" + $AD_Group + "|" + $New_GrpUser + "|" + $AdminWhoAdded
}
}

然后在域控制器上创建一个新的计划程序任务,该事件由ID 4732的事件触发。发生此事件时,将向用户发送一条消息。 (Windows事件触发器文章介绍了如何将脚本链接到事件,在此不再赘述。)

但是,问题在于仅检查了一个DC的安全日志。如果已将用户添加到另一个域控制器上的组中,则不会看到此事件。当然,我们可以预订多个DC的事件,也可以在每个控制器上运行脚本,但是如果域中有很多DC,则不是很方便。

提示。循环检查域中所有DC并从中收集事件的示例可能看起来像这样(代码示例摘自文章"如何跟踪谁重置Active Directory中用户的密码"):

$time = (get-date) - (new-timespan -hour 124)
$DCs = Get-ADDomainController -Filter *
foreach ($DC in $DCs){
Get-WinEvent -ComputerName $DC -FilterHashtable @{LogName="Security";ID=4732;StartTime=$Time}| Foreach {
$event = [xml]$_.ToXml()
if($event)
{
CurrTime = Get-Date $_.TimeCreated -UFormat "%Y-%d-%m %H:%M:%S"
$New_GrpUser = $event.Event.EventData.Data[0]."#text"
$AD_Group = $event.Event.EventData.Data[2]."#text"
$AdminWhoAdded = $event.Event.EventData.Data[6]."#text"
$dc = $event.Event.System.computer
$dc + "|" + $CurrTime + "|" + "|" + $AD_Group + "|" + $New_GrpUser + "|" + $AdminWhoAdded
}
}
}

让我们考虑另一种方法。

将域组的当前成员与保存的模板进行比较

让我们使用Get-ADGroupMember cmdlet显示Domain Admin组中的用户列表,并将结果列表保存到文本文件(我们正在构建包括嵌套组的递归用户列表):

(Get-ADGroupMember -Identity "Domain Admins" -recursive).Name | Out-File C:\PS\DomainAdmins.txt

然后将新用户添加到Domain Admins组,并将用户列表再次保存到另一个文件:

(Get-ADGroupMember -Identity "Domain Admins" -recursive).Name | Out-File C:\PS\DomainAdminsActual.txt

现在比较两个文件并在列表中显示差异:

$old_adgroup_members=GC C:\PS\DomainAdmins.txt
$new_adgroup_members=GC C:\PS\DomainAdminsActual.txt
$diff=Compare-Object -ReferenceObject $old_adgroup_members -DifferenceObject $new_adgroup_members | Select-Object -ExpandProperty InputObject
write-host $diff

显示添加到AD组的新帐户。

我们还可以在控制台中显示消息:

$result=(Compare-Object -ReferenceObject $old_adgroup_members -DifferenceObject $diff | Where-Object {$_.SideIndicator -eq "=>"} | Select-Object -ExpandProperty InputObject) -join ", "
If ($result)
{msg * "A user $result has been added to Domain the Admins group"}

或者使用Send-MailMessage cmdlet发送电子邮件:

If ($result)
{Send-MailMessage -SmtpServer war-msg01 -From [email protected] -To [email protected] -Subject "A user $result has been added to the Domain Admins group" -Body "Created on $date" -Priority High}

我们可以将此脚本保存到文件admins_group_changes.ps1中,并使用Task Scheduler定期运行它(可以使用PowerShell创建调度程序任务)。创建一个新的Scheduler作业,该作业每24小时运行一次PowerShell脚本。它将把Domain Admins组的成员与本地保存的列表进行比较。

$Trigger= New-ScheduledTaskTrigger -At 17:00am -Daily
$User= "NT AUTHORITY\SYSTEM"
$Action= New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "C:\PS\admins_group_changes.ps1 "
Register-ScheduledTask -TaskName "Check Domain Group Changes" -Trigger $Trigger -User $User -Action $Action -RunLevel Highest –Force

因此,将每天检查一次域管理员组的成员,如果有任何更改,管理员将收到警报(在弹出窗口或者通过电子邮件)。