public/Restart-UnraidContainer.ps1
|
function Restart-UnraidContainer { <# .SYNOPSIS Restarts a container. .PARAMETER InputObject Container to restart (accepts pipeline). .PARAMETER Name Container name. .PARAMETER TimeoutSeconds Stop timeout (default 300 seconds). .PARAMETER Batch Send restart commands to all containers in the batch, then wait for completion (faster for multiple containers). .PARAMETER Session Unraid session (defaults to current session). .EXAMPLE Restart-UnraidContainer -Name "plex" .EXAMPLE Get-UnraidContainer -Name "*arr" | Restart-UnraidContainer -Batch #> [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = "ByName")] [OutputType('void')] param( [Parameter(Mandatory, ParameterSetName = "ByObject", ValueFromPipeline)] [UnraidContainer[]]$InputObject, [Parameter(Mandatory, ParameterSetName = "ByName", Position = 0)] [string]$Name, [Parameter()] [int]$TimeoutSeconds = 300, [Parameter()] [switch]$Batch, [Parameter()] [UnraidSession]$Session = $script:DefaultUnraidSession ) begin { if ($Batch) { $ContainersToRestart = [System.Collections.Generic.List[UnraidContainer]]::new() } } process { $containers = Resolve-UnraidContainer -InputObject $InputObject -Name $Name -ParameterSetName $PSCmdlet.ParameterSetName -Session $Session if (!$containers) { return } if ($Batch) { foreach ($container in $containers) { $ContainersToRestart.Add($container) } } else { foreach ($targetContainer in $containers) { if ($PSCmdlet.ShouldProcess($targetContainer.Name, "Restart Container")) { try { if ($targetContainer.State -eq "running") { Write-Verbose "Stopping container: $($targetContainer.Name)" $stopQuery = "mutation { docker { stop(id: `"$($targetContainer.Id)`") { id } } }" Invoke-UnraidQuery -Query $stopQuery -Session $Session | Out-Null $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() $stopped = $false while ($stopwatch.Elapsed.TotalSeconds -lt $TimeoutSeconds) { Start-Sleep -Seconds 1 $statusCheck = Get-UnraidContainer -Name $targetContainer.Name -Session $Session if ($statusCheck.State -eq "exited") { Write-Verbose "Container stopped successfully." $stopped = $true break } } $stopwatch.Stop() if (!$stopped) { throw "Container '$($targetContainer.Name)' did not stop within $TimeoutSeconds seconds." } } Write-Verbose "Starting container: $($targetContainer.Name)" $startQuery = "mutation { docker { start(id: `"$($targetContainer.Id)`") { id } } }" Invoke-UnraidQuery -Query $startQuery -Session $Session | Out-Null Write-Information "Container restarted: $($targetContainer.Name)" -InformationAction Continue } catch { $PSCmdlet.WriteError($_) } } } } } end { if ($Batch -and $ContainersToRestart.Count -gt 0) { Write-Verbose "Bulk restarting $($ContainersToRestart.Count) containers" $containersToStop = @() foreach ($targetContainer in $ContainersToRestart) { if ($PSCmdlet.ShouldProcess($targetContainer.Name, "Restart Container")) { try { if ($targetContainer.State -eq "running") { Write-Verbose "Stopping container: $($targetContainer.Name)" $stopQuery = "mutation { docker { stop(id: `"$($targetContainer.Id)`") { id } } }" Invoke-UnraidQuery -Query $stopQuery -Session $Session | Out-Null $containersToStop += $targetContainer } } catch { $PSCmdlet.WriteError($_) } } } if ($containersToStop.Count -gt 0) { Write-Verbose "Waiting for $($containersToStop.Count) containers to stop..." $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() $stoppedContainers = @{} while ($stopwatch.Elapsed.TotalSeconds -lt $TimeoutSeconds -and $stoppedContainers.Count -lt $containersToStop.Count) { Start-Sleep -Seconds 1 # Fetch once per iteration instead of N times to avoid hammering the API $allContainers = Get-UnraidContainer -Session $Session # Use hashtable so we can check each container's state without repeated lookups $containersByName = @{} foreach ($containerToName in $allContainers) { $containersByName[$containerToName.Name] = $containerToName } foreach ($container in $containersToStop) { if (!$stoppedContainers.ContainsKey($container.Name)) { if ($containersByName.ContainsKey($container.Name) -and $containersByName[$container.Name].State -eq "exited") { Write-Verbose "Container stopped: $($container.Name)" $stoppedContainers[$container.Name] = $true } } } } $stopwatch.Stop() foreach ($container in $containersToStop) { if (!$stoppedContainers.ContainsKey($container.Name)) { Write-Warning "Container '$($container.Name)' did not stop within $TimeoutSeconds seconds." } } } foreach ($targetContainer in $ContainersToRestart) { if ($PSCmdlet.ShouldProcess($targetContainer.Name, "Start Container")) { try { Write-Verbose "Starting container: $($targetContainer.Name)" $startQuery = "mutation { docker { start(id: `"$($targetContainer.Id)`") { id } } }" Invoke-UnraidQuery -Query $startQuery -Session $Session | Out-Null Write-Information "Container restarted: $($targetContainer.Name)" -InformationAction Continue } catch { $PSCmdlet.WriteError($_) } } } } } } |