Skip to content

Instantly share code, notes, and snippets.

@MyITGuy
Last active September 28, 2020 18:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MyITGuy/6033a03368757871b16b2c3c3eddcd56 to your computer and use it in GitHub Desktop.
Save MyITGuy/6033a03368757871b16b2c3c3eddcd56 to your computer and use it in GitHub Desktop.
This function will run the repadmin command and format the results into a PSCustomObject.
Get-ADGroup -Identity $GroupName | Get-RepAdmin | Where-Object { $_.Type -eq 'ABSENT' } | Select-Object -Property Type, Attribute, LastModTime, DistinguishedName | Sort-Object -Property LastModTime -Descending
Get-ADUser -Identity $env:USERNAME | Get-RepAdmin | Select-Object -Property Attribute, OrgTimeDate | Sort-Object -Property OrgTimeDate -Descending
Get-ADObject -Identity $GroupPolicyLinkDN | Get-RepAdmin -Verbose | Select-Object -Property Attribute, OrgTimeDate | Sort-Object -Property OrgTimeDate -Descending
#region Get-RepAdmin
function Get-RepAdmin {
[CmdletBinding()]
PARAM(
[Parameter(Mandatory = $false, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[string]
$Server = ([System.DirectoryServices.ActiveDirectory.Domain]::GetDomain((New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext([System.DirectoryServices.ActiveDirectory.DirectoryContextType]"Domain")))).FindDomainController().Name
,
[Parameter(Mandatory = $true, Position = 1, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[string]
$distinguishedName
)
begin {
Write-Verbose $MyInvocation.MyCommand
Write-Verbose "Server: $($Server)"
Write-Verbose "distinguishedName: $($distinguishedName)"
}
process {
try {
$objectClass = ([adsi]"LDAP://$($distinguishedName)").Class
Write-Verbose "Class: $($objectClass)"
switch ($true) {
($objectClass -eq 'group') {
Write-Verbose "Using group"
[regex]$line1pattern = '(?<Type>\w+)\s+(?<Attribute>\w+)\s+(?<LastModTime>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})\s+(?<OriginatingDSA>\S+)\s+(?<LocUSN>\w+)\s+(?<OrgUSN>\w+)\s+(?<Ver>\d+)'
[regex]$pattern = "$($line1pattern)\s+(?<DistinguishedName>.*)"
$return = repadmin /showobjmeta $DomainController $distinguishedName | Select-String -Pattern $line1pattern -Context 2
Write-Verbose "Return Count: $(($return | Measure-Object).Count)"
$return | ForEach-Object {
if ( $_ -match $pattern ) {
$Properties = [ordered]@{
Type = $matches.Type
Attribute = $matches.Attribute
LastModTime = $matches.LastModTime
OriginatingDSA = $matches.OriginatingDSA
LocUSN = $matches.LocUSN
OrgUSN = $matches.OrgUSN
Ver = $matches.Ver
DistinguishedName = $matches.DistinguishedName
}
[PSCustomObject]$Properties
}
}
}
default {
Write-Verbose "Using default"
[regex]$pattern = "(?<LocUSN>\d{1,10})\s{0,6}(?<OriginatingDSA>.{0,36})\s{0,10}(?<OrgUSN>\d{1,10})\s{0,1}(?<OrgTimeDate>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})\s{0,6}(?<Ver>\d{1,6})\s{1}(?<Attribute>\w+)"
$return = repadmin /showobjmeta $DomainController $distinguishedName | Select-String -Pattern $pattern
Write-Verbose "Return Count: $(($return | Measure-Object).Count)"
$return | ForEach-Object {
if ( $_ -match $pattern ) {
$Properties = [ordered]@{
LocUSN = $matches.LocUSN.Trim()
OriginatingDSA = $matches.OriginatingDSA.Trim()
OrgUSN = $matches.OrgUSN.Trim()
OrgTimeDate = $matches.OrgTimeDate.Trim()
Ver = $matches.Ver.Trim()
Attribute = $matches.Attribute.Trim()
}
[PSCustomObject]$Properties
}
}
}
}
}
catch {
Throw $_
}
}
end {
}
}
#endregion Get-RepAdmin
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment