public/Get-UnraidLog.ps1
|
function Get-UnraidLog { <# .SYNOPSIS Retrieves log file contents. .DESCRIPTION Fetches the content of system log files. This function uses Dynamic Parameters to query the Unraid server for the logs exposed through the API, providing tab-completion for the -LogName parameter based on what is actually on the server. .PARAMETER Path Direct path to a log file on the server. .PARAMETER LogName The name of the log to retrieve (e.g., "syslog", "docker"). If connected, this list is dynamically populated from the server. .PARAMETER Lines Number of lines to return. .PARAMETER StartLine Starting line number for pagination. .PARAMETER Session Unraid session (defaults to current session). .EXAMPLE Get-UnraidLog -LogName syslog #> [CmdletBinding(DefaultParameterSetName = 'ByCommonName')] [OutputType('string')] param( [Parameter(Mandatory, ParameterSetName = 'ByPath')] [string]$Path, [Parameter()] [int]$Lines, [Parameter()] [int]$StartLine, [Parameter()] [UnraidSession]$Session = $script:DefaultUnraidSession ) DynamicParam { # This dynamically generates the 'LogName' parameter with a ValidateSet # populated by the actual logs available on the server. $paramName = 'LogName' $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $attributes = New-Object System.Collections.ObjectModel.Collection[System.Attribute] # Define standard parameter attributes (Mandatory, Position 0, ParameterSet) $paramAttribute = New-Object System.Management.Automation.ParameterAttribute $paramAttribute.ParameterSetName = 'ByCommonName' $paramAttribute.Mandatory = $true $paramAttribute.Position = 0 $attributes.Add($paramAttribute) # Try to fetch logs for the ValidateSet ONLY if we have a default session # If we are disconnected, we skip the ValidateSet so the user can still type a name manually # or get a generic parameter prompt without the script crashing. if ($script:DefaultUnraidSession) { try { # We use a lightweight query just to get names for the UI $gqlQuery = "query GetLogNames { logFiles { name } }" # Note: We must use the script-scope session directly here because # parameter binding for $Session hasn't happened yet. $result = Invoke-UnraidQuery -Query $gqlQuery -Session $script:DefaultUnraidSession -ErrorAction Stop if ($result.logFiles) { $validLogNames = $result.logFiles.name $validateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($validLogNames) $attributes.Add($validateSetAttribute) } } catch { # If the dynamic fetch fails (timeout, api error), we sililently ignore it # and return the parameter without validation to ensure the cmdlet remains usable. Write-Debug "Dynamic parameter fetch failed: $_" } } # Create the dynamic parameter $runtimeParam = New-Object System.Management.Automation.RuntimeDefinedParameter($paramName, [string], $attributes) $paramDictionary.Add($paramName, $runtimeParam) return $paramDictionary } process { # Because LogName is dynamic, it doesn't exist as a regular variable and must be pulled from BoundParmams if ($PSBoundParameters.ContainsKey('LogName')) { $requestedLogName = $PSBoundParameters['LogName'] # Now we need to resolve the friendly Name to a file Path. $gqlQuery = "query GetLogPaths { logFiles { name path } }" $result = Invoke-UnraidQuery -Query $gqlQuery -Session $Session $targetLog = $result.logFiles | Where-Object { $_.name -eq $requestedLogName } | Select-Object -First 1 if ($targetLog) { $Path = $targetLog.path Write-Verbose "Resolved LogName '$requestedLogName' to path '$Path'" } else { Write-Error "Log '$requestedLogName' not found on server." return } } # Construct arguments for the retrieval query $queryArgs = [System.Collections.Generic.List[string]]::new() $queryArgs.Add("path: `"$Path`"") if ($PSBoundParameters.ContainsKey('Lines')) { $queryArgs.Add("lines: $Lines") } if ($PSBoundParameters.ContainsKey('StartLine')) { $queryArgs.Add("startLine: $StartLine") } $argString = $queryArgs -join ", " $gqlQuery = @" query GetLogFile { logFile($argString) { content } } "@ Write-Verbose "Fetching log content from: $Path" $result = Invoke-UnraidQuery -Query $gqlQuery -Session $Session if ($result.logFile) { return $result.logFile.content } else { Write-Warning "File not found or empty response for path: $Path" } } } |