Retrieve blocked DNS queries from PiHole using PowerShell

I use PiHole for Ad-blocking at home, and yes, sometimes that causes some issues if it blocks Microsoft (Or other) management addresses. In this blog post, I will show how you can live-track blocked DNS queries and get some insights while troubleshooting 🙂

What is PiHole?

“The Pi-hole® is a DNS sinkhole that protects your devices from unwanted content, without installing any client-side software.

Free: open-source software which helps ensure you are the sole person in control of your privacy

Easy-to-install: our versatile installer walks you through the process and takes less than ten minutes

Resolute: content is blocked in non-browser locations, such as ad-laden mobile apps and smart TVs

Responsive: seamlessly speeds up the feel of everyday browsing by caching DNS queries

Lightweight: runs smoothly with minimal hardware and software requirements

Robust: a command-line interface that is quality assured for interoperability

Insightful: a beautiful responsive Web Interface dashboard to view and control your Pi-hole

Versatile: can optionally function as a DHCP server, ensuring all your devices are protected automatically

Scalablecapable of handling hundreds of millions of queries when installed on server-grade hardware

Modern: blocks ads over both IPv4 and IPv6″

Source: https://docs.pi-hole.net/

Why I use PiHole

Well… It removes advertisements from pages, eliminating all the clutter from both sides of most web pages or in-between text, but it also blocks malicious/questionable URLs from being accessed. It’s active in my home network (I use a Raspberry Pi 4 for that), but also when traveling or at the office because I use a VPN on my mobile and laptop, which uses my home PiHole system as DNS 🙂

Issues when using PiHole

I had my share of issues because of PiHole, too. If you subscribe to many blocklists, you might run into problems reaching Microsoft (management) sites. Testing Intune Autopilot failed because of that because some blocklists that I used added “manage.microsoft.com” (It’s always DNS 😀 )

Why this script?

And that’s why I wrote this small script if I run into issues… I can run it in the background, repeat the failed process, and live-check if URLs are blocked. (And Allow those in the PiHole interface to avoid those issues)

Prerequisites

You must get the API token from your PiHole installation to use the script. You can retrieve that by doing the following:

