forked from PyroTek3/PowerShell-AD-Recon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Get-PSADForestInfo
298 lines (244 loc) · 14.2 KB
/
Get-PSADForestInfo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
function Get-PSADForestInfo
{
<#
.SYNOPSIS
This script is used to gather information on the Active Directory environment.
PowerSploit Function: Get-PSADForestInfo
Author: Sean Metcalf, Twitter: @PyroTek3
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
Version: 0.31
.DESCRIPTION
This script is used to gather information on the Active Directory environment using system .Net calls and built-in PowerShell functionality.
REQUIRES: Active Directory user authentication. Standard user access is fine - admin access is not necessary.
Currently, the script performs the following actions:
* Identifies the current AD forest and lists Forest Mode & Forest FSMOs.
* Enumerates all domain details (including child domains).
* Domain details (for all domains including forest root) include:
- Netbios Name
- Domain SID
- Domain Mode
- Domain krbtgt Last Password Set Date
- Domain FSMOs
- Domain Password Policy
- Domain Trusts
- Child Domains
* Identifies AD & Exchange schema versions
* Enumerates AD Sites and provides Forest Subnet data
.EXAMPLE
Get-PSADForestInfo
This script is used to gather information on the Active Directory environment.
.NOTES
This script is used to gather information on the Active Directory environment.
.LINK
#>
Param
(
)
# Get RootDSE Info
$rootDSE = [adsi]"LDAP://rootDSE"
$rootDSEconfigurationNamingContext = $rootDSE.configurationNamingContext
$rootDSEcurrentTime = $rootDSE.currentTime ## Convert
$rootDSEdefaultNamingContext = $rootDSE.defaultNamingContext
$rootDSEdnsHostName = $rootDSE.dnsHostName
$rootDSEdomainControllerFunctionality = $rootDSE.domainControllerFunctionality
$rootDSEdomainFunctionality = $rootDSE.domainFunctionality ## Convert
$rootDSEdsServiceName = $rootDSE.dsServiceName
$rootDSEforestFunctionality = $rootDSE.forestFunctionality ## Convert
$rootDSEhighestCommittedUSN = $rootDSE.highestCommittedUSN
$rootDSEisGlobalCatalogReady = $rootDSE.isGlobalCatalogReady
$rootDSEisSynchronized = $rootDSE.isSynchronized
$rootDSEldapServiceName = $rootDSE.ldapServiceName
$rootDSEnamingContexts = $rootDSE.namingContexts
$rootDSErootDomainNamingContext = $rootDSE.rootDomainNamingContext
$rootDSEschemaNamingContext = $rootDSE.schemaNamingContext
$rootDSEserverName = $rootDSE.serverName
$rootDSEsubschemaSubentry = $rootDSE.subschemaSubentry
$rootDSEsupportedCapabilities = $rootDSE.supportedCapabilities
$rootDSEsupportedControl = $rootDSE.supportedControl
$rootDSEsupportedLDAPPolicies = $rootDSE.supportedLDAPPolicies
$rootDSEsupportedLDAPVersion = $rootDSE.supportedLDAPVersion
$rootDSEsupportedSASLMechanisms = $rootDSE.supportedSASLMechanisms
$ADForestInfo = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
$ADForestInfoName = $ADForestInfo.Name
$ADForestInfoSites = $ADForestInfo.Sites
$ADForestInfoGlobalCatalogs = $ADForestInfo.GlobalCatalogs
$ADForestInfoApplicationPartitions = $ADForestInfo.ApplicationPartitions
$ADForestInfoForestMode = $ADForestInfo.ForestMode
$ADForestInfoSchema = $ADForestInfo.Schema
$ADForestInfoSchemaRoleOwner = $ADForestInfo.SchemaRoleOwner
$ADForestInfoNamingRoleOwner = $ADForestInfo.NamingRoleOwner
$ADForestInfoRootDomain = $ADForestInfo.RootDomain
$ADDomainInfo = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$ADDomainInfoName = $ADDomainInfo.Name
$ADDomainInfoForest = $ADDomainInfo.Forest
$ADDomainInfoDomainControllers = $ADDomainInfo.DomainControllers
$ADDomainInfoChildren = $ADDomainInfo.Children
$ADDomainInfoDomainMode = $ADDomainInfo.DomainMode
$ADDomainInfoParent = $ADDomainInfo.Parent
$ADDomainInfoPdcRoleOwner = $ADDomainInfo.PdcRoleOwner
$ADDomainInfoRidRoleOwner = $ADDomainInfo.RidRoleOwner
$ADDomainInfoInfrastructureRoleOwner = $ADDomainInfo.InfrastructureRoleOwner
$LocalSiteInfo = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite()
$ADForestDomains = ([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()).domains
$ADForestPartitionsContainer = "CN=Partitions," + $rootDSEconfigurationNamingContext
<#
#######################################
# IN PROGRESS - AD Instantiation Date #
#######################################
#$ADForestInstatiationDate = Get-ADObject -SearchBase (Get-ADForest).PartitionsContainer `
#-LDAPFilter "(&(objectClass=crossRef)(systemFlags=3))" `
#-Property dnsRoot, nETBIOSName, whenCreated | Sort-Object whenCreated | Format-Table dnsRoot, nETBIOSName, whenCreated -AutoSize
$ADSISearcherFID = New-Object DirectoryServices.DirectorySearcher([ADSI]"")
$ADSISearcherFID.SearchRoot = "LDAP://CN=$ADForestPartitionsContainer"
$ADSISearcherFID.PageSize = 500
$ADSISearcherFID.Filter = "(&(objectClass=crossRef)(systemFlags=3))"
$ADForestInstatiationDateResults = $ADSISearcherFID.FindOne()
Write-Output "AD Forest Instatiation Date: $ADForestInstatiationDate"
#>
# Set Report Variables
$ADForestInfoReport = New-Object -TypeName System.Object
$ADSISearcher = New-Object System.DirectoryServices.DirectorySearcher
$ADSISearcher.SearchScope = "subtree"
$ADSISearcher.PropertiesToLoad.Add("nETBIOSName") > $Null
$ADSISearcher.SearchRoot = "LDAP://$ADForestPartitionsContainer"
$ADForestInfoReport | Add-Member -MemberType NoteProperty -Name ForestName -Value $ADForestInfoName
$ADForestInfoReport | Add-Member -MemberType NoteProperty -Name ForestMode -Value $ADForestInfoForestMode
$ADForestInfoReport | Add-Member -MemberType NoteProperty -Name ForestFSMOSchema -Value $ADForestInfoSchemaRoleOwner
$ADForestInfoReport | Add-Member -MemberType NoteProperty -Name ForestFSMODomNaming -Value $ADForestInfoNamingRoleOwner
# Get AD and Exchange Schema version
Write-Verbose "Create Schema Version hashtable `r "
$SchemaVersionTable =
@{
"13" = "Windows 2000 Schema" ;
"30" = "Windows 2003 Schema";
"31" = "Windows 2003 R2 Schema" ;
"39" = "Windows 2008 BETA Schema" ;
"44" = "Windows 2008 Schema" ;
"47" = "Windows 2008 R2 Schema" ;
"51" = "Windows Server 8 Developer Preview Schema" ;
"52" = "Windows Server 8 BETA Schema" ;
"56" = "Windows Server 2012 Schema" ;
"69" = "Windows Server 2012 R2 Schema" ;
"4397" = "Exchange 2000 RTM Schema" ;
"4406" = "Exchange 2000 SP3 Schema" ;
"6870" = "Exchange 2003 RTM Schema" ;
"6936" = "Exchange 2003 SP3 Schema" ;
"10637" = "Exchange 2007 RTM Schema" ;
"11116" = "Exchange 2007 RTM Schema" ;
"14622" = "Exchange 2007 SP2 & Exchange 2010 RTM Schema" ;
"14625" = "Exchange 2007 SP3 Schema" ;
"14726" = "Exchange 2010 SP1 Schema" ;
"14732" = "Exchange 2010 SP2 Schema" ;
"14734" = "Exchange 2010 SP3 Schema" ;
"15137" = "Exchange 2013 RTM Schema" ;
"15254" = "Exchange 2013 CU1 Schema" ;
"15281" = "Exchange 2013 CU2 Schema" ;
"15283" = "Exchange 2013 CU3 Schema" ;
"15292" = "Exchange 2013 SP1/CU4 Schema" ;
"15300" = "Exchange 2013 CU5 Schema" ;
"15303" = "Exchange 2013 CU6 Schema"
}
Write-Verbose "Get Exchange Forest Prep Version"
$RootDSE= ([ADSI]"").distinguishedName
$RootDSEExchangerangeUpper = ([ADSI]"LDAP://CN=ms-Exch-Schema-Version-Pt,CN=Schema,CN=Configuration,$RootDSE").rangeUpper
$RootDSEExchangeobjectVersion =([ADSI]"LDAP://cn=<ExhangeOrg>,cn=Microsoft Exchange,cn=Services,cn=Configuration,$RootDSE").objectVersion
$ExchangeSchemaVersionName = $SchemaVersionTable.Get_Item("$RootDSEExchangerangeUpper")
$ADForestInfoReport | Add-Member -MemberType NoteProperty -Name ExchangeSchemaVersionNum -Value $RootDSEExchangerangeUpper
$ADForestInfoReport | Add-Member -MemberType NoteProperty -Name ExchangeSchemaVersion -Value $ExchangeSchemaVersionName
Write-Verbose "Get AD Forest Prep Version"
$RootDSE= ([ADSI]"").distinguishedName
$RootDSEADObjectVersion =([ADSI]"LDAP://$rootDSEschemaNamingContext").objectVersion
$ADSchemaVersionName = $SchemaVersionTable.Get_Item("$RootDSEADObjectVersion")
$ADForestInfoReport | Add-Member -MemberType NoteProperty -Name ADSchemaVersionNum -Value $RootDSEADObjectVersion
$ADForestInfoReport | Add-Member -MemberType NoteProperty -Name ADSchemaVersion -Value $ADSchemaVersionName
# Get Tombstone Setting
Write-Verbose "Get Tombstone Setting `r"
$RootDSE= ([ADSI]"").distinguishedName
$RootDSEADTombstoneLifetime =([ADSI]"LDAP://CN=Directory Service,CN=Windows NT,CN=Services,$rootDSEconfigurationNamingContext")
$TombstoneLifetime = $RootDSEADTombstoneLifetime.tombstoneLifetime
$ADForestInfoReport | Add-Member -MemberType NoteProperty -Name TombstoneLifetime -Value $TombstoneLifetime
# Get AD Site List
Write-Verbose "Get AD Site List `r"
$ADSites = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().Sites
[int]$ADSitesCount = $ADSites.Count
$ADForestInfoReport | Add-Member -MemberType NoteProperty -Name ForestSites -Value $ADSitesCount
Write-Verbose "Processing AD Site & Subnet data "
$ADSitesItemSubnets = $Null
ForEach ($ADSitesItem in $ADSites)
{
[array]$ADSitesItemSubnetArray = $ADSitesItem.Subnets
ForEach ($ADSitesItemSubnetArrayItem in $ADSitesItemSubnetArray)
{ [array]$ADForestSiteSubnets += $ADSitesItemSubnetArrayItem.Name }
}
$ADForestInfoReport | Add-Member -MemberType NoteProperty -Name ForestSubnets -Value $ADForestSiteSubnets
$ADSISearcher = New-Object System.DirectoryServices.DirectorySearcher
$ADSISearcher.SearchScope = "subtree"
$ADSISearcher.PropertiesToLoad.Add("nETBIOSName") > $Null
$ADSISearcher.SearchRoot = "LDAP://$ADForestPartitionsContainer"
[array]$ALLADForestDomainControllers = $Null
$ALLADDomainInfoReport = @()
ForEach ($ADForestDomainsItem in $ADForestDomains)
{
$DomainChildrenList = $Null
[array]$ALLADForestDomainControllers += $ADForestDomainsItem.DomainControllers
$ADForestDomainsItemName = $ADForestDomainsItem.Name
$DomainDetail = [ADSI]"LDAP://$ADForestDomainsItemName"
$DomainDetailmaxPwdAgeValue = $DomainDetail.maxPwdAge.Value
$DomainDetailminPwdAgeValue = $DomainDetail.minPwdAge.Value
$DomainDetailmaxPwdAgeInt64 = $DomainDetail.ConvertLargeIntegerToInt64($DomainDetailmaxPwdAgeValue)
$DomainDetailminPwdAgeInt64 = $DomainDetail.ConvertLargeIntegerToInt64($DomainDetailminPwdAgeValue)
$MaxPwdAge = -$DomainDetailmaxPwdAgeInt64/(600000000 * 1440)
$MinPwdAge = -$DomainDetailminPwdAgeInt64/(600000000 * 1440)
$DomainDetailminPwdLength = $DomainDetail.minPwdLength
$DomainDetailpwdHistoryLength = $DomainDetail.pwdHistoryLength
$DomainDetaildistinguishedName = $DomainDetail.distinguishedName
#$DomainDetailrIDManagerReference = $DomainDetail.rIDManagerReference
$DomainDetailSID = (New-Object System.Security.Principal.SecurityIdentifier($DomainDetail.objectSid[0], 0)).Value
$ADForestDomainsDN = "DC=" + $ADForestDomainsItem.Name -Replace("\.",',DC=')
$ADSISearcher.Filter = "(nCName=$ADForestDomainsDN)"
$ADForestDomainsItemNetBIOSName = ($ADSISearcher.FindOne()).Properties.Item("nETBIOSName")
## Find Trust Objects
$ADTDOSearch = New-Object DirectoryServices.DirectorySearcher([ADSI]"")
$ADTDOSearch.SearchRoot = "LDAP://$ADForestDomainsDN"
$ADTDOSearch.PageSize = 500
$ADTDOSearch.Filter = "(ObjectClass=trustedDomain)"
$ADTrustArray = $ADTDOSearch.FindAll()
$AllADDomainTrusts = $Null
ForEach ($ADTrustArrayItem in $ADTrustArray)
{ [string]$AllADDomainTrusts = $ADTrustArrayItem.Properties.name }
$ADUserKRBSearch = New-Object DirectoryServices.DirectorySearcher([ADSI]"")
$ADUserKRBSearch.SearchRoot = "LDAP://$ADForestDomainsDN"
$ADUserKRBSearch.PageSize = 500
$ADUserKRBSearch.Filter = "(&(objectCategory=User)(name=krbtgt))"
$KRBADInfo = $ADUserKRBSearch.FindAll()
[string]$KRBADInfopwdlastsetInt8 = $KRBADInfo.Properties.pwdlastset
$KRBADInfopwdlastset = [DateTime]::FromFileTimeutc($KRBADInfopwdlastsetInt8)
ForEach ($ADForestDomainsItemChildrenItem in $ADForestDomainsItemChildren)
{
[string]$DomainChildrenList += $ADForestDomainsItemChildrenItem.Name
Write-Output " * $ADForestDomainsItemChildrenItemName"
}
$ADDomainInfoReport = New-Object -TypeName System.Object
$ADDomainInfoReport | Add-Member -MemberType NoteProperty -Name ForestName -Value $ADForestDomainsItemForest
$ADDomainInfoReport | Add-Member -MemberType NoteProperty -Name DomainName -Value $ADForestDomainsItem.Name
$ADDomainInfoReport | Add-Member -MemberType NoteProperty -Name NetbiosName -Value $ADForestDomainsItemNetBIOSName
$ADDomainInfoReport | Add-Member -MemberType NoteProperty -Name DomainSID -Value $DomainDetailSID
$ADDomainInfoReport | Add-Member -MemberType NoteProperty -Name DomainMode -Value $ADForestDomainsItemDomainMode
$ADDomainInfoReport | Add-Member -MemberType NoteProperty -Name DomainFSMOPDC -Value $ADForestDomainsItem.PdcRoleOwner
$ADDomainInfoReport | Add-Member -MemberType NoteProperty -Name DomainFSMORID -Value $ADForestDomainsItem.RidRoleOwner
$ADDomainInfoReport | Add-Member -MemberType NoteProperty -Name DomainFSMOInfra -Value $ADForestDomainsItem.InfrastructureRoleOwner
$ADDomainInfoReport | Add-Member -MemberType NoteProperty -Name DomainChildren -Value $ADForestDomainsItem.Children
$ADDomainInfoReport | Add-Member -MemberType NoteProperty -Name DomainTrusts -Value $ADTrustArray
$ADDomainInfoReport | Add-Member -MemberType NoteProperty -Name DomainMaxPwdAge -Value $MaxPwdAge
$ADDomainInfoReport | Add-Member -MemberType NoteProperty -Name DomainMinPwdAge -Value $MinPwdAge
$ADDomainInfoReport | Add-Member -MemberType NoteProperty -Name DomainPwdHistory -Value $DomainDetailpwdHistoryLength
$ADDomainInfoReport | Add-Member -MemberType NoteProperty -Name DomainMinPwdLen -Value $DomainDetailminPwdLength
$ADDomainInfoReport | Add-Member -MemberType NoteProperty -Name DomainkrbtgtPwdLastSet -Value $KRBADInfopwdlastset
[array]$ALLADDomainInfoReport += $ADDomainInfoReport
}
$ADForestInfoReport | Add-Member -MemberType NoteProperty -Name ForestDomainDetail -Value $ALLADDomainInfoReport
$ADForestInfoReport | Add-Member -MemberType NoteProperty -Name ForestDCs -Value $ALLADForestDomainControllers.Count
return $ADForestInfoReport
}