Public/Get-DNSFilterStatus.ps1
|
function Get-DNSFilterStatus { <# .SYNOPSIS Reports whether the DNSFilter roaming client is installed and which DNS servers it's actually using. .DESCRIPTION DNSFilter's Windows roaming client (a.k.a. "DNS Agent") binds a local DNS proxy to 127.0.0.1 and forwards queries upstream to resolvers of its own choosing. Because Windows itself is pointed at the loopback address, tools like Get-DnsClientServerAddress and ipconfig /all only ever show 127.0.0.1 - the real upstream servers are hidden inside the agent's own configuration file. This function locates that configuration file (appsettings.json, which lives under a few different ProgramData folder names depending on branding/version), reads its LoopbackProxy.LocalResolvers list, and reports it alongside the agent's install status. It also checks the Windows service as a fallback so installs can still be flagged even if the config file has moved. No administrator privileges are required; ProgramData is world-readable. .PARAMETER ConfigPath Overrides the automatic search and reads the given appsettings.json path directly. Useful for testing or nonstandard install locations. .EXAMPLE Get-DNSFilterStatus Installed ConfigPath DNSServers --------- ---------- ---------- True C:\ProgramData\DNS Agent\Settings\appsettings.json {192.168.100.5, 192.168.100.10} .EXAMPLE (Get-DNSFilterStatus).DNSServers Returns just the list of upstream DNS servers the agent is forwarding to. .EXAMPLE Get-DNSFilterStatus -ConfigPath 'D:\backup\appsettings.json' Reads a config file from a nonstandard location instead of searching the default ProgramData paths. .OUTPUTS PSCustomObject Installed (bool), DNSServers (string[]), ConfigPath (string). .LINK https://github.com/DailenG/DNSFilterStatus #> [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter()] [string]$ConfigPath ) process { $result = [PSCustomObject]@{ PSTypeName = 'DNSFilterStatus.AgentStatus' Installed = $false DNSServers = @() ConfigPath = $null } $foundPath = if ($ConfigPath) { if (Test-Path -LiteralPath $ConfigPath -PathType Leaf) { $ConfigPath } else { $null } } else { Resolve-DNSFilterConfigPath } if ($foundPath) { $result.ConfigPath = $foundPath $result.Installed = $true try { $settings = Get-Content -LiteralPath $foundPath -Raw | ConvertFrom-Json -ErrorAction Stop if ($settings.LoopbackProxy.LocalResolvers) { $result.DNSServers = @($settings.LoopbackProxy.LocalResolvers) } else { Write-Warning "Config file found at '$foundPath' but it has no LoopbackProxy.LocalResolvers entry." } } catch { Write-Warning "Config file found at '$foundPath' but could not be parsed as JSON: $($_.Exception.Message)" } } elseif (-not $ConfigPath) { # No config file at any known location. Fall back to the service so an # install can still be reported even though the DNS server list can't be. $service = Get-DNSFilterAgentService if ($service) { $result.Installed = $true Write-Warning "The '$($service.Name)' service is present, but its config file was not found in any known ProgramData location. DNS server list is unavailable." } } return $result } } |