public/Start-UnraidArray.ps1
|
function Start-UnraidArray { <# .SYNOPSIS Starts the Unraid array. .DESCRIPTION Initiates a start of the Unraid array via the GraphQL API. LIMITATION: This function CANNOT unlock encrypted arrays. The Unraid 7.0 API does not currently accept encryption keys or passphrases during the start operation. If your array is encrypted and locked, you must unlock it via the WebUI. .PARAMETER Array An object representing the current array state. .PARAMETER Session The active Unraid session. .PARAMETER WaitTimeout Seconds to wait for the array to reach the STARTED state. .PARAMETER Force Sends the start command even if the API reports the array is already started. Useful for recovering from 'stuck' states caused by unsynced API. #> [CmdletBinding(SupportsShouldProcess)] [OutputType('String')] param( [Parameter(ValueFromPipeline)] [psobject]$Array, [Parameter()] [UnraidSession]$Session = $script:DefaultUnraidSession, [Parameter()] [int]$WaitTimeout = 120, [Parameter()] [switch]$Force ) process { if (!$Array) { Write-Verbose "Checking status..." $Array = Get-UnraidArray -Session $Session } # Check for unsynced state (Started but unmounted - caused by API issue) or standard Started state if ($Array.State -match "STARTED") { if ($Force) { Write-Verbose "Array is '$($Array.State)', but -Force was used. Proceeding..." } else { if ($Array.State -like "*UNMOUNTED*") { Write-Warning "Array reports 'STARTED' but is unmounted (0 capacity). The API is likely not synced to the current server state.`nYou likely need to run 'Restart-UnraidApi' to reset the state, then rerun this command." } else { Write-Warning "The Unraid array is already in the 'STARTED' state." } return } } if ($PSCmdlet.ShouldProcess("Unraid Array", "Start array")) { $gqlQuery = @" mutation SetArrayState { array { setState(input: { desiredState: START }) { state } } } "@ $commandSent = $false try { Write-Verbose "Sending start mutation..." $result = Invoke-UnraidQuery -Query $gqlQuery -Session $Session $commandSent = $true $currentState = $result.array.setState.state } catch { $ex = $_.Exception # Check for "already started" state if ($ex.Message -match "already STARTED") { $verify = Get-UnraidArray -Session $Session if ($verify.TotalSize -eq "0 B") { Write-Error "API returns STARTED, but API may be unsynced.`nRun 'Stop-UnraidArray -Force' to force stop." return } Write-Information "Array is already STARTED." -InformationAction Continue return } # Handle API limitation for Encryption elseif ($ex.Message -match "passphrase" -or $ex.Message -match "encrypted" -or $ex.Message -match "key") { Write-Error "Start Failed: The array requires an encryption key, but the Unraid API does not support unlocking arrays yet.`nPlease unlock the array via the WebUI." return } # Handle Timeouts elseif ($ex.Message -match "504" -or ($ex.Response -and $ex.Response.StatusCode -eq 504)) { Write-Warning "Server timed out (504) waiting for start. Switching to polling mode." $commandSent = $true $currentState = "UNKNOWN" } else { $PSCmdlet.ThrowTerminatingError($_) } } if ($commandSent) { $timer = [System.Diagnostics.Stopwatch]::StartNew() while ($currentState -ne "STARTED" -and $timer.Elapsed.TotalSeconds -lt $WaitTimeout) { $remaining = $WaitTimeout - [int]$timer.Elapsed.TotalSeconds Write-Progress -Activity "Starting Unraid Array" -Status "Current State: $currentState" -SecondsRemaining $remaining Start-Sleep -Seconds 5 try { $statusCheck = Get-UnraidArray -Session $Session $currentState = $statusCheck.State } catch { Write-Verbose "Poll failed: $($_.Exception.Message)" } } $timer.Stop() Write-Progress -Activity "Starting Unraid Array" -Completed if ($currentState -eq "STARTED") { Write-Information "Array started." -InformationAction Continue } else { Write-Error "Timed out waiting for start ($WaitTimeout s). Current state: $currentState" } } } } } |