Version 5

  • Connect to your PiHole and log in (Something like http://server_ip:port/admin/index.php, you should know this, of course)
  • Select Settings
  • Select the API tab
  • Click on Show API Token
  • Click on Yes, Show API Token
  • Copy the Raw API Token in your clipboard (CTRL-C)

Version 6

  • Connect to your PiHole and log in (Something like http://server_ip:port/admin/index.php, you should know this, of course)
  • Select Settings
  • Select Web interface / API
  • Click on Configure app password
  • Copy the new app password in your clipboard (Select text, CTRL-C)
  • Select Replace App Password (This might be different for you; I already did this step before updating this blog post for PiHole version 6)
  • Select Yes, replace password
  • Select OK to log in again, use your App Password to log in, and verify that the password copied is correct.
  • Select the menu in the top right corner
  • Select Log out
  • Log in again with your password

How does the script work?

Version 5

The script uses your retrieved API token to connect and authenticate to the PiHole API. It then uses api.php to retrieve the value from “recentBlocked.” It will continue reading it while checking if the value retrieved didn’t match the previous value to avoid double lines in your screen output. To stop the script, you can press CTRL-C.

At the top of the script, you can insert the API key and the PiHole server address, including the port. (Mine is 8082. Yours can be different. If it’s https without a port, use 443). If you have other PiHoles or must connect using a different port, etc., then you can use these Parameters:

  • -Token: The API token you retrieved from the PiHole settings page
  • -Address: The FQDN or IP-Address of your PiHole installation
  • -Port: The port number of your PiHole installation

For example, you can connect to the PiHole server running on pihole.psif.local on port 8082 using:

.\Get-PiHoleV5RecentBlocked.ps1 -Address pihole.psif.local -Port 8082

In the screenshot below, I started the script, which connects to the API and checks any blocked address. I then opened my browser and msn.com (Which is full of advertisements), and it showed all the items blocked there. I pressed CTRL-C afterward to make it stop retrieving any more blocked URLs.

Version 6

The script uses your retrieved App Password to connect and authenticate to the PiHole API. It then uses the session ID returned to retrieve the value from “recent_blocked.” It will continue reading it while checking if the value retrieved didn’t match the previous value to avoid double lines in your screen output. To stop the script, you can press CTRL-C.

At the top of the script, you can insert the App Password and the PiHole server address, including the port. (Mine is 1010. Yours can be different, and I used the HTTP port for version 6 because I couldn’t get it to work on HTTPS with the self-signed certificate from the PiHole installation. If you have other PiHoles or must connect using a different port, etc., then you can use these Parameters:

  • -AppPassword: The App Password token you retrieved from the PiHole settings page
  • -Address: The FQDN or IP-Address of your PiHole installation
  • -Port: The port number of your PiHole installation

For example, you can connect to the PiHole server running on pihole.psif.local on port 1010 using:

.\Get-PiHoleV6RecentBlocked.ps1 -Address pihole.psif.local -Port 1010

In the screenshot below, I started the script, which connects to the API and checks any blocked address. I then opened my browser and msn.com (Which is full of advertisements), and it showed all the items blocked there. I pressed CTRL-C afterward to make it stop retrieving any more blocked URLs.

Wrapping up

In this blog post, I showed how you can use PowerShell and the PiHole API option to retrieve blocked URLs while testing applications or installations or just when you want to see what’s happening while browsing :). Have a lovely weekend!

The scripts

Below are the contents of the scripts (For PiHole versions 5 and 6). Please save the one you need to c:\scripts\Get-PiHoleV6RecentBlocked.ps, for example. (I removed the Token/App Password and replaced it with XXXX, you must replace XXX with your API token, server address and port)

Version 5

param(
  [parameter(mandatory = $false)][String]$Token = 'XXXX',
  [parameter(mandatory = $false)][String]$Address = 'XXXX',
  [parameter(mandatory = $false)][String]$Port = 'XXXX'
)
  
#Connecting to PiHole and retrieving blocked items using $Token, $Address and $Port 
Write-Host ("Connecting to {0} and retrieving recently blocked queries. (Use CTRL-C to stop)" -f $Address) -ForegroundColor Green
while ($true) {
  try {
    $Recent = Invoke-RestMethod -Uri "http://$($Address):$($Port)/admin/api.php?auth=$Token&recentBlocked" -ErrorAction Stop
    if ($Recent -ne $Previous) {
      Write-Host ("PiHole blocked {0} at {1}" -f $Recent, $(Get-Date -Format "dd-MM-yy HH:mm:ss:ff")) 
      $Previous = $Recent
    }
  }
  catch {
    Write-Warning ("Error reading data from {0} on port {1}, check token/network access. Exiting..." -f $Address, $Port)
    return  
  }
}

Version 6

param(
  [parameter(mandatory = $false)][String]$AppPassword = 'XXXX',
  [parameter(mandatory = $false)][String]$Address = 'XXXX',
  [parameter(mandatory = $false)][String]$Port = 'XXXX'
)
  
#Connecting to PiHole using $AppPassword, and retrieve API key for this session
try {
  $request = @{
    'password' = $AppPassword
  }
  $API = (Invoke-RestMethod -Uri "http://$($Address):$($Port)/api/auth" -Method Post -Body $($Request | ConvertTo-Json) -ContentType 'application/json' -ErrorAction Stop).session.sid
}
catch {
  Write-Warning ("Could not connect to PiHole using App Password, check address/port/AppPassword. Exiting...")
  return
}

#Connecting to PiHole and retrieving blocked items using $AppPassword, $Address and $Port
Write-Host ("Connecting to {0} and retrieving recently blocked queries. (Use CTRL-C to stop)" -f $Address) -ForegroundColor Green
while ($true) {
  try {
    $Recent = (Invoke-RestMethod -Uri "http://$($Address):$($Port)/api/stats/recent_blocked?sid=$($API)" -ErrorAction Stop).blocked
    if ($Recent -ne $Previous) {
      Write-Host ("PiHole blocked {0} at {1}" -f $($Recent), $(Get-Date -Format "dd-MM-yy HH:mm:ss:ff")) 
      $Previous = $Recent
    }
  }
  catch {
    Write-Warning ("Error reading data from {0} on port {1}, check token/network access. Exiting..." -f $Address, $Port)
    return  
  }
}

Download the script(s) from GitHub here.

4 thoughts on “Retrieve blocked DNS queries from PiHole using PowerShell

  1. I´d like to know if it´s possible to use PiHole as a blocker for Porn sites? I have Firewalla (a small Firewall device) which supposed to block this, but my son found a way thru a VPN or Add-on on his pc to bypass Firewalla.
    If it´s possible can you share some information? Thanks in advance!

    1. Yes, that works just fine. There are lists which you can add to it, Google for pihole block lists and add them. But if the vpn switches the DNS… Then it’s not going to work I’m afraid

  2. yes, you might be right… definetively the VPN would bypass the DNS block (I think)

    Thanks anyways! I added you as contact on Linkedin.

    Regrards,
    CR

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.