Today I will show you script to check when user was added to AD group.
Script is using functionality of repadmin tool to check when users were modified inside the group.
Showobjmeta displays the replication metadata for a specified object stored in Active Directory, so it can be used not only for group membership checking.
You can find other functionalities of this tool on TechNet site.
Output from repadmin tool is parsed by regex to read all information in easy way and put them in Powershell object(in our case it’s Array).
Example of usage:
Get-ADGroupMemberDate -Group "Domain Admins"
Script:
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 {$_.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 } } } End { $Array = $Array | Format-Table -AutoSize $Array } }
In result you will receive array with information with folowing informations:
– Username – full name of the user which is/was a member of specific group
– LastModified – information when user was added or removed from group
– DomainController – information on which DC user was added/removed
– Group – name of the group
– State – information about user membership – PRESENT or ABSENT
– ModifiedCounter – information about how often user account was modified in group
Now you know how to check when user was added to AD Group.
I hope it will be usefull for some of you 🙂
Enjoy!
Get-ADGroupMemberDate : The term ‘Get-ADGroupMemberDate’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the
path is correct and try again.
At line:1 char:1
+ Get-ADGroupMemberDate
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-ADGroupMemberDate:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Hi Chad,
Before you call function you must load it to your PowerShell code editor (ISE, Visual Studio Code, etc).
Copy code from Script part, paste to your editor and run.
Right after that you can use command Get-ADGroupMemberDate -Group “GroupName”.
Hope now it’s clear 😉
Regards,
Artur
Great script, I tested it on a Server 2016 environment and got positive results. The only thing missing is which UserAccount added the user as member to the ADGroup.
This function works for me but does not show the LastModified date, only shows State, Username, Group.
Have you been able to solve the issue? I’ve got the same one
I believe there is a bug. If the AD user name has a comma which AD escapes for the DN with a slash, then the slash is erroneously returned. e.g. User name “Bob Smith, MD” returns a user name of “Bob Smith /”
Username = [regex]::Matches($rep.context.postcontext,”CN=(?.*\\?),.*”) | ForEach {$_.Groups[‘Username’].Value}
add \\ see above.
Can you please tell how to change the script to check only one specific user? Just to not having performance issue on DC.
Thanks Brah!
Can you tell me how I can get who modified the >
You can find this in security eventlog:
$DCs = (Get-ADDomainController -filter *).name
$Results = @()
$Results = Invoke-Command -ComputerName $DCs -ErrorAction SilentlyContinue -ScriptBlock {
#Events criteria
$Filter = @{
LogName = ‘Security’
ID = 4732, 4728, 4729
}
# Get events
$Events = Get-WinEvent -FilterHashtable $Filter | select id, timecreated, properties,message
If( $Events ){
Foreach ( $Event in $Events ){
$Object = @{} | Select ‘Event ID’, ‘Time created’, ‘Message’, ‘Subject user’, ‘Target user’, ‘Group name’
$Object.’Event ID’ = [string]$Event.id
$Object.’Time created’ = $Event.timecreated
$Object.’Message’ = ($Event.Message -split (‘[\r\n]’))[0]
$Object.’Subject user’ = $Event.Properties[-4].value
$Object.’Target user’ = $Event.Properties[0].value
$Object.’Group name’ = $Event.Properties[2].value
$Object
}
}
} | Select @{n=’ServerName’;e={$_.pscomputername}},’Event ID’, ‘Time created’, ‘Message’, ‘Subject user’, ‘Target user’, ‘Group name’
$Results | ogv -title ‘Events’
How can you get the user’s email address?
Get-ADGroupMemberDate -Group “Domain Admins” |out-gridview
Get-ADGroupMemberDate -Group “Domain Admins” |export-csv -path .\desktop\adgroup.csv -notypeinformation
output format is not support. please help me how can i do
There’s a small (but significant) bug: if repadmin returns the DC’s name rather than GUID, if the DC’s name has a hyphen in it, the RegEx will only capture PRESENT or ABSENT and will not match any of the rest of the details. A simple fix is to change the part of the DC capture that has ‘\w+’ to instead read ‘\w[-\w]+’. This will accurately capture letters, numbers, underscores, and hyphens in DC names.
Additionally from my last comment, this does not work in a multi-domain forest, and I recommend adding a -Server parameter instead of relying solely on the logon server
Hi All,
I am new to powershell and i was looking for a same script but with some advancement like-
1.The script should be able to iterate through specific group like(Group1,Group2,Group3).
2.I want the script to fetch data of users added/removed from specific group(Group1,Group2,Group3) in last 24 hours.
3. And in the last it should contain the below mentioned columns exported to csv with it’s values.
‘ID’ = $obj.SamAccountName
‘Name’ = $obj.name
‘Group Name’ = $groupName
‘Created on’ = $obj.whenCreated
‘Email Address’ = $obj.EmailAddress
‘UPN’ = $obj.UserPrincipalName
‘DN’ = $obj.DistinguishedName
‘State’ = $matches.state
‘ModifiedCounter’ = $matches.modified
Thanks in advance!!!!