Skip to content

Instantly share code, notes, and snippets.

@IISResetMe
Last active April 10, 2024 06:30
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save IISResetMe/399a75cfccabc1a17d0cc3b5ae29f3aa to your computer and use it in GitHub Desktop.
Save IISResetMe/399a75cfccabc1a17d0cc3b5ae29f3aa to your computer and use it in GitHub Desktop.
Find-VulnerableSchemas.ps1
# Dictionary to hold superclass names
$superClass = @{}
# List to hold class names that inherit from container and are allowed to live under computer object
$vulnerableSchemas = [System.Collections.Generic.List[string]]::new()
# Resolve schema naming context
$schemaNC = (Get-ADRootDSE).schemaNamingContext
# Enumerate all class schemas
$classSchemas = Get-ADObject -LDAPFilter '(objectClass=classSchema)' -SearchBase $schemaNC -Properties lDAPDisplayName,subClassOf,possSuperiors
# Enumerate all class schemas that computer is allowed to contain
$computerInferiors = $classSchemas |Where-Object possSuperiors -eq 'computer'
# Populate superclass table
$classSchemas |ForEach-Object {
$superClass[$_.lDAPDisplayName] = $_.subClassOf
}
# Resolve class inheritance for computer inferiors
$computerInferiors |ForEach-Object {
$class = $cursor = $_.lDAPDisplayName
while($superClass[$cursor] -notin 'top'){
if($superClass[$cursor] -eq 'container'){
$vulnerableSchemas.Add($class)
break
}
$cursor = $superClass[$cursor]
}
}
# Outpupt list of vulnerable class schemas
$vulnerableSchemas
param(
[switch]$Force
)
if(-not $Force){
Write-Warning "This will cripple Exchange-related schema entries"
Write-Warning "DO NOT run this if you have an active Exchange organization in the current forest"
Write-Warning "Instead, apply the latest Exchange Server CU from Microsoft"
Write-Warning "If you've already removed all Exchange Server installations from the forest, go ahead and run this script with '-Force'"
return
}
# Discover schema NC
$rootDSE = Get-ADRootDSE
$schemaNC = $rootDSE.schemaNamingContext
# Discover schema master
$schemaMaster = Get-ADObject $schemaNC -Properties fSMORoleOwner | Get-ADDomainController -Identity { $_.fSMORoleOwner }
# Re-bind against RootDSE on schema master
$rootDSE = [ADSI]::new("LDAP://$($schemaMaster.HostName)/RootDSE")
# Prepare to refresh the schema!!!
$schemaRefresh = {
$rootDSE.Put("schemaUpdateNow", 1)
$rootDSE.SetInfo()
}
# Fetch msExchStorageGroup schema object
$schemaObject = Get-ADObject -LDAPFilter '(&(objectClass=classSchema)(lDAPDisplayName=msExchStorageGroup))' -SearchBase $schemaNC
# Update schema object
Set-ADObject -Identity $schemaObject.distinguishedName -Remove @{possSuperiors = 'computer'} -Server $schemaMaster
# Refresh schema
& $schemaRefresh
@browolf
Copy link

browolf commented Feb 7, 2022

What to do with this error running the update script?

Set-ADObject : Insufficient access rights to perform the operation

@IISResetMe
Copy link
Author

@browolf you need membership of Schema Admins (RID 518) in the forest root domain to modify schema objects

@billylepandaroux
Copy link

Hi,
could you tell me if i can use this script : we dont have an onpremise exchange server, but we use AADSync to synchronize our AD to M365
Thanx in advance

@billylepandaroux
Copy link

I would also like to know the answer to this...

despite having no answer from the author, i did it on my AD, no issue

@IISResetMe
Copy link
Author

@billylepandaroux No, this shouldn't affect AADSync at all :)

@winadminfvo
Copy link

@browolf you need membership of Schema Admins (RID 518) in the forest root domain to modify schema objects

I am Schema Admins but still get the error Set-ADObject : Insufficient access rights to perform the operation

@natiT
Copy link

natiT commented Jan 12, 2024

Hey,

on Update-msExchStorageGroupSchema.ps1 Line 18 I get the error that Get-ADDomainController does not accept pipeline inputs.

Runned this on PSVersion 7.1.0 maybe that was the Problem but well it's an easy fix.

$fsmoRoleOwner = (Get-ADObject $schemaNC -Properties fSMORoleOwner).fSMORoleOwner
$schemaMaster = Get-ADDomainController -Identity $fsmoRoleOwner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment