Skip to content

Commit 112c8e1

Browse files
committed
SID History Functions
1 parent e609e9f commit 112c8e1

File tree

3 files changed

+307
-0
lines changed

3 files changed

+307
-0
lines changed
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
function Get-TrustedDomainSIDMapping {
2+
<#
3+
.SYNOPSIS
4+
Get the SID and DNSRoot name of trusted domains and forests.
5+
6+
.DESCRIPTION
7+
This function retrieves the SID and DNSRoot name of trusted domains and forests in the current Active Directory forest.
8+
9+
.PARAMETER ManualEntry
10+
If specified, the user may manually provide a SID and DNS name to add to the list of trusted domains.
11+
12+
.EXAMPLE
13+
$SIDMappingTable = Get-TrustedDomainSIDMapping -ManualEntry 'S-1-5-21-1234567890-1234567890-1234567890', 'example.com' -Verbose
14+
15+
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.
16+
17+
.NOTES
18+
Author: Sam Erde, Sentinel Technologies, Inc.
19+
Version: 0.0.1
20+
Modified: 2024-11-14
21+
22+
To-Do:
23+
- Add support for trusted forests and external trusts.
24+
- Add support for manually including a CSV file with trusted domain information.
25+
- Add support for exporting a CSV file with trusted domain information.
26+
- Add support for taking an array of trusted domain SIDs and DNS root names as input for ManualEntry.
27+
28+
.LINK
29+
https://github.com/SamErde
30+
31+
.LINK
32+
https://linktr.ee/SamErde
33+
34+
.LINK
35+
https://www.sentinel.com/
36+
#>
37+
[CmdletBinding()]
38+
param (
39+
# If specified, the user may manually provide a SID and DNS name to add to the list of trusted domains.
40+
[Parameter(HelpMessage = 'Enter the SID and DNS name of a trusted domain in the format ''S-1-5-21-1234567890-1234567890-1234567890'', ''example.com''.')]
41+
[array]$ManualEntry
42+
)
43+
44+
begin {
45+
# Import the ActiveDirectory module if it is not already loaded.
46+
if (-not (Get-Module -Name ActiveDirectory)) {
47+
Write-Verbose -Message 'Importing ActiveDirectory module.'
48+
Import-Module ActiveDirectory
49+
Write-Verbose -Message '------------------------------'
50+
Write-Verbose -Message 'Beginning to process trusts...'
51+
}
52+
53+
# Create a dictionary to store domain SIDs with their corresponding DNS root names.
54+
$DomainSIDMapping = [ordered] @{}
55+
$CurrentDomain = (Get-ADDomain)
56+
$DomainSIDMapping.Add(
57+
$CurrentDomain.DomainSID.Value,
58+
$CurrentDomain.DNSRoot
59+
)
60+
61+
# If the user provided a manual entry, add it to the dictionary.
62+
if ($PSBoundParameters.ContainsKey('ManualEntry')) {
63+
Write-Verbose -Message "Manually entered SID: $($ManualEntry[0])"
64+
Write-Verbose -Message "Manually entered DNS root name: $($ManualEntry[1])"
65+
$DomainSIDMapping.Add(
66+
$ManualEntry[0],
67+
$ManualEntry[1]
68+
)
69+
}
70+
71+
$Trusts = Get-ADTrust -Filter *
72+
}
73+
74+
process {
75+
# Loop through all trusts and add the trusted domain SIDs and DNS root names to the dictionary.
76+
foreach ($trust in $Trusts) {
77+
# Need to see if checking SID and DNSRoot requires a different process for trusted forests vs trusted domains.
78+
switch ($trust.TrustType) {
79+
<#
80+
"DomainTrust" {
81+
Write-Verbose -Message "Processing domain trust: $($trust.Target)"
82+
try {
83+
Write-Verbose -Message "Processing trust: $($trust.Target)"
84+
$TrustedDomain = Get-ADDomain -Identity $trust.Target
85+
$DomainSIDMapping.Add(
86+
$TrustedDomain.DomainSID.Value,
87+
$TrustedDomain.DNSRoot
88+
)
89+
} catch {
90+
Write-Warning -Message "$_"
91+
continue
92+
}
93+
}
94+
"ForestTrust" {
95+
Write-Verbose -Message "Processing forest trust: $($trust.Target)"
96+
# ... (add code to handle external trusts here
97+
}
98+
"External" {
99+
Write-Verbose -Message "Processing external trust: $($trust.Target)"
100+
# ... (add code to handle external trusts here
101+
}
102+
#>
103+
default {
104+
try {
105+
Write-Verbose -Message "Processing trust: $($trust.Target)"
106+
$TrustedDomain = Get-ADDomain -Identity $trust.Target
107+
$DomainSIDMapping.Add(
108+
$TrustedDomain.DomainSID.Value,
109+
$TrustedDomain.DNSRoot
110+
)
111+
} catch {
112+
Write-Warning -Message "$_"
113+
continue
114+
}
115+
}
116+
} # end switch ($trust.TrustType)
117+
} # end foreach ($trust in $Trusts)
118+
} # end process
119+
120+
end {
121+
$DomainSIDMapping
122+
} # end end
123+
} # end function
124+
125+
126+
function Get-AllAdSidHistorySourceDomains {
127+
<#
128+
.SYNOPSIS
129+
Get a list of source domains from all Active Directory objects that have SID history.
130+
131+
.DESCRIPTION
132+
This function gets all Active Directory objects that have SID history and returns a list of source domain SIDs.
133+
134+
.EXAMPLE
135+
Get-AllAdSidHistorySourceDomains
136+
137+
.NOTES
138+
Author: Sam Erde, Sentinel Technologies, Inc.
139+
Version: 0.0.1
140+
Modified: 2024-11-14
141+
#>
142+
[CmdletBinding()]
143+
param (
144+
145+
)
146+
147+
begin {
148+
if (-not (Get-Module -Name ActiveDirectory)) {
149+
Write-Verbose -Message 'Importing ActiveDirectory module.'
150+
Import-Module ActiveDirectory
151+
Write-Verbose -Message '------------------------------'
152+
Write-Verbose -Message "Beginning ${MyInvocation.InvocationName}..."
153+
}
154+
155+
$DomainSIDs = New-Object -TypeName System.Collections.Generic.List[System.String]
156+
} # end begin
157+
158+
process {
159+
# Get all ActiveDirectory objects that have SID history.
160+
$AllSIDHistory = Get-ADObject -Filter { SIDHistory -like '*' } -Properties SIDHistory | Select-Object -ExpandProperty SIDHistory
161+
162+
foreach ($SID in $AllSIDHistory) {
163+
$DomainSIDs.Add($SID.Substring(0, $SID.LastIndexOf('-')))
164+
}
165+
} # end process
166+
167+
end {
168+
169+
} # end end
170+
171+
} # end function
172+
173+
174+
function Get-AllADSIDHistoryDetails {
175+
[CmdletBinding()]
176+
param ()
177+
178+
begin {
179+
if (-not (Get-Module -Name ActiveDirectory)) {
180+
Write-Verbose -Message 'Importing ActiveDirectory module.'
181+
Import-Module ActiveDirectory
182+
Write-Verbose -Message '------------------------------'
183+
Write-Verbose -Message "Beginning ${MyInvocation.InvocationName}..."
184+
}
185+
186+
$DomainSIDMapping = Get-TrustedDomainSIDMapping
187+
$SourceDomainAssociatedObjects = @{}
188+
} # end begin
189+
190+
process {
191+
# Get all Active Directory objects that have a value in SID history.
192+
$ADObjectsWithSIDHistory = Get-ADObject -Filter 'SIDHistory -like "*"' -Properties SIDHistory
193+
194+
# Loop through each ADObject and loop through each SID history item on that object.
195+
# For each SID history item, remove the RID and add the domain SID to the $SourceDomains hash table.
196+
foreach ($ADObject in $ADObjectsWithSIDHistory) {
197+
foreach ($SIDHistory in $ADObject.SIDHistory) {
198+
$DomainSID = $SIDHistory.Substring(0, $SIDHistory.LastIndexOf('-'))
199+
# If the domain SID is in the $DomainSIDMapping hash table, use the domain name as the key. If not, use the DomainSID as the key in the $SourceDomains hash table.
200+
$Domain = if ($DomainSIDMapping[$DomainSID]) {
201+
$DomainSIDMapping[$DomainSID].Value
202+
} else {
203+
$DomainSID
204+
}
205+
# Add the domain name as the key and the ADObject as the value to the $SourceDomainAssociatedObjects hash table.
206+
$SourceDomainAssociatedObjects.Add(
207+
$Domain,
208+
([System.Collections.Generic.List[object]]).Add($ADObject)
209+
)
210+
}
211+
}
212+
} # end process
213+
214+
end {
215+
$SourceDomainAssociatedObjects
216+
}
217+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
function Get-AllADSIDHistoryDetails {
2+
[CmdletBinding()]
3+
param ()
4+
5+
begin {
6+
if (-not (Get-Module -Name ActiveDirectory)) {
7+
Write-Verbose -Message 'Importing ActiveDirectory module.'
8+
Import-Module ActiveDirectory
9+
Write-Verbose -Message '------------------------------'
10+
Write-Verbose -Message "Beginning ${MyInvocation.InvocationName}..."
11+
}
12+
13+
$DomainSIDMapping = Get-TrustedDomainSIDMapping
14+
$SourceDomainAssociatedObjects = @{}
15+
} # end begin
16+
17+
process {
18+
# Get all Active Directory objects that have a value in SID history.
19+
$ADObjectsWithSIDHistory = Get-ADObject -Filter 'SIDHistory -like "*"' -Properties SIDHistory
20+
21+
# Loop through each ADObject and loop through each SID history item on that object.
22+
# For each SID history item, remove the RID and add the domain SID to the $SourceDomains hash table.
23+
foreach ($ADObject in $ADObjectsWithSIDHistory) {
24+
foreach ($SIDHistory in $ADObject.SIDHistory) {
25+
$DomainSID = $SIDHistory.Substring(0, $SIDHistory.LastIndexOf('-'))
26+
# If the domain SID is in the $DomainSIDMapping hash table, use the domain name as the key. If not, use the DomainSID as the key in the $SourceDomains hash table.
27+
$Domain = if ($DomainSIDMapping[$DomainSID]) {
28+
$DomainSIDMapping[$DomainSID].Value
29+
} else {
30+
$DomainSID
31+
}
32+
# Add the domain name as the key and the ADObject as the value to the $SourceDomainAssociatedObjects hash table.
33+
$SourceDomainAssociatedObjects.Add(
34+
$Domain,
35+
([System.Collections.Generic.List[object]]).Add($ADObject)
36+
)
37+
}
38+
}
39+
} # end process
40+
41+
end {
42+
$SourceDomainAssociatedObjects
43+
}
44+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
function Get-AllADSIDHistorySourceDomains {
2+
<#
3+
.SYNOPSIS
4+
Get a list of source domains from all Active Directory objects that have SID history.
5+
6+
.DESCRIPTION
7+
This function gets all Active Directory objects that have SID history and returns a list of source domain SIDs.
8+
9+
.EXAMPLE
10+
Get-AllAdSidHistorySourceDomains
11+
12+
.NOTES
13+
Author: Sam Erde, Sentinel Technologies, Inc.
14+
Version: 0.0.1
15+
Modified: 2024-11-14
16+
#>
17+
[CmdletBinding()]
18+
param (
19+
20+
)
21+
22+
begin {
23+
if (-not (Get-Module -Name ActiveDirectory)) {
24+
Write-Verbose -Message 'Importing ActiveDirectory module.'
25+
Import-Module ActiveDirectory
26+
Write-Verbose -Message '------------------------------'
27+
Write-Verbose -Message "Beginning ${MyInvocation.InvocationName}..."
28+
}
29+
30+
$DomainSIDs = New-Object -TypeName System.Collections.Generic.List[System.String]
31+
} # end begin
32+
33+
process {
34+
# Get all ActiveDirectory objects that have SID history.
35+
$AllSIDHistory = Get-ADObject -Filter { SIDHistory -like '*' } -Properties SIDHistory | Select-Object -ExpandProperty SIDHistory
36+
37+
foreach ($SID in $AllSIDHistory) {
38+
$DomainSIDs.Add($SID.Substring(0, $SID.LastIndexOf('-')))
39+
}
40+
} # end process
41+
42+
end {
43+
44+
} # end end
45+
46+
} # end function

0 commit comments

Comments
 (0)