Public/ClientManagement/Update-PiHoleClient.ps1
|
function Update-PiHoleClient { <# .SYNOPSIS Update a client .DESCRIPTION Updates an existing client's Comment and/or Group(s). The underlying Pi-hole API replaces the entire client entry on update, so any property you don't pass here is preserved by first reading the client's current value and resending it - nothing is silently cleared just because you only meant to change one property. .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 Client The client to update - an IP address, IP subnet (CIDR), MAC address, hostname, or interface (prefixed with a colon, e.g. ":eth0") .PARAMETER Comment The new comment for the client. Leave unset to keep the client's current comment .PARAMETER Group The group(s) this client should apply to. Leave unset to keep the client's current group(s) .PARAMETER IgnoreSsl Set to $true to skip SSL certificate validation .PARAMETER RawOutput This will dump the response instead of the formatted object .EXAMPLE Update-PiHoleClient -PiHoleServer "http://pihole.domain.com:8080" -Password "your-app-password" -Client "192.168.1.50" -Comment "Kid's tablet" #> [CmdletBinding(HelpUri = 'https://ftl.pi-hole.net/master/docs/#put-/clients/-client-')] [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]$Client, [string]$Comment, [string[]]$Group, [bool]$IgnoreSsl = $false, [bool]$RawOutput = $false ) try { if (-not $PSBoundParameters.ContainsKey('Comment') -and -not $PSBoundParameters.ContainsKey('Group')) { throw "To update $Client, you must specify the Comment and/or Group parameter" } $ExistingClient = Get-PiHoleClient -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl -Client $Client if (-not $ExistingClient) { throw "Cannot find $Client on $PiHoleServer! Please use New-PiHoleClient to create it" } $AllGroups = Get-PiHoleGroup -PiHoleServer $PiHoleServer -Password $Password -IgnoreSsl $IgnoreSsl $GroupNamesToResolve = if ($PSBoundParameters.ContainsKey('Group')) { $Group } else { $ExistingClient.Groups } $AllGroupsNames = @() $AllGroupsIds = @() foreach ($GroupItem in $GroupNamesToResolve) { $FoundGroup = $AllGroups | Where-Object { $_.Name -eq $GroupItem } if ($FoundGroup) { $AllGroupsNames += $FoundGroup.Name $AllGroupsIds += $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 # The API replaces the whole client entry on update, so any property not explicitly # passed here is resent using the client's current value to avoid silently clearing it. $Body = @{ comment = if ($PSBoundParameters.ContainsKey('Comment')) { $Comment } else { $ExistingClient.Comment } groups = [Object[]]($AllGroupsIds) } $Params = @{ Headers = @{sid = $($Sid) } Uri = "$($PiHoleServer.OriginalString)/api/clients/$([System.Uri]::EscapeDataString($Client))" Method = "Put" SkipCertificateCheck = $IgnoreSsl Body = $Body | ConvertTo-Json -Depth 10 ContentType = "application/json" } $Response = Invoke-RestMethod @Params if ($RawOutput) { Write-Output $Response } else { $ObjectFinal = foreach ($Item in $Response.clients) { [PSCustomObject]@{ Client = $Item.client Name = $Item.name Comment = $Item.comment Groups = $AllGroupsNames Id = $Item.id DateAdded = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_added).LocalTime DateModified = (Convert-PiHoleUnixTimeToLocalTime -UnixTime $Item.date_modified).LocalTime } } Write-Output $ObjectFinal } } catch { Write-Error -Message $_.Exception.Message } finally { if ($Sid) { Remove-PiHoleCurrentAuthSession -PiHoleServer $PiHoleServer -Sid $Sid -IgnoreSsl $IgnoreSsl } } } |