From 9cf6a541ef647fe0bf1637309976ef1fc08c28a5 Mon Sep 17 00:00:00 2001 From: Mike Madeja Date: Wed, 30 Sep 2026 19:44:22 -0500 Subject: [PATCH 1/3] feat: add remaining Authentication API endpoints Adds Get-PiHoleAuthStatus (GET /auth), Get-PiHoleAuthTotp (GET /auth/totp), and New-PiHoleAppPassword (GET /auth/app), completing the Authentication API area. Get-PiHoleAuthStatus's -Password is optional, unlike every other function in the module: its real value is checking whether a Pi-hole requires a login at all for the calling client, which only works when called without credentials. Passing -Password instead checks the status of a real login. New-PiHoleAppPassword only generates a candidate password/hash pair - confirmed via testing that it has no effect, including no session invalidation, until the returned hash is explicitly applied via config, despite the API's own description text suggesting otherwise. Co-Authored-By: Claude Sonnet 5 --- PiHoleShell/PiHoleShell.psm1 | 2 +- .../Authentication/Get-PiHoleAuthStatus.ps1 | 82 ++++ .../Authentication/Get-PiHoleAuthTotp.ps1 | 76 ++++ .../Authentication/New-PiHoleAppPassword.ps1 | 76 ++++ README.md | 3 + docs/EXAMPLES.md | 423 ++++++++++-------- ...Get-PiHoleAuthStatus.Integration.Tests.ps1 | 51 +++ .../Get-PiHoleAuthTotp.Integration.Tests.ps1 | 42 ++ ...ew-PiHoleAppPassword.Integration.Tests.ps1 | 58 +++ tools/Update-ExampleOutput.ps1 | 14 + 10 files changed, 643 insertions(+), 184 deletions(-) create mode 100644 PiHoleShell/Public/Authentication/Get-PiHoleAuthStatus.ps1 create mode 100644 PiHoleShell/Public/Authentication/Get-PiHoleAuthTotp.ps1 create mode 100644 PiHoleShell/Public/Authentication/New-PiHoleAppPassword.ps1 create mode 100644 tests/Authentication/Get-PiHoleAuthStatus.Integration.Tests.ps1 create mode 100644 tests/Authentication/Get-PiHoleAuthTotp.Integration.Tests.ps1 create mode 100644 tests/Authentication/New-PiHoleAppPassword.Integration.Tests.ps1 diff --git a/PiHoleShell/PiHoleShell.psm1 b/PiHoleShell/PiHoleShell.psm1 index 6482163..2424610 100644 --- a/PiHoleShell/PiHoleShell.psm1 +++ b/PiHoleShell/PiHoleShell.psm1 @@ -18,7 +18,7 @@ Export-ModuleMember -Function @( #Actions 'Update-PiHoleActionsGravity', 'Invoke-PiHoleFlushNetwork', 'Invoke-PiHoleFlushLogs', 'Restart-PiHoleDnsService' ` #Authentication - 'Remove-PiHoleCurrentAuthSession' , 'Get-PiHoleCurrentAuthSession', 'Remove-PiHoleAuthSession', ` + 'Remove-PiHoleCurrentAuthSession' , 'Get-PiHoleCurrentAuthSession', 'Remove-PiHoleAuthSession', 'Get-PiHoleAuthStatus', 'Get-PiHoleAuthTotp', 'New-PiHoleAppPassword', ` #GroupManagement 'Get-PiHoleGroup', 'New-PiHoleGroup', 'Update-PiHoleGroup', 'Remove-PiHoleGroup', ` #DnsControl diff --git a/PiHoleShell/Public/Authentication/Get-PiHoleAuthStatus.ps1 b/PiHoleShell/Public/Authentication/Get-PiHoleAuthStatus.ps1 new file mode 100644 index 0000000..3666bb7 --- /dev/null +++ b/PiHoleShell/Public/Authentication/Get-PiHoleAuthStatus.ps1 @@ -0,0 +1,82 @@ +function Get-PiHoleAuthStatus { + <# +.SYNOPSIS +Check if authentication is required + +.DESCRIPTION +Checks whether your Pi-hole requires a login for the calling client. Some Pi-hole +configurations skip authentication entirely for trusted local clients, in which case this +reports a valid session without needing a password at all. Pass -Password to instead check +the status of a real login with that password. + +.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. Optional - omit it to check whether +your Pi-hole requires a login at all for this client, without authenticating. + +.PARAMETER IgnoreSsl +Set to $true to skip SSL certificate validation + +.PARAMETER RawOutput +This will dump the response instead of the formatted object + +.EXAMPLE +Get-PiHoleAuthStatus -PiHoleServer "http://pihole.domain.com:8080" + +.EXAMPLE +Get-PiHoleAuthStatus -PiHoleServer "http://pihole.domain.com:8080" -Password "your-app-password" + #> + [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#get-/auth')] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [string]$Password, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + ) + try { + if ($PSBoundParameters.ContainsKey('Password')) { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + } + + $Params = @{ + Uri = "$($PiHoleServer.OriginalString)/api/auth" + Method = "Get" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + if ($Sid) { + $Params.Headers = @{sid = $($Sid) } + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + else { + $Object = [PSCustomObject]@{ + Valid = $Response.session.valid + Totp = $Response.session.totp + Sid = $Response.session.sid + Csrf = $Response.session.csrf + Validity = $Response.session.validity + Message = $Response.session.message + } + Write-Output $Object + } + } + + catch { + Write-Error -Message $_.Exception.Message + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} diff --git a/PiHoleShell/Public/Authentication/Get-PiHoleAuthTotp.ps1 b/PiHoleShell/Public/Authentication/Get-PiHoleAuthTotp.ps1 new file mode 100644 index 0000000..427248c --- /dev/null +++ b/PiHoleShell/Public/Authentication/Get-PiHoleAuthTotp.ps1 @@ -0,0 +1,76 @@ +function Get-PiHoleAuthTotp { + <# +.SYNOPSIS +Suggest new TOTP credentials + +.DESCRIPTION +Suggests new TOTP credentials for setting up two-factor authentication (2FA) on your Pi-hole. +This only suggests a secret; it does not enable 2FA by itself. + +.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 IgnoreSsl +Set to $true to skip SSL certificate validation + +.PARAMETER RawOutput +This will dump the response instead of the formatted object + +.EXAMPLE +Get-PiHoleAuthTotp -PiHoleServer "http://pihole.domain.com:8080" -Password "your-app-password" + #> + [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#get-/auth/totp')] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + [string]$Password, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + ) + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/auth/totp" + Method = "Get" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + else { + $Object = [PSCustomObject]@{ + Type = $Response.totp.type + Account = $Response.totp.account + Issuer = $Response.totp.issuer + Algorithm = $Response.totp.algorithm + Digits = $Response.totp.digits + Period = $Response.totp.period + Offset = $Response.totp.offset + Secret = $Response.totp.secret + Codes = $Response.totp.codes + } + Write-Output $Object + } + } + + catch { + Write-Error -Message $_.Exception.Message + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} diff --git a/PiHoleShell/Public/Authentication/New-PiHoleAppPassword.ps1 b/PiHoleShell/Public/Authentication/New-PiHoleAppPassword.ps1 new file mode 100644 index 0000000..aaaa14b --- /dev/null +++ b/PiHoleShell/Public/Authentication/New-PiHoleAppPassword.ps1 @@ -0,0 +1,76 @@ +function New-PiHoleAppPassword { + <# +.SYNOPSIS +Create a new application password + +.DESCRIPTION +Generates a new application password that can be used to authenticate against the API instead +of the regular password, without requiring 2FA verification. The generated password is shown +only once by Pi-hole and cannot be retrieved later - make sure to store it in a safe place. + +Generating a new application password only returns it; it does not take effect until the +returned Hash is set as webserver.api.app_pwhash in the Pi-hole configuration, for example via +Set-PiHoleConfig or the web interface (Settings -> All Settings). Doing so also invalidates all +currently active sessions. + +.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 IgnoreSsl +Set to $true to skip SSL certificate validation + +.PARAMETER RawOutput +This will dump the response instead of the formatted object + +.EXAMPLE +New-PiHoleAppPassword -PiHoleServer "http://pihole.domain.com:8080" -Password "your-app-password" + #> + [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#get-/auth/app')] + [Diagnostics.CodeAnalysis.SuppressMessage("PSUseShouldProcessForStateChangingFunctions", "", Justification = "Ignoring for now")] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + [string]$Password, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + ) + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/auth/app" + Method = "Get" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + else { + $Object = [PSCustomObject]@{ + Password = $Response.app.password + Hash = $Response.app.hash + } + Write-Output $Object + } + } + + catch { + Write-Error -Message $_.Exception.Message + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} diff --git a/README.md b/README.md index 1a29f29..402790e 100644 --- a/README.md +++ b/README.md @@ -200,7 +200,10 @@ Session handling is automatic for every command above, but these are available f | Function | Description | |---|---| +| `Get-PiHoleAuthStatus` | Check if authentication is required | +| `Get-PiHoleAuthTotp` | Suggest new TOTP credentials | | `Get-PiHoleCurrentAuthSession` | List of all current sessions including their validity and further information about the client such as the IP address and user agent. | +| `New-PiHoleAppPassword` | Create a new application password | | `Remove-PiHoleAuthSession` | Using this endpoint, a session can be deleted by its ID. | diff --git a/docs/EXAMPLES.md b/docs/EXAMPLES.md index 95fd82e..15b4653 100644 --- a/docs/EXAMPLES.md +++ b/docs/EXAMPLES.md @@ -99,9 +99,9 @@ New-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -GroupName "PiHo Name : PiHoleShellDocsExampleGroup Comment : Example group Enabled : True -Id : 53 -DateAdded : 9/30/2026 9:12:05 AM -DateModified : 9/30/2026 9:12:05 AM +Id : 61 +DateAdded : 9/30/2026 7:36:16 PM +DateModified : 9/30/2026 7:36:16 PM ``` ### Get-PiHoleGroup @@ -143,9 +143,9 @@ DateModified : 9/30/2026 8:48:26 AM Name : PiHoleShellDocsExampleGroup Comment : Example group Enabled : True -Id : 53 -DateAdded : 9/30/2026 9:12:05 AM -DateModified : 9/30/2026 9:12:05 AM +Id : 61 +DateAdded : 9/30/2026 7:36:16 PM +DateModified : 9/30/2026 7:36:16 PM ``` ### Update-PiHoleGroup @@ -159,9 +159,9 @@ Update-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -GroupName "P Name : PiHoleShellDocsExampleGroup Comment : Example group Enabled : False -Id : 53 -DateAdded : 9/30/2026 9:12:05 AM -DateModified : 9/30/2026 9:12:24 AM +Id : 61 +DateAdded : 9/30/2026 7:36:16 PM +DateModified : 9/30/2026 7:36:34 PM ``` ### Remove-PiHoleGroup @@ -190,9 +190,9 @@ Address : https://blocklistproject.github.io/Lists/alt-version/ransomware Comment : Example list Groups : {Default} Enabled : True -Id : 80 -DateAdded : 9/30/2026 9:13:02 AM -DateModified : 9/30/2026 9:13:02 AM +Id : 73 +DateAdded : 9/30/2026 7:37:11 PM +DateModified : 9/30/2026 7:37:11 PM Type : Block DateUpdated : Number : 0 @@ -246,7 +246,7 @@ DateAdded : 7/6/2025 2:20:46 AM DateModified : 7/6/2025 2:20:46 AM Type : block DateUpdated : 7/6/2025 2:20:46 AM -Number : 175219 +Number : 175912 InvalidDomains : 0 AbpEntries : 0 Status : 2 @@ -294,9 +294,9 @@ Address : https://blocklistproject.github.io/Lists/alt-version/ransomware Comment : Example list Groups : {Default} Enabled : False -Id : 80 -DateAdded : 9/30/2026 9:13:02 AM -DateModified : 9/30/2026 9:13:36 AM +Id : 73 +DateAdded : 9/30/2026 7:37:11 PM +DateModified : 9/30/2026 7:37:45 PM Type : Block DateUpdated : Number : 0 @@ -352,8 +352,8 @@ Type : block Groups : {0} DateAdded : 7/6/2025 2:20:46 AM DateModified : 7/6/2025 2:20:46 AM -DateUpdated : 9/28/2026 3:20:00 PM -Number : 175219 +DateUpdated : 9/30/2026 10:20:00 AM +Number : 175912 InvalidDomains : 0 AbpEntries : 0 Status : 2 @@ -421,9 +421,9 @@ Kind : Exact Comment : Example domain Groups : {Default} Enabled : True -Id : 18 -DateAdded : 9/30/2026 9:14:17 AM -DateModified : 9/30/2026 9:14:17 AM +Id : 24 +DateAdded : 9/30/2026 7:38:22 PM +DateModified : 9/30/2026 7:38:22 PM ``` ### Get-PiHoleDomain @@ -441,9 +441,9 @@ Kind : exact Comment : Example domain Groups : {Default} Enabled : True -Id : 18 -DateAdded : 9/30/2026 9:14:17 AM -DateModified : 9/30/2026 9:14:17 AM +Id : 24 +DateAdded : 9/30/2026 7:38:22 PM +DateModified : 9/30/2026 7:38:22 PM ``` ### Update-PiHoleDomain @@ -461,9 +461,9 @@ Kind : Exact Comment : Example domain Groups : {Default} Enabled : False -Id : 18 -DateAdded : 9/30/2026 9:14:17 AM -DateModified : 9/30/2026 9:14:50 AM +Id : 24 +DateAdded : 9/30/2026 7:38:22 PM +DateModified : 9/30/2026 7:38:56 PM ``` ### Remove-PiHoleDomain @@ -494,9 +494,9 @@ Client : 192.168.99.99 Name : Comment : Example client Groups : {Default} -Id : 20 -DateAdded : 9/30/2026 9:15:21 AM -DateModified : 9/30/2026 9:15:21 AM +Id : 25 +DateAdded : 9/30/2026 7:39:27 PM +DateModified : 9/30/2026 7:39:27 PM ``` ### Get-PiHoleClient @@ -511,9 +511,9 @@ Client : 192.168.99.99 Name : Comment : Example client Groups : {Default} -Id : 20 -DateAdded : 9/30/2026 9:15:21 AM -DateModified : 9/30/2026 9:15:21 AM +Id : 25 +DateAdded : 9/30/2026 7:39:27 PM +DateModified : 9/30/2026 7:39:27 PM ``` ### Get-PiHoleClientSuggestion @@ -526,13 +526,13 @@ Get-PiHoleClientSuggestion -PiHoleServer $PiHoleServer -Password $Password HwAddr : ip-127.0.0.1 MacVendor : -LastQuery : 9/30/2026 9:00:01 AM +LastQuery : 9/30/2026 7:00:00 PM Addresses : 127.0.0.1 Names : localhost HwAddr : 74:56:3c:bb:f4:0b MacVendor : Giga-Byte Technology Co.,Ltd. -LastQuery : 9/30/2026 7:49:13 AM +LastQuery : 9/30/2026 4:19:27 PM Addresses : 192.168.1.162 Names : ``` @@ -549,9 +549,9 @@ Client : 192.168.99.99 Name : Comment : Updated comment Groups : {Default} -Id : 20 -DateAdded : 9/30/2026 9:15:21 AM -DateModified : 9/30/2026 9:16:00 AM +Id : 25 +DateAdded : 9/30/2026 7:39:27 PM +DateModified : 9/30/2026 7:40:08 PM ``` ### Remove-PiHoleClient @@ -576,18 +576,18 @@ Get-PiHoleStatsSummary -PiHoleServer $PiHoleServer -Password $Password ``` -Total : 287 -Blocked : 93 -PercentBlocked : 32.404182434082 -UniqueDomains : 22 -Forwarded : 33 -Cached : 161 +Total : 49 +Blocked : 8 +PercentBlocked : 16.326530456543 +UniqueDomains : 15 +Forwarded : 27 +Cached : 14 Frequency : 0 -Types : @{A=136; AAAA=139; ANY=0; SRV=0; SOA=0; PTR=12; TXT=0; NAPTR=0; MX=0; DS=0; RRSIG=0; DNSKEY=0; NS=0; SVCB=0; HTTPS=0; OTHER=0} -Status : @{Unknown=0; Gravity=93; Forwarded=33; Cache=122; Regex=0; DenyList=0; ExternalBlockedIp=0; ExternalBlockedNull=0; ExternalBlockedNxra=0; GravityCname=0; RegexCname=0; DenyListCname=0; Retired=0; RetiredDnssec=0; InProgress=0; Dbbusy=0; SpecialDomain=0; CacheStale=39; ExternalBlockedEde15=0} -Replies : @{Unknown=7; Nodata=17; Nxdomain=3; Cname=0; Ip=251; Domain=9; Rrname=0; ServFail=0; Refused=0; Notimp=0; Other=0; Dnssec=0; None=0; Blob=0} +Types : @{A=19; AAAA=20; ANY=0; SRV=0; SOA=0; PTR=10; TXT=0; NAPTR=0; MX=0; DS=0; RRSIG=0; DNSKEY=0; NS=0; SVCB=0; HTTPS=0; OTHER=0} +Status : @{Unknown=0; Gravity=8; Forwarded=27; Cache=14; Regex=0; DenyList=0; ExternalBlockedIp=0; ExternalBlockedNull=0; ExternalBlockedNxra=0; GravityCname=0; RegexCname=0; DenyListCname=0; Retired=0; RetiredDnssec=0; InProgress=0; Dbbusy=0; SpecialDomain=0; CacheStale=0; ExternalBlockedEde15=0} +Replies : @{Unknown=10; Nodata=2; Nxdomain=3; Cname=0; Ip=27; Domain=7; Rrname=0; ServFail=0; Refused=0; Notimp=0; Other=0; Dnssec=0; None=0; Blob=0} Clients : @{Active=2; Total=2} -Gravity : @{DomainsBeingBlocked=494568; LastUpdate=1790769668} +Gravity : @{DomainsBeingBlocked=494952; LastUpdate=1790799702} ``` ### Get-PiHoleStatsRecentBlocked @@ -598,7 +598,7 @@ Get-PiHoleStatsRecentBlocked -PiHoleServer $PiHoleServer -Password $Password ``` -Blocked : googlesyndication.com +Blocked : adservice.google.com ``` ### Get-PiHoleStatsQueryType @@ -610,10 +610,10 @@ Get-PiHoleStatsQueryType -PiHoleServer $PiHoleServer -Password $Password ``` Type : A -Count : 136 +Count : 19 Type : AAAA -Count : 139 +Count : 20 Type : ANY Count : 0 @@ -635,20 +635,20 @@ Get-PiHoleStatsTopDomain -PiHoleServer $PiHoleServer -Password $Password ``` -Domain : bbc.com -Count : 22 - -Domain : microsoft.com -Count : 22 +Domain : mozilla.org +Count : 4 -Domain : example.com -Count : 20 +Domain : bbc.com +Count : 4 -Domain : apple.com -Count : 20 +Domain : stackoverflow.com +Count : 4 Domain : cloudflare.com -Count : 16 +Count : 4 + +Domain : 1.0.0.127.in-addr.arpa +Count : 4 _(showing 5 of 10 results)_ ``` @@ -663,11 +663,11 @@ Get-PiHoleStatsTopClient -PiHoleServer $PiHoleServer -Password $Password IP : 192.168.1.162 Name : -Count : 275 +Count : 39 IP : 127.0.0.1 Name : localhost -Count : 12 +Count : 10 ``` ### Get-PiHoleStatsUpstream @@ -678,9 +678,9 @@ Get-PiHoleStatsUpstream -PiHoleServer $PiHoleServer -Password $Password ``` -TotalQueries : 287 -ForwardedQueries : 33 -Upstreams : {@{Ip=blocklist; Name=blocklist; Port=-1; Count=93; ResponseTime=0; Variance=0}, @{Ip=cache; Name=cache; Port=-1; Count=161; ResponseTime=0; Variance=0}, @{Ip=8.8.4.4; Name=dns.google; Port=53; Count=18; ResponseTime=0.0253777056932449; Variance=0.00323175294284653}, @{Ip=8.8.8.8; Name=dns.google; Port=53; Count=15; ResponseTime=0.0273200273513794; Variance=0.00394722979890426}} +TotalQueries : 49 +ForwardedQueries : 27 +Upstreams : {@{Ip=blocklist; Name=blocklist; Port=-1; Count=8; ResponseTime=0; Variance=0}, @{Ip=cache; Name=cache; Port=-1; Count=14; ResponseTime=0; Variance=0}, @{Ip=8.8.8.8; Name=dns.google; Port=53; Count=27; ResponseTime=0.0287302732467651; Variance=0.00306724246755919}} ``` ### Get-PiHoleStatsQuerySuggestions @@ -691,10 +691,10 @@ Get-PiHoleStatsQuerySuggestions -PiHoleServer $PiHoleServer -Password $Password ``` -Domain : {bbc.com, microsoft.com, example.com, apple.com…} +Domain : {mozilla.org, bbc.com, stackoverflow.com, cloudflare.com…} ClientIp : {192.168.1.162, 127.0.0.1} ClientName : {localhost} -Upstream : {blocklist, cache, 8.8.4.4#53 (dns.google), 8.8.8.8#53 (dns.google)…} +Upstream : {blocklist, cache, 8.8.8.8#53 (dns.google), permitted} Type : {A, AAAA, ANY, SRV…} Status : {UNKNOWN, GRAVITY, FORWARDED, CACHE…} Reply : {UNKNOWN, NODATA, NXDOMAIN, CNAME…} @@ -711,9 +711,9 @@ Get-PiHoleStatsDatabaseSummary -PiHoleServer $PiHoleServer -Password $Password ``` -SumQueries : 287 -SumBlocked : 93 -PercentBlocked : 32.404182434082 +SumQueries : 49 +SumBlocked : 8 +PercentBlocked : 16.326530456543 TotalClients : 3 ``` @@ -728,7 +728,7 @@ Get-PiHoleStatsDatabaseQueryType -PiHoleServer $PiHoleServer -Password $Password ``` Type : A -Count : 139 +Count : 20 Type : AAAA Count : 0 @@ -740,7 +740,7 @@ Type : SRV Count : 0 Type : SOA -Count : 12 +Count : 10 _(showing 5 of 16 results)_ ``` @@ -755,20 +755,20 @@ Get-PiHoleStatsDatabaseTopDomain -PiHoleServer $PiHoleServer -Password $Password ``` +Domain : nytimes.com +Count : 4 + Domain : bbc.com -Count : 22 +Count : 4 -Domain : microsoft.com -Count : 22 +Domain : mozilla.org +Count : 4 Domain : example.com -Count : 20 - -Domain : apple.com -Count : 20 +Count : 4 -Domain : cloudflare.com -Count : 16 +Domain : stackoverflow.com +Count : 4 _(showing 5 of 10 results)_ ``` @@ -785,15 +785,15 @@ Get-PiHoleStatsDatabaseTopClient -PiHoleServer $PiHoleServer -Password $Password IP : 192.168.1.162 Name : -Count : 182 +Count : 31 IP : 127.0.0.1 Name : localhost -Count : 9 +Count : 8 IP : 127.0.0.1 Name : -Count : 3 +Count : 2 ``` ### Get-PiHoleStatsDatabaseUpstream @@ -806,9 +806,9 @@ Get-PiHoleStatsDatabaseUpstream -PiHoleServer $PiHoleServer -Password $Password ``` -TotalQueries : 287 -ForwardedQueries : 33 -Upstreams : {@{Ip=1; Name=; Port=4294967295; Count=22; ResponseTime=0; Variance=0}, @{Ip=2; Name=; Port=4294967295; Count=11; ResponseTime=0; Variance=0}, @{Ip=cache; Name=cache; Port=-1; Count=122; ResponseTime=0; Variance=0}, @{Ip=blocklist; Name=blocklist; Port=-1; Count=132; ResponseTime=0; Variance=0}} +TotalQueries : 49 +ForwardedQueries : 27 +Upstreams : {@{Ip=2; Name=; Port=4294967295; Count=27; ResponseTime=0; Variance=0}, @{Ip=cache; Name=cache; Port=-1; Count=14; ResponseTime=0; Variance=0}, @{Ip=blocklist; Name=blocklist; Port=-1; Count=8; ResponseTime=0; Variance=0}} ``` ### Get-PiHoleQuery @@ -821,67 +821,67 @@ Get-PiHoleQuery -PiHoleServer $PiHoleServer -Password $Password -Length 5 ``` -Id : 286 -Time : 9/30/2026 9:00:01 AM +Id : 48 +Time : 9/30/2026 7:00:01 PM Type : PTR -Domain : 4.4.8.8.in-addr.arpa +Domain : 1.0.0.127.in-addr.arpa Cname : Status : CACHE Client : @{Ip=127.0.0.1; Name=localhost} Dnssec : UNKNOWN -Reply : @{Type=DOMAIN; Time=0.0011289119720459} +Reply : @{Type=DOMAIN; Time=0.000156879425048828} ListId : Upstream : Ede : @{Code=-1; Text=} -Id : 285 -Time : 9/30/2026 9:00:01 AM +Id : 47 +Time : 9/30/2026 6:00:01 PM Type : PTR Domain : 8.8.8.8.in-addr.arpa Cname : Status : CACHE Client : @{Ip=127.0.0.1; Name=localhost} Dnssec : UNKNOWN -Reply : @{Type=DOMAIN; Time=0.00119900703430176} +Reply : @{Type=DOMAIN; Time=0.00014805793762207} ListId : Upstream : Ede : @{Code=-1; Text=} -Id : 284 -Time : 9/30/2026 9:00:01 AM +Id : 46 +Time : 9/30/2026 6:00:01 PM Type : PTR Domain : 1.0.0.127.in-addr.arpa Cname : Status : CACHE Client : @{Ip=127.0.0.1; Name=localhost} Dnssec : UNKNOWN -Reply : @{Type=DOMAIN; Time=0.0010991096496582} +Reply : @{Type=DOMAIN; Time=0.000154972076416016} ListId : Upstream : Ede : @{Code=-1; Text=} -Id : 283 -Time : 9/30/2026 9:00:01 AM +Id : 45 +Time : 9/30/2026 6:00:01 PM Type : PTR Domain : 162.1.168.192.in-addr.arpa Cname : Status : CACHE Client : @{Ip=127.0.0.1; Name=localhost} Dnssec : UNKNOWN -Reply : @{Type=NXDOMAIN; Time=0.0204389095306396} +Reply : @{Type=NXDOMAIN; Time=0.000169992446899414} ListId : Upstream : Ede : @{Code=-1; Text=} -Id : 282 -Time : 9/30/2026 8:00:00 AM +Id : 44 +Time : 9/30/2026 5:00:01 PM Type : PTR -Domain : 4.4.8.8.in-addr.arpa +Domain : 8.8.8.8.in-addr.arpa Cname : Status : CACHE Client : @{Ip=127.0.0.1; Name=localhost} Dnssec : UNKNOWN -Reply : @{Type=DOMAIN; Time=0.00113701820373535} +Reply : @{Type=DOMAIN; Time=0.00167107582092285} ListId : Upstream : Ede : @{Code=-1; Text=} @@ -978,20 +978,20 @@ CpuPercent : 0 MemoryPercent : 0 ActiveClients : 2 Blocking : enabled -Cache : @{Size=10000; Inserted=157; Evicted=0} +Cache : @{Size=10000; Inserted=38; Evicted=0} Config : @{DhcpActive=False; DhcpStart=; DhcpEnd=; DhcpIpv6=False; DnsDnssec=False; DnsDomain=lan; DnsNumUpstreams=2; DnsPort=53; DnsrevServerAactive=False; PrivacyLevel=0} -GravitySize : 494568 +GravitySize : 494952 HostModel : Raspberry Pi Zero W Rev 1.1 IFace : @{v4=; v6=} NodeName : dns3.localdomain Pid : 388 -Queries : @{Total=287; Blocked=93; PercentBlocked=32.404182434082; QueryFrequency=0} -RecentBlocked : googlesyndication.com -Sensors : @{CpuTemp=40.622; HotLimit=60; Unit=C} -System : @{Uptime=127777; Memory=; Procs=73; Cpu=; Ftl=} -TopBlocked : ads.pubmatic.com +Queries : @{Total=49; Blocked=8; PercentBlocked=16.326530456543; QueryFrequency=0} +RecentBlocked : adservice.google.com +Sensors : @{CpuTemp=39.546; HotLimit=60; Unit=C} +System : @{Uptime=165232; Memory=; Procs=74; Cpu=; Ftl=} +TopBlocked : googleadservices.com TopClient : 192.168.1.162 -TopDomain : bbc.com +TopDomain : nytimes.com Version : @{Core=; Web=; Ftl=; Docker=} ``` @@ -1028,11 +1028,11 @@ Get-PiHoleInfoSystem -PiHoleServer $PiHoleServer -Password $Password ``` -Uptime : 127787 +Uptime : 165242 Memory : @{Ram=; Swap=} -Procs : 73 -Cpu : @{NumProcessors=1; PercentCpu=95.8000030517578; Load=} -Ftl : @{PercentMemory=2.42485022544861; PercentCpu=95.5} +Procs : 74 +Cpu : @{NumProcessors=1; PercentCpu=97; Load=} +Ftl : @{PercentMemory=2.59335684776306; PercentCpu=96.4000015258789} ``` ### Get-PiHoleInfoFtl @@ -1043,16 +1043,16 @@ Get-PiHoleInfoFtl -PiHoleServer $PiHoleServer -Password $Password ``` -Database : @{Gravity=494568; Antigravity=0; Groups=4; Lists=14; Clients=0; Domains=; Regex=} +Database : @{Gravity=494952; Antigravity=0; Groups=4; Lists=14; Clients=0; Domains=; Regex=} PrivacyLevel : 0 QueryFrequency : 0 Clients : @{Total=2; Active=2} Pid : 388 -Uptime : 7963466.771567 -PercentMemory : 2.42485022544861 -PercentCpu : 96.5999984741211 +Uptime : 15409712.410978 +PercentMemory : 2.59335684776306 +PercentCpu : 96.4000015258789 AllowDestructive : True -Dnsmasq : @{DnsCacheInserted=157; DnsCacheLiveFreed=0; DnsQueriesForwarded=72; DnsAuthAnswered=0; DnsLocalAnswered=215; DnsStaleAnswered=39; DnsUnanswered=0; DnssecMaxCryptoUse=0; DnssecMaxSigFail=0; DnssecMaxWork=0; Bootp=0; Pxe=0; DhcpAck=0; DhcpDecline=0; DhcpDiscover=0; DhcpInform=0; DhcpNak=0; DhcpOffer=0; DhcpRelease=0; DhcpRequest=0; Noanswer=0; LeasesAllocated4=0; LeasesPruned4=0; LeasesAllocated6=0; LeasesPruned6=0; TcpConnections=0; DhcpLeasequery=0; DhcpLeaseUnassigned=0; DhcpLeaseActve=0; DhcpLeaseUnknown=0} +Dnsmasq : @{DnsCacheInserted=38; DnsCacheLiveFreed=0; DnsQueriesForwarded=27; DnsAuthAnswered=0; DnsLocalAnswered=22; DnsStaleAnswered=0; DnsUnanswered=0; DnssecMaxCryptoUse=0; DnssecMaxSigFail=0; DnssecMaxWork=0; Bootp=0; Pxe=0; DhcpAck=0; DhcpDecline=0; DhcpDiscover=0; DhcpInform=0; DhcpNak=0; DhcpOffer=0; DhcpRelease=0; DhcpRequest=0; Noanswer=0; LeasesAllocated4=0; LeasesPruned4=0; LeasesAllocated6=0; LeasesPruned6=0; TcpConnections=0; DhcpLeasequery=0; DhcpLeaseUnassigned=0; DhcpLeaseActve=0; DhcpLeaseUnknown=0} ``` ### Get-PiHoleInfoSensors @@ -1064,7 +1064,7 @@ Get-PiHoleInfoSensors -PiHoleServer $PiHoleServer -Password $Password ``` List : {@{Name=cpu_thermal; Path=hwmon0; Source=devices/virtual/thermal/thermal_zone0; Temps=}, @{Name=rpi_volt; Path=hwmon1; Source=devices/platform/soc/soc:firmware/raspberrypi-hwmon; Temps=}} -CpuTemp : 40.622 +CpuTemp : 39.546 HotLimit : 60 Unit : C ``` @@ -1081,12 +1081,12 @@ Size : 13983744 Type : Regular file Mode : rw-r----- AccessTime : 6/25/2025 12:32:44 AM -ModifiedTime : 9/30/2026 6:58:06 AM -ChangeTime : 9/30/2026 6:58:06 AM +ModifiedTime : 9/30/2026 6:41:00 PM +ChangeTime : 9/30/2026 6:41:00 PM Owner : @{User=; Group=} -Queries : 287 -EarliestTimestamp : 9/29/2026 9:10:00 AM -QueriesDisk : 287 +Queries : 49 +EarliestTimestamp : 9/29/2026 7:30:00 PM +QueriesDisk : 49 EarliestTimestampDisk : SqliteVersion : 3.53.1 ``` @@ -1155,11 +1155,17 @@ Get-PiHoleInfoMessage -PiHoleServer $PiHoleServer -Password $Password ``` -Id : 1 -Timestamp : 9/30/2026 7:38:07 AM +Id : 30 +Timestamp : 9/30/2026 4:26:17 PM +Type : LIST +Plain : List with ID 63 (https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/domains/light.txt) was inaccessible during last gravity run +Html : List with ID 63 (https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/domains/light.txt) was inaccessible during last gravity run + +Id : 31 +Timestamp : 9/30/2026 4:33:16 PM Type : LOAD -Plain : Long-term load (15min avg) larger than number of processors: 1.0 > 1 -Html : Long-term load (15min avg) larger than number of processors: 1.0 > 1
This may slow down DNS resolution and can cause bottlenecks. +Plain : Long-term load (15min avg) larger than number of processors: 1.1 > 1 +Html : Long-term load (15min avg) larger than number of processors: 1.1 > 1
This may slow down DNS resolution and can cause bottlenecks. ``` ### Get-PiHoleInfoMessageCount @@ -1170,7 +1176,7 @@ Get-PiHoleInfoMessageCount -PiHoleServer $PiHoleServer -Password $Password ``` -Count : 1 +Count : 2 ``` ### Remove-PiHoleInfoMessage @@ -1194,8 +1200,8 @@ Get-PiHoleLogWebserver -PiHoleServer $PiHoleServer -Password $Password ``` -Log : {@{Timestamp=9/30/2026 6:58:08 AM; Message=Initializing HTTP server on ports "8089,8489s"; Priority=}, @{Timestamp=9/30/2026 7:16:07 AM; Message=ACCESS: 192.168.1.162 - - [30/Sep/2026:12:16:06 +0000] "PATCH /api/config?restart=false HTTP/1.1" 200 4590 - Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6; Priority=}, @{Timestamp=9/30/2026 7:16:08 AM; Message=ACCESS: 192.168.1.162 - - [30/Sep/2026:12:16:07 +0000] "DELETE /api/auth HTTP/1.1" 204 558 - Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6; Priority=}, @{Timestamp=9/30/2026 7:16:12 AM; Message=ACCESS: 192.168.1.162 - - [30/Sep/2026:12:16:07 +0000] "POST /api/auth HTTP/1.1" 200 808 - Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6; Priority=}…} -NextID : 13 +Log : {@{Timestamp=9/30/2026 3:18:16 PM; Message=Initializing HTTP server on ports "8089,8489s"; Priority=}, @{Timestamp=9/30/2026 3:29:52 PM; Message=ACCESS: 192.168.1.162 - - [30/Sep/2026:20:29:51 +0000] "PATCH /api/config?restart=false HTTP/1.1" 200 4588 - Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6; Priority=}, @{Timestamp=9/30/2026 3:29:53 PM; Message=ACCESS: 192.168.1.162 - - [30/Sep/2026:20:29:52 +0000] "DELETE /api/auth HTTP/1.1" 204 558 - Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6; Priority=}, @{Timestamp=9/30/2026 3:29:54 PM; Message=ACCESS: 192.168.1.162 - - [30/Sep/2026:20:29:45 +0000] "POST /api/auth HTTP/1.1" 200 806 - Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6; Priority=}…} +NextID : 36 Pid : 388 File : /var/log/pihole/webserver.log ``` @@ -1208,8 +1214,8 @@ Get-PiHoleLogDnsmasq -PiHoleServer $PiHoleServer -Password $Password ``` -Log : {@{Timestamp=9/30/2026 6:58:08 AM; Message=started, version pi-hole-v2.93 cachesize 10000; Priority=}, @{Timestamp=9/30/2026 6:58:08 AM; Message=DNS service limited to local subnets; Priority=}, @{Timestamp=9/30/2026 6:58:08 AM; Message=compile time options: IPv6 GNU-getopt no-DBus no-UBus no-i18n IDN2 DHCP DHCPv6 Lua TFTP no-conntrack ipset no-nftset auth DNSSEC loop-detect inotify dumpfile; Priority=}, @{Timestamp=9/30/2026 6:58:08 AM; Message=using nameserver 8.8.8.8#53; Priority=}…} -NextID : 57 +Log : {@{Timestamp=9/30/2026 3:18:16 PM; Message=started, version pi-hole-v2.93 cachesize 10000; Priority=}, @{Timestamp=9/30/2026 3:18:16 PM; Message=DNS service limited to local subnets; Priority=}, @{Timestamp=9/30/2026 3:18:16 PM; Message=compile time options: IPv6 GNU-getopt no-DBus no-UBus no-i18n IDN2 DHCP DHCPv6 Lua TFTP no-conntrack ipset no-nftset auth DNSSEC loop-detect inotify dumpfile; Priority=}, @{Timestamp=9/30/2026 3:18:16 PM; Message=using nameserver 8.8.8.8#53; Priority=}…} +NextID : 75 Pid : 388 File : /var/log/pihole/pihole.log ``` @@ -1222,8 +1228,8 @@ Get-PiHoleLogFtl -PiHoleServer $PiHoleServer -Password $Password ``` -Log : {@{Timestamp=9/30/2026 6:58:08 AM; Message= -> Unknown DNS queries: 0; Priority=INFO}, @{Timestamp=9/30/2026 6:58:08 AM; Message= -> Unique domains: 0; Priority=INFO}, @{Timestamp=9/30/2026 6:58:08 AM; Message= -> Unique clients: 0; Priority=INFO}, @{Timestamp=9/30/2026 6:58:08 AM; Message= -> DNS cache records: 0; Priority=INFO}…} -NextID : 535 +Log : {@{Timestamp=9/30/2026 3:47:52 PM; Message=Compiled 0 allow and 0 deny regex for 0 client in 0.9 msec; Priority=INFO}, @{Timestamp=9/30/2026 3:47:52 PM; Message=List with ID 63 (https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/domains/light.txt) was inaccessible during last gravity run; Priority=WARNING}, @{Timestamp=9/30/2026 3:47:52 PM; Message=Requested API URI: 192.168.1.162 -> POST /api/auth ? (null) (Content-Type application/json); Priority=DEBUG_API}, @{Timestamp=9/30/2026 3:47:52 PM; Message=Received payload with size: 66; Priority=DEBUG_API}…} +NextID : 1025 Pid : 388 File : /var/log/pihole/FTL.log ``` @@ -1252,31 +1258,31 @@ Get-PiHoleHistory -PiHoleServer $PiHoleServer -Password $Password ``` -Timestamp : 9/29/2026 9:15:00 AM +Timestamp : 9/29/2026 7:45:00 PM Total : 0 Cached : 0 Blocked : 0 Forwarded : 0 -Timestamp : 9/29/2026 9:25:00 AM +Timestamp : 9/29/2026 7:55:00 PM Total : 0 Cached : 0 Blocked : 0 Forwarded : 0 -Timestamp : 9/29/2026 9:35:00 AM +Timestamp : 9/29/2026 8:05:00 PM Total : 0 Cached : 0 Blocked : 0 Forwarded : 0 -Timestamp : 9/29/2026 9:45:00 AM +Timestamp : 9/29/2026 8:15:00 PM Total : 0 Cached : 0 Blocked : 0 Forwarded : 0 -Timestamp : 9/29/2026 9:55:00 AM +Timestamp : 9/29/2026 8:25:00 PM Total : 0 Cached : 0 Blocked : 0 @@ -1293,19 +1299,19 @@ Get-PiHoleHistoryClient -PiHoleServer $PiHoleServer -Password $Password ``` -Timestamp : 9/29/2026 9:15:00 AM +Timestamp : 9/29/2026 7:45:00 PM Clients : {@{IP=192.168.1.162; Name=; Count=0}, @{IP=others; Name=; Count=0}} -Timestamp : 9/29/2026 9:25:00 AM +Timestamp : 9/29/2026 7:55:00 PM Clients : {@{IP=192.168.1.162; Name=; Count=0}, @{IP=others; Name=; Count=0}} -Timestamp : 9/29/2026 9:35:00 AM +Timestamp : 9/29/2026 8:05:00 PM Clients : {@{IP=192.168.1.162; Name=; Count=0}, @{IP=others; Name=; Count=0}} -Timestamp : 9/29/2026 9:45:00 AM +Timestamp : 9/29/2026 8:15:00 PM Clients : {@{IP=192.168.1.162; Name=; Count=0}, @{IP=others; Name=; Count=0}} -Timestamp : 9/29/2026 9:55:00 AM +Timestamp : 9/29/2026 8:25:00 PM Clients : {@{IP=192.168.1.162; Name=; Count=0}, @{IP=others; Name=; Count=0}} _(showing 5 of 145 results)_ @@ -1321,27 +1327,27 @@ Get-PiHoleHistoryDatabase -PiHoleServer $PiHoleServer -Password $Password ``` -Timestamp : 9/30/2026 7:30:00 AM -Total : 47 -Cached : 12 -Blocked : 9 -Forwarded : 26 +Timestamp : 9/30/2026 4:10:00 PM +Total : 42 +Cached : 7 +Blocked : 8 +Forwarded : 27 -Timestamp : 9/30/2026 7:40:00 AM -Total : 232 -Cached : 141 -Blocked : 84 -Forwarded : 7 +Timestamp : 9/30/2026 5:00:00 PM +Total : 3 +Cached : 3 +Blocked : 0 +Forwarded : 0 -Timestamp : 9/30/2026 8:00:00 AM -Total : 4 -Cached : 4 +Timestamp : 9/30/2026 6:00:00 PM +Total : 3 +Cached : 3 Blocked : 0 Forwarded : 0 -Timestamp : 9/30/2026 9:00:00 AM -Total : 4 -Cached : 4 +Timestamp : 9/30/2026 7:00:00 PM +Total : 1 +Cached : 1 Blocked : 0 Forwarded : 0 ``` @@ -1356,16 +1362,16 @@ Get-PiHoleHistoryDatabaseClient -PiHoleServer $PiHoleServer -Password $Password ``` -Timestamp : 9/30/2026 9:00:00 AM +Timestamp : 9/30/2026 7:00:00 PM Clients : @{ClientId=3; Count=1} -Timestamp : 9/30/2026 8:00:00 AM +Timestamp : 9/30/2026 6:00:00 PM Clients : @{ClientId=3; Count=1} -Timestamp : 9/30/2026 7:40:00 AM -Clients : @{ClientId=5; Count=1} +Timestamp : 9/30/2026 5:00:00 PM +Clients : @{ClientId=3; Count=1} -Timestamp : 9/30/2026 7:30:00 AM +Timestamp : 9/30/2026 4:10:00 PM Clients : {@{ClientId=3; Count=1}, @{ClientId=2; Count=1}, @{ClientId=5; Count=1}} ``` @@ -1462,7 +1468,7 @@ ProtoDown : False Address : 00:00:00:00:00:00 Broadcast : 00:00:00:00:00:00 Stats : @{RxBytes=; TxBytes=; Bits=64} -Addresses : {@{Family=inet; Scope=host; Flags=permanent; Prefixlen=8; Address=127.0.0.1; AddressType=loopback; Local=127.0.0.1; LocalType=loopback; Label=lo; Prefered=4294967295; Valid=4294967295; Cstamp=1790649663.02; Tstamp=1790649663.02}, @{Family=inet6; Scope=host; Flags=permanent; Prefixlen=128; Address=::1; AddressType=loopback; Prefered=4294967295; Valid=4294967295; Cstamp=1790649663.02; Tstamp=1790649663.02}} +Addresses : {@{Family=inet; Scope=host; Flags=permanent; Prefixlen=8; Address=127.0.0.1; AddressType=loopback; Local=127.0.0.1; LocalType=loopback; Label=lo; Prefered=4294967295; Valid=4294967295; Cstamp=1790649664.02; Tstamp=1790649664.02}, @{Family=inet6; Scope=host; Flags=permanent; Prefixlen=128; Address=::1; AddressType=loopback; Prefered=4294967295; Valid=4294967295; Cstamp=1790649664.02; Tstamp=1790649664.02}} Name : wlan0 Speed : @@ -1475,7 +1481,7 @@ Address : b8:27:eb:11:a4:d5 Broadcast : ff:ff:ff:ff:ff:ff PermAddress : b8:27:eb:11:a4:d5 Stats : @{RxBytes=; TxBytes=; Bits=64} -Addresses : {@{Family=inet; Scope=universe; Flags=; Prefixlen=24; Address=192.168.1.248; AddressType=private; Local=192.168.1.248; LocalType=private; Broadcast=192.168.1.255; BroadcastType=private; Label=wlan0; Prefered=71284; Valid=71284; Cstamp=1790649687.41; Tstamp=1790762750.49}, @{Family=inet6; Scope=link; Flags=permanent; Prefixlen=64; Address=fe80::ba27:ebff:fe11:a4d5; AddressType=link-local (LL); Prefered=4294967295; Valid=4294967295; Cstamp=1790649682.83; Tstamp=1790649682.83}} +Addresses : {@{Family=inet; Scope=universe; Flags=; Prefixlen=24; Address=192.168.1.248; AddressType=private; Local=192.168.1.248; LocalType=private; Broadcast=192.168.1.255; BroadcastType=private; Label=wlan0; Prefered=64531; Valid=64531; Cstamp=1790649688.41; Tstamp=1790793451.81}, @{Family=inet6; Scope=link; Flags=permanent; Prefixlen=64; Address=fe80::ba27:ebff:fe11:a4d5; AddressType=link-local (LL); Prefered=4294967295; Valid=4294967295; Cstamp=1790649683.83; Tstamp=1790649683.83}} ``` ### Get-PiHoleNetworkDevice @@ -1491,20 +1497,20 @@ Get-PiHoleNetworkDevice -PiHoleServer $PiHoleServer -Password $Password Id : 2 HwAddr : ip-127.0.0.1 Interface : lo -FirstSeen : 9/30/2026 7:34:38 AM -LastQuery : 9/30/2026 9:00:01 AM -NumQueries : 12 +FirstSeen : 9/30/2026 4:19:27 PM +LastQuery : 9/30/2026 7:00:00 PM +NumQueries : 10 MacVendor : -Ips : @{Ip=127.0.0.1; Name=localhost; LastSeen=9/30/2026 9:17:00 AM; NameUpdated=9/30/2026 9:17:00 AM} +Ips : @{Ip=127.0.0.1; Name=localhost; LastSeen=9/30/2026 7:42:00 PM; NameUpdated=9/30/2026 7:42:00 PM} Id : 1 HwAddr : 74:56:3c:bb:f4:0b Interface : wlan0 -FirstSeen : 9/30/2026 7:34:37 AM -LastQuery : 9/30/2026 7:49:13 AM -NumQueries : 275 +FirstSeen : 9/30/2026 4:19:27 PM +LastQuery : 9/30/2026 4:19:27 PM +NumQueries : 39 MacVendor : Giga-Byte Technology Co.,Ltd. -Ips : @{Ip=192.168.1.162; Name=; LastSeen=9/30/2026 9:17:00 AM; NameUpdated=12/31/1969 6:00:00 PM} +Ips : @{Ip=192.168.1.162; Name=; LastSeen=9/30/2026 7:42:00 PM; NameUpdated=12/31/1969 6:00:00 PM} ``` ### Remove-PiHoleNetworkDevice @@ -1522,6 +1528,43 @@ Error : Response status code does not indicate success: 404 (Not Found). ## Authentication +### Get-PiHoleAuthStatus + +_Password is optional - omit it to check whether your Pi-hole requires a login at all for this client, without authenticating. This test server does require login, so the result below is from a real authenticated check._ + +```powershell +Get-PiHoleAuthStatus -PiHoleServer $PiHoleServer -Password $Password +``` + +``` + +Valid : True +Totp : False +Sid : m7PdLA09AyiOFzvUJZrFJg= +Csrf : 0zYblKxFxLvLjid7c2W7MA= +Validity : 1800 +Message : correct password +``` + +### Get-PiHoleAuthTotp + +```powershell +Get-PiHoleAuthTotp -PiHoleServer $PiHoleServer -Password $Password +``` + +``` + +Type : totp +Account : pi.hole +Issuer : Pi-hole%20API +Algorithm : SHA1 +Digits : 6 +Period : 30 +Offset : 0 +Secret : XN4ZOSTT2AZW3DGP2LWD2KOUF2SZDL6B +Codes : {425012, 386064, 867509, 644038…} +``` + ### Get-PiHoleCurrentAuthSession ```powershell @@ -1535,9 +1578,9 @@ CurrentSession : True Valid : True TlsLogin : True TlsMixed : False -LoginAt : 9/30/2026 9:09:06 AM -LastActive : 9/30/2026 9:09:11 AM -ValidUntil : 9/30/2026 9:39:11 AM +LoginAt : 9/30/2026 7:33:19 PM +LastActive : 9/30/2026 7:33:24 PM +ValidUntil : 9/30/2026 8:03:24 PM RemoteAddress : 192.168.1.162 UserAgent : Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6 XForwardedFor : @@ -1560,6 +1603,20 @@ Id : 0 Status : Removed ``` +### New-PiHoleAppPassword + +_This only generates a candidate password/hash pair - it has no effect until the returned Hash is set as webserver.api.app_pwhash in the Pi-hole configuration, which this example deliberately does not do, so the real password used throughout this document keeps working._ + +```powershell +New-PiHoleAppPassword -PiHoleServer $PiHoleServer -Password $Password +``` + +``` + +Password : xoDAAWnYntBvvpoevm5JqTeObfsFGM3THk/4ZIrZ8ro= +Hash : $BALLOON-SHA256$v=1$s=1024,t=32$bk227/Pz7DiVXdoYSIpjkg==$wwbesgv4Pw9ldd7V6OUXCqp/UenQqJlXHbIIqn0ZS+U= +``` + ### Remove-PiHoleCurrentAuthSession _The internal best-effort logout every other function calls automatically when it finishes - it never produces output, even on failure (a warning only). Shown here for completeness since it is still a publicly exported function._ diff --git a/tests/Authentication/Get-PiHoleAuthStatus.Integration.Tests.ps1 b/tests/Authentication/Get-PiHoleAuthStatus.Integration.Tests.ps1 new file mode 100644 index 0000000..26adfa0 --- /dev/null +++ b/tests/Authentication/Get-PiHoleAuthStatus.Integration.Tests.ps1 @@ -0,0 +1,51 @@ +# Requires -Module Pester +# +# Integration tests that call a REAL Pi-hole server. Configure tests/IntegrationConfig.local.ps1 +# (copy it from IntegrationConfig.example.ps1) before running. Tests are skipped automatically +# if that file is missing. + +$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1') + +Describe 'Get-PiHoleAuthStatus (Integration)' -Tag 'Integration' { + BeforeAll { + Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force + + $configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1' + if (Test-Path $configPath) { + . $configPath + $script:PiHoleServer = $PiHoleServer + $script:PiHoleToken = $PiHoleToken + $script:PiHoleIgnoreSsl = $PiHoleIgnoreSsl + } + } + + It 'returns a valid session when given a real password' -Skip:(-not $script:ConfigAvailable) { + $result = Get-PiHoleAuthStatus -PiHoleServer $script:PiHoleServer -Password $script:PiHoleToken -IgnoreSsl $script:PiHoleIgnoreSsl + $result | Format-List | Out-String | Write-Host + + $result | Should -Not -BeNullOrEmpty + $result.Valid | Should -BeTrue + } + + # This test server requires a login for API clients, so calling with no password at all is + # expected to fail - this still exercises the real anonymous-check code path. A Pi-hole + # configured to skip auth for trusted local clients would instead return a valid session here. + It 'errors when called with no password and the server requires login' -Skip:(-not $script:ConfigAvailable) { + $result = Get-PiHoleAuthStatus -PiHoleServer $script:PiHoleServer -IgnoreSsl $script:PiHoleIgnoreSsl -ErrorVariable errOut -ErrorAction SilentlyContinue + + $errOut | Should -Not -BeNullOrEmpty + } + + It 'returns the raw API response when RawOutput is set' -Skip:(-not $script:ConfigAvailable) { + $result = Get-PiHoleAuthStatus -PiHoleServer $script:PiHoleServer -Password $script:PiHoleToken -IgnoreSsl $script:PiHoleIgnoreSsl -RawOutput $true + $result | Format-List | Out-String | Write-Host + + $result.PSObject.Properties.Name | Should -Contain 'session' + } + + It 'errors when given a bad password' -Skip:(-not $script:ConfigAvailable) { + $result = Get-PiHoleAuthStatus -PiHoleServer $script:PiHoleServer -Password 'definitely-not-the-real-token' -IgnoreSsl $script:PiHoleIgnoreSsl -ErrorVariable errOut -ErrorAction SilentlyContinue + + $errOut | Should -Not -BeNullOrEmpty + } +} diff --git a/tests/Authentication/Get-PiHoleAuthTotp.Integration.Tests.ps1 b/tests/Authentication/Get-PiHoleAuthTotp.Integration.Tests.ps1 new file mode 100644 index 0000000..90ac40d --- /dev/null +++ b/tests/Authentication/Get-PiHoleAuthTotp.Integration.Tests.ps1 @@ -0,0 +1,42 @@ +# Requires -Module Pester +# +# Integration tests that call a REAL Pi-hole server. Configure tests/IntegrationConfig.local.ps1 +# (copy it from IntegrationConfig.example.ps1) before running. Tests are skipped automatically +# if that file is missing. + +$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1') + +Describe 'Get-PiHoleAuthTotp (Integration)' -Tag 'Integration' { + BeforeAll { + Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force + + $configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1' + if (Test-Path $configPath) { + . $configPath + $script:PiHoleServer = $PiHoleServer + $script:PiHoleToken = $PiHoleToken + $script:PiHoleIgnoreSsl = $PiHoleIgnoreSsl + } + } + + It 'returns a suggested TOTP secret as a formatted object' -Skip:(-not $script:ConfigAvailable) { + $result = Get-PiHoleAuthTotp -PiHoleServer $script:PiHoleServer -Password $script:PiHoleToken -IgnoreSsl $script:PiHoleIgnoreSsl + $result | Format-List | Out-String | Write-Host + + $result | Should -Not -BeNullOrEmpty + $result.Secret | Should -Not -BeNullOrEmpty + } + + It 'returns the raw API response when RawOutput is set' -Skip:(-not $script:ConfigAvailable) { + $result = Get-PiHoleAuthTotp -PiHoleServer $script:PiHoleServer -Password $script:PiHoleToken -IgnoreSsl $script:PiHoleIgnoreSsl -RawOutput $true + $result | Format-List | Out-String | Write-Host + + $result.PSObject.Properties.Name | Should -Contain 'totp' + } + + It 'errors when given a bad password' -Skip:(-not $script:ConfigAvailable) { + $result = Get-PiHoleAuthTotp -PiHoleServer $script:PiHoleServer -Password 'definitely-not-the-real-token' -IgnoreSsl $script:PiHoleIgnoreSsl -ErrorVariable errOut -ErrorAction SilentlyContinue + + $errOut | Should -Not -BeNullOrEmpty + } +} diff --git a/tests/Authentication/New-PiHoleAppPassword.Integration.Tests.ps1 b/tests/Authentication/New-PiHoleAppPassword.Integration.Tests.ps1 new file mode 100644 index 0000000..a37640d --- /dev/null +++ b/tests/Authentication/New-PiHoleAppPassword.Integration.Tests.ps1 @@ -0,0 +1,58 @@ +# Requires -Module Pester +# +# Integration tests that call a REAL Pi-hole server. Configure tests/IntegrationConfig.local.ps1 +# (copy it from IntegrationConfig.example.ps1) before running. Tests are skipped automatically +# if that file is missing. +# +# NOTE: This only generates a candidate application password/hash pair - it has no effect until +# the returned Hash is explicitly set as webserver.api.app_pwhash in the Pi-hole configuration, +# which these tests deliberately never do, so there's nothing to clean up afterward and the +# server's real app password is left untouched. + +$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1') + +Describe 'New-PiHoleAppPassword (Integration)' -Tag 'Integration' { + BeforeAll { + Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force + + $configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1' + if (Test-Path $configPath) { + . $configPath + $script:PiHoleServer = $PiHoleServer + $script:PiHoleToken = $PiHoleToken + $script:PiHoleIgnoreSsl = $PiHoleIgnoreSsl + } + } + + It 'generates a new application password and hash as a formatted object' -Skip:(-not $script:ConfigAvailable) { + $result = New-PiHoleAppPassword -PiHoleServer $script:PiHoleServer -Password $script:PiHoleToken -IgnoreSsl $script:PiHoleIgnoreSsl + $result | Format-List | Out-String | Write-Host + + $result | Should -Not -BeNullOrEmpty + $result.Password | Should -Not -BeNullOrEmpty + $result.Hash | Should -Not -BeNullOrEmpty + } + + # Generating a password only ever hands back a fresh candidate - confirms the real password + # used throughout this suite still works afterward, i.e. generating one has no side effects + # until its hash is explicitly applied via config. + It 'does not invalidate the password used to generate it' -Skip:(-not $script:ConfigAvailable) { + New-PiHoleAppPassword -PiHoleServer $script:PiHoleServer -Password $script:PiHoleToken -IgnoreSsl $script:PiHoleIgnoreSsl | Out-Null + + $status = Get-PiHoleAuthStatus -PiHoleServer $script:PiHoleServer -Password $script:PiHoleToken -IgnoreSsl $script:PiHoleIgnoreSsl + $status.Valid | Should -BeTrue + } + + It 'returns the raw API response when RawOutput is set' -Skip:(-not $script:ConfigAvailable) { + $result = New-PiHoleAppPassword -PiHoleServer $script:PiHoleServer -Password $script:PiHoleToken -IgnoreSsl $script:PiHoleIgnoreSsl -RawOutput $true + $result | Format-List | Out-String | Write-Host + + $result.PSObject.Properties.Name | Should -Contain 'app' + } + + It 'errors when given a bad password' -Skip:(-not $script:ConfigAvailable) { + $result = New-PiHoleAppPassword -PiHoleServer $script:PiHoleServer -Password 'definitely-not-the-real-token' -IgnoreSsl $script:PiHoleIgnoreSsl -ErrorVariable errOut -ErrorAction SilentlyContinue + + $errOut | Should -Not -BeNullOrEmpty + } +} diff --git a/tools/Update-ExampleOutput.ps1 b/tools/Update-ExampleOutput.ps1 index c58b1ad..e192dc9 100644 --- a/tools/Update-ExampleOutput.ps1 +++ b/tools/Update-ExampleOutput.ps1 @@ -108,6 +108,15 @@ function Invoke-Quietly { Write-Host "Capturing example output against $PiHoleServer ..." #region Authentication +Add-Example -Category Authentication -FunctionName 'Get-PiHoleAuthStatus' ` + -Invocation 'Get-PiHoleAuthStatus -PiHoleServer $PiHoleServer -Password $Password' ` + -Note 'Password is optional - omit it to check whether your Pi-hole requires a login at all for this client, without authenticating. This test server does require login, so the result below is from a real authenticated check.' ` + -Result (Get-PiHoleAuthStatus -PiHoleServer $PiHoleServer -Password $PiHoleToken -IgnoreSsl $PiHoleIgnoreSsl) + +Add-Example -Category Authentication -FunctionName 'Get-PiHoleAuthTotp' ` + -Invocation 'Get-PiHoleAuthTotp -PiHoleServer $PiHoleServer -Password $Password' ` + -Result (Get-PiHoleAuthTotp -PiHoleServer $PiHoleServer -Password $PiHoleToken -IgnoreSsl $PiHoleIgnoreSsl) + Add-Example -Category Authentication -FunctionName 'Get-PiHoleCurrentAuthSession' ` -Invocation 'Get-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Password $Password' ` -Result (Get-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Password $PiHoleToken -IgnoreSsl $PiHoleIgnoreSsl) @@ -125,6 +134,11 @@ Add-Example -Category Authentication -FunctionName 'Remove-PiHoleAuthSession' ` -Note 'Deletes a session by its ID (as shown by Get-PiHoleCurrentAuthSession), not the caller''s own session.' ` -Result (Remove-PiHoleAuthSession -PiHoleServer $PiHoleServer -Password $PiHoleToken -IgnoreSsl $PiHoleIgnoreSsl -Id $extraSessionId) +Add-Example -Category Authentication -FunctionName 'New-PiHoleAppPassword' ` + -Invocation 'New-PiHoleAppPassword -PiHoleServer $PiHoleServer -Password $Password' ` + -Note 'This only generates a candidate password/hash pair - it has no effect until the returned Hash is set as webserver.api.app_pwhash in the Pi-hole configuration, which this example deliberately does not do, so the real password used throughout this document keeps working.' ` + -Result (New-PiHoleAppPassword -PiHoleServer $PiHoleServer -Password $PiHoleToken -IgnoreSsl $PiHoleIgnoreSsl) + $extraSid2 = & (Get-Module PiHoleShell) { param($s, $p, $i) Request-PiHoleAuth -PiHoleServer $s -Password $p -IgnoreSsl $i } $PiHoleServer $PiHoleToken $PiHoleIgnoreSsl Add-Example -Category Authentication -FunctionName 'Remove-PiHoleCurrentAuthSession' ` -Invocation 'Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid' ` From 4c89bdb773f4fc9bcf0e1ccb34f22945f4d9bf0c Mon Sep 17 00:00:00 2001 From: Mike Madeja Date: Thu, 1 Oct 2026 09:25:17 -0500 Subject: [PATCH 2/3] docs: regenerate EXAMPLES.md after merging develop Picks up DHCP's examples alongside the Authentication ones added on this branch, and refreshes stale stats/history output with fresh captured data. Co-Authored-By: Claude Sonnet 5 --- docs/EXAMPLES.md | 429 +++++++++++++++++++++++++---------------------- 1 file changed, 232 insertions(+), 197 deletions(-) diff --git a/docs/EXAMPLES.md b/docs/EXAMPLES.md index 15b4653..e1d0903 100644 --- a/docs/EXAMPLES.md +++ b/docs/EXAMPLES.md @@ -99,9 +99,9 @@ New-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -GroupName "PiHo Name : PiHoleShellDocsExampleGroup Comment : Example group Enabled : True -Id : 61 -DateAdded : 9/30/2026 7:36:16 PM -DateModified : 9/30/2026 7:36:16 PM +Id : 49 +DateAdded : 10/1/2026 9:09:43 AM +DateModified : 10/1/2026 9:09:43 AM ``` ### Get-PiHoleGroup @@ -143,9 +143,9 @@ DateModified : 9/30/2026 8:48:26 AM Name : PiHoleShellDocsExampleGroup Comment : Example group Enabled : True -Id : 61 -DateAdded : 9/30/2026 7:36:16 PM -DateModified : 9/30/2026 7:36:16 PM +Id : 49 +DateAdded : 10/1/2026 9:09:43 AM +DateModified : 10/1/2026 9:09:43 AM ``` ### Update-PiHoleGroup @@ -159,9 +159,9 @@ Update-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -GroupName "P Name : PiHoleShellDocsExampleGroup Comment : Example group Enabled : False -Id : 61 -DateAdded : 9/30/2026 7:36:16 PM -DateModified : 9/30/2026 7:36:34 PM +Id : 49 +DateAdded : 10/1/2026 9:09:43 AM +DateModified : 10/1/2026 9:10:16 AM ``` ### Remove-PiHoleGroup @@ -190,9 +190,9 @@ Address : https://blocklistproject.github.io/Lists/alt-version/ransomware Comment : Example list Groups : {Default} Enabled : True -Id : 73 -DateAdded : 9/30/2026 7:37:11 PM -DateModified : 9/30/2026 7:37:11 PM +Id : 69 +DateAdded : 10/1/2026 9:11:26 AM +DateModified : 10/1/2026 9:11:26 AM Type : Block DateUpdated : Number : 0 @@ -294,9 +294,9 @@ Address : https://blocklistproject.github.io/Lists/alt-version/ransomware Comment : Example list Groups : {Default} Enabled : False -Id : 73 -DateAdded : 9/30/2026 7:37:11 PM -DateModified : 9/30/2026 7:37:45 PM +Id : 69 +DateAdded : 10/1/2026 9:11:26 AM +DateModified : 10/1/2026 9:12:28 AM Type : Block DateUpdated : Number : 0 @@ -421,9 +421,9 @@ Kind : Exact Comment : Example domain Groups : {Default} Enabled : True -Id : 24 -DateAdded : 9/30/2026 7:38:22 PM -DateModified : 9/30/2026 7:38:22 PM +Id : 17 +DateAdded : 10/1/2026 9:13:40 AM +DateModified : 10/1/2026 9:13:40 AM ``` ### Get-PiHoleDomain @@ -434,6 +434,17 @@ Get-PiHoleDomain -PiHoleServer $PiHoleServer -Password $Password ``` +Domain : piholeshell-test-domain.example.com +Unicode : piholeshell-test-domain.example.com +Type : allow +Kind : exact +Comment : +Groups : {Default} +Enabled : True +Id : 16 +DateAdded : 10/1/2026 9:13:34 AM +DateModified : 10/1/2026 9:13:34 AM + Domain : piholeshell-docs-example.com Unicode : piholeshell-docs-example.com Type : allow @@ -441,9 +452,9 @@ Kind : exact Comment : Example domain Groups : {Default} Enabled : True -Id : 24 -DateAdded : 9/30/2026 7:38:22 PM -DateModified : 9/30/2026 7:38:22 PM +Id : 17 +DateAdded : 10/1/2026 9:13:40 AM +DateModified : 10/1/2026 9:13:40 AM ``` ### Update-PiHoleDomain @@ -461,9 +472,9 @@ Kind : Exact Comment : Example domain Groups : {Default} Enabled : False -Id : 24 -DateAdded : 9/30/2026 7:38:22 PM -DateModified : 9/30/2026 7:38:56 PM +Id : 17 +DateAdded : 10/1/2026 9:13:40 AM +DateModified : 10/1/2026 9:14:42 AM ``` ### Remove-PiHoleDomain @@ -494,9 +505,9 @@ Client : 192.168.99.99 Name : Comment : Example client Groups : {Default} -Id : 25 -DateAdded : 9/30/2026 7:39:27 PM -DateModified : 9/30/2026 7:39:27 PM +Id : 20 +DateAdded : 10/1/2026 9:15:42 AM +DateModified : 10/1/2026 9:15:42 AM ``` ### Get-PiHoleClient @@ -511,9 +522,9 @@ Client : 192.168.99.99 Name : Comment : Example client Groups : {Default} -Id : 25 -DateAdded : 9/30/2026 7:39:27 PM -DateModified : 9/30/2026 7:39:27 PM +Id : 20 +DateAdded : 10/1/2026 9:15:42 AM +DateModified : 10/1/2026 9:15:42 AM ``` ### Get-PiHoleClientSuggestion @@ -526,13 +537,13 @@ Get-PiHoleClientSuggestion -PiHoleServer $PiHoleServer -Password $Password HwAddr : ip-127.0.0.1 MacVendor : -LastQuery : 9/30/2026 7:00:00 PM +LastQuery : 10/1/2026 9:03:34 AM Addresses : 127.0.0.1 Names : localhost HwAddr : 74:56:3c:bb:f4:0b MacVendor : Giga-Byte Technology Co.,Ltd. -LastQuery : 9/30/2026 4:19:27 PM +LastQuery : 10/1/2026 9:03:33 AM Addresses : 192.168.1.162 Names : ``` @@ -549,9 +560,9 @@ Client : 192.168.99.99 Name : Comment : Updated comment Groups : {Default} -Id : 25 -DateAdded : 9/30/2026 7:39:27 PM -DateModified : 9/30/2026 7:40:08 PM +Id : 20 +DateAdded : 10/1/2026 9:15:42 AM +DateModified : 10/1/2026 9:16:53 AM ``` ### Remove-PiHoleClient @@ -576,18 +587,18 @@ Get-PiHoleStatsSummary -PiHoleServer $PiHoleServer -Password $Password ``` -Total : 49 -Blocked : 8 -PercentBlocked : 16.326530456543 +Total : 42 +Blocked : 10 +PercentBlocked : 23.8095245361328 UniqueDomains : 15 Forwarded : 27 -Cached : 14 +Cached : 5 Frequency : 0 -Types : @{A=19; AAAA=20; ANY=0; SRV=0; SOA=0; PTR=10; TXT=0; NAPTR=0; MX=0; DS=0; RRSIG=0; DNSKEY=0; NS=0; SVCB=0; HTTPS=0; OTHER=0} -Status : @{Unknown=0; Gravity=8; Forwarded=27; Cache=14; Regex=0; DenyList=0; ExternalBlockedIp=0; ExternalBlockedNull=0; ExternalBlockedNxra=0; GravityCname=0; RegexCname=0; DenyListCname=0; Retired=0; RetiredDnssec=0; InProgress=0; Dbbusy=0; SpecialDomain=0; CacheStale=0; ExternalBlockedEde15=0} -Replies : @{Unknown=10; Nodata=2; Nxdomain=3; Cname=0; Ip=27; Domain=7; Rrname=0; ServFail=0; Refused=0; Notimp=0; Other=0; Dnssec=0; None=0; Blob=0} +Types : @{A=20; AAAA=19; ANY=0; SRV=0; SOA=0; PTR=3; TXT=0; NAPTR=0; MX=0; DS=0; RRSIG=0; DNSKEY=0; NS=0; SVCB=0; HTTPS=0; OTHER=0} +Status : @{Unknown=0; Gravity=10; Forwarded=27; Cache=5; Regex=0; DenyList=0; ExternalBlockedIp=0; ExternalBlockedNull=0; ExternalBlockedNxra=0; GravityCname=0; RegexCname=0; DenyListCname=0; Retired=0; RetiredDnssec=0; InProgress=0; Dbbusy=0; SpecialDomain=0; CacheStale=0; ExternalBlockedEde15=0} +Replies : @{Unknown=10; Nodata=3; Nxdomain=1; Cname=0; Ip=26; Domain=2; Rrname=0; ServFail=0; Refused=0; Notimp=0; Other=0; Dnssec=0; None=0; Blob=0} Clients : @{Active=2; Total=2} -Gravity : @{DomainsBeingBlocked=494952; LastUpdate=1790799702} +Gravity : @{DomainsBeingBlocked=495564; LastUpdate=1790861541} ``` ### Get-PiHoleStatsRecentBlocked @@ -598,7 +609,7 @@ Get-PiHoleStatsRecentBlocked -PiHoleServer $PiHoleServer -Password $Password ``` -Blocked : adservice.google.com +Blocked : googleadservices.com ``` ### Get-PiHoleStatsQueryType @@ -610,10 +621,10 @@ Get-PiHoleStatsQueryType -PiHoleServer $PiHoleServer -Password $Password ``` Type : A -Count : 19 +Count : 20 Type : AAAA -Count : 20 +Count : 19 Type : ANY Count : 0 @@ -635,19 +646,19 @@ Get-PiHoleStatsTopDomain -PiHoleServer $PiHoleServer -Password $Password ``` -Domain : mozilla.org +Domain : cloudflare.com Count : 4 -Domain : bbc.com +Domain : example.com Count : 4 -Domain : stackoverflow.com +Domain : bbc.com Count : 4 -Domain : cloudflare.com +Domain : reddit.com Count : 4 -Domain : 1.0.0.127.in-addr.arpa +Domain : stackoverflow.com Count : 4 _(showing 5 of 10 results)_ @@ -667,7 +678,7 @@ Count : 39 IP : 127.0.0.1 Name : localhost -Count : 10 +Count : 3 ``` ### Get-PiHoleStatsUpstream @@ -678,9 +689,9 @@ Get-PiHoleStatsUpstream -PiHoleServer $PiHoleServer -Password $Password ``` -TotalQueries : 49 +TotalQueries : 42 ForwardedQueries : 27 -Upstreams : {@{Ip=blocklist; Name=blocklist; Port=-1; Count=8; ResponseTime=0; Variance=0}, @{Ip=cache; Name=cache; Port=-1; Count=14; ResponseTime=0; Variance=0}, @{Ip=8.8.8.8; Name=dns.google; Port=53; Count=27; ResponseTime=0.0287302732467651; Variance=0.00306724246755919}} +Upstreams : {@{Ip=blocklist; Name=blocklist; Port=-1; Count=10; ResponseTime=0; Variance=0}, @{Ip=cache; Name=cache; Port=-1; Count=5; ResponseTime=0; Variance=0}, @{Ip=8.8.8.8; Name=dns.google; Port=53; Count=27; ResponseTime=0.0202921777963638; Variance=0.00264818341859654}} ``` ### Get-PiHoleStatsQuerySuggestions @@ -691,7 +702,7 @@ Get-PiHoleStatsQuerySuggestions -PiHoleServer $PiHoleServer -Password $Password ``` -Domain : {mozilla.org, bbc.com, stackoverflow.com, cloudflare.com…} +Domain : {cloudflare.com, example.com, bbc.com, reddit.com…} ClientIp : {192.168.1.162, 127.0.0.1} ClientName : {localhost} Upstream : {blocklist, cache, 8.8.8.8#53 (dns.google), permitted} @@ -711,9 +722,9 @@ Get-PiHoleStatsDatabaseSummary -PiHoleServer $PiHoleServer -Password $Password ``` -SumQueries : 49 -SumBlocked : 8 -PercentBlocked : 16.326530456543 +SumQueries : 42 +SumBlocked : 10 +PercentBlocked : 23.8095245361328 TotalClients : 3 ``` @@ -728,7 +739,7 @@ Get-PiHoleStatsDatabaseQueryType -PiHoleServer $PiHoleServer -Password $Password ``` Type : A -Count : 20 +Count : 19 Type : AAAA Count : 0 @@ -740,7 +751,7 @@ Type : SRV Count : 0 Type : SOA -Count : 10 +Count : 3 _(showing 5 of 16 results)_ ``` @@ -755,13 +766,10 @@ Get-PiHoleStatsDatabaseTopDomain -PiHoleServer $PiHoleServer -Password $Password ``` -Domain : nytimes.com -Count : 4 - Domain : bbc.com Count : 4 -Domain : mozilla.org +Domain : wikipedia.org Count : 4 Domain : example.com @@ -770,6 +778,9 @@ Count : 4 Domain : stackoverflow.com Count : 4 +Domain : reddit.com +Count : 4 + _(showing 5 of 10 results)_ ``` @@ -785,15 +796,15 @@ Get-PiHoleStatsDatabaseTopClient -PiHoleServer $PiHoleServer -Password $Password IP : 192.168.1.162 Name : -Count : 31 - -IP : 127.0.0.1 -Name : localhost -Count : 8 +Count : 29 IP : 127.0.0.1 Name : Count : 2 + +IP : 127.0.0.1 +Name : localhost +Count : 1 ``` ### Get-PiHoleStatsDatabaseUpstream @@ -806,9 +817,9 @@ Get-PiHoleStatsDatabaseUpstream -PiHoleServer $PiHoleServer -Password $Password ``` -TotalQueries : 49 +TotalQueries : 42 ForwardedQueries : 27 -Upstreams : {@{Ip=2; Name=; Port=4294967295; Count=27; ResponseTime=0; Variance=0}, @{Ip=cache; Name=cache; Port=-1; Count=14; ResponseTime=0; Variance=0}, @{Ip=blocklist; Name=blocklist; Port=-1; Count=8; ResponseTime=0; Variance=0}} +Upstreams : {@{Ip=2; Name=; Port=4294967295; Count=27; ResponseTime=0; Variance=0}, @{Ip=cache; Name=cache; Port=-1; Count=5; ResponseTime=0; Variance=0}, @{Ip=blocklist; Name=blocklist; Port=-1; Count=10; ResponseTime=0; Variance=0}} ``` ### Get-PiHoleQuery @@ -821,69 +832,69 @@ Get-PiHoleQuery -PiHoleServer $PiHoleServer -Password $Password -Length 5 ``` -Id : 48 -Time : 9/30/2026 7:00:01 PM +Id : 41 +Time : 10/1/2026 9:03:34 AM Type : PTR Domain : 1.0.0.127.in-addr.arpa Cname : Status : CACHE Client : @{Ip=127.0.0.1; Name=localhost} Dnssec : UNKNOWN -Reply : @{Type=DOMAIN; Time=0.000156879425048828} +Reply : @{Type=DOMAIN; Time=0.00114798545837402} ListId : Upstream : Ede : @{Code=-1; Text=} -Id : 47 -Time : 9/30/2026 6:00:01 PM -Type : PTR -Domain : 8.8.8.8.in-addr.arpa +Id : 40 +Time : 10/1/2026 9:03:33 AM +Type : A +Domain : stackoverflow.com Cname : -Status : CACHE -Client : @{Ip=127.0.0.1; Name=localhost} +Status : FORWARDED +Client : @{Ip=192.168.1.162; Name=} Dnssec : UNKNOWN -Reply : @{Type=DOMAIN; Time=0.00014805793762207} +Reply : @{Type=IP; Time=0.0158865451812744} ListId : -Upstream : +Upstream : 8.8.8.8#53 Ede : @{Code=-1; Text=} -Id : 46 -Time : 9/30/2026 6:00:01 PM -Type : PTR -Domain : 1.0.0.127.in-addr.arpa +Id : 39 +Time : 10/1/2026 9:03:33 AM +Type : AAAA +Domain : stackoverflow.com Cname : Status : CACHE -Client : @{Ip=127.0.0.1; Name=localhost} +Client : @{Ip=192.168.1.162; Name=} Dnssec : UNKNOWN -Reply : @{Type=DOMAIN; Time=0.000154972076416016} +Reply : @{Type=NODATA; Time=0.000108003616333008} ListId : Upstream : Ede : @{Code=-1; Text=} -Id : 45 -Time : 9/30/2026 6:00:01 PM -Type : PTR -Domain : 162.1.168.192.in-addr.arpa +Id : 38 +Time : 10/1/2026 9:03:33 AM +Type : AAAA +Domain : stackoverflow.com Cname : -Status : CACHE -Client : @{Ip=127.0.0.1; Name=localhost} +Status : FORWARDED +Client : @{Ip=192.168.1.162; Name=} Dnssec : UNKNOWN -Reply : @{Type=NXDOMAIN; Time=0.000169992446899414} +Reply : @{Type=NODATA; Time=0.0325107574462891} ListId : -Upstream : +Upstream : 8.8.8.8#53 Ede : @{Code=-1; Text=} -Id : 44 -Time : 9/30/2026 5:00:01 PM -Type : PTR -Domain : 8.8.8.8.in-addr.arpa +Id : 37 +Time : 10/1/2026 9:03:33 AM +Type : A +Domain : stackoverflow.com Cname : -Status : CACHE -Client : @{Ip=127.0.0.1; Name=localhost} +Status : FORWARDED +Client : @{Ip=192.168.1.162; Name=} Dnssec : UNKNOWN -Reply : @{Type=DOMAIN; Time=0.00167107582092285} +Reply : @{Type=UNKNOWN; Time=0} ListId : -Upstream : +Upstream : 8.8.8.8#53 Ede : @{Code=-1; Text=} ``` @@ -978,20 +989,20 @@ CpuPercent : 0 MemoryPercent : 0 ActiveClients : 2 Blocking : enabled -Cache : @{Size=10000; Inserted=38; Evicted=0} +Cache : @{Size=10000; Inserted=35; Evicted=0} Config : @{DhcpActive=False; DhcpStart=; DhcpEnd=; DhcpIpv6=False; DnsDnssec=False; DnsDomain=lan; DnsNumUpstreams=2; DnsPort=53; DnsrevServerAactive=False; PrivacyLevel=0} -GravitySize : 494952 +GravitySize : 495564 HostModel : Raspberry Pi Zero W Rev 1.1 IFace : @{v4=; v6=} NodeName : dns3.localdomain Pid : 388 -Queries : @{Total=49; Blocked=8; PercentBlocked=16.326530456543; QueryFrequency=0} -RecentBlocked : adservice.google.com -Sensors : @{CpuTemp=39.546; HotLimit=60; Unit=C} -System : @{Uptime=165232; Memory=; Procs=74; Cpu=; Ftl=} +Queries : @{Total=42; Blocked=10; PercentBlocked=23.8095245361328; QueryFrequency=0} +RecentBlocked : googleadservices.com +Sensors : @{CpuTemp=42.774; HotLimit=60; Unit=C} +System : @{Uptime=213957; Memory=; Procs=72; Cpu=; Ftl=} TopBlocked : googleadservices.com TopClient : 192.168.1.162 -TopDomain : nytimes.com +TopDomain : bbc.com Version : @{Core=; Web=; Ftl=; Docker=} ``` @@ -1028,11 +1039,11 @@ Get-PiHoleInfoSystem -PiHoleServer $PiHoleServer -Password $Password ``` -Uptime : 165242 +Uptime : 213977 Memory : @{Ram=; Swap=} -Procs : 74 -Cpu : @{NumProcessors=1; PercentCpu=97; Load=} -Ftl : @{PercentMemory=2.59335684776306; PercentCpu=96.4000015258789} +Procs : 72 +Cpu : @{NumProcessors=1; PercentCpu=99.6999969482422; Load=} +Ftl : @{PercentMemory=2.38457298278809; PercentCpu=99.1999969482422} ``` ### Get-PiHoleInfoFtl @@ -1043,16 +1054,16 @@ Get-PiHoleInfoFtl -PiHoleServer $PiHoleServer -Password $Password ``` -Database : @{Gravity=494952; Antigravity=0; Groups=4; Lists=14; Clients=0; Domains=; Regex=} +Database : @{Gravity=495564; Antigravity=0; Groups=4; Lists=14; Clients=0; Domains=; Regex=} PrivacyLevel : 0 QueryFrequency : 0 Clients : @{Total=2; Active=2} Pid : 388 -Uptime : 15409712.410978 -PercentMemory : 2.59335684776306 -PercentCpu : 96.4000015258789 +Uptime : 2344208.686637 +PercentMemory : 2.38457298278809 +PercentCpu : 99.3000030517578 AllowDestructive : True -Dnsmasq : @{DnsCacheInserted=38; DnsCacheLiveFreed=0; DnsQueriesForwarded=27; DnsAuthAnswered=0; DnsLocalAnswered=22; DnsStaleAnswered=0; DnsUnanswered=0; DnssecMaxCryptoUse=0; DnssecMaxSigFail=0; DnssecMaxWork=0; Bootp=0; Pxe=0; DhcpAck=0; DhcpDecline=0; DhcpDiscover=0; DhcpInform=0; DhcpNak=0; DhcpOffer=0; DhcpRelease=0; DhcpRequest=0; Noanswer=0; LeasesAllocated4=0; LeasesPruned4=0; LeasesAllocated6=0; LeasesPruned6=0; TcpConnections=0; DhcpLeasequery=0; DhcpLeaseUnassigned=0; DhcpLeaseActve=0; DhcpLeaseUnknown=0} +Dnsmasq : @{DnsCacheInserted=35; DnsCacheLiveFreed=0; DnsQueriesForwarded=27; DnsAuthAnswered=0; DnsLocalAnswered=15; DnsStaleAnswered=0; DnsUnanswered=0; DnssecMaxCryptoUse=0; DnssecMaxSigFail=0; DnssecMaxWork=0; Bootp=0; Pxe=0; DhcpAck=0; DhcpDecline=0; DhcpDiscover=0; DhcpInform=0; DhcpNak=0; DhcpOffer=0; DhcpRelease=0; DhcpRequest=0; Noanswer=0; LeasesAllocated4=0; LeasesPruned4=0; LeasesAllocated6=0; LeasesPruned6=0; TcpConnections=0; DhcpLeasequery=0; DhcpLeaseUnassigned=0; DhcpLeaseActve=0; DhcpLeaseUnknown=0} ``` ### Get-PiHoleInfoSensors @@ -1064,7 +1075,7 @@ Get-PiHoleInfoSensors -PiHoleServer $PiHoleServer -Password $Password ``` List : {@{Name=cpu_thermal; Path=hwmon0; Source=devices/virtual/thermal/thermal_zone0; Temps=}, @{Name=rpi_volt; Path=hwmon1; Source=devices/platform/soc/soc:firmware/raspberrypi-hwmon; Temps=}} -CpuTemp : 39.546 +CpuTemp : 42.774 HotLimit : 60 Unit : C ``` @@ -1081,12 +1092,12 @@ Size : 13983744 Type : Regular file Mode : rw-r----- AccessTime : 6/25/2025 12:32:44 AM -ModifiedTime : 9/30/2026 6:41:00 PM -ChangeTime : 9/30/2026 6:41:00 PM +ModifiedTime : 10/1/2026 8:28:19 AM +ChangeTime : 10/1/2026 8:28:20 AM Owner : @{User=; Group=} -Queries : 49 -EarliestTimestamp : 9/29/2026 7:30:00 PM -QueriesDisk : 49 +Queries : 42 +EarliestTimestamp : 9/30/2026 9:00:00 AM +QueriesDisk : 42 EarliestTimestampDisk : SqliteVersion : 3.53.1 ``` @@ -1155,17 +1166,17 @@ Get-PiHoleInfoMessage -PiHoleServer $PiHoleServer -Password $Password ``` -Id : 30 -Timestamp : 9/30/2026 4:26:17 PM +Id : 1 +Timestamp : 10/1/2026 8:28:21 AM Type : LIST Plain : List with ID 63 (https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/domains/light.txt) was inaccessible during last gravity run Html : List with ID 63 (https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/domains/light.txt) was inaccessible during last gravity run -Id : 31 -Timestamp : 9/30/2026 4:33:16 PM +Id : 2 +Timestamp : 10/1/2026 9:03:21 AM Type : LOAD -Plain : Long-term load (15min avg) larger than number of processors: 1.1 > 1 -Html : Long-term load (15min avg) larger than number of processors: 1.1 > 1
This may slow down DNS resolution and can cause bottlenecks. +Plain : Long-term load (15min avg) larger than number of processors: 1.9 > 1 +Html : Long-term load (15min avg) larger than number of processors: 1.9 > 1
This may slow down DNS resolution and can cause bottlenecks. ``` ### Get-PiHoleInfoMessageCount @@ -1200,8 +1211,8 @@ Get-PiHoleLogWebserver -PiHoleServer $PiHoleServer -Password $Password ``` -Log : {@{Timestamp=9/30/2026 3:18:16 PM; Message=Initializing HTTP server on ports "8089,8489s"; Priority=}, @{Timestamp=9/30/2026 3:29:52 PM; Message=ACCESS: 192.168.1.162 - - [30/Sep/2026:20:29:51 +0000] "PATCH /api/config?restart=false HTTP/1.1" 200 4588 - Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6; Priority=}, @{Timestamp=9/30/2026 3:29:53 PM; Message=ACCESS: 192.168.1.162 - - [30/Sep/2026:20:29:52 +0000] "DELETE /api/auth HTTP/1.1" 204 558 - Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6; Priority=}, @{Timestamp=9/30/2026 3:29:54 PM; Message=ACCESS: 192.168.1.162 - - [30/Sep/2026:20:29:45 +0000] "POST /api/auth HTTP/1.1" 200 806 - Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6; Priority=}…} -NextID : 36 +Log : {@{Timestamp=10/1/2026 8:28:22 AM; Message=Initializing HTTP server on ports "8089,8489s"; Priority=}, @{Timestamp=10/1/2026 8:31:16 AM; Message=ACCESS: 192.168.1.162 - - [01/Oct/2026:13:31:15 +0000] "PATCH /api/config?restart=false HTTP/1.1" 200 4588 - Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6; Priority=}, @{Timestamp=10/1/2026 8:31:17 AM; Message=ACCESS: 192.168.1.162 - - [01/Oct/2026:13:31:16 +0000] "DELETE /api/auth HTTP/1.1" 204 558 - Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6; Priority=}, @{Timestamp=10/1/2026 8:31:26 AM; Message=ACCESS: 192.168.1.162 - - [01/Oct/2026:13:31:17 +0000] "POST /api/auth HTTP/1.1" 200 807 - Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6; Priority=}…} +NextID : 28 Pid : 388 File : /var/log/pihole/webserver.log ``` @@ -1214,8 +1225,8 @@ Get-PiHoleLogDnsmasq -PiHoleServer $PiHoleServer -Password $Password ``` -Log : {@{Timestamp=9/30/2026 3:18:16 PM; Message=started, version pi-hole-v2.93 cachesize 10000; Priority=}, @{Timestamp=9/30/2026 3:18:16 PM; Message=DNS service limited to local subnets; Priority=}, @{Timestamp=9/30/2026 3:18:16 PM; Message=compile time options: IPv6 GNU-getopt no-DBus no-UBus no-i18n IDN2 DHCP DHCPv6 Lua TFTP no-conntrack ipset no-nftset auth DNSSEC loop-detect inotify dumpfile; Priority=}, @{Timestamp=9/30/2026 3:18:16 PM; Message=using nameserver 8.8.8.8#53; Priority=}…} -NextID : 75 +Log : {@{Timestamp=10/1/2026 8:28:22 AM; Message=started, version pi-hole-v2.93 cachesize 10000; Priority=}, @{Timestamp=10/1/2026 8:28:22 AM; Message=DNS service limited to local subnets; Priority=}, @{Timestamp=10/1/2026 8:28:22 AM; Message=compile time options: IPv6 GNU-getopt no-DBus no-UBus no-i18n IDN2 DHCP DHCPv6 Lua TFTP no-conntrack ipset no-nftset auth DNSSEC loop-detect inotify dumpfile; Priority=}, @{Timestamp=10/1/2026 8:28:22 AM; Message=using nameserver 8.8.8.8#53; Priority=}…} +NextID : 63 Pid : 388 File : /var/log/pihole/pihole.log ``` @@ -1228,8 +1239,8 @@ Get-PiHoleLogFtl -PiHoleServer $PiHoleServer -Password $Password ``` -Log : {@{Timestamp=9/30/2026 3:47:52 PM; Message=Compiled 0 allow and 0 deny regex for 0 client in 0.9 msec; Priority=INFO}, @{Timestamp=9/30/2026 3:47:52 PM; Message=List with ID 63 (https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/domains/light.txt) was inaccessible during last gravity run; Priority=WARNING}, @{Timestamp=9/30/2026 3:47:52 PM; Message=Requested API URI: 192.168.1.162 -> POST /api/auth ? (null) (Content-Type application/json); Priority=DEBUG_API}, @{Timestamp=9/30/2026 3:47:52 PM; Message=Received payload with size: 66; Priority=DEBUG_API}…} -NextID : 1025 +Log : {@{Timestamp=10/1/2026 8:48:25 AM; Message=Compiled 0 allow and 0 deny regex for 0 client in 0.9 msec; Priority=INFO}, @{Timestamp=10/1/2026 8:48:31 AM; Message=Wrote config file:; Priority=INFO}, @{Timestamp=10/1/2026 8:48:31 AM; Message= - 167 total entries; Priority=INFO}, @{Timestamp=10/1/2026 8:48:31 AM; Message= - 156 entries are default; Priority=INFO}…} +NextID : 666 Pid : 388 File : /var/log/pihole/FTL.log ``` @@ -1258,31 +1269,31 @@ Get-PiHoleHistory -PiHoleServer $PiHoleServer -Password $Password ``` -Timestamp : 9/29/2026 7:45:00 PM +Timestamp : 9/30/2026 9:25:00 AM Total : 0 Cached : 0 Blocked : 0 Forwarded : 0 -Timestamp : 9/29/2026 7:55:00 PM +Timestamp : 9/30/2026 9:35:00 AM Total : 0 Cached : 0 Blocked : 0 Forwarded : 0 -Timestamp : 9/29/2026 8:05:00 PM +Timestamp : 9/30/2026 9:45:00 AM Total : 0 Cached : 0 Blocked : 0 Forwarded : 0 -Timestamp : 9/29/2026 8:15:00 PM +Timestamp : 9/30/2026 9:55:00 AM Total : 0 Cached : 0 Blocked : 0 Forwarded : 0 -Timestamp : 9/29/2026 8:25:00 PM +Timestamp : 9/30/2026 10:05:00 AM Total : 0 Cached : 0 Blocked : 0 @@ -1299,19 +1310,19 @@ Get-PiHoleHistoryClient -PiHoleServer $PiHoleServer -Password $Password ``` -Timestamp : 9/29/2026 7:45:00 PM +Timestamp : 9/30/2026 9:25:00 AM Clients : {@{IP=192.168.1.162; Name=; Count=0}, @{IP=others; Name=; Count=0}} -Timestamp : 9/29/2026 7:55:00 PM +Timestamp : 9/30/2026 9:35:00 AM Clients : {@{IP=192.168.1.162; Name=; Count=0}, @{IP=others; Name=; Count=0}} -Timestamp : 9/29/2026 8:05:00 PM +Timestamp : 9/30/2026 9:45:00 AM Clients : {@{IP=192.168.1.162; Name=; Count=0}, @{IP=others; Name=; Count=0}} -Timestamp : 9/29/2026 8:15:00 PM +Timestamp : 9/30/2026 9:55:00 AM Clients : {@{IP=192.168.1.162; Name=; Count=0}, @{IP=others; Name=; Count=0}} -Timestamp : 9/29/2026 8:25:00 PM +Timestamp : 9/30/2026 10:05:00 AM Clients : {@{IP=192.168.1.162; Name=; Count=0}, @{IP=others; Name=; Count=0}} _(showing 5 of 145 results)_ @@ -1327,29 +1338,11 @@ Get-PiHoleHistoryDatabase -PiHoleServer $PiHoleServer -Password $Password ``` -Timestamp : 9/30/2026 4:10:00 PM +Timestamp : 10/1/2026 9:00:00 AM Total : 42 -Cached : 7 -Blocked : 8 +Cached : 5 +Blocked : 10 Forwarded : 27 - -Timestamp : 9/30/2026 5:00:00 PM -Total : 3 -Cached : 3 -Blocked : 0 -Forwarded : 0 - -Timestamp : 9/30/2026 6:00:00 PM -Total : 3 -Cached : 3 -Blocked : 0 -Forwarded : 0 - -Timestamp : 9/30/2026 7:00:00 PM -Total : 1 -Cached : 1 -Blocked : 0 -Forwarded : 0 ``` ### Get-PiHoleHistoryDatabaseClient @@ -1362,16 +1355,7 @@ Get-PiHoleHistoryDatabaseClient -PiHoleServer $PiHoleServer -Password $Password ``` -Timestamp : 9/30/2026 7:00:00 PM -Clients : @{ClientId=3; Count=1} - -Timestamp : 9/30/2026 6:00:00 PM -Clients : @{ClientId=3; Count=1} - -Timestamp : 9/30/2026 5:00:00 PM -Clients : @{ClientId=3; Count=1} - -Timestamp : 9/30/2026 4:10:00 PM +Timestamp : 10/1/2026 9:00:00 AM Clients : {@{ClientId=3; Count=1}, @{ClientId=2; Count=1}, @{ClientId=5; Count=1}} ``` @@ -1468,7 +1452,7 @@ ProtoDown : False Address : 00:00:00:00:00:00 Broadcast : 00:00:00:00:00:00 Stats : @{RxBytes=; TxBytes=; Bits=64} -Addresses : {@{Family=inet; Scope=host; Flags=permanent; Prefixlen=8; Address=127.0.0.1; AddressType=loopback; Local=127.0.0.1; LocalType=loopback; Label=lo; Prefered=4294967295; Valid=4294967295; Cstamp=1790649664.02; Tstamp=1790649664.02}, @{Family=inet6; Scope=host; Flags=permanent; Prefixlen=128; Address=::1; AddressType=loopback; Prefered=4294967295; Valid=4294967295; Cstamp=1790649664.02; Tstamp=1790649664.02}} +Addresses : {@{Family=inet; Scope=host; Flags=permanent; Prefixlen=8; Address=127.0.0.1; AddressType=loopback; Local=127.0.0.1; LocalType=loopback; Label=lo; Prefered=4294967295; Valid=4294967295; Cstamp=1790649663.02; Tstamp=1790649663.02}, @{Family=inet6; Scope=host; Flags=permanent; Prefixlen=128; Address=::1; AddressType=loopback; Prefered=4294967295; Valid=4294967295; Cstamp=1790649663.02; Tstamp=1790649663.02}} Name : wlan0 Speed : @@ -1481,7 +1465,7 @@ Address : b8:27:eb:11:a4:d5 Broadcast : ff:ff:ff:ff:ff:ff PermAddress : b8:27:eb:11:a4:d5 Stats : @{RxBytes=; TxBytes=; Bits=64} -Addresses : {@{Family=inet; Scope=universe; Flags=; Prefixlen=24; Address=192.168.1.248; AddressType=private; Local=192.168.1.248; LocalType=private; Broadcast=192.168.1.255; BroadcastType=private; Label=wlan0; Prefered=64531; Valid=64531; Cstamp=1790649688.41; Tstamp=1790793451.81}, @{Family=inet6; Scope=link; Flags=permanent; Prefixlen=64; Address=fe80::ba27:ebff:fe11:a4d5; AddressType=link-local (LL); Prefered=4294967295; Valid=4294967295; Cstamp=1790649683.83; Tstamp=1790649683.83}} +Addresses : {@{Family=inet; Scope=universe; Flags=; Prefixlen=24; Address=192.168.1.248; AddressType=private; Local=192.168.1.248; LocalType=private; Broadcast=192.168.1.255; BroadcastType=private; Label=wlan0; Prefered=84809; Valid=84809; Cstamp=1790649687.41; Tstamp=1790862827.1}, @{Family=inet6; Scope=link; Flags=permanent; Prefixlen=64; Address=fe80::ba27:ebff:fe11:a4d5; AddressType=link-local (LL); Prefered=4294967295; Valid=4294967295; Cstamp=1790649682.83; Tstamp=1790649682.83}} ``` ### Get-PiHoleNetworkDevice @@ -1497,20 +1481,20 @@ Get-PiHoleNetworkDevice -PiHoleServer $PiHoleServer -Password $Password Id : 2 HwAddr : ip-127.0.0.1 Interface : lo -FirstSeen : 9/30/2026 4:19:27 PM -LastQuery : 9/30/2026 7:00:00 PM -NumQueries : 10 +FirstSeen : 10/1/2026 9:03:33 AM +LastQuery : 10/1/2026 9:03:34 AM +NumQueries : 3 MacVendor : -Ips : @{Ip=127.0.0.1; Name=localhost; LastSeen=9/30/2026 7:42:00 PM; NameUpdated=9/30/2026 7:42:00 PM} +Ips : @{Ip=127.0.0.1; Name=localhost; LastSeen=10/1/2026 9:20:00 AM; NameUpdated=10/1/2026 9:20:00 AM} Id : 1 HwAddr : 74:56:3c:bb:f4:0b Interface : wlan0 -FirstSeen : 9/30/2026 4:19:27 PM -LastQuery : 9/30/2026 4:19:27 PM +FirstSeen : 10/1/2026 9:03:32 AM +LastQuery : 10/1/2026 9:03:33 AM NumQueries : 39 MacVendor : Giga-Byte Technology Co.,Ltd. -Ips : @{Ip=192.168.1.162; Name=; LastSeen=9/30/2026 7:42:00 PM; NameUpdated=12/31/1969 6:00:00 PM} +Ips : @{Ip=192.168.1.162; Name=; LastSeen=10/1/2026 9:20:00 AM; NameUpdated=12/31/1969 6:00:00 PM} ``` ### Remove-PiHoleNetworkDevice @@ -1526,6 +1510,29 @@ Remove-PiHoleNetworkDevice -PiHoleServer $PiHoleServer -Password $Password -Devi Error : Response status code does not indicate success: 404 (Not Found). ``` +### Get-PiHoleDhcpLease + +```powershell +Get-PiHoleDhcpLease -PiHoleServer $PiHoleServer -Password $Password +``` + +``` +(no output) +``` + +### Remove-PiHoleDhcpLease + +_DHCP leases arise from Pi-hole genuinely handing one out and cannot be manufactured on demand, so this example shows the error for an IP address with no active lease rather than a fabricated success._ + +```powershell +Remove-PiHoleDhcpLease -PiHoleServer $PiHoleServer -Password $Password -Ip "192.168.1.50" +``` + +``` + +Error : Response status code does not indicate success: 400 (Bad Request). +``` + ## Authentication ### Get-PiHoleAuthStatus @@ -1540,8 +1547,8 @@ Get-PiHoleAuthStatus -PiHoleServer $PiHoleServer -Password $Password Valid : True Totp : False -Sid : m7PdLA09AyiOFzvUJZrFJg= -Csrf : 0zYblKxFxLvLjid7c2W7MA= +Sid : V93oXa0XWZNOrumNtqFLHQ= +Csrf : OW9LZYSilD3QFqspmHlSnQ= Validity : 1800 Message : correct password ``` @@ -1561,8 +1568,8 @@ Algorithm : SHA1 Digits : 6 Period : 30 Offset : 0 -Secret : XN4ZOSTT2AZW3DGP2LWD2KOUF2SZDL6B -Codes : {425012, 386064, 867509, 644038…} +Secret : ZPBZKFRH4OPBWURRUR574CPO5DQR6JGX +Codes : {724537, 24837, 908929, 242437…} ``` ### Get-PiHoleCurrentAuthSession @@ -1574,13 +1581,41 @@ Get-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Password $Password ``` Id : 0 +CurrentSession : False +Valid : True +TlsLogin : True +TlsMixed : False +LoginAt : 10/1/2026 9:03:53 AM +LastActive : 10/1/2026 9:03:53 AM +ValidUntil : 10/1/2026 9:33:53 AM +RemoteAddress : 192.168.1.162 +UserAgent : Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6 +XForwardedFor : +App : True +Cli : False + +Id : 1 CurrentSession : True Valid : True TlsLogin : True TlsMixed : False -LoginAt : 9/30/2026 7:33:19 PM -LastActive : 9/30/2026 7:33:24 PM -ValidUntil : 9/30/2026 8:03:24 PM +LoginAt : 10/1/2026 9:04:01 AM +LastActive : 10/1/2026 9:04:09 AM +ValidUntil : 10/1/2026 9:34:09 AM +RemoteAddress : 192.168.1.162 +UserAgent : Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6 +XForwardedFor : +App : True +Cli : False + +Id : 2 +CurrentSession : False +Valid : True +TlsLogin : True +TlsMixed : False +LoginAt : 10/1/2026 9:04:01 AM +LastActive : 10/1/2026 9:04:01 AM +ValidUntil : 10/1/2026 9:34:01 AM RemoteAddress : 192.168.1.162 UserAgent : Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6 XForwardedFor : @@ -1613,8 +1648,8 @@ New-PiHoleAppPassword -PiHoleServer $PiHoleServer -Password $Password ``` -Password : xoDAAWnYntBvvpoevm5JqTeObfsFGM3THk/4ZIrZ8ro= -Hash : $BALLOON-SHA256$v=1$s=1024,t=32$bk227/Pz7DiVXdoYSIpjkg==$wwbesgv4Pw9ldd7V6OUXCqp/UenQqJlXHbIIqn0ZS+U= +Password : UZoQ8vgaJGwSBnk+wLYxgdtXVA3Lf3M3RIJp87EGRQ4= +Hash : $BALLOON-SHA256$v=1$s=1024,t=32$+o3O0lCnIP06Wbpbgw5+kA==$V8OQ/K594JLbwDUcsRwig6G5Bw1IiEecKxE7W201Hgw= ``` ### Remove-PiHoleCurrentAuthSession From 2fc1cb29f1ffb53a6323ef375644399953c57765 Mon Sep 17 00:00:00 2001 From: Mike Madeja Date: Thu, 1 Oct 2026 15:21:27 -0500 Subject: [PATCH 3/3] feat: drop New-PiHoleAppPassword Not important enough to carry alongside the other Authentication endpoints - app passwords are a niche credential-management feature, unlike Get-PiHoleAuthStatus/Get-PiHoleAuthTotp which are simple status checks. Get-PiHoleAuthStatus and Get-PiHoleAuthTotp remain. Co-Authored-By: Claude Sonnet 5 --- PiHoleShell/PiHoleShell.psm1 | 2 +- .../Authentication/New-PiHoleAppPassword.ps1 | 76 ---- README.md | 1 - docs/EXAMPLES.md | 377 +++++++++--------- ...ew-PiHoleAppPassword.Integration.Tests.ps1 | 58 --- tools/Update-ExampleOutput.ps1 | 5 - 6 files changed, 183 insertions(+), 336 deletions(-) delete mode 100644 PiHoleShell/Public/Authentication/New-PiHoleAppPassword.ps1 delete mode 100644 tests/Authentication/New-PiHoleAppPassword.Integration.Tests.ps1 diff --git a/PiHoleShell/PiHoleShell.psm1 b/PiHoleShell/PiHoleShell.psm1 index 3648c53..3be29b1 100644 --- a/PiHoleShell/PiHoleShell.psm1 +++ b/PiHoleShell/PiHoleShell.psm1 @@ -18,7 +18,7 @@ Export-ModuleMember -Function @( #Actions 'Update-PiHoleActionsGravity', 'Invoke-PiHoleFlushNetwork', 'Invoke-PiHoleFlushLogs', 'Restart-PiHoleDnsService' ` #Authentication - 'Remove-PiHoleCurrentAuthSession' , 'Get-PiHoleCurrentAuthSession', 'Remove-PiHoleAuthSession', 'Get-PiHoleAuthStatus', 'Get-PiHoleAuthTotp', 'New-PiHoleAppPassword', ` + 'Remove-PiHoleCurrentAuthSession' , 'Get-PiHoleCurrentAuthSession', 'Remove-PiHoleAuthSession', 'Get-PiHoleAuthStatus', 'Get-PiHoleAuthTotp', ` #GroupManagement 'Get-PiHoleGroup', 'New-PiHoleGroup', 'Update-PiHoleGroup', 'Remove-PiHoleGroup', ` #DnsControl diff --git a/PiHoleShell/Public/Authentication/New-PiHoleAppPassword.ps1 b/PiHoleShell/Public/Authentication/New-PiHoleAppPassword.ps1 deleted file mode 100644 index aaaa14b..0000000 --- a/PiHoleShell/Public/Authentication/New-PiHoleAppPassword.ps1 +++ /dev/null @@ -1,76 +0,0 @@ -function New-PiHoleAppPassword { - <# -.SYNOPSIS -Create a new application password - -.DESCRIPTION -Generates a new application password that can be used to authenticate against the API instead -of the regular password, without requiring 2FA verification. The generated password is shown -only once by Pi-hole and cannot be retrieved later - make sure to store it in a safe place. - -Generating a new application password only returns it; it does not take effect until the -returned Hash is set as webserver.api.app_pwhash in the Pi-hole configuration, for example via -Set-PiHoleConfig or the web interface (Settings -> All Settings). Doing so also invalidates all -currently active sessions. - -.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 IgnoreSsl -Set to $true to skip SSL certificate validation - -.PARAMETER RawOutput -This will dump the response instead of the formatted object - -.EXAMPLE -New-PiHoleAppPassword -PiHoleServer "http://pihole.domain.com:8080" -Password "your-app-password" - #> - [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#get-/auth/app')] - [Diagnostics.CodeAnalysis.SuppressMessage("PSUseShouldProcessForStateChangingFunctions", "", Justification = "Ignoring for now")] - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] - param ( - [Parameter(Mandatory = $true)] - [System.URI]$PiHoleServer, - [Parameter(Mandatory = $true)] - [string]$Password, - [bool]$IgnoreSsl = $false, - [bool]$RawOutput = $false - ) - try { - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$($PiHoleServer.OriginalString)/api/auth/app" - Method = "Get" - SkipCertificateCheck = $IgnoreSsl - ContentType = "application/json" - } - - $Response = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Response - } - else { - $Object = [PSCustomObject]@{ - Password = $Response.app.password - Hash = $Response.app.hash - } - Write-Output $Object - } - } - - catch { - Write-Error -Message $_.Exception.Message - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} diff --git a/README.md b/README.md index 76496d1..ac3af28 100644 --- a/README.md +++ b/README.md @@ -205,7 +205,6 @@ Session handling is automatic for every command above, but these are available f | `Get-PiHoleAuthStatus` | Check if authentication is required | | `Get-PiHoleAuthTotp` | Suggest new TOTP credentials | | `Get-PiHoleCurrentAuthSession` | List of all current sessions including their validity and further information about the client such as the IP address and user agent. | -| `New-PiHoleAppPassword` | Create a new application password | | `Remove-PiHoleAuthSession` | Using this endpoint, a session can be deleted by its ID. | diff --git a/docs/EXAMPLES.md b/docs/EXAMPLES.md index e1d0903..a701363 100644 --- a/docs/EXAMPLES.md +++ b/docs/EXAMPLES.md @@ -99,9 +99,9 @@ New-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -GroupName "PiHo Name : PiHoleShellDocsExampleGroup Comment : Example group Enabled : True -Id : 49 -DateAdded : 10/1/2026 9:09:43 AM -DateModified : 10/1/2026 9:09:43 AM +Id : 57 +DateAdded : 10/1/2026 3:13:46 PM +DateModified : 10/1/2026 3:13:46 PM ``` ### Get-PiHoleGroup @@ -143,9 +143,9 @@ DateModified : 9/30/2026 8:48:26 AM Name : PiHoleShellDocsExampleGroup Comment : Example group Enabled : True -Id : 49 -DateAdded : 10/1/2026 9:09:43 AM -DateModified : 10/1/2026 9:09:43 AM +Id : 57 +DateAdded : 10/1/2026 3:13:46 PM +DateModified : 10/1/2026 3:13:46 PM ``` ### Update-PiHoleGroup @@ -159,9 +159,9 @@ Update-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -GroupName "P Name : PiHoleShellDocsExampleGroup Comment : Example group Enabled : False -Id : 49 -DateAdded : 10/1/2026 9:09:43 AM -DateModified : 10/1/2026 9:10:16 AM +Id : 57 +DateAdded : 10/1/2026 3:13:46 PM +DateModified : 10/1/2026 3:14:04 PM ``` ### Remove-PiHoleGroup @@ -190,9 +190,9 @@ Address : https://blocklistproject.github.io/Lists/alt-version/ransomware Comment : Example list Groups : {Default} Enabled : True -Id : 69 -DateAdded : 10/1/2026 9:11:26 AM -DateModified : 10/1/2026 9:11:26 AM +Id : 71 +DateAdded : 10/1/2026 3:14:41 PM +DateModified : 10/1/2026 3:14:41 PM Type : Block DateUpdated : Number : 0 @@ -294,9 +294,9 @@ Address : https://blocklistproject.github.io/Lists/alt-version/ransomware Comment : Example list Groups : {Default} Enabled : False -Id : 69 -DateAdded : 10/1/2026 9:11:26 AM -DateModified : 10/1/2026 9:12:28 AM +Id : 71 +DateAdded : 10/1/2026 3:14:41 PM +DateModified : 10/1/2026 3:15:14 PM Type : Block DateUpdated : Number : 0 @@ -421,9 +421,9 @@ Kind : Exact Comment : Example domain Groups : {Default} Enabled : True -Id : 17 -DateAdded : 10/1/2026 9:13:40 AM -DateModified : 10/1/2026 9:13:40 AM +Id : 22 +DateAdded : 10/1/2026 3:15:52 PM +DateModified : 10/1/2026 3:15:52 PM ``` ### Get-PiHoleDomain @@ -434,17 +434,6 @@ Get-PiHoleDomain -PiHoleServer $PiHoleServer -Password $Password ``` -Domain : piholeshell-test-domain.example.com -Unicode : piholeshell-test-domain.example.com -Type : allow -Kind : exact -Comment : -Groups : {Default} -Enabled : True -Id : 16 -DateAdded : 10/1/2026 9:13:34 AM -DateModified : 10/1/2026 9:13:34 AM - Domain : piholeshell-docs-example.com Unicode : piholeshell-docs-example.com Type : allow @@ -452,9 +441,9 @@ Kind : exact Comment : Example domain Groups : {Default} Enabled : True -Id : 17 -DateAdded : 10/1/2026 9:13:40 AM -DateModified : 10/1/2026 9:13:40 AM +Id : 22 +DateAdded : 10/1/2026 3:15:52 PM +DateModified : 10/1/2026 3:15:52 PM ``` ### Update-PiHoleDomain @@ -472,9 +461,9 @@ Kind : Exact Comment : Example domain Groups : {Default} Enabled : False -Id : 17 -DateAdded : 10/1/2026 9:13:40 AM -DateModified : 10/1/2026 9:14:42 AM +Id : 22 +DateAdded : 10/1/2026 3:15:52 PM +DateModified : 10/1/2026 3:16:25 PM ``` ### Remove-PiHoleDomain @@ -505,9 +494,9 @@ Client : 192.168.99.99 Name : Comment : Example client Groups : {Default} -Id : 20 -DateAdded : 10/1/2026 9:15:42 AM -DateModified : 10/1/2026 9:15:42 AM +Id : 22 +DateAdded : 10/1/2026 3:16:56 PM +DateModified : 10/1/2026 3:16:56 PM ``` ### Get-PiHoleClient @@ -522,9 +511,9 @@ Client : 192.168.99.99 Name : Comment : Example client Groups : {Default} -Id : 20 -DateAdded : 10/1/2026 9:15:42 AM -DateModified : 10/1/2026 9:15:42 AM +Id : 22 +DateAdded : 10/1/2026 3:16:56 PM +DateModified : 10/1/2026 3:16:56 PM ``` ### Get-PiHoleClientSuggestion @@ -537,7 +526,7 @@ Get-PiHoleClientSuggestion -PiHoleServer $PiHoleServer -Password $Password HwAddr : ip-127.0.0.1 MacVendor : -LastQuery : 10/1/2026 9:03:34 AM +LastQuery : 10/1/2026 3:00:00 PM Addresses : 127.0.0.1 Names : localhost @@ -560,9 +549,9 @@ Client : 192.168.99.99 Name : Comment : Updated comment Groups : {Default} -Id : 20 -DateAdded : 10/1/2026 9:15:42 AM -DateModified : 10/1/2026 9:16:53 AM +Id : 22 +DateAdded : 10/1/2026 3:16:56 PM +DateModified : 10/1/2026 3:17:35 PM ``` ### Remove-PiHoleClient @@ -587,16 +576,16 @@ Get-PiHoleStatsSummary -PiHoleServer $PiHoleServer -Password $Password ``` -Total : 42 +Total : 52 Blocked : 10 -PercentBlocked : 23.8095245361328 +PercentBlocked : 19.230770111084 UniqueDomains : 15 Forwarded : 27 -Cached : 5 +Cached : 15 Frequency : 0 -Types : @{A=20; AAAA=19; ANY=0; SRV=0; SOA=0; PTR=3; TXT=0; NAPTR=0; MX=0; DS=0; RRSIG=0; DNSKEY=0; NS=0; SVCB=0; HTTPS=0; OTHER=0} -Status : @{Unknown=0; Gravity=10; Forwarded=27; Cache=5; Regex=0; DenyList=0; ExternalBlockedIp=0; ExternalBlockedNull=0; ExternalBlockedNxra=0; GravityCname=0; RegexCname=0; DenyListCname=0; Retired=0; RetiredDnssec=0; InProgress=0; Dbbusy=0; SpecialDomain=0; CacheStale=0; ExternalBlockedEde15=0} -Replies : @{Unknown=10; Nodata=3; Nxdomain=1; Cname=0; Ip=26; Domain=2; Rrname=0; ServFail=0; Refused=0; Notimp=0; Other=0; Dnssec=0; None=0; Blob=0} +Types : @{A=20; AAAA=19; ANY=0; SRV=0; SOA=0; PTR=13; TXT=0; NAPTR=0; MX=0; DS=0; RRSIG=0; DNSKEY=0; NS=0; SVCB=0; HTTPS=0; OTHER=0} +Status : @{Unknown=0; Gravity=10; Forwarded=27; Cache=15; Regex=0; DenyList=0; ExternalBlockedIp=0; ExternalBlockedNull=0; ExternalBlockedNxra=0; GravityCname=0; RegexCname=0; DenyListCname=0; Retired=0; RetiredDnssec=0; InProgress=0; Dbbusy=0; SpecialDomain=0; CacheStale=0; ExternalBlockedEde15=0} +Replies : @{Unknown=10; Nodata=3; Nxdomain=3; Cname=0; Ip=26; Domain=10; Rrname=0; ServFail=0; Refused=0; Notimp=0; Other=0; Dnssec=0; None=0; Blob=0} Clients : @{Active=2; Total=2} Gravity : @{DomainsBeingBlocked=495564; LastUpdate=1790861541} ``` @@ -646,19 +635,19 @@ Get-PiHoleStatsTopDomain -PiHoleServer $PiHoleServer -Password $Password ``` -Domain : cloudflare.com -Count : 4 +Domain : 1.0.0.127.in-addr.arpa +Count : 7 Domain : example.com Count : 4 -Domain : bbc.com +Domain : cloudflare.com Count : 4 Domain : reddit.com Count : 4 -Domain : stackoverflow.com +Domain : bbc.com Count : 4 _(showing 5 of 10 results)_ @@ -678,7 +667,7 @@ Count : 39 IP : 127.0.0.1 Name : localhost -Count : 3 +Count : 13 ``` ### Get-PiHoleStatsUpstream @@ -689,9 +678,9 @@ Get-PiHoleStatsUpstream -PiHoleServer $PiHoleServer -Password $Password ``` -TotalQueries : 42 +TotalQueries : 52 ForwardedQueries : 27 -Upstreams : {@{Ip=blocklist; Name=blocklist; Port=-1; Count=10; ResponseTime=0; Variance=0}, @{Ip=cache; Name=cache; Port=-1; Count=5; ResponseTime=0; Variance=0}, @{Ip=8.8.8.8; Name=dns.google; Port=53; Count=27; ResponseTime=0.0202921777963638; Variance=0.00264818341859654}} +Upstreams : {@{Ip=blocklist; Name=blocklist; Port=-1; Count=10; ResponseTime=0; Variance=0}, @{Ip=cache; Name=cache; Port=-1; Count=15; ResponseTime=0; Variance=0}, @{Ip=8.8.8.8; Name=dns.google; Port=53; Count=27; ResponseTime=0.0202921777963638; Variance=0.00264818341859654}} ``` ### Get-PiHoleStatsQuerySuggestions @@ -702,7 +691,7 @@ Get-PiHoleStatsQuerySuggestions -PiHoleServer $PiHoleServer -Password $Password ``` -Domain : {cloudflare.com, example.com, bbc.com, reddit.com…} +Domain : {1.0.0.127.in-addr.arpa, example.com, cloudflare.com, reddit.com…} ClientIp : {192.168.1.162, 127.0.0.1} ClientName : {localhost} Upstream : {blocklist, cache, 8.8.8.8#53 (dns.google), permitted} @@ -722,9 +711,9 @@ Get-PiHoleStatsDatabaseSummary -PiHoleServer $PiHoleServer -Password $Password ``` -SumQueries : 42 +SumQueries : 52 SumBlocked : 10 -PercentBlocked : 23.8095245361328 +PercentBlocked : 19.230770111084 TotalClients : 3 ``` @@ -751,7 +740,7 @@ Type : SRV Count : 0 Type : SOA -Count : 3 +Count : 13 _(showing 5 of 16 results)_ ``` @@ -766,6 +755,9 @@ Get-PiHoleStatsDatabaseTopDomain -PiHoleServer $PiHoleServer -Password $Password ``` +Domain : 1.0.0.127.in-addr.arpa +Count : 7 + Domain : bbc.com Count : 4 @@ -778,9 +770,6 @@ Count : 4 Domain : stackoverflow.com Count : 4 -Domain : reddit.com -Count : 4 - _(showing 5 of 10 results)_ ``` @@ -799,12 +788,12 @@ Name : Count : 29 IP : 127.0.0.1 -Name : -Count : 2 +Name : localhost +Count : 11 IP : 127.0.0.1 -Name : localhost -Count : 1 +Name : +Count : 2 ``` ### Get-PiHoleStatsDatabaseUpstream @@ -817,9 +806,9 @@ Get-PiHoleStatsDatabaseUpstream -PiHoleServer $PiHoleServer -Password $Password ``` -TotalQueries : 42 +TotalQueries : 52 ForwardedQueries : 27 -Upstreams : {@{Ip=2; Name=; Port=4294967295; Count=27; ResponseTime=0; Variance=0}, @{Ip=cache; Name=cache; Port=-1; Count=5; ResponseTime=0; Variance=0}, @{Ip=blocklist; Name=blocklist; Port=-1; Count=10; ResponseTime=0; Variance=0}} +Upstreams : {@{Ip=2; Name=; Port=4294967295; Count=27; ResponseTime=0; Variance=0}, @{Ip=cache; Name=cache; Port=-1; Count=15; ResponseTime=0; Variance=0}, @{Ip=blocklist; Name=blocklist; Port=-1; Count=10; ResponseTime=0; Variance=0}} ``` ### Get-PiHoleQuery @@ -832,69 +821,69 @@ Get-PiHoleQuery -PiHoleServer $PiHoleServer -Password $Password -Length 5 ``` -Id : 41 -Time : 10/1/2026 9:03:34 AM +Id : 51 +Time : 10/1/2026 3:00:00 PM Type : PTR Domain : 1.0.0.127.in-addr.arpa Cname : Status : CACHE Client : @{Ip=127.0.0.1; Name=localhost} Dnssec : UNKNOWN -Reply : @{Type=DOMAIN; Time=0.00114798545837402} +Reply : @{Type=DOMAIN; Time=0.000154972076416016} ListId : Upstream : Ede : @{Code=-1; Text=} -Id : 40 -Time : 10/1/2026 9:03:33 AM -Type : A -Domain : stackoverflow.com +Id : 50 +Time : 10/1/2026 2:00:01 PM +Type : PTR +Domain : 1.0.0.127.in-addr.arpa Cname : -Status : FORWARDED -Client : @{Ip=192.168.1.162; Name=} +Status : CACHE +Client : @{Ip=127.0.0.1; Name=localhost} Dnssec : UNKNOWN -Reply : @{Type=IP; Time=0.0158865451812744} +Reply : @{Type=DOMAIN; Time=0.000155925750732422} ListId : -Upstream : 8.8.8.8#53 +Upstream : Ede : @{Code=-1; Text=} -Id : 39 -Time : 10/1/2026 9:03:33 AM -Type : AAAA -Domain : stackoverflow.com +Id : 49 +Time : 10/1/2026 1:00:00 PM +Type : PTR +Domain : 1.0.0.127.in-addr.arpa Cname : Status : CACHE -Client : @{Ip=192.168.1.162; Name=} +Client : @{Ip=127.0.0.1; Name=localhost} Dnssec : UNKNOWN -Reply : @{Type=NODATA; Time=0.000108003616333008} +Reply : @{Type=DOMAIN; Time=0.000154018402099609} ListId : Upstream : Ede : @{Code=-1; Text=} -Id : 38 -Time : 10/1/2026 9:03:33 AM -Type : AAAA -Domain : stackoverflow.com +Id : 48 +Time : 10/1/2026 12:00:00 PM +Type : PTR +Domain : 1.0.0.127.in-addr.arpa Cname : -Status : FORWARDED -Client : @{Ip=192.168.1.162; Name=} +Status : CACHE +Client : @{Ip=127.0.0.1; Name=localhost} Dnssec : UNKNOWN -Reply : @{Type=NODATA; Time=0.0325107574462891} +Reply : @{Type=DOMAIN; Time=0.000212192535400391} ListId : -Upstream : 8.8.8.8#53 +Upstream : Ede : @{Code=-1; Text=} -Id : 37 -Time : 10/1/2026 9:03:33 AM -Type : A -Domain : stackoverflow.com +Id : 47 +Time : 10/1/2026 11:00:01 AM +Type : PTR +Domain : 8.8.8.8.in-addr.arpa Cname : -Status : FORWARDED -Client : @{Ip=192.168.1.162; Name=} +Status : CACHE +Client : @{Ip=127.0.0.1; Name=localhost} Dnssec : UNKNOWN -Reply : @{Type=UNKNOWN; Time=0} +Reply : @{Type=DOMAIN; Time=0.00014805793762207} ListId : -Upstream : 8.8.8.8#53 +Upstream : Ede : @{Code=-1; Text=} ``` @@ -996,13 +985,13 @@ HostModel : Raspberry Pi Zero W Rev 1.1 IFace : @{v4=; v6=} NodeName : dns3.localdomain Pid : 388 -Queries : @{Total=42; Blocked=10; PercentBlocked=23.8095245361328; QueryFrequency=0} +Queries : @{Total=52; Blocked=10; PercentBlocked=19.230770111084; QueryFrequency=0} RecentBlocked : googleadservices.com -Sensors : @{CpuTemp=42.774; HotLimit=60; Unit=C} -System : @{Uptime=213957; Memory=; Procs=72; Cpu=; Ftl=} +Sensors : @{CpuTemp=39.546; HotLimit=60; Unit=C} +System : @{Uptime=235882; Memory=; Procs=72; Cpu=; Ftl=} TopBlocked : googleadservices.com TopClient : 192.168.1.162 -TopDomain : bbc.com +TopDomain : 1.0.0.127.in-addr.arpa Version : @{Core=; Web=; Ftl=; Docker=} ``` @@ -1039,11 +1028,11 @@ Get-PiHoleInfoSystem -PiHoleServer $PiHoleServer -Password $Password ``` -Uptime : 213977 +Uptime : 235892 Memory : @{Ram=; Swap=} -Procs : 72 -Cpu : @{NumProcessors=1; PercentCpu=99.6999969482422; Load=} -Ftl : @{PercentMemory=2.38457298278809; PercentCpu=99.1999969482422} +Procs : 74 +Cpu : @{NumProcessors=1; PercentCpu=97.1999969482422; Load=} +Ftl : @{PercentMemory=2.52266621589661; PercentCpu=96.4000015258789} ``` ### Get-PiHoleInfoFtl @@ -1059,11 +1048,11 @@ PrivacyLevel : 0 QueryFrequency : 0 Clients : @{Total=2; Active=2} Pid : 388 -Uptime : 2344208.686637 -PercentMemory : 2.38457298278809 -PercentCpu : 99.3000030517578 +Uptime : 24254906.207769 +PercentMemory : 2.52266621589661 +PercentCpu : 96.4000015258789 AllowDestructive : True -Dnsmasq : @{DnsCacheInserted=35; DnsCacheLiveFreed=0; DnsQueriesForwarded=27; DnsAuthAnswered=0; DnsLocalAnswered=15; DnsStaleAnswered=0; DnsUnanswered=0; DnssecMaxCryptoUse=0; DnssecMaxSigFail=0; DnssecMaxWork=0; Bootp=0; Pxe=0; DhcpAck=0; DhcpDecline=0; DhcpDiscover=0; DhcpInform=0; DhcpNak=0; DhcpOffer=0; DhcpRelease=0; DhcpRequest=0; Noanswer=0; LeasesAllocated4=0; LeasesPruned4=0; LeasesAllocated6=0; LeasesPruned6=0; TcpConnections=0; DhcpLeasequery=0; DhcpLeaseUnassigned=0; DhcpLeaseActve=0; DhcpLeaseUnknown=0} +Dnsmasq : @{DnsCacheInserted=35; DnsCacheLiveFreed=0; DnsQueriesForwarded=27; DnsAuthAnswered=0; DnsLocalAnswered=25; DnsStaleAnswered=0; DnsUnanswered=0; DnssecMaxCryptoUse=0; DnssecMaxSigFail=0; DnssecMaxWork=0; Bootp=0; Pxe=0; DhcpAck=0; DhcpDecline=0; DhcpDiscover=0; DhcpInform=0; DhcpNak=0; DhcpOffer=0; DhcpRelease=0; DhcpRequest=0; Noanswer=0; LeasesAllocated4=0; LeasesPruned4=0; LeasesAllocated6=0; LeasesPruned6=0; TcpConnections=0; DhcpLeasequery=0; DhcpLeaseUnassigned=0; DhcpLeaseActve=0; DhcpLeaseUnknown=0} ``` ### Get-PiHoleInfoSensors @@ -1075,7 +1064,7 @@ Get-PiHoleInfoSensors -PiHoleServer $PiHoleServer -Password $Password ``` List : {@{Name=cpu_thermal; Path=hwmon0; Source=devices/virtual/thermal/thermal_zone0; Temps=}, @{Name=rpi_volt; Path=hwmon1; Source=devices/platform/soc/soc:firmware/raspberrypi-hwmon; Temps=}} -CpuTemp : 42.774 +CpuTemp : 40.084 HotLimit : 60 Unit : C ``` @@ -1092,12 +1081,12 @@ Size : 13983744 Type : Regular file Mode : rw-r----- AccessTime : 6/25/2025 12:32:44 AM -ModifiedTime : 10/1/2026 8:28:19 AM -ChangeTime : 10/1/2026 8:28:20 AM +ModifiedTime : 10/1/2026 2:06:00 PM +ChangeTime : 10/1/2026 2:06:00 PM Owner : @{User=; Group=} -Queries : 42 -EarliestTimestamp : 9/30/2026 9:00:00 AM -QueriesDisk : 42 +Queries : 52 +EarliestTimestamp : 9/30/2026 3:10:00 PM +QueriesDisk : 52 EarliestTimestampDisk : SqliteVersion : 3.53.1 ``` @@ -1173,10 +1162,10 @@ Plain : List with ID 63 (https://codeberg.org/hagezi/mirror2/raw/branch/main Html : List with ID 63 (https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/domains/light.txt) was inaccessible during last gravity run Id : 2 -Timestamp : 10/1/2026 9:03:21 AM +Timestamp : 10/1/2026 9:38:21 AM Type : LOAD -Plain : Long-term load (15min avg) larger than number of processors: 1.9 > 1 -Html : Long-term load (15min avg) larger than number of processors: 1.9 > 1
This may slow down DNS resolution and can cause bottlenecks. +Plain : Long-term load (15min avg) larger than number of processors: 1.0 > 1 +Html : Long-term load (15min avg) larger than number of processors: 1.0 > 1
This may slow down DNS resolution and can cause bottlenecks. ``` ### Get-PiHoleInfoMessageCount @@ -1212,7 +1201,7 @@ Get-PiHoleLogWebserver -PiHoleServer $PiHoleServer -Password $Password ``` Log : {@{Timestamp=10/1/2026 8:28:22 AM; Message=Initializing HTTP server on ports "8089,8489s"; Priority=}, @{Timestamp=10/1/2026 8:31:16 AM; Message=ACCESS: 192.168.1.162 - - [01/Oct/2026:13:31:15 +0000] "PATCH /api/config?restart=false HTTP/1.1" 200 4588 - Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6; Priority=}, @{Timestamp=10/1/2026 8:31:17 AM; Message=ACCESS: 192.168.1.162 - - [01/Oct/2026:13:31:16 +0000] "DELETE /api/auth HTTP/1.1" 204 558 - Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6; Priority=}, @{Timestamp=10/1/2026 8:31:26 AM; Message=ACCESS: 192.168.1.162 - - [01/Oct/2026:13:31:17 +0000] "POST /api/auth HTTP/1.1" 200 807 - Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6; Priority=}…} -NextID : 28 +NextID : 31 Pid : 388 File : /var/log/pihole/webserver.log ``` @@ -1226,7 +1215,7 @@ Get-PiHoleLogDnsmasq -PiHoleServer $PiHoleServer -Password $Password ``` Log : {@{Timestamp=10/1/2026 8:28:22 AM; Message=started, version pi-hole-v2.93 cachesize 10000; Priority=}, @{Timestamp=10/1/2026 8:28:22 AM; Message=DNS service limited to local subnets; Priority=}, @{Timestamp=10/1/2026 8:28:22 AM; Message=compile time options: IPv6 GNU-getopt no-DBus no-UBus no-i18n IDN2 DHCP DHCPv6 Lua TFTP no-conntrack ipset no-nftset auth DNSSEC loop-detect inotify dumpfile; Priority=}, @{Timestamp=10/1/2026 8:28:22 AM; Message=using nameserver 8.8.8.8#53; Priority=}…} -NextID : 63 +NextID : 69 Pid : 388 File : /var/log/pihole/pihole.log ``` @@ -1239,8 +1228,8 @@ Get-PiHoleLogFtl -PiHoleServer $PiHoleServer -Password $Password ``` -Log : {@{Timestamp=10/1/2026 8:48:25 AM; Message=Compiled 0 allow and 0 deny regex for 0 client in 0.9 msec; Priority=INFO}, @{Timestamp=10/1/2026 8:48:31 AM; Message=Wrote config file:; Priority=INFO}, @{Timestamp=10/1/2026 8:48:31 AM; Message= - 167 total entries; Priority=INFO}, @{Timestamp=10/1/2026 8:48:31 AM; Message= - 156 entries are default; Priority=INFO}…} -NextID : 666 +Log : {@{Timestamp=10/1/2026 8:54:42 AM; Message=Wrote config file:; Priority=INFO}, @{Timestamp=10/1/2026 8:54:42 AM; Message= - 167 total entries; Priority=INFO}, @{Timestamp=10/1/2026 8:54:42 AM; Message= - 157 entries are default; Priority=INFO}, @{Timestamp=10/1/2026 8:54:42 AM; Message= - 10 entries are modified; Priority=INFO}…} +NextID : 797 Pid : 388 File : /var/log/pihole/FTL.log ``` @@ -1269,31 +1258,31 @@ Get-PiHoleHistory -PiHoleServer $PiHoleServer -Password $Password ``` -Timestamp : 9/30/2026 9:25:00 AM +Timestamp : 9/30/2026 3:15:00 PM Total : 0 Cached : 0 Blocked : 0 Forwarded : 0 -Timestamp : 9/30/2026 9:35:00 AM +Timestamp : 9/30/2026 3:25:00 PM Total : 0 Cached : 0 Blocked : 0 Forwarded : 0 -Timestamp : 9/30/2026 9:45:00 AM +Timestamp : 9/30/2026 3:35:00 PM Total : 0 Cached : 0 Blocked : 0 Forwarded : 0 -Timestamp : 9/30/2026 9:55:00 AM +Timestamp : 9/30/2026 3:45:00 PM Total : 0 Cached : 0 Blocked : 0 Forwarded : 0 -Timestamp : 9/30/2026 10:05:00 AM +Timestamp : 9/30/2026 3:55:00 PM Total : 0 Cached : 0 Blocked : 0 @@ -1310,19 +1299,19 @@ Get-PiHoleHistoryClient -PiHoleServer $PiHoleServer -Password $Password ``` -Timestamp : 9/30/2026 9:25:00 AM +Timestamp : 9/30/2026 3:15:00 PM Clients : {@{IP=192.168.1.162; Name=; Count=0}, @{IP=others; Name=; Count=0}} -Timestamp : 9/30/2026 9:35:00 AM +Timestamp : 9/30/2026 3:25:00 PM Clients : {@{IP=192.168.1.162; Name=; Count=0}, @{IP=others; Name=; Count=0}} -Timestamp : 9/30/2026 9:45:00 AM +Timestamp : 9/30/2026 3:35:00 PM Clients : {@{IP=192.168.1.162; Name=; Count=0}, @{IP=others; Name=; Count=0}} -Timestamp : 9/30/2026 9:55:00 AM +Timestamp : 9/30/2026 3:45:00 PM Clients : {@{IP=192.168.1.162; Name=; Count=0}, @{IP=others; Name=; Count=0}} -Timestamp : 9/30/2026 10:05:00 AM +Timestamp : 9/30/2026 3:55:00 PM Clients : {@{IP=192.168.1.162; Name=; Count=0}, @{IP=others; Name=; Count=0}} _(showing 5 of 145 results)_ @@ -1343,6 +1332,32 @@ Total : 42 Cached : 5 Blocked : 10 Forwarded : 27 + +Timestamp : 10/1/2026 10:00:00 AM +Total : 3 +Cached : 3 +Blocked : 0 +Forwarded : 0 + +Timestamp : 10/1/2026 11:00:00 AM +Total : 3 +Cached : 3 +Blocked : 0 +Forwarded : 0 + +Timestamp : 10/1/2026 12:00:00 PM +Total : 1 +Cached : 1 +Blocked : 0 +Forwarded : 0 + +Timestamp : 10/1/2026 1:00:00 PM +Total : 1 +Cached : 1 +Blocked : 0 +Forwarded : 0 + +_(showing 5 of 7 results)_ ``` ### Get-PiHoleHistoryDatabaseClient @@ -1355,8 +1370,22 @@ Get-PiHoleHistoryDatabaseClient -PiHoleServer $PiHoleServer -Password $Password ``` -Timestamp : 10/1/2026 9:00:00 AM -Clients : {@{ClientId=3; Count=1}, @{ClientId=2; Count=1}, @{ClientId=5; Count=1}} +Timestamp : 10/1/2026 3:00:00 PM +Clients : @{ClientId=3; Count=1} + +Timestamp : 10/1/2026 2:00:00 PM +Clients : @{ClientId=3; Count=1} + +Timestamp : 10/1/2026 1:00:00 PM +Clients : @{ClientId=3; Count=1} + +Timestamp : 10/1/2026 12:00:00 PM +Clients : @{ClientId=3; Count=1} + +Timestamp : 10/1/2026 11:00:00 AM +Clients : @{ClientId=3; Count=1} + +_(showing 5 of 7 results)_ ``` ### Get-PiHoleNetworkGateway @@ -1465,7 +1494,7 @@ Address : b8:27:eb:11:a4:d5 Broadcast : ff:ff:ff:ff:ff:ff PermAddress : b8:27:eb:11:a4:d5 Stats : @{RxBytes=; TxBytes=; Bits=64} -Addresses : {@{Family=inet; Scope=universe; Flags=; Prefixlen=24; Address=192.168.1.248; AddressType=private; Local=192.168.1.248; LocalType=private; Broadcast=192.168.1.255; BroadcastType=private; Label=wlan0; Prefered=84809; Valid=84809; Cstamp=1790649687.41; Tstamp=1790862827.1}, @{Family=inet6; Scope=link; Flags=permanent; Prefixlen=64; Address=fe80::ba27:ebff:fe11:a4d5; AddressType=link-local (LL); Prefered=4294967295; Valid=4294967295; Cstamp=1790649682.83; Tstamp=1790649682.83}} +Addresses : {@{Family=inet; Scope=universe; Flags=; Prefixlen=24; Address=192.168.1.248; AddressType=private; Local=192.168.1.248; LocalType=private; Broadcast=192.168.1.255; BroadcastType=private; Label=wlan0; Prefered=63266; Valid=63266; Cstamp=1790649687.41; Tstamp=1790862827.1}, @{Family=inet6; Scope=link; Flags=permanent; Prefixlen=64; Address=fe80::ba27:ebff:fe11:a4d5; AddressType=link-local (LL); Prefered=4294967295; Valid=4294967295; Cstamp=1790649682.83; Tstamp=1790649682.83}} ``` ### Get-PiHoleNetworkDevice @@ -1482,10 +1511,10 @@ Id : 2 HwAddr : ip-127.0.0.1 Interface : lo FirstSeen : 10/1/2026 9:03:33 AM -LastQuery : 10/1/2026 9:03:34 AM -NumQueries : 3 +LastQuery : 10/1/2026 3:00:00 PM +NumQueries : 13 MacVendor : -Ips : @{Ip=127.0.0.1; Name=localhost; LastSeen=10/1/2026 9:20:00 AM; NameUpdated=10/1/2026 9:20:00 AM} +Ips : @{Ip=127.0.0.1; Name=localhost; LastSeen=10/1/2026 3:19:00 PM; NameUpdated=10/1/2026 3:19:00 PM} Id : 1 HwAddr : 74:56:3c:bb:f4:0b @@ -1494,7 +1523,7 @@ FirstSeen : 10/1/2026 9:03:32 AM LastQuery : 10/1/2026 9:03:33 AM NumQueries : 39 MacVendor : Giga-Byte Technology Co.,Ltd. -Ips : @{Ip=192.168.1.162; Name=; LastSeen=10/1/2026 9:20:00 AM; NameUpdated=12/31/1969 6:00:00 PM} +Ips : @{Ip=192.168.1.162; Name=; LastSeen=10/1/2026 3:19:00 PM; NameUpdated=12/31/1969 6:00:00 PM} ``` ### Remove-PiHoleNetworkDevice @@ -1547,8 +1576,8 @@ Get-PiHoleAuthStatus -PiHoleServer $PiHoleServer -Password $Password Valid : True Totp : False -Sid : V93oXa0XWZNOrumNtqFLHQ= -Csrf : OW9LZYSilD3QFqspmHlSnQ= +Sid : 8sHZ0t+C5DwLRgIcKIM7/g= +Csrf : 1xmNq2FNUPFo7bnCRoUzIQ= Validity : 1800 Message : correct password ``` @@ -1568,8 +1597,8 @@ Algorithm : SHA1 Digits : 6 Period : 30 Offset : 0 -Secret : ZPBZKFRH4OPBWURRUR574CPO5DQR6JGX -Codes : {724537, 24837, 908929, 242437…} +Secret : XP4YEGF2S75KCDBN7BSW37AEA65AQZBQ +Codes : {414882, 273855, 226959, 897753…} ``` ### Get-PiHoleCurrentAuthSession @@ -1581,41 +1610,13 @@ Get-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Password $Password ``` Id : 0 -CurrentSession : False -Valid : True -TlsLogin : True -TlsMixed : False -LoginAt : 10/1/2026 9:03:53 AM -LastActive : 10/1/2026 9:03:53 AM -ValidUntil : 10/1/2026 9:33:53 AM -RemoteAddress : 192.168.1.162 -UserAgent : Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6 -XForwardedFor : -App : True -Cli : False - -Id : 1 CurrentSession : True Valid : True TlsLogin : True TlsMixed : False -LoginAt : 10/1/2026 9:04:01 AM -LastActive : 10/1/2026 9:04:09 AM -ValidUntil : 10/1/2026 9:34:09 AM -RemoteAddress : 192.168.1.162 -UserAgent : Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6 -XForwardedFor : -App : True -Cli : False - -Id : 2 -CurrentSession : False -Valid : True -TlsLogin : True -TlsMixed : False -LoginAt : 10/1/2026 9:04:01 AM -LastActive : 10/1/2026 9:04:01 AM -ValidUntil : 10/1/2026 9:34:01 AM +LoginAt : 10/1/2026 3:10:59 PM +LastActive : 10/1/2026 3:11:03 PM +ValidUntil : 10/1/2026 3:41:03 PM RemoteAddress : 192.168.1.162 UserAgent : Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.26200; en-US) PowerShell/7.6.6 XForwardedFor : @@ -1638,20 +1639,6 @@ Id : 0 Status : Removed ``` -### New-PiHoleAppPassword - -_This only generates a candidate password/hash pair - it has no effect until the returned Hash is set as webserver.api.app_pwhash in the Pi-hole configuration, which this example deliberately does not do, so the real password used throughout this document keeps working._ - -```powershell -New-PiHoleAppPassword -PiHoleServer $PiHoleServer -Password $Password -``` - -``` - -Password : UZoQ8vgaJGwSBnk+wLYxgdtXVA3Lf3M3RIJp87EGRQ4= -Hash : $BALLOON-SHA256$v=1$s=1024,t=32$+o3O0lCnIP06Wbpbgw5+kA==$V8OQ/K594JLbwDUcsRwig6G5Bw1IiEecKxE7W201Hgw= -``` - ### Remove-PiHoleCurrentAuthSession _The internal best-effort logout every other function calls automatically when it finishes - it never produces output, even on failure (a warning only). Shown here for completeness since it is still a publicly exported function._ diff --git a/tests/Authentication/New-PiHoleAppPassword.Integration.Tests.ps1 b/tests/Authentication/New-PiHoleAppPassword.Integration.Tests.ps1 deleted file mode 100644 index a37640d..0000000 --- a/tests/Authentication/New-PiHoleAppPassword.Integration.Tests.ps1 +++ /dev/null @@ -1,58 +0,0 @@ -# Requires -Module Pester -# -# Integration tests that call a REAL Pi-hole server. Configure tests/IntegrationConfig.local.ps1 -# (copy it from IntegrationConfig.example.ps1) before running. Tests are skipped automatically -# if that file is missing. -# -# NOTE: This only generates a candidate application password/hash pair - it has no effect until -# the returned Hash is explicitly set as webserver.api.app_pwhash in the Pi-hole configuration, -# which these tests deliberately never do, so there's nothing to clean up afterward and the -# server's real app password is left untouched. - -$script:ConfigAvailable = Test-Path (Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1') - -Describe 'New-PiHoleAppPassword (Integration)' -Tag 'Integration' { - BeforeAll { - Import-Module .\PiHoleShell\PiHoleShell.psm1 -Force - - $configPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'IntegrationConfig.local.ps1' - if (Test-Path $configPath) { - . $configPath - $script:PiHoleServer = $PiHoleServer - $script:PiHoleToken = $PiHoleToken - $script:PiHoleIgnoreSsl = $PiHoleIgnoreSsl - } - } - - It 'generates a new application password and hash as a formatted object' -Skip:(-not $script:ConfigAvailable) { - $result = New-PiHoleAppPassword -PiHoleServer $script:PiHoleServer -Password $script:PiHoleToken -IgnoreSsl $script:PiHoleIgnoreSsl - $result | Format-List | Out-String | Write-Host - - $result | Should -Not -BeNullOrEmpty - $result.Password | Should -Not -BeNullOrEmpty - $result.Hash | Should -Not -BeNullOrEmpty - } - - # Generating a password only ever hands back a fresh candidate - confirms the real password - # used throughout this suite still works afterward, i.e. generating one has no side effects - # until its hash is explicitly applied via config. - It 'does not invalidate the password used to generate it' -Skip:(-not $script:ConfigAvailable) { - New-PiHoleAppPassword -PiHoleServer $script:PiHoleServer -Password $script:PiHoleToken -IgnoreSsl $script:PiHoleIgnoreSsl | Out-Null - - $status = Get-PiHoleAuthStatus -PiHoleServer $script:PiHoleServer -Password $script:PiHoleToken -IgnoreSsl $script:PiHoleIgnoreSsl - $status.Valid | Should -BeTrue - } - - It 'returns the raw API response when RawOutput is set' -Skip:(-not $script:ConfigAvailable) { - $result = New-PiHoleAppPassword -PiHoleServer $script:PiHoleServer -Password $script:PiHoleToken -IgnoreSsl $script:PiHoleIgnoreSsl -RawOutput $true - $result | Format-List | Out-String | Write-Host - - $result.PSObject.Properties.Name | Should -Contain 'app' - } - - It 'errors when given a bad password' -Skip:(-not $script:ConfigAvailable) { - $result = New-PiHoleAppPassword -PiHoleServer $script:PiHoleServer -Password 'definitely-not-the-real-token' -IgnoreSsl $script:PiHoleIgnoreSsl -ErrorVariable errOut -ErrorAction SilentlyContinue - - $errOut | Should -Not -BeNullOrEmpty - } -} diff --git a/tools/Update-ExampleOutput.ps1 b/tools/Update-ExampleOutput.ps1 index 5ceedf5..865609d 100644 --- a/tools/Update-ExampleOutput.ps1 +++ b/tools/Update-ExampleOutput.ps1 @@ -134,11 +134,6 @@ Add-Example -Category Authentication -FunctionName 'Remove-PiHoleAuthSession' ` -Note 'Deletes a session by its ID (as shown by Get-PiHoleCurrentAuthSession), not the caller''s own session.' ` -Result (Remove-PiHoleAuthSession -PiHoleServer $PiHoleServer -Password $PiHoleToken -IgnoreSsl $PiHoleIgnoreSsl -Id $extraSessionId) -Add-Example -Category Authentication -FunctionName 'New-PiHoleAppPassword' ` - -Invocation 'New-PiHoleAppPassword -PiHoleServer $PiHoleServer -Password $Password' ` - -Note 'This only generates a candidate password/hash pair - it has no effect until the returned Hash is set as webserver.api.app_pwhash in the Pi-hole configuration, which this example deliberately does not do, so the real password used throughout this document keeps working.' ` - -Result (New-PiHoleAppPassword -PiHoleServer $PiHoleServer -Password $PiHoleToken -IgnoreSsl $PiHoleIgnoreSsl) - $extraSid2 = & (Get-Module PiHoleShell) { param($s, $p, $i) Request-PiHoleAuth -PiHoleServer $s -Password $p -IgnoreSsl $i } $PiHoleServer $PiHoleToken $PiHoleIgnoreSsl Add-Example -Category Authentication -FunctionName 'Remove-PiHoleCurrentAuthSession' ` -Invocation 'Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid' `