Public/DnsControl/Get-PiHoleDnsRecord.ps1
|
function Get-PiHoleDnsRecord { <# .SYNOPSIS Get local DNS records .DESCRIPTION Returns Pi-hole's local DNS records (A, AAAA, and CNAME) as a flat list of objects shaped the same way as Add-PiHoleDnsRecord/Remove-PiHoleDnsRecord, so the result can be piped straight into Remove-PiHoleDnsRecord. This is a DNS-specific convenience wrapper around Get-PiHoleConfig, which it calls internally - using that directly (.Dns.Hosts / .Dns.CnameRecords) is equivalent, just not already split into A/AAAA/CNAME or filterable by -Type/-Hostname. .PARAMETER PiHoleServer The URL to the PiHole Server, for example "http://pihole.domain.com:8080", or "http://192.168.1.100" .PARAMETER Password The API Password you generated from your PiHole server .PARAMETER Type Only return records of this kind: A (IPv4), AAAA (IPv6), or CNAME. If omitted, all are returned .PARAMETER Hostname Only return the record(s) for this exact hostname (the alias, for a CNAME). If omitted, every record is returned .PARAMETER IgnoreSsl Set to $true to skip SSL certificate validation .PARAMETER RawOutput This will dump the response instead of the formatted object .EXAMPLE Get-PiHoleDnsRecord -PiHoleServer "http://pihole.domain.com:8080" -Password "your-app-password" .EXAMPLE Get-PiHoleDnsRecord -PiHoleServer "http://pihole.domain.com:8080" -Password "your-app-password" -Type CNAME .EXAMPLE Get-PiHoleDnsRecord -PiHoleServer "http://pihole.domain.com:8080" -Password "your-app-password" -Hostname "test.local" | Remove-PiHoleDnsRecord -PiHoleServer "http://pihole.domain.com:8080" -Password "your-app-password" #> [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#get-/config')] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] param ( [Parameter(Mandatory = $true)] [System.URI]$PiHoleServer, [Parameter(Mandatory = $true)] [string]$Password, [ValidateSet('A', 'AAAA', 'CNAME')] [string]$Type, [string]$Hostname, [bool]$IgnoreSsl = $false, [bool]$RawOutput = $false ) try { $Config = Get-PiHoleConfig -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl -ErrorAction Stop if ($RawOutput) { $Object = [PSCustomObject]@{ Hosts = $Config.Dns.Hosts CnameRecords = $Config.Dns.CnameRecords } Write-Output $Object } else { $Records = foreach ($Entry in $Config.Dns.Hosts) { # Each entry is "<ip> <hostname>" - hostnames never contain spaces, so splitting # into at most 2 parts on the first space is safe even if an IPv6 address itself # cannot contain one. $Parts = $Entry.Split(' ', 2) $Address = $Parts[0] $RecordHostname = $Parts[1] $ParsedAddress = $null $IsIPv6 = [System.Net.IPAddress]::TryParse($Address, [ref]$ParsedAddress) -and $ParsedAddress.AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetworkV6 [PSCustomObject]@{ Type = if ($IsIPv6) { 'AAAA' } else { 'A' } Hostname = $RecordHostname IPv4Address = if ($IsIPv6) { $null } else { $Address } IPv6Address = if ($IsIPv6) { $Address } else { $null } Target = $null Ttl = $null } } $Records += foreach ($Entry in $Config.Dns.CnameRecords) { # Each entry is "<alias>,<target>[,<ttl>]" - the TTL segment is optional. $Parts = $Entry.Split(',') [PSCustomObject]@{ Type = 'CNAME' Hostname = $Parts[0] IPv4Address = $null IPv6Address = $null Target = $Parts[1] Ttl = if ($Parts.Count -gt 2) { [int]$Parts[2] } else { $null } } } if ($PSBoundParameters.ContainsKey('Type')) { $Records = $Records | Where-Object { $_.Type -eq $Type } } if ($PSBoundParameters.ContainsKey('Hostname')) { $Records = $Records | Where-Object { $_.Hostname -eq $Hostname } } Write-Output $Records } } catch { Write-Error -Message $_.Exception.Message } } |