diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d669de9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +notes.txt \ No newline at end of file diff --git a/PiHoleShell/PiHoleShell.psm1 b/PiHoleShell/PiHoleShell.psm1 index 0a5b5d4..efb4717 100644 --- a/PiHoleShell/PiHoleShell.psm1 +++ b/PiHoleShell/PiHoleShell.psm1 @@ -3,8 +3,8 @@ if ($PSVersionTable.PSEdition -ne 'Core') { } # Get all .ps1 files in the 'Public' directory and dot-source them -$PublicFunctions = Get-ChildItem -Path (Join-Path $PSScriptRoot 'Public') -Filter '*.ps1' -File -$PrivateFunctions = Get-ChildItem -Path (Join-Path $PSScriptRoot 'Private') -Filter '*.ps1' -File +$PublicFunctions = Get-ChildItem -Verbose -Path (Join-Path $PSScriptRoot 'Public') -Filter '*.ps1' -File -Recurse +$PrivateFunctions = Get-ChildItem -Path (Join-Path $PSScriptRoot 'Private') -Filter '*.ps1' -File -Recurse foreach ($File in $PublicFunctions) { . $File.FullName @@ -15,22 +15,22 @@ foreach ($File in $PrivateFunctions) { } Export-ModuleMember -Function @( - #Actions.ps1 - 'Update-PiHoleActionsGravity', 'Invoke-PiHoleFlushNetwork' ` - #Authentication.ps1 + #Actions + 'Update-PiHoleActionsGravity', 'Invoke-PiHoleFlushNetwork', 'Restart-PiHoleDnsService' ` + #Authentication 'Remove-PiHoleCurrentAuthSession' , 'Get-PiHoleCurrentAuthSession', 'Remove-PiHoleAuthSession', ` - #GroupManagement.ps1 + #GroupManagement 'Get-PiHoleGroup', 'New-PiHoleGroup', 'Update-PiHoleGroup', 'Remove-PiHoleGroup', ` - #DnsControl.ps1 + #DnsControl 'Get-PiHoleDnsBlockingStatus', 'Set-PiHoleDnsBlocking', ` - #Config.ps1 - 'Get-PiHoleConfig', 'Get-PiHoleCurrentAuthSession', 'Remove-PiHoleAuthSession', ` - #Padd.ps1 + #Config + 'Get-PiHoleConfig', ` + #Padd 'Get-PiHolePadd', ` - #Metrics.ps1 + #Metrics 'Get-PiHoleStatsRecentBlocked', 'Get-PiHoleStatsQueryType', 'Get-PiHoleStatsTopDomain', 'Get-PiHoleStatsSummary', 'Get-PiHoleStatsTopClient' ` - #ListManagement.ps1 + #ListManagement 'Get-PiHoleList', 'Search-PiHoleListDomain', 'Add-PiHoleList', 'Remove-PiHoleList', ` - #FTLInformation.ps1 + #FTLInformation 'Get-PiHoleInfoMessage', 'Get-PiHoleInfoHost' ) \ No newline at end of file diff --git a/PiHoleShell/Public/Actions.ps1 b/PiHoleShell/Public/Actions.ps1 deleted file mode 100644 index 518eb26..0000000 --- a/PiHoleShell/Public/Actions.ps1 +++ /dev/null @@ -1,193 +0,0 @@ -function Update-PiHoleActionsGravity { - <# -.SYNOPSIS -https://ftl.pi-hole.net/master/docs/#post-/action/gravity - - #> - #Work In Progress - [CmdletBinding(SupportsShouldProcess = $true)] - [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/action/gravity" - Method = "Post" - SkipCertificateCheck = $IgnoreSsl - ContentType = "application/json" - } - - if ($PSCmdlet.ShouldProcess("Pi-Hole server at $PiHoleServer", "Update gravity actions")) { - $Response = Invoke-RestMethod @Params - } - - if ($RawOutput) { - Write-Output $Response - } - - else { - $ObjectFinal = @() - $Object = $null - if ($Object) { - $ObjectFinal += $Object - } - Write-Output $ObjectFinal - } - } - - catch { - Write-Error -Message $_.Exception.Message - break - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} - -function Invoke-PiHoleFlushNetwork { - <# -.SYNOPSIS -https://ftl.pi-hole.net/master/docs/#post-/action/flush/network - -.DESCRIPTION -Flushes the Pi-hole log file (/var/log/pihole/pihole.log). - -.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 -Invoke-PiHoleFlushNetwork -PiHoleServer "http://pihole.domain.com:8080" -Password "fjdsjfldsjfkldjslafjskdl" - #> - [CmdletBinding()] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Flushes PiHole logs')] - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] - param ( - $PiHoleServer, - $Password, - [bool]$IgnoreSsl = $false, - [bool]$RawOutput = $false - ) - - try { - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$PiHoleServer/api/action/flush/logs" - Method = "Post" - ContentType = "application/json" - SkipCertificateCheck = $IgnoreSsl - } - - $Response = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Response - } - else { - $Object = [PSCustomObject]@{ - Status = "Flushed" - } - Write-Output $Object - } - } - - catch { - Write-Error -Message $_.Exception.Message - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} - -function Restart-PiHoleDnsService { - <# -.SYNOPSIS -https://dns3.local:8489/api/docs/#post-/action/restartdns - -.DESCRIPTION -Restarts the Pi-hole DNS resolver (FTL). - -.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 -Invoke-PiHoleRestartDns -PiHoleServer "http://pihole.domain.com:8080" -Password "fjdsjfldsjfkldjslafjskdl" - #> - [CmdletBinding()] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Restarts PiHole DNS')] - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] - param ( - $PiHoleServer, - $Password, - [bool]$IgnoreSsl = $false, - [bool]$RawOutput = $false - ) - - try { - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$PiHoleServer/api/action/restartdns" - Method = "Post" - ContentType = "application/json" - SkipCertificateCheck = $IgnoreSsl - } - - $Response = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Response - } - else { - $Object = [PSCustomObject]@{ - Status = "Restarted" - } - Write-Output $Object - } - } - - catch { - Write-Error -Message $_.Exception.Message - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} \ No newline at end of file diff --git a/PiHoleShell/Public/Actions/Invoke-PiHoleFlushNetwork.ps1 b/PiHoleShell/Public/Actions/Invoke-PiHoleFlushNetwork.ps1 new file mode 100644 index 0000000..87c0847 --- /dev/null +++ b/PiHoleShell/Public/Actions/Invoke-PiHoleFlushNetwork.ps1 @@ -0,0 +1,67 @@ +function Invoke-PiHoleFlushNetwork { + <# +.SYNOPSIS +Flushes the network table. This includes removing both all known devices and their associated addresses. + +.DESCRIPTION +Flushes the Pi-hole log file (/var/log/pihole/pihole.log). + +.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 +Invoke-PiHoleFlushNetwork -PiHoleServer "http://pihole.domain.com:8080" -Password "fjdsjfldsjfkldjslafjskdl" + #> + [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#post-/action/flush/network')] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Flushes PiHole logs')] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + $PiHoleServer, + $Password, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + ) + + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$PiHoleServer/api/action/flush/logs" + Method = "Post" + ContentType = "application/json" + SkipCertificateCheck = $IgnoreSsl + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + else { + $Object = [PSCustomObject]@{ + Status = "Flushed" + } + Write-Output $Object + } + } + + catch { + Write-Error -Message $_.Exception.Message + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/Actions/Restart-PiHoleDnsService.ps1 b/PiHoleShell/Public/Actions/Restart-PiHoleDnsService.ps1 new file mode 100644 index 0000000..7ee1e4a --- /dev/null +++ b/PiHoleShell/Public/Actions/Restart-PiHoleDnsService.ps1 @@ -0,0 +1,67 @@ +function Restart-PiHoleDnsService { + <# +.SYNOPSIS +Restarts the pihole-FTL service + +.DESCRIPTION +Restarts the Pi-hole DNS resolver (FTL). + +.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 +Invoke-PiHoleRestartDns -PiHoleServer "http://pihole.domain.com:8080" -Password "fjdsjfldsjfkldjslafjskdl" + #> + [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#post-/action/restartdns')] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Restarts PiHole DNS')] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + $PiHoleServer, + $Password, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + ) + + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$PiHoleServer/api/action/restartdns" + Method = "Post" + ContentType = "application/json" + SkipCertificateCheck = $IgnoreSsl + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + else { + $Object = [PSCustomObject]@{ + Status = "Restarted" + } + Write-Output $Object + } + } + + catch { + Write-Error -Message $_.Exception.Message + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/Actions/Update-PiHoleActionsGravity.ps1 b/PiHoleShell/Public/Actions/Update-PiHoleActionsGravity.ps1 new file mode 100644 index 0000000..8d392db --- /dev/null +++ b/PiHoleShell/Public/Actions/Update-PiHoleActionsGravity.ps1 @@ -0,0 +1,57 @@ +function Update-PiHoleActionsGravity { + <# +.SYNOPSIS +Update Pi-hole's adlists by running pihole -g. The output of the process is streamed with chunked encoding. Use the optional color query parameter to include ANSI color escape codes in the output. + + #> + #Work In Progress + [CmdletBinding(SupportsShouldProcess = $true, HelpUri = 'https://ftl.pi-hole.net/master/docs/#post-/action/gravity')] + [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/action/gravity" + Method = "Post" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + if ($PSCmdlet.ShouldProcess("Pi-Hole server at $PiHoleServer", "Update gravity actions")) { + $Response = Invoke-RestMethod @Params + } + + if ($RawOutput) { + Write-Output $Response + } + + else { + $ObjectFinal = @() + $Object = $null + if ($Object) { + $ObjectFinal += $Object + } + Write-Output $ObjectFinal + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/Authentication.ps1 b/PiHoleShell/Public/Authentication/Get-PiHoleCurrentAuthSession.ps1 similarity index 50% rename from PiHoleShell/Public/Authentication.ps1 rename to PiHoleShell/Public/Authentication/Get-PiHoleCurrentAuthSession.ps1 index a8e4d8a..2ae3603 100644 --- a/PiHoleShell/Public/Authentication.ps1 +++ b/PiHoleShell/Public/Authentication/Get-PiHoleCurrentAuthSession.ps1 @@ -1,38 +1,7 @@ -function Request-PiHoleAuth { - #INTERNAL FUNCTION - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] - param ( - [CmdletBinding()] - [System.URI]$PiHoleServer, - [string]$Password, - [bool]$IgnoreSsl = $false - ) - - try { - $Params = @{ - Uri = "$($PiHoleServer.OriginalString)/api/auth" - Method = "Post" - ContentType = "application/json" - SkipCertificateCheck = $IgnoreSsl - Body = @{password = $Password } | ConvertTo-Json - } - - $Response = Invoke-RestMethod @Params -Verbose: $false - Write-Verbose -Message "Request-PiHoleAuth Successful!" - - Write-Output $Response.session.sid - } - - catch { - Write-Error -Message $_.Exception.Message - break - } -} - function Get-PiHoleCurrentAuthSession { <# .SYNOPSIS -https://ftl.pi-hole.net/master/docs/#get-/auth +List of all current sessions including their validity and further information about the client such as the IP address and user agent. .PARAMETER PiHoleServer The URL to the PiHole Server, for example "http://pihole.domain.com:8080", or "http://192.168.1.100" @@ -49,7 +18,7 @@ This will dump the response instead of the formatted object .EXAMPLE Get-PiHoleCurrentAuthSession -PiHoleServer "http://pihole.domain.com:8080" -Password "fjdsjfldsjfkldjslafjskdl" #> - [CmdletBinding()] + [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#get-/auth/sessions')] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] param ( [Parameter(Mandatory = $true)] @@ -113,64 +82,4 @@ Get-PiHoleCurrentAuthSession -PiHoleServer "http://pihole.domain.com:8080" -Pass Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid } } -} - -function Remove-PiHoleAuthSession { - <# -.SYNOPSIS -https://ftl.pi-hole.net/master/docs/#get-/auth - -.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 -Ignore SSL when interacting with the PiHole API - -.EXAMPLE -Get-PiHoleCurrentAuthSession -PiHoleServer "http://pihole.domain.com:8080" -Password "fjdsjfldsjfkldjslafjskdl" - #> - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Does not change state')] - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] - param ( - [Parameter(Mandatory = $true)] - [System.URI]$PiHoleServer, - [Parameter(Mandatory = $true)] - [string]$Password, - [bool]$IgnoreSsl = $false, - [int]$Id - ) - - try { - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$($PiHoleServer.OriginalString)/api/auth/session/$Id" - Method = "Delete" - SkipCertificateCheck = $IgnoreSsl - ContentType = "application/json" - } - - Invoke-RestMethod @Params - - $ObjectFinal = @() - $Object = [PSCustomObject]@{ - Id = $Id - Status = "Removed" - } - $ObjectFinal = $Object - Write-Output $ObjectFinal - } - - catch { - Write-Error -Message $_.Exception.Message - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } } \ No newline at end of file diff --git a/PiHoleShell/Public/Authentication/Remove-PiHoleAuthSession.ps1 b/PiHoleShell/Public/Authentication/Remove-PiHoleAuthSession.ps1 new file mode 100644 index 0000000..c448ad7 --- /dev/null +++ b/PiHoleShell/Public/Authentication/Remove-PiHoleAuthSession.ps1 @@ -0,0 +1,60 @@ +function Remove-PiHoleAuthSession { + <# +.SYNOPSIS +Using this endpoint, a session can be deleted by its ID. + +.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 +Ignore SSL when interacting with the PiHole API + +.EXAMPLE +Get-PiHoleCurrentAuthSession -PiHoleServer "http://pihole.domain.com:8080" -Password "fjdsjfldsjfkldjslafjskdl" + #> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Does not change state')] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#delete-/auth/session/-id-')] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + [string]$Password, + [bool]$IgnoreSsl = $false, + [int]$Id + ) + + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/auth/session/$Id" + Method = "Delete" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + Invoke-RestMethod @Params + + $ObjectFinal = @() + $Object = [PSCustomObject]@{ + Id = $Id + Status = "Removed" + } + $ObjectFinal = $Object + Write-Output $ObjectFinal + } + + catch { + Write-Error -Message $_.Exception.Message + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/Authentication/Request-PiHoleAuth.ps1 b/PiHoleShell/Public/Authentication/Request-PiHoleAuth.ps1 new file mode 100644 index 0000000..aaec1a4 --- /dev/null +++ b/PiHoleShell/Public/Authentication/Request-PiHoleAuth.ps1 @@ -0,0 +1,30 @@ +function Request-PiHoleAuth { + #INTERNAL FUNCTION + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [CmdletBinding()] + [System.URI]$PiHoleServer, + [string]$Password, + [bool]$IgnoreSsl = $false + ) + + try { + $Params = @{ + Uri = "$($PiHoleServer.OriginalString)/api/auth" + Method = "Post" + ContentType = "application/json" + SkipCertificateCheck = $IgnoreSsl + Body = @{password = $Password } | ConvertTo-Json + } + + $Response = Invoke-RestMethod @Params -Verbose: $false + Write-Verbose -Message "Request-PiHoleAuth Successful!" + + Write-Output $Response.session.sid + } + + catch { + Write-Error -Message $_.Exception.Message + break + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/Config.ps1 b/PiHoleShell/Public/Config/Get-PiHoleConfig.ps1 similarity index 98% rename from PiHoleShell/Public/Config.ps1 rename to PiHoleShell/Public/Config/Get-PiHoleConfig.ps1 index a938f07..5a2ace8 100644 --- a/PiHoleShell/Public/Config.ps1 +++ b/PiHoleShell/Public/Config/Get-PiHoleConfig.ps1 @@ -1,7 +1,7 @@ function Get-PiHoleConfig { <# .SYNOPSIS -https://TODO +https://ftl.pi-hole.net/master/docs/#get-/config #> #Work In Progress diff --git a/PiHoleShell/Public/DnsControl/Get-PiHoleDnsBlockingStatus.ps1 b/PiHoleShell/Public/DnsControl/Get-PiHoleDnsBlockingStatus.ps1 new file mode 100644 index 0000000..e27a504 --- /dev/null +++ b/PiHoleShell/Public/DnsControl/Get-PiHoleDnsBlockingStatus.ps1 @@ -0,0 +1,68 @@ +function Get-PiHoleDnsBlockingStatus { + <# +.SYNOPSIS +https://ftl.pi-hole.net/master/docs/#get-/config + +.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 +Ignore SSL when interacting with the PiHole API + +.PARAMETER RawOutput +This will dump the response instead of the formatted object + +.EXAMPLE +Get-PiHoleDnsBlockingStatus -PiHoleServer "http://pihole.domain.com:8080" -Password "fjdsjfldsjfkldjslafjskdl" + #> + [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/dns/blocking" + Method = "Get" + ContentType = "application/json" + SkipCertificateCheck = $IgnoreSsl + } + + $Data = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Data + } + else { + $ObjectFinal = @() + $Object = [PSCustomObject]@{ + Blocking = $Data.blocking + Timer = (Format-PiHoleSecond -TimeInSeconds $Data.timer).TimeInSeconds + } + + $ObjectFinal += $Object + Write-Output $ObjectFinal + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/DnsControl.ps1 b/PiHoleShell/Public/DnsControl/Set-PiHoleDnsBlocking.ps1 similarity index 56% rename from PiHoleShell/Public/DnsControl.ps1 rename to PiHoleShell/Public/DnsControl/Set-PiHoleDnsBlocking.ps1 index e45c7fb..ab64125 100644 --- a/PiHoleShell/Public/DnsControl.ps1 +++ b/PiHoleShell/Public/DnsControl/Set-PiHoleDnsBlocking.ps1 @@ -1,77 +1,7 @@ -function Get-PiHoleDnsBlockingStatus { - <# -.SYNOPSIS -Get current blocking status - -.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 -Ignore SSL when interacting with the PiHole API - -.PARAMETER RawOutput -This will dump the response instead of the formatted object - -.EXAMPLE -Get-PiHoleDnsBlockingStatus -PiHoleServer "http://pihole.domain.com:8080" -Password "fjdsjfldsjfkldjslafjskdl" - #> - [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/dns/blocking" - Method = "Get" - ContentType = "application/json" - SkipCertificateCheck = $IgnoreSsl - } - - $Data = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Data - } - else { - $ObjectFinal = @() - $Object = [PSCustomObject]@{ - Blocking = $Data.blocking - Timer = (Format-PiHoleSecond -TimeInSeconds $Data.timer).TimeInSeconds - } - - $ObjectFinal += $Object - Write-Output $ObjectFinal - } - - } - - catch { - Write-Error -Message $_.Exception.Message - break - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} - function Set-PiHoleDnsBlocking { <# .SYNOPSIS -https://ftl.pi-hole.net/development-v6/docs/#post-/dns/blocking +https://ftl.pi-hole.net/master/docs/#get-/dns/blocking .PARAMETER PiHoleServer The URL to the PiHole Server, for example "http://pihole.domain.com:8080", or "http://192.168.1.100" diff --git a/PiHoleShell/Public/FTLInformation.ps1 b/PiHoleShell/Public/FTLInformation.ps1 deleted file mode 100644 index ad14d80..0000000 --- a/PiHoleShell/Public/FTLInformation.ps1 +++ /dev/null @@ -1,195 +0,0 @@ -function Get-PiHoleInfoMessage { - <# -.SYNOPSIS -Get Pi-hole diagnosis messages -Request Pi-hole diagnosis messages - #> - [CmdletBinding()] - [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/info/messages" - Method = "Get" - SkipCertificateCheck = $IgnoreSsl - ContentType = "application/json" - } - - $Response = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Response - } - - else { - $ObjectFinal = @() - foreach ($Item in $Response.messages) { - $Object = $null - $Object = [PSCustomObject]@{ - Id = $Item.id - Timestamp = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.timestamp).LocalTime - Type = $Item.type - Plain = $Item.plain - Html = $Item.html - - } - - Write-Verbose -Message "Name - $($Object.Id)" - Write-Verbose -Message "Timestamp - $($Object.Timestamp)" - Write-Verbose -Message "Type - $($Object.Type)" - Write-Verbose -Message "Plain - $($Object.Plain)" - Write-Verbose -Message "Html - $($Object.Html)" - $ObjectFinal += $Object - } - - Write-Output $ObjectFinal - } - } - - catch { - Write-Error -Message $_.Exception.Message - break - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} - -function Get-PiHoleInfoHost { - <# -.SYNOPSIS -Get info about various host parameters -This API hook returns a collection of host infos. - - #> - #Work In Progress - [CmdletBinding()] - [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/info/host" - Method = "Get" - SkipCertificateCheck = $IgnoreSsl - ContentType = "application/json" - } - - $Response = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Response - } - - else { - $ObjectFinal = @() - foreach ($Item in $Response.host) { - $Object = $null - $Object = [PSCustomObject]@{ - DomainName = $Item.uname.domainname - Machine = $Item.uname.machine - NodeName = $Item.uname.nodename - Release = $Item.uname.release - SysName = $Item.uname.sysname - Version = $Item.uname.version - - } - $ObjectFinal += $Object - Write-Output $ObjectFinal - } - } - } - - catch { - Write-Error -Message $_.Exception.Message - break - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} - -function Get-PiHoleLogWebserver { - <# -.SYNOPSIS -Get info about logs for webserver - - #> - #Work In Progress - [CmdletBinding()] - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] - param ( - [Parameter(Mandatory = $true)] - [System.URI]$PiHoleServer, - [Parameter(Mandatory = $true)] - [string]$Password, - [int]$NextID, - [bool]$IgnoreSsl = $false, - [bool]$RawOutput = $false - ) - try { - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - - if ($NextID) { - $Uri = "$($PiHoleServer.OriginalString)/api/logs/webserver?nextId=$NextId" - - } - else { - $Uri = "$($PiHoleServer.OriginalString)/api/logs/webserver" - } - - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = $Uri - Method = "Get" - SkipCertificateCheck = $IgnoreSsl - ContentType = "application/json" - } - - $Response = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Response - } - - else { - #$ObjectFinal = @() - } - } - - catch { - Write-Error -Message $_.Exception.Message - break - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} \ No newline at end of file diff --git a/PiHoleShell/Public/FTLInformation/Get-PiHoleInfoHost.ps1 b/PiHoleShell/Public/FTLInformation/Get-PiHoleInfoHost.ps1 new file mode 100644 index 0000000..6ea7d84 --- /dev/null +++ b/PiHoleShell/Public/FTLInformation/Get-PiHoleInfoHost.ps1 @@ -0,0 +1,65 @@ +function Get-PiHoleInfoHost { + <# +.SYNOPSIS +Get info about various host parameters +This API hook returns a collection of host infos. + + #> + #Work In Progress + [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#get-/info/host')] + [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/info/host" + Method = "Get" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + + else { + $ObjectFinal = @() + foreach ($Item in $Response.host) { + $Object = $null + $Object = [PSCustomObject]@{ + DomainName = $Item.uname.domainname + Machine = $Item.uname.machine + NodeName = $Item.uname.nodename + Release = $Item.uname.release + SysName = $Item.uname.sysname + Version = $Item.uname.version + + } + $ObjectFinal += $Object + Write-Output $ObjectFinal + } + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/FTLInformation/Get-PiHoleInfoMessage.ps1 b/PiHoleShell/Public/FTLInformation/Get-PiHoleInfoMessage.ps1 new file mode 100644 index 0000000..fcd4f28 --- /dev/null +++ b/PiHoleShell/Public/FTLInformation/Get-PiHoleInfoMessage.ps1 @@ -0,0 +1,69 @@ +function Get-PiHoleInfoMessage { + <# +.SYNOPSIS +Get Pi-hole diagnosis messages +Request Pi-hole diagnosis messages + #> + [CmdletBinding()] + [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/info/messages" + Method = "Get" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + + else { + $ObjectFinal = @() + foreach ($Item in $Response.messages) { + $Object = $null + $Object = [PSCustomObject]@{ + Id = $Item.id + Timestamp = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.timestamp).LocalTime + Type = $Item.type + Plain = $Item.plain + Html = $Item.html + + } + + Write-Verbose -Message "Name - $($Object.Id)" + Write-Verbose -Message "Timestamp - $($Object.Timestamp)" + Write-Verbose -Message "Type - $($Object.Type)" + Write-Verbose -Message "Plain - $($Object.Plain)" + Write-Verbose -Message "Html - $($Object.Html)" + $ObjectFinal += $Object + } + + Write-Output $ObjectFinal + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/FTLInformation/Get-PiHoleLogWebserver.ps1 b/PiHoleShell/Public/FTLInformation/Get-PiHoleLogWebserver.ps1 new file mode 100644 index 0000000..16ab4df --- /dev/null +++ b/PiHoleShell/Public/FTLInformation/Get-PiHoleLogWebserver.ps1 @@ -0,0 +1,60 @@ + +function Get-PiHoleLogWebserver { + <# +.SYNOPSIS +Get info about logs for webserver + + #> + #Work In Progress + [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#get-/logs/webserver')] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + [string]$Password, + [int]$NextID, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + ) + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + if ($NextID) { + $Uri = "$($PiHoleServer.OriginalString)/api/logs/webserver?nextId=$NextId" + + } + else { + $Uri = "$($PiHoleServer.OriginalString)/api/logs/webserver" + } + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = $Uri + Method = "Get" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + + else { + #$ObjectFinal = @() + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/GroupManagement.ps1 b/PiHoleShell/Public/GroupManagement.ps1 deleted file mode 100644 index a874595..0000000 --- a/PiHoleShell/Public/GroupManagement.ps1 +++ /dev/null @@ -1,341 +0,0 @@ -function Get-PiHoleGroup { - <# -.SYNOPSIS -https://TODO - - #> - #Work In Progress - [CmdletBinding()] - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] - param ( - [Parameter(Mandatory = $true)] - [System.URI]$PiHoleServer, - [Parameter(Mandatory = $true)] - $Password, - $GroupName = $null, - [bool]$IgnoreSsl = $false, - [bool]$RawOutput = $false - ) - try { - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$($PiHoleServer.OriginalString)/api/groups" - Method = "Get" - SkipCertificateCheck = $IgnoreSsl - ContentType = "application/json" - } - - $Response = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Response - } - - else { - $ObjectFinal = @() - foreach ($Item in $Response.Groups) { - $Object = $null - $Object = [PSCustomObject]@{ - Name = $Item.name - Comment = $Item.comment - Enabled = $Item.enabled - Id = $Item.id - DateAdded = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_added).LocalTime - DateModified = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_modified).LocalTime - - } - Write-Verbose -Message "Name - $($Item.name)" - Write-Verbose -Message "Comment - $($Item.comment)" - Write-Verbose -Message "Enabled - $($Item.enabled)" - Write-Verbose -Message "Id - $($Item.id)" - Write-Verbose -Message "Date Added - $($Item.date_added)" - Write-Verbose -Message "Date Date Modified - $(($Item.date_modified))" - $ObjectFinal += $Object - } - - if ($GroupName) { - $GroupNameObject = $ObjectFinal | Where-Object { $_.Name -eq $GroupName } - if ($GroupNameObject) { - Write-Output $GroupNameObject - } - else { - Write-Warning "Did not find $GroupName on $PiHoleServer" - } - } - - else { - Write-Output $ObjectFinal - } - - } - } - - catch { - Write-Error -Message $_.Exception.Message - break - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} - -function New-PiHoleGroup { - <# -.SYNOPSIS -https://TODO - - #> - #Work In Progress - [CmdletBinding()] - [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, - [Parameter(Mandatory = $true)] - [string]$GroupName, - [string]$Comment = $null, - [bool]$Enabled = $true, - [bool]$IgnoreSsl = $false, - [bool]$RawOutput = $false - - ) - try { - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - - $GetGroupName = Get-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl -GroupName $GroupName - - if ($GetGroupName) { - Write-Warning -Message "Group $GroupName already exists" - } - - else { - $Body = @{ - comment = $Comment - enabled = $Enabled - name = $GroupName - } - - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$($PiHoleServer.OriginalString)/api/groups" - Method = "Post" - SkipCertificateCheck = $IgnoreSsl - ContentType = "application/json" - Body = $Body | ConvertTo-Json -Depth 10 - } - - $Response = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Response - } - - else { - $ObjectFinal = @() - $Object = [PSCustomObject]@{ - Name = $GroupName - Comment = $Comment - Enabled = $Enabled - } - Write-Verbose -Message "Name - $($Object.GroupName)" - Write-Verbose -Message "Comment - $($Object.Comment)" - Write-Verbose -Message "Enabled - $($Object.Enabled)" - $ObjectFinal = $Object - } - Write-Output $ObjectFinal - } - } - - catch { - Write-Error -Message $_.Exception.Message - break - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} - -function Update-PiHoleGroup { - <# -.SYNOPSIS -https://TODO - - #> - #Work In Progress - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] - [Diagnostics.CodeAnalysis.SuppressMessage("PSUseShouldProcessForStateChangingFunctions", "", Justification = "Ignoring for now")] - param ( - [Parameter(Mandatory = $true)] - [System.URI]$PiHoleServer, - [Parameter(Mandatory = $true)] - [string]$Password, - [Parameter(Mandatory = $true)] - [string]$GroupName, - [string]$Comment = $null, - [bool]$Enabled, - [bool]$IgnoreSsl = $false, - [bool]$RawOutput = $false - - ) - #Enabled is weird here.. look into it - try { - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - - $Body = @{ - name = $GroupName - } - - $GetGroupName = Get-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl -GroupName $GroupName - - if ($Comment -eq $null -and $Enabled -eq $null) { - Write-Warning -Message "failed" - throw -Message "To update $GroupName, you must either use the Comment and/or Enabled parameter" - } - - if ($Comment) { - $Body += @{ - comment = $Comment - } - } - if ($Enabled -ne $null) { - $Body += @{ - enabled = $Enabled - } - } - else { - switch ($GetGroupStatus) { - "True" { - $true - } - "False" { - $false - } - } - - $Body += @{ - enabled = $GetGroupStatus - } - } - - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$($PiHoleServer.OriginalString)/api/groups/$GroupName" - Method = "Put" - SkipCertificateCheck = $IgnoreSsl - ContentType = "application/json" - Body = $Body | ConvertTo-Json -Depth 10 - } - - if ($GetGroupName) { - $Response = Invoke-RestMethod @Params - if ($RawOutput) { - Write-Output $Response - } - else { - $ObjectFinal = @() - $Object = [PSCustomObject]@{ - Name = $GroupName - Comment = $Comment - Enabled = $Enabled - } - Write-Verbose -Message "Name - $($Object.GroupName)" - Write-Verbose -Message "Comment - $($Object.Comment)" - Write-Verbose -Message "Enabled - $($Object.Enabled)" - $ObjectFinal = $Object - } - Write-Output $ObjectFinal - - } - } - - catch { - Write-Error -Message $_.Exception.Message - break - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} - -function Remove-PiHoleGroup { - <# -.SYNOPSIS -https://TODO - - #> - #Work In Progress - [CmdletBinding()] - [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, - [Parameter(Mandatory = $true)] - [string]$GroupName, - [bool]$IgnoreSsl = $false, - [bool]$RawOutput = $false - - ) - try { - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - - $Body = @{ - name = $GroupName - } - - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$($PiHoleServer.OriginalString)/api/groups/$GroupName" - Method = "Delete" - SkipCertificateCheck = $IgnoreSsl - ContentType = "application/json" - Body = $Body | ConvertTo-Json -Depth 10 - } - $GetGroupName = Get-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl -GroupName $GroupName - - if ($GetGroupName) { - $Response = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Response - } - else { - $ObjectFinal = @() - $Object = [PSCustomObject]@{ - Name = $GroupName - Status = "Deleted" - } - $ObjectFinal = $Object - } - Write-Verbose -Message "Deleted $($Object.GroupName)" - Write-Output $ObjectFinal - } - } - - catch { - Write-Error -Message $_.Exception.Message - break - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} \ No newline at end of file diff --git a/PiHoleShell/Public/GroupManagement/Get-PiHoleGroup.ps1 b/PiHoleShell/Public/GroupManagement/Get-PiHoleGroup.ps1 new file mode 100644 index 0000000..5bd952c --- /dev/null +++ b/PiHoleShell/Public/GroupManagement/Get-PiHoleGroup.ps1 @@ -0,0 +1,84 @@ +function Get-PiHoleGroup { + <# +.SYNOPSIS +Get groups + + #> + [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#get-/groups/-name-')] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + $Password, + $GroupName = $null, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + ) + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/groups" + Method = "Get" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + + else { + $ObjectFinal = @() + foreach ($Item in $Response.Groups) { + $Object = $null + $Object = [PSCustomObject]@{ + Name = $Item.name + Comment = $Item.comment + Enabled = $Item.enabled + Id = $Item.id + DateAdded = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_added).LocalTime + DateModified = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_modified).LocalTime + + } + Write-Verbose -Message "Name - $($Item.name)" + Write-Verbose -Message "Comment - $($Item.comment)" + Write-Verbose -Message "Enabled - $($Item.enabled)" + Write-Verbose -Message "Id - $($Item.id)" + Write-Verbose -Message "Date Added - $($Item.date_added)" + Write-Verbose -Message "Date Date Modified - $(($Item.date_modified))" + $ObjectFinal += $Object + } + + if ($GroupName) { + $GroupNameObject = $ObjectFinal | Where-Object { $_.Name -eq $GroupName } + if ($GroupNameObject) { + Write-Output $GroupNameObject + } + else { + Write-Warning "Did not find $GroupName on $PiHoleServer" + } + } + + else { + Write-Output $ObjectFinal + } + + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/GroupManagement/New-PiHoleGroup.ps1 b/PiHoleShell/Public/GroupManagement/New-PiHoleGroup.ps1 new file mode 100644 index 0000000..50458e0 --- /dev/null +++ b/PiHoleShell/Public/GroupManagement/New-PiHoleGroup.ps1 @@ -0,0 +1,80 @@ +function New-PiHoleGroup { + <# +.SYNOPSIS +Creates a new group in the groups object. + + #> + [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#post-/groups')] + [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, + [Parameter(Mandatory = $true)] + [string]$GroupName, + [string]$Comment = $null, + [bool]$Enabled = $true, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + + ) + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $GetGroupName = Get-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl -GroupName $GroupName + + if ($GetGroupName) { + Write-Warning -Message "Group $GroupName already exists" + } + + else { + $Body = @{ + comment = $Comment + enabled = $Enabled + name = $GroupName + } + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/groups" + Method = "Post" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + Body = $Body | ConvertTo-Json -Depth 10 + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + + else { + $ObjectFinal = @() + $Object = [PSCustomObject]@{ + Name = $GroupName + Comment = $Comment + Enabled = $Enabled + } + Write-Verbose -Message "Name - $($Object.GroupName)" + Write-Verbose -Message "Comment - $($Object.Comment)" + Write-Verbose -Message "Enabled - $($Object.Enabled)" + $ObjectFinal = $Object + } + Write-Output $ObjectFinal + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/GroupManagement/Remove-PiHoleGroup.ps1 b/PiHoleShell/Public/GroupManagement/Remove-PiHoleGroup.ps1 new file mode 100644 index 0000000..4af5500 --- /dev/null +++ b/PiHoleShell/Public/GroupManagement/Remove-PiHoleGroup.ps1 @@ -0,0 +1,80 @@ +function Remove-PiHoleGroup { + <# +.SYNOPSIS +Delete group + +.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 + + #> + #Work In Progress + [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#delete-/groups/-name-')] + [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, + [Parameter(Mandatory = $true)] + [string]$GroupName, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + + ) + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $Body = @{ + name = $GroupName + } + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/groups/$GroupName" + Method = "Delete" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + Body = $Body | ConvertTo-Json -Depth 10 + } + $GetGroupName = Get-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl -GroupName $GroupName + + if ($GetGroupName) { + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + else { + $ObjectFinal = @() + $Object = [PSCustomObject]@{ + Name = $GroupName + Status = "Deleted" + } + $ObjectFinal = $Object + } + Write-Verbose -Message "Deleted $($Object.GroupName)" + Write-Output $ObjectFinal + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/GroupManagement/Update-PiHoleGroup.ps1 b/PiHoleShell/Public/GroupManagement/Update-PiHoleGroup.ps1 new file mode 100644 index 0000000..f0d9878 --- /dev/null +++ b/PiHoleShell/Public/GroupManagement/Update-PiHoleGroup.ps1 @@ -0,0 +1,116 @@ +function Update-PiHoleGroup { + <# +.SYNOPSIS +Items may be updated by replacing them. + +.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 + + #> + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + [Diagnostics.CodeAnalysis.SuppressMessage("PSUseShouldProcessForStateChangingFunctions", "", Justification = "Ignoring for now")] + [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#put-/groups/-name-')] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + [string]$Password, + [Parameter(Mandatory = $true)] + [string]$GroupName, + [string]$Comment = $null, + [bool]$Enabled, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + + ) + #Enabled is weird here.. look into it + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $Body = @{ + name = $GroupName + } + + $GetGroupName = Get-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl -GroupName $GroupName + + if ($Comment -eq $null -and $Enabled -eq $null) { + Write-Warning -Message "failed" + throw -Message "To update $GroupName, you must either use the Comment and/or Enabled parameter" + } + + if ($Comment) { + $Body += @{ + comment = $Comment + } + } + if ($Enabled -ne $null) { + $Body += @{ + enabled = $Enabled + } + } + else { + switch ($GetGroupStatus) { + "True" { + $true + } + "False" { + $false + } + } + + $Body += @{ + enabled = $GetGroupStatus + } + } + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/groups/$GroupName" + Method = "Put" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + Body = $Body | ConvertTo-Json -Depth 10 + } + + if ($GetGroupName) { + $Response = Invoke-RestMethod @Params + if ($RawOutput) { + Write-Output $Response + } + else { + $ObjectFinal = @() + $Object = [PSCustomObject]@{ + Name = $GroupName + Comment = $Comment + Enabled = $Enabled + } + Write-Verbose -Message "Name - $($Object.GroupName)" + Write-Verbose -Message "Comment - $($Object.Comment)" + Write-Verbose -Message "Enabled - $($Object.Enabled)" + $ObjectFinal = $Object + } + Write-Output $ObjectFinal + + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/ListManagement.ps1 b/PiHoleShell/Public/ListManagement.ps1 deleted file mode 100644 index c50efce..0000000 --- a/PiHoleShell/Public/ListManagement.ps1 +++ /dev/null @@ -1,369 +0,0 @@ -function Get-PiHoleList { - <# -.SYNOPSIS -https://TODO - - #> - #Work In Progress - [CmdletBinding()] - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] - param ( - [Parameter(Mandatory = $true)] - [System.URI]$PiHoleServer, - [Parameter(Mandatory = $true)] - [string]$Password, - [System.URI]$List = $null, - [bool]$IgnoreSsl = $false, - [bool]$RawOutput = $false - ) - try { - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - - $Groups = Get-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$($PiHoleServer.OriginalString)/api/lists/$List" - Method = "Get" - SkipCertificateCheck = $IgnoreSsl - ContentType = "application/json" - } - - $Response = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Response - } - - else { - $ObjectFinal = @() - foreach ($Item in $Response.lists) { - $GroupNames = [System.Collections.ArrayList]@() - foreach ($Group in $Item.groups) { - $GroupNames += ($Groups | Where-Object { $_.Id -eq $Group }).Name - } - - $Object = $null - if ($Item.date_updated -eq 0) { - $DateUpdated = $null - } - else { - $DateUpdated = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_modified).LocalTime - } - $Object = [PSCustomObject]@{ - Address = $Item.address - Comment = $Item.comment - Groups = $GroupNames - Enabled = $Item.enabled - Id = $Item.id - DateAdded = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_added).LocalTime - DateModified = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_modified).LocalTime - Type = $Item.type - DateUpdated = $DateUpdated - Number = $Item.number - InvalidDomains = $Item.invalid_domains - AbpEntries = $Item.abp_entries - Status = $Item.status - } - if ($Object) { - $ObjectFinal += $Object - } - - } - Write-Output $ObjectFinal - } - } - - catch { - Write-Error -Message $_.Exception.Message - break - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} - -function Search-PiHoleListDomain { - <# -.SYNOPSIS -https://TODO - - #> - #Work In Progress - [CmdletBinding()] - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] - param ( - [Parameter(Mandatory = $true)] - [System.URI]$PiHoleServer, - [Parameter(Mandatory = $true)] - [string]$Password, - [Parameter(Mandatory = $true)] - [System.URI]$Domain, - [bool]$PartialMatch = $false, - [int]$MaxResults = 20, - [bool]$IgnoreSsl = $false, - [bool]$RawOutput = $false - ) - try { - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - - $Body = @{ - n = $MaxResults - partial = $PartialMatch - name = $GroupName - } - - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$($PiHoleServer.OriginalString)/api/search/$Domain" - Method = "Get" - SkipCertificateCheck = $IgnoreSsl - Body = $Body - ContentType = "application/json" - } - - $Response = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Response - } - - else { - $ObjectFinal = @() - foreach ($Item in $Response.lists) { - } - Write-Output $ObjectFinal - } - } - - catch { - Write-Error -Message $_.Exception.Message - break - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} - -function Add-PiHoleList { - <# -.SYNOPSIS -https://TODO - - #> - #Work In Progress - [CmdletBinding()] - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] - param ( - [Parameter(Mandatory = $true)] - [System.URI]$PiHoleServer, - [Parameter(Mandatory = $true)] - [string]$Password, - [bool]$IgnoreSsl = $false, - [System.Uri]$Address, - [Parameter(Mandatory = $true)] - [ValidateSet("Allow", "Block")] - [string]$Type, - [string]$Comment = $null, - [string[]]$Group = "Default", - [bool]$Enabled = $true, - [bool]$RawOutput = $false - ) - try { - $FindMatchingList = Get-PiHoleList -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl | Where-Object { $_.Address -eq $Address } - - if ($FindMatchingList) { - throw "List $Address already exists on $PiHoleServer! Please use Update-PiHoleList to update the list" - } - - $AllGroups = Get-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - $AllGroupsNames = @() - $AllGroupsIds = @() - foreach ($GroupItem in $Group) { - - $FoundGroup = $AllGroups | Where-Object { $_.Name -eq $GroupItem } - if ($FoundGroup) { - $AllGroupsNames += $FoundGroup.Name - $AllGroupsIds += $FoundGroup.Id - Write-Verbose -Message "Found Group $($FoundGroup.Name) with $($FoundGroup.Id)" - } - else { - throw "Cannot find $GroupItem on $PiHoleServer! Please use Get-PiHoleGroup to list all groups" - } - } - - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - - $Body = @{ - address = $Address - type = $Type - groups = [Object[]]($AllGroupsIds) - comment = $Comment - enabled = $Enabled - } - - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$($PiHoleServer.OriginalString)/api/lists" - Method = "Post" - SkipCertificateCheck = $IgnoreSsl - Body = $Body | ConvertTo-Json -Depth 10 - ContentType = "application/json" - } - - $Response = Invoke-RestMethod @Params - - if ($Item.date_updated -eq 0) { - $DateUpdated = $null - } - else { - $DateUpdated = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_modified).LocalTime - } - - if ($RawOutput) { - Write-Output $Response - } - - else { - $ObjectFinal = @() - $Object = $null - foreach ($Item in $Response.lists) { - - $Object = [PSCustomObject]@{ - Address = $Item.address - Comment = $Item.comment - Groups = $AllGroupsNames - Enabled = $Item.enabled - Id = $Item.id - DateAdded = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_added).LocalTime - DateModified = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_modified).LocalTime - Type = $Item.type.SubString(0, 1).ToUpper() + $Item.type.SubString(1).ToLower() - DateUpdated = $DateUpdated - Number = $Item.number - InvalidDomains = $Item.invalid_domains - AbpEntries = $Item.abp_entries - Status = $Item.status - } - if ($Object) { - $ObjectFinal += $Object - } - - } - Write-Output $ObjectFinal - } - } - - catch { - Write-Error -Message $_.Exception.Message - break - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} - -function Remove-PiHoleList { - <# -.SYNOPSIS -https://TODO - - #> - #Work In Progress (NEED TO FINISH) - [CmdletBinding(SupportsShouldProcess = $true)] - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] - param ( - [Parameter(Mandatory = $true)] - [System.URI]$PiHoleServer, - [Parameter(Mandatory = $true)] - [string]$Password, - [bool]$IgnoreSsl = $false, - [System.Uri]$Address, - [string]$Type, - [bool]$RawOutput = $false - ) - try { - $Target = "Pi-Hole list $Address of type $Type" - if ($PSCmdlet.ShouldProcess($Target, "Remove list")) { - $FindMatchingList = Get-PiHoleList -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl | Where-Object { $_.Address -eq $Address } - - if ($FindMatchingList) { - - } - - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - - $Body = @( - @{ - item = $Address - type = $Type.ToLower() - } - ) - - #For some reason this needs to be here to make it an array - $Body = , $Body - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$($PiHoleServer.OriginalString)/api/lists:batchDelete" - Method = "Post" - SkipCertificateCheck = $IgnoreSsl - Body = $Body | ConvertTo-Json -Depth 10 -Compress - ContentType = "application/json" - } - - $Response = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Response - } - - else { - $ObjectFinal = @() - $Object = $null - foreach ($Item in $Response.lists) { - - $Object = [PSCustomObject]@{ - Address = $Item.address - Comment = $Item.comment - Groups = $AllGroupsNames - Enabled = $Item.enabled - Id = $Item.id - DateAdded = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_added).LocalTime - DateModified = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_modified).LocalTime - Type = $Item.type.SubString(0, 1).ToUpper() + $Item.type.SubString(1).ToLower() - DateUpdated = $DateUpdated - Number = $Item.number - InvalidDomains = $Item.invalid_domains - AbpEntries = $Item.abp_entries - Status = $Item.status - } - if ($Object) { - $ObjectFinal += $Object - } - - } - Write-Output $ObjectFinal - } - - } - } - - catch { - Write-Error -Message $_.Exception.Message - break - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} \ No newline at end of file diff --git a/PiHoleShell/Public/ListManagement/Add-PiHoleList.ps1 b/PiHoleShell/Public/ListManagement/Add-PiHoleList.ps1 new file mode 100644 index 0000000..af8acc5 --- /dev/null +++ b/PiHoleShell/Public/ListManagement/Add-PiHoleList.ps1 @@ -0,0 +1,131 @@ +function Add-PiHoleList { + <# +.SYNOPSIS +Add new list + +.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 + + #> + #Work In Progress + [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#post-/lists')] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + [string]$Password, + [bool]$IgnoreSsl = $false, + [System.Uri]$Address, + [Parameter(Mandatory = $true)] + [ValidateSet("Allow", "Block")] + [string]$Type, + [string]$Comment = $null, + [string[]]$Group = "Default", + [bool]$Enabled = $true, + [bool]$RawOutput = $false + ) + try { + $FindMatchingList = Get-PiHoleList -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl | Where-Object { $_.Address -eq $Address } + + if ($FindMatchingList) { + throw "List $Address already exists on $PiHoleServer! Please use Update-PiHoleList to update the list" + } + + $AllGroups = Get-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + $AllGroupsNames = @() + $AllGroupsIds = @() + foreach ($GroupItem in $Group) { + + $FoundGroup = $AllGroups | Where-Object { $_.Name -eq $GroupItem } + if ($FoundGroup) { + $AllGroupsNames += $FoundGroup.Name + $AllGroupsIds += $FoundGroup.Id + Write-Verbose -Message "Found Group $($FoundGroup.Name) with $($FoundGroup.Id)" + } + else { + throw "Cannot find $GroupItem on $PiHoleServer! Please use Get-PiHoleGroup to list all groups" + } + } + + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $Body = @{ + address = $Address + type = $Type + groups = [Object[]]($AllGroupsIds) + comment = $Comment + enabled = $Enabled + } + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/lists" + Method = "Post" + SkipCertificateCheck = $IgnoreSsl + Body = $Body | ConvertTo-Json -Depth 10 + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($Item.date_updated -eq 0) { + $DateUpdated = $null + } + else { + $DateUpdated = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_modified).LocalTime + } + + if ($RawOutput) { + Write-Output $Response + } + + else { + $ObjectFinal = @() + $Object = $null + foreach ($Item in $Response.lists) { + + $Object = [PSCustomObject]@{ + Address = $Item.address + Comment = $Item.comment + Groups = $AllGroupsNames + Enabled = $Item.enabled + Id = $Item.id + DateAdded = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_added).LocalTime + DateModified = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_modified).LocalTime + Type = $Item.type.SubString(0, 1).ToUpper() + $Item.type.SubString(1).ToLower() + DateUpdated = $DateUpdated + Number = $Item.number + InvalidDomains = $Item.invalid_domains + AbpEntries = $Item.abp_entries + Status = $Item.status + } + if ($Object) { + $ObjectFinal += $Object + } + + } + Write-Output $ObjectFinal + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/ListManagement/Get-PiHoleList.ps1 b/PiHoleShell/Public/ListManagement/Get-PiHoleList.ps1 new file mode 100644 index 0000000..5539fda --- /dev/null +++ b/PiHoleShell/Public/ListManagement/Get-PiHoleList.ps1 @@ -0,0 +1,99 @@ +function Get-PiHoleList { + <# +.SYNOPSIS +Get lists + +.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 + + #> + #Work In Progress + [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#get-/lists/-list-')] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + [string]$Password, + [System.URI]$List = $null, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + ) + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $Groups = Get-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/lists/$List" + Method = "Get" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + + else { + $ObjectFinal = @() + foreach ($Item in $Response.lists) { + $GroupNames = [System.Collections.ArrayList]@() + foreach ($Group in $Item.groups) { + $GroupNames += ($Groups | Where-Object { $_.Id -eq $Group }).Name + } + + $Object = $null + if ($Item.date_updated -eq 0) { + $DateUpdated = $null + } + else { + $DateUpdated = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_modified).LocalTime + } + $Object = [PSCustomObject]@{ + Address = $Item.address + Comment = $Item.comment + Groups = $GroupNames + Enabled = $Item.enabled + Id = $Item.id + DateAdded = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_added).LocalTime + DateModified = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_modified).LocalTime + Type = $Item.type + DateUpdated = $DateUpdated + Number = $Item.number + InvalidDomains = $Item.invalid_domains + AbpEntries = $Item.abp_entries + Status = $Item.status + } + if ($Object) { + $ObjectFinal += $Object + } + + } + Write-Output $ObjectFinal + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/ListManagement/Remove-PiHoleList.ps1 b/PiHoleShell/Public/ListManagement/Remove-PiHoleList.ps1 new file mode 100644 index 0000000..e2fda10 --- /dev/null +++ b/PiHoleShell/Public/ListManagement/Remove-PiHoleList.ps1 @@ -0,0 +1,107 @@ +function Remove-PiHoleList { + <# +.SYNOPSIS +Deletes multiple lists in the lists object. + +.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 objec + + #> + #Work In Progress (NEED TO FINISH) + [CmdletBinding(SupportsShouldProcess = $true, HelpUri = 'https://ftl.pi-hole.net/master/docs/#post-/lists-batchDelete')] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + [string]$Password, + [bool]$IgnoreSsl = $false, + [System.Uri]$Address, + [string]$Type, + [bool]$RawOutput = $false + ) + try { + $Target = "Pi-Hole list $Address of type $Type" + if ($PSCmdlet.ShouldProcess($Target, "Remove list")) { + $FindMatchingList = Get-PiHoleList -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl | Where-Object { $_.Address -eq $Address } + + if ($FindMatchingList) { + + } + + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $Body = @( + @{ + item = $Address + type = $Type.ToLower() + } + ) + + #For some reason this needs to be here to make it an array + $Body = , $Body + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/lists:batchDelete" + Method = "Post" + SkipCertificateCheck = $IgnoreSsl + Body = $Body | ConvertTo-Json -Depth 10 -Compress + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + + else { + $ObjectFinal = @() + $Object = $null + + foreach ($Item in $Response.lists) { + $Object = [PSCustomObject]@{ + Address = $Item.address + Comment = $Item.comment + Groups = $AllGroupsNames + Enabled = $Item.enabled + Id = $Item.id + DateAdded = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_added).LocalTime + DateModified = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_modified).LocalTime + Type = $Item.type.SubString(0, 1).ToUpper() + $Item.type.SubString(1).ToLower() + DateUpdated = $DateUpdated + Number = $Item.number + InvalidDomains = $Item.invalid_domains + AbpEntries = $Item.abp_entries + Status = $Item.status + } + if ($Object) { + $ObjectFinal += $Object + } + } + + Write-Output $ObjectFinal + } + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/ListManagement/Search-PiHoleListDomain.ps1 b/PiHoleShell/Public/ListManagement/Search-PiHoleListDomain.ps1 new file mode 100644 index 0000000..dad94f5 --- /dev/null +++ b/PiHoleShell/Public/ListManagement/Search-PiHoleListDomain.ps1 @@ -0,0 +1,76 @@ +function Search-PiHoleListDomain { + <# +.SYNOPSIS +Search domains in Pi-hole's lists + +.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 + + #> + #Work In Progress + [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#get-/search/-domain-')] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + [string]$Password, + [Parameter(Mandatory = $true)] + [System.URI]$Domain, + [bool]$PartialMatch = $false, + [int]$MaxResults = 20, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + ) + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $Body = @{ + n = $MaxResults + partial = $PartialMatch + name = $GroupName + } + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/search/$Domain" + Method = "Get" + SkipCertificateCheck = $IgnoreSsl + Body = $Body + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + + else { + $ObjectFinal = @() + foreach ($Item in $Response.lists) { + } + Write-Output $ObjectFinal + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/Metrics.ps1 b/PiHoleShell/Public/Metrics.ps1 deleted file mode 100644 index de2119c..0000000 --- a/PiHoleShell/Public/Metrics.ps1 +++ /dev/null @@ -1,393 +0,0 @@ -function Get-PiHoleStatsRecentBlocked { - <# -.SYNOPSIS -Get most recently blocked domain -Request most recently blocked domain - -.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 MaxResult -How many results should be returned - -.PARAMETER RawOutput -This will dump the response instead of the formatted object - -.EXAMPLE -Get-PiHoleStatsRecentBlocked -PiHoleServer "http://pihole.domain.com:8080" -Password "fjdsjfldsjfkldjslafjskdl" -MaxResult 20 - #> - [CmdletBinding()] - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] - param ( - [Parameter(Mandatory = $true)] - [System.URI]$PiHoleServer, - [Parameter(Mandatory = $true)] - [string]$Password, - [int]$MaxResult = 1, - [bool]$IgnoreSsl = $false, - [bool]$RawOutput - ) - try { - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - Write-Verbose -Message "MaxResults - $MaxResult" - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$($PiHoleServer.OriginalString)/api/stats/recent_blocked?count=$MaxResult" - Method = "Get" - SkipCertificateCheck = $IgnoreSsl - ContentType = "application/json" - } - - $Response = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Response - } - else { - $ObjectFinal = @() - foreach ($Item in $Response.blocked) { - $Object = $null - $Object = [PSCustomObject]@{ - Blocked = $Item - } - Write-Verbose -Message "Blocked - $Item" - $ObjectFinal += $Object - } - Write-Output $ObjectFinal - } - } - - catch { - Write-Error -Message $_.Exception.Message - break - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} - -function Get-PiHoleStatsQueryType { - <# -.SYNOPSIS -https://TODOFINDNEWAPILINK - #> - [CmdletBinding()] - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] - param ( - [Parameter(Mandatory = $true)] - [System.URI]$PiHoleServer, - [Parameter(Mandatory = $true)] - [string]$Password, - [bool]$IgnoreSsl = $false, - [bool]$RawOutput = $false - ) - - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - Write-Verbose -Message "MaxResults - $MaxResult" - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$($PiHoleServer.OriginalString)/api/stats/query_types" - Method = "Get" - SkipCertificateCheck = $IgnoreSsl - ContentType = "application/json" - } - - $Response = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Response - } - else { - $Object = [PSCustomObject]@{ - A = $Response.types.A - AAAA = $Response.types.AAAA - ANY = $Response.types.ANY - SRV = $Response.types.SRV - SOA = $Response.types.SOA - PTR = $Response.types.PTR - TXT = $Response.types.TXT - NAPTR = $Response.types.NAPTR - MX = $Response.types.MX - DS = $Response.types.DS - RRSIG = $Response.types.RRSIG - DNSKEY = $Response.types.DNSKEY - NS = $Response.types.NS - SVCB = $Response.types.SVCB - HTTPS = $Response.types.HTTPS - OTHER = $Response.types.OTHER - } - $ObjectFinal += $Object - Write-Output $ObjectFinal - } -} - -function Get-PiHoleStatsTopDomain { - <# -.SYNOPSIS -https://TODOFINDNEWAPILINK - #> - [CmdletBinding()] - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] - param ( - [Parameter(Mandatory = $true)] - [System.URI]$PiHoleServer, - [Parameter(Mandatory = $true)] - [string]$Password, - [int]$MaxResult = 10, - [bool]$Blocked = $false, - [bool]$IgnoreSsl = $false, - [bool]$RawOutput = $false - ) - - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - - switch ($Blocked) { - $false { - $Blocked = "false" - } - $true { - $Blocked = "true" - } - Default { - throw "ERROR" - } - } - Write-Verbose "Blocked: $Blocked" - - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$($PiHoleServer.OriginalString)/api/stats/top_domains?blocked=$Blocked&count=$MaxResult" - Method = "Get" - SkipCertificateCheck = $IgnoreSsl - ContentType = "application/json" - } - - $Response = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Response - } - - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } -} - -function Get-PiHoleStatsTopClient { - <# -.SYNOPSIS -Get top clients -Request the top clients (by query count) - -.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 MaxResult -How many results should be returned - -.PARAMETER Blocked -If true, returns top clients by blocked queries instead of total queries - -.PARAMETER RawOutput -This will dump the response instead of the formatted object - -.EXAMPLE -Get-PiHoleStatsTopClient -PiHoleServer "http://pihole.domain.com:8080" -Password "fjdsjfldsjfkldjslafjskdl" -MaxResult 10 - #> - [CmdletBinding()] - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] - param ( - [Parameter(Mandatory = $true)] - [System.URI]$PiHoleServer, - [Parameter(Mandatory = $true)] - [string]$Password, - [int]$MaxResult = 10, - [bool]$Blocked = $false, - [bool]$IgnoreSsl = $false, - [bool]$RawOutput = $false - ) - try { - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - - switch ($Blocked) { - $false { $BlockedParam = "false" } - $true { $BlockedParam = "true" } - Default { throw "ERROR" } - } - Write-Verbose "Blocked: $BlockedParam" - Write-Verbose "MaxResult: $MaxResult" - - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$($PiHoleServer.OriginalString)/api/stats/top_clients?blocked=$BlockedParam&count=$MaxResult" - Method = "Get" - SkipCertificateCheck = $IgnoreSsl - ContentType = "application/json" - } - - $Response = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Response - } - else { - $ObjectFinal = @() - foreach ($Item in $Response.clients) { - $Object = $null - $Object = [PSCustomObject]@{ - IP = $Item.ip - Name = $Item.name - Count = $Item.count - } - Write-Verbose -Message "Client - $($Item.ip) ($($Item.name)): $($Item.count)" - $ObjectFinal += $Object - } - Write-Output $ObjectFinal - } - } - - catch { - Write-Error -Message $_.Exception.Message - break - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} - -function Get-PiHoleStatsSummary { - <# -.SYNOPSIS -Get overview of Pi-hole activity -Request various query, system, and FTL properties - -.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 - - -This will dump the response instead of the formatted object - -.PARAMETER RawOutput -This will dump the response instead of the formatted object - -.EXAMPLE -Get-PiHoleStatsSummary -PiHoleServer "http://pihole.domain.com:8080" -Password "fjdsjfldsjfkldjslafjskdl" - #> - [CmdletBinding()] - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] - param ( - [Parameter(Mandatory = $true)] - [System.URI]$PiHoleServer, - [Parameter(Mandatory = $true)] - [string]$Password, - [bool]$IgnoreSsl = $false, - [bool]$RawOutput - ) - try { - $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl - - $Params = @{ - Headers = @{sid = $($Sid) } - Uri = "$($PiHoleServer.OriginalString)/api/stats/summary" - Method = "Get" - SkipCertificateCheck = $IgnoreSsl - ContentType = "application/json" - } - - $Response = Invoke-RestMethod @Params - - if ($RawOutput) { - Write-Output $Response - } - else { - $Object = [PSCustomObject]@{ - Total = $Response.queries.total - Blocked = $Response.queries.blocked - PercentBlocked = $Response.queries.percent_blocked - Types = [PSCustomObject]@{ - A = $Response.queries.types.A - AAAA = $Response.queries.types.AAAA - ANY = $Response.queries.types.ANY - SRV = $Response.queries.types.SRV - SOA = $Response.queries.types.SOA - PTR = $Response.queries.types.PTR - TXT = $Response.queries.types.TXT - NAPTR = $Response.queries.types.NAPTR - MX = $Response.queries.types.MX - DS = $Response.queries.types.DS - RRSIG = $Response.queries.types.RRSIG - DNSKEY = $Response.queries.types.DNSKEY - NS = $Response.queries.types.NS - SVCB = $Response.queries.types.SVCB - HTTPS = $Response.queries.types.HTTPS - OTHER = $Response.queries.types.OTHER - } - Status = [PSCustomObject]@{ - Unknown = $Response.queries.status.UNKNOWN - Gravity = $Response.queries.status.GRAVITY - Forwarded = $Response.queries.status.FORWARDED - Cache = $Response.queries.status.CACHE - Regex = $Response.queries.status.REGEX - DenyList = $Response.queries.status.DENYLIST - ExternalBlockedIp = $Response.queries.status.EXTERNAL_BLOCKED_IP - ExternalBlockedNull = $Response.queries.status.EXTERNAL_BLOCKED_NULL - ExternalBlockedNxra = $Response.queries.status.EXTERNAL_BLOCKED_NXRA - GravityCname = $Response.queries.status.GRAVITY_CNAME - RegexCname = $Response.queries.status.REGEX_CNAME - DenyListCname = $Response.queries.status.DENYLIST_CNAME - Retired = $Response.queries.status.RETRIED - RetiredDnssec = $Response.queries.status.RETRIED_DNSSEC - InProgress = $Response.queries.status.IN_PROGRESS - Dbbusy = $Response.queries.status.DBBUSY - SpecialDomain = $Response.queries.status.SPECIAL_DOMAIN - CacheStale = $Response.queries.status.CACHE_STALE - ExternalBlockedEde15 = $Response.queries.status.EXTERNAL_BLOCKED_EDE15 - } - Replies = [PSCustomObject]@{ - Unknown = $Response.queries.replies.UNKNOWN - Nodata = $Response.queries.replies.NODATA - Nxdomain = $Response.queries.replies.NXDOMAIN - Cname = $Response.queries.replies.CNAME - Ip = $Response.queries.replies.IP - Domain = $Response.queries.replies.DOMAIN - Rrname = $Response.queries.replies.RRNAME - ServFail = $Response.queries.replies.SERVFAIL - Refused = $Response.queries.replies.REFUSED - Notimp = $Response.queries.replies.NOTIMP - Other = $Response.queries.replies.OTHER - Dnssec = $Response.queries.replies.DNSSEC - None = $Response.queries.replies.NONE - Blob = $Response.queries.replies.BLOB - } - } - $ObjectFinal += $Object - Write-Output $ObjectFinal - } - } - - catch { - Write-Error -Message $_.Exception.Message - break - } - - finally { - if ($Sid) { - Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl - } - } -} \ No newline at end of file diff --git a/PiHoleShell/Public/Metrics/Get-PiHoleStatsQueryType.ps1 b/PiHoleShell/Public/Metrics/Get-PiHoleStatsQueryType.ps1 new file mode 100644 index 0000000..2cc78e7 --- /dev/null +++ b/PiHoleShell/Public/Metrics/Get-PiHoleStatsQueryType.ps1 @@ -0,0 +1,54 @@ +function Get-PiHoleStatsQueryType { + <# +.SYNOPSIS +https://TODOFINDNEWAPILINK + #> + [CmdletBinding()] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + [string]$Password, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + ) + + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + Write-Verbose -Message "MaxResults - $MaxResult" + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/stats/query_types" + Method = "Get" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + else { + $Object = [PSCustomObject]@{ + A = $Response.types.A + AAAA = $Response.types.AAAA + ANY = $Response.types.ANY + SRV = $Response.types.SRV + SOA = $Response.types.SOA + PTR = $Response.types.PTR + TXT = $Response.types.TXT + NAPTR = $Response.types.NAPTR + MX = $Response.types.MX + DS = $Response.types.DS + RRSIG = $Response.types.RRSIG + DNSKEY = $Response.types.DNSKEY + NS = $Response.types.NS + SVCB = $Response.types.SVCB + HTTPS = $Response.types.HTTPS + OTHER = $Response.types.OTHER + } + $ObjectFinal += $Object + Write-Output $ObjectFinal + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/Metrics/Get-PiHoleStatsRecentBlocked.ps1 b/PiHoleShell/Public/Metrics/Get-PiHoleStatsRecentBlocked.ps1 new file mode 100644 index 0000000..b390fcd --- /dev/null +++ b/PiHoleShell/Public/Metrics/Get-PiHoleStatsRecentBlocked.ps1 @@ -0,0 +1,73 @@ +function Get-PiHoleStatsRecentBlocked { + <# +.SYNOPSIS +Request most recently blocked domain + +.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 MaxResult +How many results should be returned + +.PARAMETER RawOutput +This will dump the response instead of the formatted object + +.EXAMPLE +Get-PiHoleStatsRecentBlocked -PiHoleServer "http://pihole.domain.com:8080" -Password "fjdsjfldsjfkldjslafjskdl" -MaxResult 20 + #> + [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#get-/stats/recent_blocked')] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + [string]$Password, + [int]$MaxResult = 1, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput + ) + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + Write-Verbose -Message "MaxResults - $MaxResult" + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/stats/recent_blocked?count=$MaxResult" + Method = "Get" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + else { + $ObjectFinal = @() + foreach ($Item in $Response.blocked) { + $Object = $null + $Object = [PSCustomObject]@{ + Blocked = $Item + } + Write-Verbose -Message "Blocked - $Item" + $ObjectFinal += $Object + } + Write-Output $ObjectFinal + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} + diff --git a/PiHoleShell/Public/Metrics/Get-PiHoleStatsSummary.ps1 b/PiHoleShell/Public/Metrics/Get-PiHoleStatsSummary.ps1 new file mode 100644 index 0000000..17c8274 --- /dev/null +++ b/PiHoleShell/Public/Metrics/Get-PiHoleStatsSummary.ps1 @@ -0,0 +1,124 @@ +function Get-PiHoleStatsSummary { + <# +.SYNOPSIS +Get overview of Pi-hole activity +Request various query, system, and FTL properties + +.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 + + +This will dump the response instead of the formatted object + +.PARAMETER RawOutput +This will dump the response instead of the formatted object + +.EXAMPLE +Get-PiHoleStatsSummary -PiHoleServer "http://pihole.domain.com:8080" -Password "fjdsjfldsjfkldjslafjskdl" + #> + [CmdletBinding()] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + [string]$Password, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput + ) + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/stats/summary" + Method = "Get" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + else { + $Object = [PSCustomObject]@{ + Total = $Response.queries.total + Blocked = $Response.queries.blocked + PercentBlocked = $Response.queries.percent_blocked + Types = [PSCustomObject]@{ + A = $Response.queries.types.A + AAAA = $Response.queries.types.AAAA + ANY = $Response.queries.types.ANY + SRV = $Response.queries.types.SRV + SOA = $Response.queries.types.SOA + PTR = $Response.queries.types.PTR + TXT = $Response.queries.types.TXT + NAPTR = $Response.queries.types.NAPTR + MX = $Response.queries.types.MX + DS = $Response.queries.types.DS + RRSIG = $Response.queries.types.RRSIG + DNSKEY = $Response.queries.types.DNSKEY + NS = $Response.queries.types.NS + SVCB = $Response.queries.types.SVCB + HTTPS = $Response.queries.types.HTTPS + OTHER = $Response.queries.types.OTHER + } + Status = [PSCustomObject]@{ + Unknown = $Response.queries.status.UNKNOWN + Gravity = $Response.queries.status.GRAVITY + Forwarded = $Response.queries.status.FORWARDED + Cache = $Response.queries.status.CACHE + Regex = $Response.queries.status.REGEX + DenyList = $Response.queries.status.DENYLIST + ExternalBlockedIp = $Response.queries.status.EXTERNAL_BLOCKED_IP + ExternalBlockedNull = $Response.queries.status.EXTERNAL_BLOCKED_NULL + ExternalBlockedNxra = $Response.queries.status.EXTERNAL_BLOCKED_NXRA + GravityCname = $Response.queries.status.GRAVITY_CNAME + RegexCname = $Response.queries.status.REGEX_CNAME + DenyListCname = $Response.queries.status.DENYLIST_CNAME + Retired = $Response.queries.status.RETRIED + RetiredDnssec = $Response.queries.status.RETRIED_DNSSEC + InProgress = $Response.queries.status.IN_PROGRESS + Dbbusy = $Response.queries.status.DBBUSY + SpecialDomain = $Response.queries.status.SPECIAL_DOMAIN + CacheStale = $Response.queries.status.CACHE_STALE + ExternalBlockedEde15 = $Response.queries.status.EXTERNAL_BLOCKED_EDE15 + } + Replies = [PSCustomObject]@{ + Unknown = $Response.queries.replies.UNKNOWN + Nodata = $Response.queries.replies.NODATA + Nxdomain = $Response.queries.replies.NXDOMAIN + Cname = $Response.queries.replies.CNAME + Ip = $Response.queries.replies.IP + Domain = $Response.queries.replies.DOMAIN + Rrname = $Response.queries.replies.RRNAME + ServFail = $Response.queries.replies.SERVFAIL + Refused = $Response.queries.replies.REFUSED + Notimp = $Response.queries.replies.NOTIMP + Other = $Response.queries.replies.OTHER + Dnssec = $Response.queries.replies.DNSSEC + None = $Response.queries.replies.NONE + Blob = $Response.queries.replies.BLOB + } + } + $ObjectFinal += $Object + Write-Output $ObjectFinal + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/Metrics/Get-PiHoleStatsTopClient.ps1 b/PiHoleShell/Public/Metrics/Get-PiHoleStatsTopClient.ps1 new file mode 100644 index 0000000..eba3963 --- /dev/null +++ b/PiHoleShell/Public/Metrics/Get-PiHoleStatsTopClient.ps1 @@ -0,0 +1,87 @@ +function Get-PiHoleStatsTopClient { + <# +.SYNOPSIS +Get top clients +Request the top clients (by query count) + +.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 MaxResult +How many results should be returned + +.PARAMETER Blocked +If true, returns top clients by blocked queries instead of total queries + +.PARAMETER RawOutput +This will dump the response instead of the formatted object + +.EXAMPLE +Get-PiHoleStatsTopClient -PiHoleServer "http://pihole.domain.com:8080" -Password "fjdsjfldsjfkldjslafjskdl" -MaxResult 10 + #> + [CmdletBinding()] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + [string]$Password, + [int]$MaxResult = 10, + [bool]$Blocked = $false, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + ) + try { + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + switch ($Blocked) { + $false { $BlockedParam = "false" } + $true { $BlockedParam = "true" } + Default { throw "ERROR" } + } + Write-Verbose "Blocked: $BlockedParam" + Write-Verbose "MaxResult: $MaxResult" + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/stats/top_clients?blocked=$BlockedParam&count=$MaxResult" + Method = "Get" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + else { + $ObjectFinal = @() + foreach ($Item in $Response.clients) { + $Object = $null + $Object = [PSCustomObject]@{ + IP = $Item.ip + Name = $Item.name + Count = $Item.count + } + Write-Verbose -Message "Client - $($Item.ip) ($($Item.name)): $($Item.count)" + $ObjectFinal += $Object + } + Write-Output $ObjectFinal + } + } + + catch { + Write-Error -Message $_.Exception.Message + break + } + + finally { + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/Metrics/Get-PiHoleStatsTopDomain.ps1 b/PiHoleShell/Public/Metrics/Get-PiHoleStatsTopDomain.ps1 new file mode 100644 index 0000000..17b78c8 --- /dev/null +++ b/PiHoleShell/Public/Metrics/Get-PiHoleStatsTopDomain.ps1 @@ -0,0 +1,51 @@ +function Get-PiHoleStatsTopDomain { + <# +.SYNOPSIS +https://TODOFINDNEWAPILINK + #> + [CmdletBinding()] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "Password")] + param ( + [Parameter(Mandatory = $true)] + [System.URI]$PiHoleServer, + [Parameter(Mandatory = $true)] + [string]$Password, + [int]$MaxResult = 10, + [bool]$Blocked = $false, + [bool]$IgnoreSsl = $false, + [bool]$RawOutput = $false + ) + + $Sid = Request-PiHoleAuth -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl + + switch ($Blocked) { + $false { + $Blocked = "false" + } + $true { + $Blocked = "true" + } + Default { + throw "ERROR" + } + } + Write-Verbose "Blocked: $Blocked" + + $Params = @{ + Headers = @{sid = $($Sid) } + Uri = "$($PiHoleServer.OriginalString)/api/stats/top_domains?blocked=$Blocked&count=$MaxResult" + Method = "Get" + SkipCertificateCheck = $IgnoreSsl + ContentType = "application/json" + } + + $Response = Invoke-RestMethod @Params + + if ($RawOutput) { + Write-Output $Response + } + + if ($Sid) { + Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl + } +} \ No newline at end of file diff --git a/PiHoleShell/Public/Padd.ps1 b/PiHoleShell/Public/Padd/Get-PiHolePadd.ps1 similarity index 96% rename from PiHoleShell/Public/Padd.ps1 rename to PiHoleShell/Public/Padd/Get-PiHolePadd.ps1 index 7dc47a3..65f1d42 100644 --- a/PiHoleShell/Public/Padd.ps1 +++ b/PiHoleShell/Public/Padd/Get-PiHolePadd.ps1 @@ -78,8 +78,8 @@ https://TODO } $Object = [PSCustomObject]@{ - CpuPercent = $Response."%cpu" - MemoryPercent = $Response."%mem" + CpuPercent = [math]::Round([double]$Response."%cpu", 2) + MemoryPercent = [math]::Round([double]$Response."%mem", 2) ActiveClients = $Response.active_clients Blocking = $Response.blocking Cache = $Cache diff --git a/PiHoleShell/Public/Teleporter.ps1 b/PiHoleShell/Public/Teleporter/Get-PiHoleTeleporterDownload.ps1 similarity index 100% rename from PiHoleShell/Public/Teleporter.ps1 rename to PiHoleShell/Public/Teleporter/Get-PiHoleTeleporterDownload.ps1