Functions/GenXdev.Windows.WireGuard/Remove-WireGuardPeer.ps1
################################################################################ <# .SYNOPSIS Removes a WireGuard VPN peer configuration. .DESCRIPTION This function removes a WireGuard VPN peer configuration from the server running in a Docker container. It deletes the peer's configuration files and updates the WireGuard server to stop accepting connections from this peer. The function validates peer existence before removal and provides confirmation prompts unless the Force parameter is specified. .PARAMETER PeerName The name of the peer to remove from the WireGuard configuration. .PARAMETER Force If specified, bypasses confirmation prompts when removing the peer. .PARAMETER NoDockerInitialize Skip Docker initialization when already called by parent function. .PARAMETER ContainerName The name for the Docker container running the WireGuard service. .PARAMETER VolumeName The name for the Docker volume used for persistent storage. .PARAMETER ServicePort The port number for the WireGuard service. .PARAMETER HealthCheckTimeout Maximum time in seconds to wait for service health check. .PARAMETER HealthCheckInterval Interval in seconds between health check attempts. .PARAMETER ImageName Custom Docker image name to use for the WireGuard container. .PARAMETER PUID User ID for permissions in the container. .PARAMETER PGID Group ID for permissions in the container. .PARAMETER TimeZone Timezone to use for the container. .EXAMPLE Remove-WireGuardPeer -PeerName "MyPhone" Removes the peer named "MyPhone" with confirmation prompt. .EXAMPLE Remove-WireGuardPeer -PeerName "Tablet" -Force Removes the peer named "Tablet" without confirmation prompt. .EXAMPLE Remove-WireGuardPeer "WorkLaptop" Removes the peer using positional parameter syntax. .NOTES This function interacts with the linuxserver/wireguard Docker container to manage WireGuard peers. It requires the container to be running (use EnsureWireGuard first). The function will validate peer existence before attempting removal and provides detailed error handling for failed operations. #> ############################################################################### function Remove-WireGuardPeer { [CmdletBinding(SupportsShouldProcess)] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] param( ####################################################################### [Parameter( Position = 0, Mandatory = $true, HelpMessage = "The name of the peer to remove" )] [ValidateNotNullOrEmpty()] [string] $PeerName, ####################################################################### [Parameter( Mandatory = $false, HelpMessage = "The name for the Docker container" )] [ValidateNotNullOrEmpty()] [string] $ContainerName = "wireguard", ####################################################################### [Parameter( Mandatory = $false, HelpMessage = "The name for the Docker volume for persistent storage" )] [ValidateNotNullOrEmpty()] [string] $VolumeName = "wireguard_data", ####################################################################### [Parameter( Mandatory = $false, HelpMessage = "The port number for the WireGuard service" )] [ValidateRange(1, 65535)] [int] $ServicePort = 51820, ####################################################################### [Parameter( Mandatory = $false, HelpMessage = "Maximum time in seconds to wait for service health check" )] [ValidateRange(10, 300)] [int] $HealthCheckTimeout = 60, ####################################################################### [Parameter( Mandatory = $false, HelpMessage = "Interval in seconds between health check attempts" )] [ValidateRange(1, 10)] [int] $HealthCheckInterval = 3, ####################################################################### [Parameter( Mandatory = $false, HelpMessage = "Custom Docker image name to use" )] [ValidateNotNullOrEmpty()] [string] $ImageName = "linuxserver/wireguard", ####################################################################### [Parameter( Mandatory = $false, HelpMessage = "User ID for permissions in the container" )] [ValidateNotNullOrEmpty()] [string] $PUID = "1000", ####################################################################### [Parameter( Mandatory = $false, HelpMessage = "Group ID for permissions in the container" )] [ValidateNotNullOrEmpty()] [string] $PGID = "1000", ####################################################################### [Parameter( Mandatory = $false, HelpMessage = "Timezone to use for the container" )] [ValidateNotNullOrEmpty()] [string] $TimeZone = "Etc/UTC", ####################################################################### [Parameter( Mandatory = $false, HelpMessage = "Force removal without confirmation" )] [switch] $Force, ####################################################################### [Parameter( Mandatory = $false, HelpMessage = "Skip Docker initialization when called by parent function" )] [switch] $NoDockerInitialize ####################################################################### ) begin { # ensure the wireguard service is running if not skipped if (-not $NoDockerInitialize) { Microsoft.PowerShell.Utility\Write-Verbose ` "Ensuring WireGuard service is available" # copy matching parameters to pass to ensurewireguard function $ensureParams = GenXdev.Helpers\Copy-IdenticalParamValues ` -BoundParameters $PSBoundParameters ` -FunctionName 'EnsureWireGuard' ` -DefaultValues (Microsoft.PowerShell.Utility\Get-Variable ` -Scope Local ` -ErrorAction SilentlyContinue) # initialize wireguard service with specified parameters $null = GenXdev.Windows\EnsureWireGuard @ensureParams } else { Microsoft.PowerShell.Utility\Write-Verbose ` "Skipping Docker initialization as requested" } # define helper function to check if peer configuration exists function Test-PeerExist { param([string]$peerName) try { # check for existing peer configuration folder using docker exec $result = docker exec $ContainerName sh -c ("[ -d /config/peer_$peerName ] && " + "echo 'exists' || echo 'not exists'") if ($result -eq 'exists') { return $true } return $false } catch { Microsoft.PowerShell.Utility\Write-Warning ` "Unable to verify peer existence: $_" # if we cannot verify assume it exists for safety return $true } } } process { try { # check if peer exists before attempting removal if (-not (Test-PeerExist -peerName $PeerName)) { throw "Peer '$PeerName' does not exist" } # get the peer's public key for wireguard configuration removal $publicKey = docker exec $ContainerName sh -c ("cat /config/peer_$PeerName/publickey " + "2>/dev/null") if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrEmpty($publicKey)) { Microsoft.PowerShell.Utility\Write-Warning ("Could not retrieve public key for " + "peer '$PeerName', but will attempt removal anyway") $publicKey = $null } else { # trim whitespace from the public key $publicKey = $publicKey.Trim() } # confirm the removal if force is not specified $confirmMessage = "Are you sure you want to remove the WireGuard peer '$PeerName'?" $operationName = "Removing WireGuard peer '$PeerName'" if ($Force -or $PSCmdlet.ShouldProcess($confirmMessage, $operationName)) { Microsoft.PowerShell.Utility\Write-Verbose ` "Removing WireGuard peer: $PeerName" # remove from wireguard configuration if we have the public key if (-not [string]::IsNullOrEmpty($publicKey)) { $removeResult = docker exec $ContainerName sh -c ("wg set wg0 peer " + "$publicKey remove") if ($LASTEXITCODE -ne 0) { Microsoft.PowerShell.Utility\Write-Warning ` "Failed to remove peer from WireGuard: $removeResult" } else { Microsoft.PowerShell.Utility\Write-Verbose ` "Peer removed from WireGuard configuration" } } # remove peer directory from container filesystem $deleteResult = docker exec $ContainerName sh -c "rm -rf /config/peer_$PeerName" if ($LASTEXITCODE -ne 0) { throw "Failed to remove peer directory: $deleteResult" } # save wireguard configuration to persist changes $saveResult = docker exec $ContainerName sh -c "wg-quick save wg0" if ($LASTEXITCODE -ne 0) { Microsoft.PowerShell.Utility\Write-Warning ` "Failed to save WireGuard configuration: $saveResult" } Microsoft.PowerShell.Utility\Write-Host -ForegroundColor Green ` "Peer '$PeerName' removed successfully" # return success information for pipeline use return [PSCustomObject]@{ PeerName = $PeerName PublicKey = $publicKey Success = $true Message = "Peer '$PeerName' removed successfully" } } # return cancellation information when user declines return [PSCustomObject]@{ PeerName = $PeerName PublicKey = $publicKey Success = $false Message = "Peer removal was canceled by user" } } catch { Microsoft.PowerShell.Utility\Write-Error ` "Failed to remove WireGuard peer '$PeerName': $_" throw } } end { } } ################################################################################ |