Skip to content

Commit

Permalink
Update SIDHistory scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
SamErde committed Jan 10, 2025
1 parent 14a67e1 commit 872e4f9
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 0 deletions.
76 changes: 76 additions & 0 deletions Active Directory/SIDHistory/Get-ADObjectWithSIDHistory.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
function Get-ADObjectWithSIDHistory {
<#
.SYNOPSIS
Get all Active Directory objects that have SID history.
.DESCRIPTION
This function gets all Active Directory objects that have SID history. It can optionally be filtered to only get
user, computer, or group objects.
.EXAMPLE
Get-AllAdSidHistory
This example gets all Active Directory objects that have SID history.
.EXAMPLE
Get-AllAdSidHistory -Type User
This example gets all Active Directory user objects that have SID history.
.EXAMPLE
Get-AllAdSidHistory -Type Computer
This example gets all Active Directory computer objects that have SID history.
.EXAMPLE
Get-AllAdSidHistory -Type Group
This example gets all Active Directory group objects that have SID history.
.EXAMPLE
Get-AllAdSidHistory -Type All
This example gets all Active Directory objects that have SID history, regardless of type.
.NOTES
Author: Sam Erde, Sentinel Technologies, Inc.
Version: 0.1.0
Modified: 2025-01-10
#>
[CmdletBinding()]
[OutputType('Microsoft.ActiveDirectory.Management.ADObject[]')]
param (
# Type of objects to get. Default is 'All'.
[Parameter()]
[ValidateSet('All', 'User', 'Computer', 'Group')]
[string]
$Type = 'All'
)

begin {
if (-not (Get-Module -Name ActiveDirectory)) {
Write-Verbose -Message 'Importing ActiveDirectory module.'
Import-Module ActiveDirectory
Write-Verbose -Message '------------------------------'
Write-Verbose -Message "Beginning ${MyInvocation.InvocationName}..."
}

$BaseFilter = 'SIDHistory -like "*"'
switch ($Type) {
'User' { $Filter = "$BaseFilter -and objectClass -eq 'user'" }
'Computer' { $Filter = "$BaseFilter -and objectClass -eq 'computer'" }
'Group' { $Filter = "$BaseFilter -and objectClass -eq 'group'" }
'All' { $Filter = $BaseFilter }
}
} # end begin

process {
# Get all ActiveDirectory objects that have SID history.
[Microsoft.ActiveDirectory.Management.ADObject[]]$ADObjectList = Get-ADObject -Filter $Filter -Properties SIDHistory | Select-Object * -ExpandProperty SIDHistory
} # end process

end {
$ADObjectList
} # end end

} # end function
70 changes: 70 additions & 0 deletions Active Directory/SIDHistory/Get-SIDHistorySourceDomainList.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
function Get-ADObjectWithSIDHistory {
<#
.SYNOPSIS
Get a list of source domain SIDs from all Active Directory objects that have SID history.
.DESCRIPTION
This function gets all Active Directory objects that have SID history and returns a list of unique source domain SIDs.
.NOTES
Author: Sam Erde, Sentinel Technologies, Inc.
Version: 0.1.0
Modified: 2025-01-10
#>
[CmdletBinding()]
[OutputType('Microsoft.ActiveDirectory.Management.ADObject[]')]
param (
<#
# Type of objects to get. Default is 'All'.
[Parameter()]
[ValidateSet('All', 'User', 'Computer', 'Group')]
[string]
$Type = 'All'
#>
)

begin {
if (-not (Get-Module -Name ActiveDirectory)) {
Write-Verbose -Message 'Importing ActiveDirectory module.'
Import-Module ActiveDirectory
Write-Verbose -Message '------------------------------'
Write-Verbose -Message "Beginning ${MyInvocation.InvocationName}..."
}

<# Build the filter for the Get-ADObject cmdlet.
$BaseFilter = 'SIDHistory -like "*"'
switch ($Type) {
'User' { $Filter = "$BaseFilter -and objectClass -eq 'user'" }
'Computer' { $Filter = "$BaseFilter -and objectClass -eq 'computer'" }
'Group' { $Filter = "$BaseFilter -and objectClass -eq 'group'" }
'All' { $Filter = $BaseFilter }
}
#>
$SIDHistorySourceDomainSIDList = [ordered]@{}
} # end begin

process {
# Get all ActiveDirectory objects that have SID history.
[Microsoft.ActiveDirectory.Management.ADObject[]]$ADObjectList = Get-ADObject -Filter $Filter -Properties SIDHistory | Select-Object * -ExpandProperty SIDHistory

foreach ($ADObject in $ADObjectList) {

foreach ($SIDHistoryEntry in $ADObject.SIDHistory) {
# Extract the source domain SID from the SIDHistory attribute.
$SourceDomainSID = $SIDHistoryEntry.Substring(0, $SIDHistoryEntry.LastIndexOf('-'))

# Add the source domain SID to the list if it doesn't already exist.
if (-not $SIDHistorySourceDomainSIDList.ContainsKey($SourceDomainSID)) {
$SIDHistorySourceDomainSIDList.Add($SourceDomainSID, $SourceDomainSID)
}
} # end foreach SIDHistoryEntry

} # end foreach ADObject
} # end process

end {
# Update to return the hash table after resolving source domain SIDs.
$SIDHistorySourceDomainSIDList.Keys
} # end end

} # end function
108 changes: 108 additions & 0 deletions Active Directory/SIDHistory/Get-TrustedDomainSIDMapping.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
function Get-TrustedDomainSIDMapping {
<#
.SYNOPSIS
Get the SID and DNSRoot name of trusted domains and forests.
.DESCRIPTION
This function retrieves the SID and DNSRoot name of trusted domains and forests in the current Active Directory forest.
.PARAMETER ManualEntry
If specified, the user may manually provide a SID and DNS name to add to the list of domains.
.EXAMPLE
$SIDMappingTable = Get-TrustedDomainSIDMapping -ManualEntry 'S-1-5-21-1234567890-1234567890-1234567890', 'example.com' -Verbose
This example retrieves the SIDs and DNSRoot names of trusted domains and forests in the current Active Directory forest and adds a manual entry to the results.
.NOTES
Author: Sam Erde, Sentinel Technologies, Inc.
Version: 0.0.1
Modified: 2024-11-14
To-Do:
- Add support for trusted forests and external trusts.
- Add support for manually including a CSV file with trusted domain information.
- Add support for exporting a CSV file with trusted domain information.
- Add support for taking an array of trusted domain SIDs and DNS root names as input for ManualEntry.
#>
[CmdletBinding()]
param (
# If specified, the user may manually provide a SID and DNS name to add to the list of trusted domains.
[Parameter(HelpMessage = 'Enter the SID and DNS name of a trusted domain in the format ''S-1-5-21-1234567890-1234567890-1234567890'', ''example.com''.')]
[array]$ManualEntry
)
begin {
# Import the ActiveDirectory module if it is not already loaded.
if (-not (Get-Module -Name ActiveDirectory)) {
Write-Verbose -Message 'Importing ActiveDirectory module.'
Import-Module ActiveDirectory
Write-Verbose -Message '------------------------------'
Write-Verbose -Message 'Beginning to process trusts...'
}
# Create a dictionary to store domain SIDs with their corresponding DNS root names.
$DomainSIDMapping = [ordered] @{}
$CurrentDomain = (Get-ADDomain)
$DomainSIDMapping.Add(
$CurrentDomain.DomainSID.Value,
$CurrentDomain.DNSRoot
)
# If the user provided a manual entry, add it to the dictionary.
if ($PSBoundParameters.ContainsKey('ManualEntry')) {
Write-Verbose -Message "Manually entered SID: $($ManualEntry[0])"
Write-Verbose -Message "Manually entered DNS root name: $($ManualEntry[1])"
$DomainSIDMapping.Add(
$ManualEntry[0],
$ManualEntry[1]
)
}
$Trusts = Get-ADTrust -Filter *
}
process {
# Loop through all trusts and add the trusted domain SIDs and DNS root names to the dictionary.
foreach ($trust in $Trusts) {
# Need to see if checking SID and DNSRoot requires a different process for trusted forests vs trusted domains.
switch ($trust.TrustType) {
<#
"DomainTrust" {
Write-Verbose -Message "Processing domain trust: $($trust.Target)"
try {
Write-Verbose -Message "Processing trust: $($trust.Target)"
$TrustedDomain = Get-ADDomain -Identity $trust.Target
$DomainSIDMapping.Add(
$TrustedDomain.DomainSID.Value,
$TrustedDomain.DNSRoot
)
} catch {
Write-Warning -Message "$_"
continue
}
}
"ForestTrust" {
Write-Verbose -Message "Processing forest trust: $($trust.Target)"
# ... (add code to handle external trusts here
}
"External" {
Write-Verbose -Message "Processing external trust: $($trust.Target)"
# ... (add code to handle external trusts here
}
#>
default {
try {
Write-Verbose -Message "Processing trust: $($trust.Target)"
$TrustedDomain = Get-ADDomain -Identity $trust.Target
$DomainSIDMapping.Add(
$TrustedDomain.DomainSID.Value,
$TrustedDomain.DNSRoot
)
} catch {
Write-Warning -Message "$_"
continue
}
}
} # end switch ($trust.TrustType)
} # end foreach ($trust in $Trusts)
} # end process
end {
$DomainSIDMapping
} # end end
} # end function

0 comments on commit 872e4f9

Please sign in to comment.