diff --git a/Get-PSADForestInfo b/Get-PSADForestInfo new file mode 100644 index 0000000..4d51ffd --- /dev/null +++ b/Get-PSADForestInfo @@ -0,0 +1,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=,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 + +}