Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions PiHoleShell/PiHoleShell.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -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', `
#GroupManagement
'Get-PiHoleGroup', 'New-PiHoleGroup', 'Update-PiHoleGroup', 'Remove-PiHoleGroup', `
#DnsControl
Expand All @@ -44,5 +44,7 @@ Export-ModuleMember -Function @(
#ClientManagement
'Get-PiHoleClient', 'New-PiHoleClient', 'Update-PiHoleClient', 'Remove-PiHoleClient', 'Get-PiHoleClientSuggestion', `
#NetworkInformation
'Get-PiHoleNetworkGateway', 'Get-PiHoleNetworkRoute', 'Get-PiHoleNetworkInterface', 'Get-PiHoleNetworkDevice', 'Remove-PiHoleNetworkDevice'
'Get-PiHoleNetworkGateway', 'Get-PiHoleNetworkRoute', 'Get-PiHoleNetworkInterface', 'Get-PiHoleNetworkDevice', 'Remove-PiHoleNetworkDevice', `
#DHCP
'Get-PiHoleDhcpLease', 'Remove-PiHoleDhcpLease'
)
82 changes: 82 additions & 0 deletions PiHoleShell/Public/Authentication/Get-PiHoleAuthStatus.ps1
Original file line number Diff line number Diff line change
@@ -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
}
}
}
76 changes: 76 additions & 0 deletions PiHoleShell/Public/Authentication/Get-PiHoleAuthTotp.ps1
Original file line number Diff line number Diff line change
@@ -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
}
}
}
81 changes: 81 additions & 0 deletions PiHoleShell/Public/DHCP/Get-PiHoleDhcpLease.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
function Get-PiHoleDhcpLease {
<#
.SYNOPSIS
Get currently active DHCP leases

.DESCRIPTION
Returns the currently active DHCP leases handed out by Pi-hole's DHCP server.

.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-PiHoleDhcpLease -PiHoleServer "http://pihole.domain.com:8080" -Password "your-app-password"
#>
[CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#get-/dhcp/leases')]
[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/dhcp/leases"
Method = "Get"
SkipCertificateCheck = $IgnoreSsl
ContentType = "application/json"
}

$Response = Invoke-RestMethod @Params

if ($RawOutput) {
Write-Output $Response
}
else {
$ObjectFinal = foreach ($Item in $Response.leases) {
# A lease's expires value of 0 means the lease is infinite and never expires.
if ($Item.expires -eq 0) {
$Expires = $null
}
else {
$Expires = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.expires).LocalTime
}

[PSCustomObject]@{
Name = $Item.name
Ip = $Item.ip
HwAddr = $Item.hwaddr
ClientId = $Item.clientid
Expires = $Expires
}
}
Write-Output $ObjectFinal
}
}

catch {
Write-Error -Message $_.Exception.Message
}

finally {
if ($Sid) {
Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl
}
}
}
80 changes: 80 additions & 0 deletions PiHoleShell/Public/DHCP/Remove-PiHoleDhcpLease.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
function Remove-PiHoleDhcpLease {
<#
.SYNOPSIS
Remove a DHCP lease

.DESCRIPTION
Removes a currently active DHCP lease. Managing DHCP leases is only possible when the DHCP
server is enabled.

.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 Ip
The IP address of the lease to remove, as shown by Get-PiHoleDhcpLease

.PARAMETER IgnoreSsl
Set to $true to skip SSL certificate validation

.PARAMETER RawOutput
This will dump the response instead of the formatted object

.EXAMPLE
Remove-PiHoleDhcpLease -PiHoleServer "http://pihole.domain.com:8080" -Password "your-app-password" -Ip "192.168.1.50"
#>
[CmdletBinding(SupportsShouldProcess = $true, HelpUri = 'https://ftl.pi-hole.net/master/docs/#delete-/dhcp/leases/-ip-')]
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")]
param (
[Parameter(Mandatory = $true)]
[System.URI]$PiHoleServer,
[Parameter(Mandatory = $true)]
[string]$Password,
[Parameter(Mandatory = $true)]
[string]$Ip,
[bool]$IgnoreSsl = $false,
[bool]$RawOutput = $false
)
try {
$Target = "Pi-Hole DHCP lease $Ip"
if ($PSCmdlet.ShouldProcess($Target, "Remove DHCP lease")) {
$Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl

$Params = @{
Headers = @{sid = $($Sid) }
Uri = "$($PiHoleServer.OriginalString)/api/dhcp/leases/$Ip"
Method = "Delete"
SkipCertificateCheck = $IgnoreSsl
ContentType = "application/json"
}

$Response = Invoke-RestMethod @Params

if ($RawOutput) {
Write-Output $Response
}

else {
# A successful delete returns 204 No Content, so there's no response body to
# build a rich object from.
$Object = [PSCustomObject]@{
Ip = $Ip
Status = "Removed"
}
Write-Output $Object
}
}
}

catch {
Write-Error -Message $_.Exception.Message
}

finally {
if ($Sid) {
Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl
}
}
}
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ See [docs/EXAMPLES.md](docs/EXAMPLES.md) for real, captured output from every fu
| `Add-PiHoleConfigArrayItem` | Add config array item |
| `Get-PiHoleConfig` | Get current configuration of Pi-hole |
| `Get-PiHoleConfigProperty` | Get special properties of your Pi-hole configuration |
| `Get-PiHoleDhcpLease` | Get currently active DHCP leases |
| `Get-PiHoleHistory` | Get activity graph data |
| `Get-PiHoleHistoryClient` | Get per-client activity graph data |
| `Get-PiHoleHistoryDatabase` | Get activity graph data (long-term data) |
Expand All @@ -190,6 +191,7 @@ See [docs/EXAMPLES.md](docs/EXAMPLES.md) for real, captured output from every fu
| `Get-PiHolePadd` | Get summarized data for PADD |
| `Get-PiHoleTeleporterDownload` | Export Pi-hole settings |
| `Remove-PiHoleConfigArrayItem` | Delete config array item |
| `Remove-PiHoleDhcpLease` | Remove a DHCP lease |
| `Remove-PiHoleInfoMessage` | Delete a Pi-hole diagnosis message |
| `Remove-PiHoleNetworkDevice` | Delete a device from the network table |
| `Set-PiHoleConfig` | Change configuration of your Pi-hole |
Expand All @@ -200,6 +202,8 @@ 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. |
| `Remove-PiHoleAuthSession` | Using this endpoint, a session can be deleted by its ID. |
<!-- COMMAND-REFERENCE:END -->
Expand Down
Loading
Loading