Detecting DNS Configuration Problems Affecting Intune · CloudEngineerHub
Detection & Remediation9 min read4 views
Detecting DNS Configuration Problems Affecting Intune with PowerShell
Detect broken name resolution before it breaks enrollment and sync: resolve real Microsoft endpoints and audit adapter DNS with a read-only PowerShell script.
C
CloudEngineerHub Team
Published: September 7, 2026· Last Updated: September 28, 2026·9 min read
Every Intune conversation a Windows device has — enrollment, token acquisition, policy
sync, Win32 app download — starts with a name lookup. When DNS breaks or drifts on a
client, the failure mode is maddeningly inconsistent: some devices at a site work while
others stall mid-enrollment, hybrid join tests time out, and the admin center shows a
scatter of devices that check in only after repeated reboots. Nine times out of ten the
root cause is not the Intune service but a resolver configuration problem on or near the
device: stale DHCP scopes, a VPN client that wrote placeholder addresses, or adapters left
with no DNS servers at all.
Visual Walkthrough
The engine behind every “Detect with PowerShell” runbook on this site.
Exit 1 flips the device into the remediation queue for this package.
remediate
3
Remediation executes
Fix script runs silently as SYSTEM with a 5-minute budget.
verify
4
Re-run detection
The same detection script must now exit 0 — proof, not hope.
telemetry
5
Results report
Per-device outcome lands in Reports → Remediations for trend analysis.
6
Repeat on schedule
The loop continues — drift gets caught the day it appears.
Continuous cycle
Proactive Remediations — The Detect → Fix → Verify Loop. 1. Detection script runs: Scheduled (daily/hourly): exit 0 healthy, exit 1 unhealthy — nothing more. — 2. Verdict: unhealthy: Exit 1 flips the device into the remediation queue for this package. — 3. Remediation executes: Fix script runs silently as SYSTEM with a 5-minute budget. — 4. Re-run detection: The same detection script must now exit 0 — proof, not hope. — 5. Results report: Per-device outcome lands in Reports → Remediations for trend analysis. — 6. Repeat on schedule: The loop continues — drift gets caught the day it appears.
C
CloudEngineerHub Team
Author
The CloudEngineerHub editorial team — Microsoft endpoint management and cloud engineers writing hands-on guides on Intune, Azure, Entra ID, Autopilot, Defender and PowerShell. Every article is reviewed against current Microsoft documentation.
This article provides a read-only detection script that attacks the problem from both
ends. It resolves three real management hostnames — manage.microsoft.com,
login.microsoftonline.com, and enterpriseregistration.windows.net — and then audits
the DNS server configuration of every connected physical adapter, flagging adapters with
no servers or known-bad placeholders such as 0.0.0.0. Deployed as a detection-only
package, it gives you per-device evidence of where name resolution is actually failing.
Symptoms
DNS problems mimic almost every other Intune failure mode, but a few patterns recur:
Enrollment, Autopilot, or hybrid join attempts hang or fail with network or timeout errors on some devices only.
Devices check in irregularly, or a whole site drops off the "last check-in" report.
Users report slow sign-ins; authentication to Microsoft 365 apps takes visibly longer.
nslookup on the device returns odd answers, timeouts, or 0.0.0.0 as the server.
The problems began after a VPN rollout, subnet migration, or DHCP scope change.
If one site is affected and others are not, suspect the resolvers that site hands out
before anything else.
Possible Causes
Adapters with no DNS servers configured
Static IPs applied by hand, reimaged machines, or botched network profile scripts can
leave a connected adapter with an empty server list. The device then has no resolver for
anything beyond cached entries and luck, and management endpoints never resolve.
Placeholder addresses such as 0.0.0.0
VPN clients, filter drivers, and aggressive "privacy" or debloat scripts sometimes write
0.0.0.0 into the adapter's server list. Windows treats these as unusable answers, and
lookups fall back in ways that are slow at best and broken at worst.
The DNS Client service is not running
Dnscache stopped or disabled breaks the normal resolution pipeline and the cache. This
is rare on managed devices but appears after tampering or broken hardening scripts.
Upstream resolver problems
The adapter's configured servers answer, but they forward to dead upstreams or stale
root hints. The device-side configuration looks fine; queries for external names fail
or crawl. This post detects the symptom, and your network team owns the fix.
NRPT rules and VPN split DNS
Intune and Always On VPN can add Name Resolution Policy Table rules that steer specific
names to internal resolvers. If those resolvers are unreachable, only the affected names
fail. Resolve-DnsName reflects the effective pipeline, so the detection sees the same
failure the device sees.
Detection Script
The script is read-only and finishes in seconds to a minute depending on resolver health:
it confirms the DNS Client service, resolves three real Microsoft management hostnames
with per-host timing, and inspects connected physical adapters for missing or suspicious
DNS server entries.
PowerShell
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
#Requires -RunAsAdministrator
[CmdletBinding()]
param(
[string[]]$EndpointHostnames = @(
'manage.microsoft.com',
'login.microsoftonline.com',
'enterpriseregistration.windows.net'
),
[double]$MaxResolutionSeconds = 5.0,
[string[]]$SuspiciousDnsAddresses = @('0.0.0.0')
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
<#
.SYNOPSIS
Detection script: verifies that real Intune/Entra management hostnames resolve
and that connected network adapters carry sane DNS server configuration.
.NOTES
Intended for Intune Scripts and Remediations, 64-bit SYSTEM context.
This script NEVER changes the system. Exit 0 = all hostnames resolve and
adapter DNS is sane, 1 = resolution failure or suspicious adapter DNS,
2 = DNS Client (Dnscache) service not running, 3 = unexpected error.
The hostnames are real Microsoft endpoints used by Intune enrollment,
authentication, and policy sync. Slow-but-successful resolutions above
$MaxResolutionSeconds are logged as WARN but do not fail the device:
verdicts stay tied to resolution success, not latency.
#>$logDir = 'C:\ProgramData\Company\Logs'$logFile = Join-Path $logDir'DnsDetection.log'function Write-DetectionLog {
param([Parameter(Mandatory)][string] $Level, [Parameter(Mandatory)][string] $Message)
if (-not (Test-Path $logDir)) { New-Item -Path$logDir -ItemType Directory -Force | Out-Null }
"$([DateTime]::UtcNow.ToString('o')) [$Level] $Message" | Out-File -FilePath$logFile -Append -Encoding utf8
}
function Test-HostnameResolution {
param([Parameter(Mandatory)][string] $Hostname)
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
$answers = $nulltry {
$answers = Resolve-DnsName -Name$Hostname -ErrorAction Stop
}
catch {
$answers = $null
}
$stopwatch.Stop()
$ipAddresses = @()
if ($null -ne$answers) {
foreach ($recordin @($answers)) {
$names = @($record.PSObject.Properties.Name)
if ($names -contains'IPAddress') { $ipAddresses += [string]$record.IPAddress }
}
}
return [pscustomobject] @{
Hostname = $Hostname
Resolved = ($ipAddresses.Count -gt0)
Addresses = ($ipAddresses -join', ')
ElapsedSeconds = [math]::Round($stopwatch.Elapsed.TotalSeconds, 2)
}
}
function Get-AdapterDnsFindings {
# Inspect physical adapters that are Up: no DNS servers at all, or known-bad # placeholder addresses such as 0.0.0.0, are configuration problems.$findings = New-Object System.Collections.Generic.List[string]
$adapters = Get-NetAdapter -Physical -ErrorAction SilentlyContinue | Where-Object { $_.Status -eq'Up' }
foreach ($adapterin @($adapters)) {
$serverConfig = Get-DnsClientServerAddress -InterfaceIndex$adapter.ifIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue
$servers = @()
if ($null -ne$serverConfig) {
foreach ($configin @($serverConfig)) { $servers += @($config.ServerAddresses) }
}
$label = "$($adapter.Name) (ifIndex $($adapter.ifIndex))"if ($servers.Count -eq0) {
$findings.Add("$label has no IPv4 DNS servers configured")
continue
}
foreach ($badin$SuspiciousDnsAddresses) {
if ($servers -contains$bad) {
$findings.Add("$label lists suspicious DNS server $bad (servers: $($servers -join ', '))")
}
}
}
return$findings
}
try {
Write-DetectionLog 'INFO''DNS detection run started.' # ---- Check 1: DNS Client service ----$dnsCacheService = Get-Service -Name Dnscache -ErrorAction SilentlyContinue
if ($null -eq$dnsCacheService -or$dnsCacheService.Status -ne'Running') {
$statusText = 'not installed'if ($null -ne$dnsCacheService) { $statusText = $dnsCacheService.Status.ToString() }
Write-DetectionLog 'ERROR'"DNS Client service (Dnscache) is $statusText - name resolution cannot be trusted."
exit 2
}
Write-DetectionLog 'INFO''DNS Client service (Dnscache) is Running.' # ---- Check 2: resolve real management endpoints ----$failedHostnames = New-Object System.Collections.Generic.List[string]
$resolvedHostnames = 0foreach ($hostnamein$EndpointHostnames) {
$result = Test-HostnameResolution -Hostname$hostnameif ($result.Resolved) {
$resolvedHostnames++
if ($result.ElapsedSeconds -gt$MaxResolutionSeconds) {
Write-DetectionLog 'WARN'"$hostname resolved to $($result.Addresses) in $($result.ElapsedSeconds)s (above ${MaxResolutionSeconds}s threshold) - monitor for resolver latency."
}
else {
Write-DetectionLog 'INFO'"$hostname resolved to $($result.Addresses) in $($result.ElapsedSeconds)s."
}
}
else {
$failedHostnames.Add($hostname)
Write-DetectionLog 'ERROR'"$hostname FAILED to resolve after $($result.ElapsedSeconds)s."
}
}
Write-DetectionLog 'INFO'"Resolution summary: $resolvedHostnames of $($EndpointHostnames.Count) hostnames resolved." # ---- Check 3: adapter DNS sanity ----$dnsFindings = Get-AdapterDnsFindings
foreach ($findingin$dnsFindings) {
Write-DetectionLog 'ERROR'"Adapter DNS problem: $finding"
}
if ($dnsFindings.Count -eq0) {
Write-DetectionLog 'INFO''All connected physical adapters have sane IPv4 DNS server configuration.'
}
if ($failedHostnames.Count -gt0 -or$dnsFindings.Count -gt0) {
Write-DetectionLog 'ERROR''DNS configuration problem detected.'
exit 1
}
Write-DetectionLog 'INFO''DNS configuration check passed.'
exit 0
}
catch {
Write-DetectionLog 'ERROR'"Unexpected failure: $($_.Exception.Message)"
exit 3
}
finally {
Write-DetectionLog 'INFO''DNS detection run finished.'
}
Detection Logic
The script evaluates the resolution pipeline from service to configuration:
DNS Client service.Get-Service Dnscache must report Running. A stopped or
disabled cache service is a different class of problem than a bad server list, so it
gets its own exit code.
Hostname resolution. For each entry in $EndpointHostnames, the script calls
Resolve-DnsName inside a stopwatch, collects any IPAddress properties from the
answer records, and requires a non-empty set. CNAME chains are handled naturally: only
records that actually carry an address count. Each result is logged with the resolved
addresses and elapsed seconds.
Resolution latency threshold. When a lookup succeeds but takes longer than
$MaxResolutionSeconds (default 5 seconds), the script logs a WARN line. The device
still passes — a slow resolver is a quality problem worth watching, not proof of a
broken configuration — and the WARN lines give you trend data before it becomes an
outage.
Adapter DNS sanity.Get-NetAdapter -Physical filters to connected physical
adapters; for each, Get-DnsClientServerAddress -AddressFamily IPv4 must return at
least one server, and none of the servers may appear in $SuspiciousDnsAddresses
(default 0.0.0.0). Findings are logged per adapter by name and interface index.
The hostname test reflects the effective resolution path — adapter settings, NRPT rules,
and split DNS included — while the adapter audit catches configuration mistakes that have
not yet caused a visible failure. Together they separate "names don't resolve" from "names
resolve through a setup that will break next week".
Remediation Script
There is no remediation script, intentionally. DNS server configuration on a managed
device should arrive from DHCP, your network policy, the VPN client, or Intune's own
settings catalog — never from a standalone script that writes adapter values. A
remediation that hardcoded resolver addresses would fight DHCP leases, break at sites
with different resolvers, and mask the underlying configuration management gap. Treat
each exit 1 as a finding with a device name, adapter name, and failing hostname
attached, and route it to whoever owns the DHCP scopes or VPN profiles.
Deploying Through Intune
Deploy as a detection-only package:
In the Microsoft Intune admin center, go to Devices → Scripts and remediations
and select + Add on the Windows 10/11 tab.
On Basics, name it Detect - DNS configuration for Intune endpoints and describe
the scope: read-only name resolution tests plus adapter audit.
On Detection script, upload detect.ps1. Set Run script in 64-bit PowerShell:
Yes and Run this script using signed-on credentials: No so it runs as SYSTEM.
Leave Remediation script set to No remediation script.
Leave Enforce script signature check: No unless your organization signs internal
scripts and deploys the certificates.
On Schedule, choose Every 1 day during network changes, then Every week
for steady state. DNS drift is rare day to day but painful when it happens.
On Assignments, start with a test ring, then broaden to device groups that
represent your physical sites so results can be compared per location.
Review and create, then check Device status after the first run window.
Post-specific notes:
Signed-on credentials: No. Name resolution and adapter enumeration are
machine-scoped; user context adds noise, not signal.
The script makes three outbound DNS queries per run. That volume is trivial, but do
not schedule it more often than hourly.
If you use per-site resolvers with different latency profiles, adjust
$MaxResolutionSeconds in the script header before deployment so WARN lines mean
something in your environment.
Visual Walkthrough
VPN/ExpressRoute troubleshooting that starts at Layer 1 and ends at policy.
Decision TreeHybrid Connectivity Debug — Tunnel to Wire5/5
Decision gate
Where does the path break?
Test from the device outward — never assume the far end.
Tunnel up, app broken
1
IPsec/ER healthy
BGP peers up, routes exchanged both directions.
2
NSG / firewall inspect
Rules on subnet + appliance checked for the flow.
3
App-level check
DNS split, proxy PAC, TLS chain verified.
4
Fix + document
Change controlled, path tested, runbook updated.
Tunnel down
1
Gateway health
VPN GW / ER circuit status + provider ticket check.
Intune treats any non-zero detection result as "remediation needed". With no remediation
script, the status simply marks the device in the script report.
Code
Meaning
0
All management hostnames resolved; connected adapters have sane DNS configuration
1
At least one hostname failed to resolve, or an adapter has no/suspicious DNS servers
2
DNS Client service (Dnscache) is not running
3
Unexpected script error — inspect the log
Logging
Results go to C:\ProgramData\Company\Logs\DnsDetection.log. Each run writes a start and
finish line, one INFO line per hostname with resolved addresses and elapsed seconds, WARN
lines for slow resolutions, ERROR lines for failures and adapter findings, and a summary
count. Lines are small and runs are short, so the file grows slowly; apply your standard
log rotation if you need a cap. When a device logs resolution failures, cross-check
whether the same device fails the proxy and connectivity checks from the companion posts
to separate resolver problems from transport problems.
Troubleshooting the Script
Everything fails on one device but works interactively. Compare contexts: the
script runs as SYSTEM. If a security agent blocks Resolve-DnsName or network
inspection for SYSTEM processes, the script sees a different path than your console
session.
Adapters flagged that look fine in the UI. The audit covers connected physical
adapters only; virtual adapters, tunnels, and loopbacks are excluded on purpose. If
your fleet uses VPN tunnels as the primary path, extend the filter deliberately rather
than by accident.
All hostnames fail at one site. Look at the DHCP scope and the resolvers that site
hands out before touching the devices; three simultaneous failures point upstream.
Exit 2 on a hardened device. Something disabled Dnscache. Find the hardening
script or policy that did it — the detection did exactly its job.
Script exits 3 under AppLocker or WDAC. Blocking rules for Resolve-DnsName's
underlying module or the script itself need your security team's review before broad
rollout.
How to Validate the Fix
On a healthy device, run the script in an elevated 64-bit PowerShell console. Expect
exit 0, three INFO lines with resolved addresses, and the "adapters have sane" line.
In a lab VM, set an adapter's DNS to 0.0.0.0 (or clear it) and re-run. Expect exit
1 with the adapter finding in the log.
Point a test VM at a resolver that black-holes external names. Expect exit 1 with
per-hostname failure lines naming exactly which endpoint broke.
In the admin center, confirm the device shows the expected status under the package's
Device status view after its next sync.
After the network team corrects DHCP scopes or VPN DNS settings, re-run detection on
affected devices and confirm they flip to exit 0 before closing the incident.
Production Considerations
Execution context. Runs as SYSTEM in 64-bit Windows PowerShell. No user data is
touched and no credentials are involved.
Idempotency. Strictly read-only: three DNS queries, service status, and adapter
enumeration. Nothing is written anywhere except the log.
Side effects. DNS queries to real Microsoft endpoints are ordinary outbound
traffic. Latency thresholds are logging-only, so the script cannot flap device status
on a congested network.
Environment sensitivity. The default hostname set covers Intune management,
Entra authentication, and device registration. If your tenant uses sovereign clouds,
adjust the hostnames in the script header to match your region's documented endpoints
before rollout.
Have your PowerShell automation SME and security team review the script and validate
it in a test ring before broad production rollout, consistent with your script signing
and review policy.
Why use Resolve-DnsName instead of nslookup?Resolve-DnsName is the Windows PowerShell native cmdlet: its output is objects, it
exposes the IPAddress property cleanly, and it honors the same effective resolution
pipeline — including NRPT and split DNS rules — that the device's real traffic uses.
Parsing nslookup text output in a script is brittle and adds no information.
Why does 0.0.0.0 in the DNS server list matter if lookups still work?
Windows ignores 0.0.0.0 as an unusable address, so any working lookups come from other
adapters or fallback behavior. The entry itself is evidence that something — usually a
VPN client or cleanup script — wrote a placeholder into the configuration, and it
predictably breaks when the working path disappears.
A hostname resolves slowly but the device passes. Is that OK?
Passing, yes; ideal, no. The script's verdict is tied to resolution success so that a
busy resolver cannot flap device status, but the WARN line with the elapsed time lands in
the log for exactly this situation. If WARN lines accumulate for a site, raise it with
your network team before the resolver degrades further.
Comments
0No comments yet — be the first to share your thoughts.