01 September 2020

AD Group Member Reporting

This tool queries specified AD groups for new users that have been added to the group within a specified number of days. The script is written so that it can be used with Azure Automation, Orchestrator, or even a scheduled task, with the addition of the send-mailmessage cmdlet. The intent of this is to track if say a user needs to be temporarily added to the domain admins group for software installation, but then the help desk forgets to remove them. It can also be a tracking tool in the event a cyber-incursion is happening and a compromised account gets added to that group. Obviously, if a user who is already in that group is compromised, then this script does not impact that type of event. This script was made possible by using the function posted over at PowerShellBros with a few modifications to it.

The script exits with a write-output statement if any new users appear in the report. The Write-Output allows for the data to be sent to the next step in say Orchestrator. If no new users appear, then the script exits with an error code 1. This is so the link in Azure Automation or Orchestrator can be set to only proceed to send an email if there was an error code 0, which would be the Write-Output statement. 

You can download the script from my GitHub repository located here


 <#  
      .SYNOPSIS  
           AD Security Group User Additions  
        
      .DESCRIPTION  
           This script retrieves a list of users added to a specified AD security group, which includes the date it was last modified. This info can be used to track whether a new user has been recently added to a security group, especially a group that elevates priviledges. This can be used as a tool to help fight cyber-crime.  
        
      .PARAMETER NumberOfDays  
           Number of days to look back for users having been added to the designated AD security group  
        
      .PARAMETER SecurityGroup  
           Name of the AD security group  
        
      .NOTES  
           ===========================================================================  
           Created with:    SAPIEN Technologies, Inc., PowerShell Studio 2017 v5.4.142  
           Created on:      9/1/2020 11:03 AM  
           Created by:      Mick Pletcher  
           Filename:        ADGroupUserInfo.ps1  
           ===========================================================================  
 #>  
   
 [CmdletBinding()]  
 param  
 (  
      [ValidateNotNullOrEmpty()]  
      [int]$NumberOfDays,  
      [ValidateNotNullOrEmpty()]  
      [string]$SecurityGroup  
 )  
   
 Function Get-ADGroupMemberDate {  
        
      [cmdletbinding()]  
      Param (  
           [parameter(ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True, Mandatory = $True)]  
           [string]$Group  
             
      )  
        
      Begin {  
           [regex]$pattern = '^(?<State>\w+)\s+member(?:\s(?<DateTime>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})\s+(?:.*\\)?(?<DC>\w+|(?:(?:\w{8}-(?:\w{4}-){3}\w{12})))\s+(?:\d+)\s+(?:\d+)\s+(?<Modified>\d+))?'  
           $DomainController = ($env:LOGONSERVER -replace "\\\\")  
           If (!$DomainController) {  
                Throw "Computer from which script is run is not joined to domain and domain controller can not be identified."  
                Break  
           }  
      }  
      Process {  
           Write-Verbose "Checking distinguished name of the group $Group"  
           Try {  
                $distinguishedName = (Get-ADGroup -Identity $Group).DistinguishedName  
           } Catch {  
                Write-Warning "$group can not be found!"  
                Break  
           }  
           $RepadminMetaData = (repadmin /showobjmeta $DomainController $distinguishedName | Select-String "^\w+\s+member" -Context 2)  
           $Array = @()  
           ForEach ($rep in $RepadminMetaData) {  
                If ($rep.line -match $pattern) {  
                     $object = New-Object PSObject -Property @{  
                          Username = [regex]::Matches($rep.context.postcontext, "CN=(?<Username>.*?),.*") | ForEach-Object {  
                               $_.Groups['Username'].Value  
                          }  
                          LastModified = If ($matches.DateTime) {  
                               [datetime]$matches.DateTime  
                          } Else {  
                               $Null  
                          }  
                          DomainController = $matches.dc  
                          Group      = $group  
                          State      = $matches.state  
                          ModifiedCounter = $matches.modified  
                     }  
                     $Array += $object  
                }  
           }  
     Return $Array  
      }  
      End {  
      }  
 }  
   
 $Users = Get-ADGroupMemberDate -Group $SecurityGroup | Select Username, LastModified  
 $NewUsers = @()  
 #Find users added to the AD Group within the designated number of days  
 Foreach ($User in $Users) {  
   If ((New-TimeSpan -Start $User.LastModified -End (Get-Date)).Days -lt $NumberOfDays) {  
     $NewUsers += $User  
   }  
 }  
 If ($NewUsers.Count -gt 0) {  
   Write-Output $NewUsers  
 } else {  
   Exit 1  
 }  
   

0 comments:

Post a Comment