Public/Get-PiHoleDbTopDomains.ps1
|
function Get-PiHoleDbTopDomains { <# .SYNOPSIS Retrieves top domains data from the Pi-hole long-term database. .DESCRIPTION This function authenticates to the Pi-hole API using Connect-PiHole, retrieves top domains data from the long-term database, and then disconnects the session using Disconnect-PiHole. .PARAMETER BaseUrl The base URL of the Pi-hole instance (e.g., http://pi.hole or https://pi.hole). .PARAMETER Credential A PSCredential object containing the Pi-hole password. .PARAMETER From DateTime from when the data should be requested. Accepts DateTime objects or date strings like '5-7-2025 3:34PM'. .PARAMETER Until DateTime until when the data should be requested. Accepts DateTime objects or date strings like '5-7-2025 3:34PM'. .PARAMETER Blocked Switch parameter to return information about blocked domains instead of permitted domains. .PARAMETER Count Number of requested items. Default is 10. .PARAMETER SkipCertificateCheck Skip SSL certificate validation. Useful for self-signed certificates. .OUTPUTS A PSCustomObject containing the top domains data, total queries, blocked queries, and processing time. .EXAMPLE $cred = Get-Credential $from = Get-Date "2023-01-01 12:00:00" $until = Get-Date "2023-01-02 12:00:00" Get-PiHoleDbTopDomains -BaseUrl 'https://pi.hole' -Credential $cred -From $from -Until $until -SkipCertificateCheck .EXAMPLE # Get top 20 blocked domains using string dates $cred = Get-Credential Get-PiHoleDbTopDomains -BaseUrl 'http://pi.hole' -Credential $cred -From '5-7-2025 3:34PM' -Until '5-7-2025 11:59PM' -Blocked -Count 20 .EXAMPLE # Get top 5 permitted domains for the last 24 hours $cred = Get-Credential $until = Get-Date $from = $until.AddDays(-1) Get-PiHoleDbTopDomains -BaseUrl 'http://pi.hole' -Credential $cred -From $from -Until $until -Count 5 #> param ( [Parameter(Mandatory = $true)] [string]$BaseUrl, [Parameter(Mandatory = $true)] [System.Management.Automation.PSCredential]$Credential, [Parameter(Mandatory = $true)] [DateTime]$From, [Parameter(Mandatory = $true)] [DateTime]$Until, [Parameter()] [switch]$Blocked, [Parameter()] [int]$Count = 10, [switch]$SkipCertificateCheck ) begin { # Validate DateTime parameters if ($From -gt $Until) { throw "Error: From DateTime cannot be greater than Until DateTime." } # Validate Count parameter if ($Count -lt 1) { throw "Error: Count must be greater than 0." } } process { $sessionData = $null try { Write-Verbose "Starting authentication to Pi-hole at $BaseUrl" # Authenticate and get session data $sessionData = Connect-PiHole -BaseUrl $BaseUrl -Credential $Credential -SkipCertificateCheck:$SkipCertificateCheck Write-Verbose "Authentication successful. Session ID: $($sessionData.ID), SID: $($sessionData.SID)" # Convert DateTime to Unix timestamps for API call $fromUnix = [DateTimeOffset]::new($From).ToUnixTimeSeconds() $untilUnix = [DateTimeOffset]::new($Until).ToUnixTimeSeconds() Write-Verbose "Converted dates - From: $From ($fromUnix), Until: $Until ($untilUnix)" # Prepare API request to get top domains data $blockedValue = if ($Blocked) { "1" } else { "0" } $url = "$BaseUrl/api/stats/database/top_domains?from=$fromUnix&until=$untilUnix&blocked=$blockedValue&count=$Count" Write-Verbose "Making API request to: $url" $headers = @{ 'X-FTL-SID' = $sessionData.SID } $invokeParams = @{ Uri = $url Method = 'Get' Headers = $headers ErrorAction = 'Stop' } if ($SkipCertificateCheck) { $invokeParams.SkipCertificateCheck = $true } $response = Invoke-RestMethod @invokeParams Write-Verbose "API request successful. Retrieved $($response.domains.Count) top domains" # Return the response as-is Write-Verbose "Successfully retrieved top domains data" return $response } catch { Write-Error "Error occurred: $($_.Exception.Message)" Write-Verbose "Full error details: $($_ | Out-String)" # Try to disconnect if we have session data if ($sessionData -and $sessionData.ID -and $sessionData.SID) { Write-Verbose "Attempting to disconnect session due to error..." try { Disconnect-PiHole -BaseUrl $BaseUrl -Id $sessionData.ID -SID $sessionData.SID -SkipCertificateCheck:$SkipCertificateCheck Write-Verbose "Session disconnected successfully" } catch { Write-Warning "Failed to disconnect session: $($_.Exception.Message)" } } throw } finally { # Clean disconnect in finally block if ($sessionData -and $sessionData.ID -and $sessionData.SID) { Write-Verbose "Attempting final session cleanup..." try { Disconnect-PiHole -BaseUrl $BaseUrl -Id $sessionData.ID -SID $sessionData.SID -SkipCertificateCheck:$SkipCertificateCheck Write-Verbose "Final session cleanup completed successfully" } catch { Write-Warning "Failed to clean up session in finally block: $($_.Exception.Message)" } } } } end { # Nothing to clean up in the end block } } |