refactor(scripts): optimize system remediation and M365 export scripts

- teams: harden Classic Teams removal, protect New Teams, and clean HKU run keys
- dotnet: add bootstrapper EXE uninstall support and remove orphaned 3.1.* folders
- teams: add MSIX package targeting and version parsing for vulnerable New Teams builds
- m365: improve Graph SDK export speed, reuse sessions, and add null-safe handling
This commit is contained in:
mattspeer committed 2026-10-04 10:58:05 -05:00
1 parent 4fd95b76d6
commit 5ef82842f2
19 files changed
+1651 -1268

No files matched your search

+90
View File
@@ -0,0 +1,90 @@
<#
.SYNOPSIS
Audits active network adapters to verify malware-filtering DNS configuration.
.DESCRIPTION
Retrieves all connected network adapters ('Up' status) and checks whether their configured
DNS server addresses match an approved list of security-filtering DNS providers
(e.g., Quad9 or Cloudflare for Families).
Outputs a compressed JSON payload for RMM systems or Intune Custom Compliance discovery.
.PARAMETER ApprovedDnsServers
Array of IPv4 DNS server addresses considered compliant.
Defaults to Quad9 (9.9.9.9, 149.112.112.11) and Cloudflare Security/Family (1.1.1.2, 1.0.0.2, 1.1.1.3, 1.0.0.3).
.EXAMPLE
.\Test-DnsCompliance.ps1
.EXAMPLE
.\Test-DnsCompliance.ps1 -ApprovedDnsServers "9.9.9.9", "1.1.1.2"
.NOTES
Created: 2025-03-05
Modified: 2026-10-04
#>
[CmdletBinding()]
param (
[string[]]$ApprovedDnsServers = @(
"9.9.9.9", # Quad9 Primary (Malware + DNSSEC)
"149.112.112.11", # Quad9 Secondary (Malware + DNSSEC)
"1.1.1.2", # Cloudflare Security Primary (Malware)
"1.0.0.2", # Cloudflare Security Secondary (Malware)
"1.1.1.3", # Cloudflare Family Primary (Malware + Adult)
"1.0.0.3" # Cloudflare Family Secondary (Malware + Adult)
)
)
# 1. Retrieve all active/connected network adapters
$ActiveAdapters = Get-NetAdapter | Where-Object { $_.Status -eq 'Up' }
if (-not $ActiveAdapters) {
Write-Verbose "No active network adapters found on this endpoint."
$NoAdapterOutput = [ordered]@{
Compliant = $true
Reason = "No active network adapters found."
Adapters = @()
}
return ($NoAdapterOutput | ConvertTo-Json -Compress)
}
$IsOverallCompliant = $true
$AdapterAuditResults = [System.Collections.Generic.List[PSCustomObject]]::new()
# 2. Audit DNS server assignments per active interface
foreach ($Adapter in $ActiveAdapters) {
# Query assigned IPv4 DNS server addresses
$DnsConfig = Get-DnsClientServerAddress -InterfaceIndex $Adapter.InterfaceIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue
$ConfiguredServers = $DnsConfig.ServerAddresses
# Verify if configured DNS contains at least one approved security DNS IP
$MatchingServers = $ConfiguredServers | Where-Object { $ApprovedDnsServers -contains $_ }
$IsAdapterCompliant = ($MatchingServers.Count -gt 0)
# If any active adapter fails the check, mark the endpoint overall non-compliant
if (-not $IsAdapterCompliant) {
$IsOverallCompliant = $false
Write-Verbose "Adapter '$($Adapter.Name)' (Index: $($Adapter.InterfaceIndex)) is NON-COMPLIANT. Configured: $($ConfiguredServers -join ', ')"
}
else {
Write-Verbose "Adapter '$($Adapter.Name)' (Index: $($Adapter.InterfaceIndex)) is COMPLIANT. Configured: $($ConfiguredServers -join ', ')"
}
$AdapterAuditResults.Add([PSCustomObject]@{
AdapterName = $Adapter.Name
InterfaceIndex = $Adapter.InterfaceIndex
ConfiguredDns = $ConfiguredServers
IsCompliant = $IsAdapterCompliant
})
}
# 3. Construct summary object and output JSON
$ComplianceReport = [ordered]@{
Compliant = $IsOverallCompliant
TestedAt = (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
Adapters = $AdapterAuditResults
}
return ($ComplianceReport | ConvertTo-Json -Compress)