Liongard-Powershell.psm1
# This function sets the LG keys in the environment variables Function Set-LiongardKeys { [OutputType('void')] Param( [AllowNull()] [String] $AccessKey, [AllowNull()] [String] $AccessSecret, [AllowNull()] [String] $Instance ) $env:LGAccessKey = $AccessKey $env:LGAccessSecret = $AccessSecret $env:LGInstance = $Instance } # This function clears the LG keys from the environment variables Function Reset-LiongardKeys { [Alias('Remove-LiongardKeys')] [OutputType('void')] Param() if ($env:LGAccessKey) { Remove-Item -Path "Env:LGAccessKey" -ErrorAction SilentlyContinue } if ($env:LGAccessSecret) { Remove-Item -Path "Env:LGAccessSecret" -ErrorAction SilentlyContinue } if ($env:LGInstance) { Remove-Item -Path "Env:LGInstance" -ErrorAction SilentlyContinue } } Function Send-LiongardRequest { [CmdletBinding()] Param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [String] $RequestToSend, [ValidateSet('GET', 'PUT', 'POST', 'DELETE')] [String] $Method = 'GET', [Parameter(Mandatory=$false)][hashtable] $Body, [Parameter(Mandatory=$false)][string] $ApiVersion = 'v1' ) # Stop if our secrets have not been learned. If ($null -eq $env:LGAccessKey) { Throw [Data.NoNullAllowedException]::new('No access key has been provided. Please run Set-LiongardKeys.') } If ($null -eq $env:LGAccessSecret) { Throw [Data.NoNullAllowedException]::new('No access secret has been provided. Please run Set-LiongardKeys.') } If ($null -eq $env:LGInstance) { Throw [Data.NoNullAllowedException]::new('No instance has been provided. Please run Set-LiongardKeys.') } # Enable TLS 1.2 and 1.3 if available [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 If ([Net.SecurityProtocolType].GetMembers() -Contains 'Tls13') { [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls13 } $Bytes = [System.Text.Encoding]::UTF8.GetBytes("$($env:LGAccessKey):$($env:LGAccessSecret)") $EncodedText = [Convert]::ToBase64String($Bytes) $Uri = "https://$($env:LGInstance).app.liongard.com/api/$ApiVersion/$($RequestToSend)" try { $params = @{ Uri = $Uri Headers = @{"X-ROAR-API-KEY" = $EncodedText} Method = $Method ErrorAction = 'Stop' } if ($Body) { $params.Body = $Body | ConvertTo-Json -Depth 10 $params.ContentType = 'application/json' } Write-Verbose "Sending $Method request to $Uri" $response = Invoke-WebRequest @params if ($response.Content) { return $response.Content | ConvertFrom-Json } return $null } catch { $statusCode = $_.Exception.Response.StatusCode.value__ $statusDescription = $_.Exception.Response.StatusDescription Write-Verbose "Request failed with status code $statusCode : $statusDescription" Write-Verbose "URI: $Uri" if ($statusCode -eq 404) { Write-Warning "Endpoint not found. This might be a v1/v2 API version mismatch." } throw $_ } } # Environment Management Functions Function Get-LiongardEnvironmentCount { [CmdletBinding()] Param() Return (Send-LiongardRequest -RequestToSend "environments/count" -ApiVersion "v2") } Function Get-LiongardEnvironments { [CmdletBinding(DefaultParameterSetName='AllEnvironments')] Param( [Parameter(ParameterSetName='OneEnvironment')] [uint32] $EnvironmentID, [Parameter(Mandatory=$false)] [int] $Page, [Parameter(Mandatory=$false)] [int] $PageSize, [Parameter(Mandatory=$false)] [string] $OrderBy, [Parameter(Mandatory=$false)] [string[]] $Columns ) $ApiVersion = "v2" $Request = "environments" If ($PSCmdlet.ParameterSetName -eq 'OneEnvironment') { $Request += "/$EnvironmentID" } else { $QueryParams = @() if ($Page) { $QueryParams += "page=$Page" } if ($PageSize) { $QueryParams += "pageSize=$PageSize" } if ($OrderBy) { $QueryParams += "orderBy=$OrderBy" } if ($Columns) { $QueryParams += "columns=$($Columns -join ',')" } if ($QueryParams.Count -gt 0) { $Request += "?" + ($QueryParams -join "&") } } Return (Send-LiongardRequest -RequestToSend $Request -ApiVersion $ApiVersion) } Function Get-LiongardEnvironmentById { [CmdletBinding()] Param( [Parameter(Mandatory)] [uint32] $EnvironmentID ) Return (Send-LiongardRequest -RequestToSend "environments/$EnvironmentID" -ApiVersion "v2") } Function New-LiongardEnvironment { [CmdletBinding()] Param( [Parameter(Mandatory)] [string] $Name, [Parameter(Mandatory=$false)] [string] $Description, [Parameter(Mandatory=$false)] [int] $Parent, [Parameter(Mandatory=$false)] [string] $ShortName, [Parameter(Mandatory=$false)] [ValidateSet('Core', 'Essentials')] [string] $Tier ) try { Write-Verbose "Creating new environment with name: $Name" $Body = @{ "Name" = $Name } if ($Description) { $Body["Description"] = $Description } if ($Parent) { $Body["Parent"] = $Parent } if ($ShortName) { $Body["ShortName"] = $ShortName } if ($Tier) { $Body["Tier"] = $Tier } Write-Verbose "Request body: $($Body | ConvertTo-Json)" $result = Send-LiongardRequest -RequestToSend "environments" -Method "POST" -Body $Body -ApiVersion "v2" if (-not $result) { throw "No response received from API" } if (-not $result.Success) { throw "API returned unsuccessful response: $($result.Message)" } if (-not $result.Data -or -not $result.Data.ID) { throw "Environment created but no ID returned in response. Full response: $($result | ConvertTo-Json)" } Write-Verbose "Environment created successfully with ID: $($result.Data.ID)" return $result.Data } catch { Write-Error "Failed to create environment: $_" throw } } Function New-LiongardEnvironmentBulk { [CmdletBinding()] Param( [Parameter(Mandatory)] [array] $Environments ) Return (Send-LiongardRequest -RequestToSend "environments/bulk" -Method "POST" -Body $Environments -ApiVersion "v2") } Function Update-LiongardEnvironment { [CmdletBinding()] Param( [Parameter(Mandatory)] [uint32] $EnvironmentID, [Parameter(Mandatory)] [hashtable] $UpdateData ) Return (Send-LiongardRequest -RequestToSend "environments/$EnvironmentID" -Method "PUT" -Body $UpdateData -ApiVersion "v2") } Function Update-LiongardEnvironmentBulk { [CmdletBinding()] Param( [Parameter(Mandatory)] [array] $Updates ) Return (Send-LiongardRequest -RequestToSend "environments" -Method "PUT" -Body $Updates -ApiVersion "v2") } Function Remove-LiongardEnvironment { [CmdletBinding()] Param( [Parameter(Mandatory)] [uint32] $EnvironmentID, [Parameter(Mandatory=$false)] [bool] $DeleteRelatedEntities = $false ) $Request = "environments/$EnvironmentID" if ($DeleteRelatedEntities) { $Request += "?relatedEntities=true" } Return (Send-LiongardRequest -RequestToSend $Request -Method "DELETE" -ApiVersion "v2") } Function Get-LiongardEnvironmentRelatedEntities { [CmdletBinding()] Param( [Parameter(Mandatory)] [uint32] $EnvironmentID ) Return (Send-LiongardRequest -RequestToSend "environments/$EnvironmentID/relatedEntities" -ApiVersion "v2") } # Metrics Management Functions Function Get-LiongardMetrics { [CmdletBinding()] Param( [Parameter(Mandatory=$false)] [int] $Page, [Parameter(Mandatory=$false)] [int] $PageSize, [Parameter(Mandatory=$false)] [array] $Filters, [Parameter(Mandatory=$false)] [array] $Sorting ) $Request = "metrics" $QueryParams = @() if ($Page) { $QueryParams += "Page=$Page" } if ($PageSize) { $QueryParams += "PageSize=$PageSize" } if ($Filters) { foreach ($Filter in $Filters) { $QueryParams += "Filters[]=$($Filter | ConvertTo-Json)" } } if ($Sorting) { foreach ($Sort in $Sorting) { $QueryParams += "Sorting[]=$($Sort | ConvertTo-Json)" } } if ($QueryParams.Count -gt 0) { $Request += "?" + ($QueryParams -join "&") } Return (Send-LiongardRequest -RequestToSend $Request -ApiVersion "v2") } Function Get-LiongardMetricValue { [CmdletBinding()] Param( [Parameter(Mandatory)] [int[]] $SystemIDs, [Parameter(Mandatory)] [int[]] $MetricIDs, [Parameter(Mandatory=$false)] [bool] $IncludeNonVisible = $false ) $Request = "metrics/evaluate" if ($IncludeNonVisible) { $Request += "?includeNonVisible=true" } $Body = @{ "Metrics" = $MetricIDs "Systems" = $SystemIDs "Filters" = @() "Sorting" = @() "Pagination" = @{ "Page" = 1 "PageSize" = 25 } } Return (Send-LiongardRequest -RequestToSend $Request -Method "POST" -Body $Body -ApiVersion "v2") } Function Invoke-LiongardMetricEvaluation { [CmdletBinding()] Param( [Parameter(Mandatory)] [array] $Metrics, [Parameter(Mandatory=$false)] [array] $Filters = @(), [Parameter(Mandatory=$false)] [array] $Sorting = @(), [Parameter(Mandatory=$false)] [bool] $IncludeNonVisible = $false, [Parameter(Mandatory=$false)] [int] $Page = 1, [Parameter(Mandatory=$false)] [int] $PageSize = 25 ) $Request = "metrics/evaluate" if ($IncludeNonVisible) { $Request += "?includeNonVisible=true" } $Body = @{ "Metrics" = $Metrics "Filters" = $Filters "Sorting" = $Sorting "Pagination" = @{ "Page" = $Page "PageSize" = $PageSize } } Return (Send-LiongardRequest -RequestToSend $Request -Method "POST" -Body $Body -ApiVersion "v2") } Function Invoke-LiongardMetricEvaluationBySystem { [CmdletBinding()] Param( [Parameter(Mandatory)] [array] $Systems, [Parameter(Mandatory=$false)] [array] $Filters = @(), [Parameter(Mandatory=$false)] [array] $Sorting = @(), [Parameter(Mandatory=$false)] [int] $Page = 1, [Parameter(Mandatory=$false)] [int] $PageSize = 25 ) $Body = @{ "Systems" = $Systems "Filters" = $Filters "Sorting" = $Sorting "Pagination" = @{ "Page" = $Page "PageSize" = $PageSize } } Return (Send-LiongardRequest -RequestToSend "metrics/evaluate/systems" -Method "POST" -Body $Body -ApiVersion "v2") } Function Get-LiongardMetricRelatedEnvironments { [CmdletBinding()] Param( [Parameter(Mandatory)] [int] $MetricID ) Return (Send-LiongardRequest -RequestToSend "metrics/$MetricID/relatedEnvironments" -ApiVersion "v2") } # Agent Management Functions Function Get-LiongardAgents { [CmdletBinding(DefaultParameterSetName='AllAgents')] Param( [Parameter(ParameterSetName='OneAgent')] [uint32] $AgentID ) $Request = 'agents' If ($PSCmdlet.ParameterSetName -eq 'OneAgent') { $Request += "/$AgentID" } Return (Send-LiongardRequest -RequestToSend $Request -ApiVersion "v1") } Function Remove-LiongardAgent { [CmdletBinding()] Param( [Parameter(Mandatory)] [int] $AgentID ) Return (Send-LiongardRequest -RequestToSend "agents/$AgentID" -Method "DELETE" -ApiVersion "v1") } Function Clear-LiongardAgent { [Alias('Flush-LiongardAgent')] [CmdletBinding()] Param( [Parameter(Mandatory)] [int] $AgentID ) Return (Send-LiongardRequest -RequestToSend "agents/$AgentID/flush" -Method "POST" -ApiVersion "v1") } Function Install-LiongardAgent { [CmdletBinding()] Param( [Parameter(Mandatory=$false)] [string] $AgentName = $env:computername, [Parameter(Mandatory)] [string] $EnvironmentName, [Parameter(Mandatory=$false)] [string] $InstallPath = "C:\Liongard", [Parameter(Mandatory=$false)] [string] $InstallerUrl = "https://agents.static.liongard.com/LiongardAgent-lts.msi", [Parameter(Mandatory=$false)] [string] $AccessKey, [Parameter(Mandatory=$false)] [string] $AccessSecret, [Parameter(Mandatory=$false)] [string] $Instance ) Begin { Write-Host "Starting Liongard Agent installation process..." -ForegroundColor Cyan # Enable TLS 1.2 [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 # Check for existing installations Write-Host "Checking for existing Liongard Agent installations..." -ForegroundColor Gray $existingAgent = Get-WmiObject -Class Win32_Product -Filter "Name = 'Liongard Agent' OR Name = 'RoarAgent'" if ($existingAgent) { Write-Host "ERROR: A previous installation of the Liongard Agent was found!" -ForegroundColor Red throw "A previous installation of the Liongard Agent was found! Installation stopped." } Write-Host "No existing Liongard Agent installation found." -ForegroundColor Green # If credentials are provided directly, temporarily set them $originalAccessKey = $env:LGAccessKey $originalAccessSecret = $env:LGAccessSecret $originalInstance = $env:LGInstance if ($AccessKey) { $env:LGAccessKey = $AccessKey } if ($AccessSecret) { $env:LGAccessSecret = $AccessSecret } if ($Instance) { $env:LGInstance = $Instance } } Process { try { # Create installation directory if it doesn't exist Write-Host "Checking installation directory [$InstallPath]..." -ForegroundColor Gray if (-not (Test-Path -Path $InstallPath)) { Write-Host "Creating Liongard folder at $InstallPath" -ForegroundColor Gray New-Item -Path $InstallPath -ItemType Directory -Force | Out-Null if (-not (Test-Path -Path $InstallPath)) { Write-Host "ERROR: Failed to create installation directory!" -ForegroundColor Red throw "Failed to create installation directory: $InstallPath" } } Write-Host "Installation directory confirmed." -ForegroundColor Green # Download the installer $installerPath = Join-Path $InstallPath "LiongardAgent-lts.msi" $logPath = Join-Path $InstallPath "AgentInstall.log" Write-Host "Downloading Liongard Agent installer..." -ForegroundColor Gray try { Invoke-WebRequest -Uri $InstallerUrl -OutFile $installerPath } catch { Write-Host "ERROR: Failed to download installer!" -ForegroundColor Red throw "Failed to download installer: $_" } if (-not (Test-Path $installerPath)) { Write-Host "ERROR: Installer download failed - file not found!" -ForegroundColor Red throw "Installer download failed - file not found at $installerPath" } Write-Host "Installer downloaded successfully." -ForegroundColor Green # Verify required environment variables Write-Host "Verifying Liongard credentials..." -ForegroundColor Gray if (-not $env:LGInstance -or -not $env:LGAccessKey -or -not $env:LGAccessSecret) { Write-Host "ERROR: Missing required Liongard credentials!" -ForegroundColor Red throw "Missing required Liongard credentials. Please either run Set-LiongardKeys first or provide credentials as parameters." } Write-Host "Credentials verified." -ForegroundColor Green # Install the agent Write-Host "Installing Liongard Agent..." -ForegroundColor Cyan $installArgs = @( "/i", "`"$installerPath`"", "LIONGARDURL=`"$($env:LGInstance).app.liongard.com`"", "LIONGARDACCESSKEY=$($env:LGAccessKey)", "LIONGARDACCESSSECRET=$($env:LGAccessSecret)", "LIONGARDENVIRONMENT=`"$EnvironmentName`"", "LIONGARDAGENTNAME=`"$AgentName`"", "/qn", "/norestart", "/L*V", "`"$logPath`"" ) $process = Start-Process -FilePath "msiexec.exe" -ArgumentList $installArgs -Wait -PassThru -NoNewWindow if ($process.ExitCode -ne 0) { Write-Host "ERROR: Installation failed with exit code: $($process.ExitCode)" -ForegroundColor Red Write-Host "Please check the log file at: $logPath" -ForegroundColor Yellow throw "Installation failed with exit code: $($process.ExitCode). Check the log file at $logPath" } Write-Host "Installation completed successfully." -ForegroundColor Green } catch { Write-Host "ERROR: Agent installation failed: $_" -ForegroundColor Red throw } finally { # Restore original environment variables if they existed if ($AccessKey) { if ($originalAccessKey) { $env:LGAccessKey = $originalAccessKey } else { Remove-Item -Path "Env:LGAccessKey" -ErrorAction SilentlyContinue } } if ($AccessSecret) { if ($originalAccessSecret) { $env:LGAccessSecret = $originalAccessSecret } else { Remove-Item -Path "Env:LGAccessSecret" -ErrorAction SilentlyContinue } } if ($Instance) { if ($originalInstance) { $env:LGInstance = $originalInstance } else { Remove-Item -Path "Env:LGInstance" -ErrorAction SilentlyContinue } } } } End { Write-Host "Installation process completed. Log file available at: $logPath" -ForegroundColor Cyan Write-Host "Agent Name: $AgentName" -ForegroundColor Gray Write-Host "Environment: $EnvironmentName" -ForegroundColor Gray Write-Host "Install Path: $InstallPath" -ForegroundColor Gray } } Function Uninstall-LiongardAgent { [CmdletBinding()] Param( [Parameter(Mandatory=$false)] [switch] $KeepLogs, [Parameter(Mandatory=$false)] [string] $LogPath = "C:\Liongard\AgentUninstall.log" ) Begin { Write-Host "Starting Liongard Agent uninstallation process..." -ForegroundColor Cyan # Check for existing installation Write-Host "Checking for Liongard Agent installation..." -ForegroundColor Gray $agent = Get-WmiObject -Class Win32_Product -Filter "Name = 'Liongard Agent' OR Name = 'RoarAgent'" if (-not $agent) { Write-Host "No Liongard Agent installation found." -ForegroundColor Yellow return } Write-Host "Found Liongard Agent installation." -ForegroundColor Green } Process { try { # Ensure log directory exists $logDir = Split-Path -Parent $LogPath if (-not (Test-Path $logDir)) { New-Item -Path $logDir -ItemType Directory -Force | Out-Null } # Uninstall the agent Write-Host "Uninstalling Liongard Agent..." -ForegroundColor Cyan $uninstallArgs = @( "/x", $agent.IdentifyingNumber, "/qn", "/norestart", "/L*V", "`"$LogPath`"" ) $process = Start-Process -FilePath "msiexec.exe" -ArgumentList $uninstallArgs -Wait -PassThru -NoNewWindow if ($process.ExitCode -ne 0) { Write-Host "ERROR: Uninstallation failed with exit code: $($process.ExitCode)" -ForegroundColor Red Write-Host "Please check the log file at: $LogPath" -ForegroundColor Yellow throw "Uninstallation failed with exit code: $($process.ExitCode). Check the log file at $LogPath" } Write-Host "Uninstallation completed successfully." -ForegroundColor Green # Clean up installation directory if specified if (-not $KeepLogs) { Write-Host "Cleaning up Liongard directories..." -ForegroundColor Gray $installDirs = @( "C:\Liongard", "${env:ProgramFiles(x86)}\LiongardInc", "${env:ProgramFiles}\LiongardInc" ) foreach ($dir in $installDirs) { if (Test-Path $dir) { Remove-Item -Path $dir -Recurse -Force -ErrorAction SilentlyContinue Write-Host "Removed directory: $dir" -ForegroundColor Gray } } } } catch { Write-Host "ERROR: Agent uninstallation failed: $_" -ForegroundColor Red throw } } End { Write-Host "Uninstallation process completed." -ForegroundColor Cyan if (-not $KeepLogs) { Write-Host "All Liongard files and directories have been removed." -ForegroundColor Gray } else { Write-Host "Uninstallation log file available at: $LogPath" -ForegroundColor Gray Write-Host "Note: Liongard directories were preserved as -KeepLogs was specified." -ForegroundColor Yellow } } } Function Get-AgentLogs { [CmdletBinding()] Param ( [Parameter(Mandatory=$false)] [ValidateScript({Test-Path $_ -PathType 'Container'})] [string] $InstallDir = "C:\", [Parameter(Mandatory=$false)] [ValidateSet('Error', 'Warning', 'Information')] [string] $LogLevel = 'Information', [Parameter(Mandatory=$false)] [switch] $KeepOriginalLogs, [Parameter(Mandatory=$false)] [string] $OutputPath ) Begin { # Setup logging if ($LogLevel -eq 'Information') { $VerbosePreference = 'Continue' } else { $VerbosePreference = 'SilentlyContinue' } if ($LogLevel -eq 'Warning') { $WarningPreference = 'Continue' } else { $WarningPreference = 'SilentlyContinue' } if ($LogLevel -eq 'Error') { $ErrorActionPreference = 'Stop' } else { $ErrorActionPreference = 'Continue' } # Define paths $AgentLogPath = Join-Path $InstallDir "Program Files (x86)\LiongardInc\LiongardAgent\logs" if (-not (Test-Path $AgentLogPath)) { throw "Agent log directory not found at: $AgentLogPath" } # If no output path specified, use the agent log path if (-not $OutputPath) { $OutputPath = $AgentLogPath } # Create timestamp for the archive $TimeStamp = Get-Date -Format "yyyyMMdd_HHmmss" $ArchiveName = "LiongardAgentLogs_$TimeStamp.zip" $ArchivePath = Join-Path $OutputPath $ArchiveName # Define log files to collect $LogFiles = @{ 'EventLog' = @{ Source = 'LiongardAgentLog' Destination = Join-Path $AgentLogPath "events-$TimeStamp.csv" } 'DebugLog' = @{ Source = Join-Path $AgentLogPath "debug.log" Destination = Join-Path $AgentLogPath "debug-$TimeStamp.log" } 'ErrorLog' = @{ Source = Join-Path $AgentLogPath "error.log" Destination = Join-Path $AgentLogPath "error-$TimeStamp.log" } 'HeartbeatLog' = @{ Source = Join-Path $AgentLogPath "heartbeat.log" Destination = Join-Path $AgentLogPath "heartbeat-$TimeStamp.log" } 'JanitorLog' = @{ Source = Join-Path $AgentLogPath "janitor.log" Destination = Join-Path $AgentLogPath "janitor-$TimeStamp.log" } 'JobsLog' = @{ Source = Join-Path $AgentLogPath "jobs.log" Destination = Join-Path $AgentLogPath "jobs-$TimeStamp.log" } 'SQSLog' = @{ Source = Join-Path $AgentLogPath "sqs.log" Destination = Join-Path $AgentLogPath "sqs-$TimeStamp.log" } } } Process { try { Write-Verbose "Starting log collection process..." $CollectedFiles = @() # Collect Event Logs Write-Verbose "Collecting Windows Event Logs..." try { Get-EventLog -LogName $LogFiles.EventLog.Source | Select-Object TimeGenerated, EntryType, Source, Message | Export-Csv -Path $LogFiles.EventLog.Destination -NoTypeInformation $CollectedFiles += $LogFiles.EventLog.Destination Write-Verbose "Successfully collected Event Logs" } catch { Write-Warning "Failed to collect Event Logs: $_" } # Collect Agent Log Files foreach ($LogType in $LogFiles.Keys | Where-Object { $_ -ne 'EventLog' }) { $LogInfo = $LogFiles[$LogType] if (Test-Path $LogInfo.Source) { Write-Verbose "Collecting $LogType..." try { Copy-Item -Path $LogInfo.Source -Destination $LogInfo.Destination -Force $CollectedFiles += $LogInfo.Destination Write-Verbose "Successfully collected $LogType" } catch { Write-Warning "Failed to collect $LogType`: $_" } } else { Write-Warning "Log file not found: $($LogInfo.Source)" } } # Create archive Write-Verbose "Creating log archive: $ArchivePath" if ($CollectedFiles.Count -gt 0) { $compress = @{ Path = $CollectedFiles CompressionLevel = "Fastest" DestinationPath = $ArchivePath } Compress-Archive @compress -Force Write-Verbose "Successfully created log archive" # Clean up temporary files unless KeepOriginalLogs is specified if (-not $KeepOriginalLogs) { Write-Verbose "Cleaning up temporary files..." foreach ($file in $CollectedFiles) { Remove-Item -Path $file -Force -ErrorAction SilentlyContinue } } } else { Write-Warning "No log files were collected" } } catch { Write-Error "Failed to collect agent logs: $_" return } } End { if (Test-Path $ArchivePath) { Write-Verbose "Log collection completed successfully" Write-Verbose "Logs archived to: $ArchivePath" return $ArchivePath } else { Write-Error "Failed to create log archive" } } } # System Management Functions Function Get-LiongardSystems { [CmdletBinding(DefaultParameterSetName='AllSystems')] Param( [Parameter(ParameterSetName='OneSystem')] [uint32] $SystemID ) $Request = 'systems' If ($PSCmdlet.ParameterSetName -eq 'OneSystem') { $Request += "/$SystemID/view" } Return (Send-LiongardRequest -RequestToSend $Request -ApiVersion "v1") } # Launchpoint Management Functions Function Get-LiongardLaunchpoints { [CmdletBinding(DefaultParameterSetName='AllLaunchpoints')] Param( [Parameter(ParameterSetName='OneLaunchpoint')] [uint32] $LaunchpointID ) $Request = 'launchpoints' If ($PSCmdlet.ParameterSetName -eq 'OneLaunchpoint') { $Request += "/$LaunchpointID" } Return (Send-LiongardRequest -RequestToSend $Request -ApiVersion "v1") } # Detection Management Functions Function Get-LiongardDetections { [CmdletBinding(DefaultParameterSetName='AllDetections')] Param( [Parameter(ParameterSetName='OneDetection')] [uint32] $DetectionID ) $Request = 'detections' If ($PSCmdlet.ParameterSetName -eq 'OneDetection') { $Request += "/$DetectionID" } Return (Send-LiongardRequest -RequestToSend $Request -ApiVersion "v1") } # Alert Management Functions Function Get-LiongardAlerts { [CmdletBinding()] Param() Return (Send-LiongardRequest -RequestToSend 'tasks' -ApiVersion "v1") } # Add these functions after the existing Environment Management Functions Function Search-LiongardEnvironments { [CmdletBinding()] Param( [Parameter(Mandatory=$false)] [int] $Page = 1, [Parameter(Mandatory=$false)] [int] $PageSize = 25, [Parameter(Mandatory=$false)] [ValidateSet('Name', 'ID', 'CreatedOn', 'UpdatedOn')] [string] $OrderBy, [Parameter(Mandatory=$false)] [ValidateSet('ASC', 'DESC')] [string] $OrderDirection = 'ASC', [Parameter(Mandatory=$false)] [string] $NameFilter, [Parameter(Mandatory=$false)] [ValidateSet('Core', 'Essentials')] [string] $TierFilter, [Parameter(Mandatory=$false)] [bool] $VisibleOnly ) $QueryParams = @() if ($Page) { $QueryParams += "page=$Page" } if ($PageSize) { $QueryParams += "pageSize=$PageSize" } if ($OrderBy) { $QueryParams += "orderBy=$OrderBy" $QueryParams += "orderDirection=$OrderDirection" } if ($NameFilter) { $QueryParams += "name=$NameFilter" } if ($TierFilter) { $QueryParams += "tier=$TierFilter" } if ($VisibleOnly) { $QueryParams += "visibleOnly=true" } $Request = "environments" if ($QueryParams.Count -gt 0) { $Request += "?" + ($QueryParams -join "&") } Return (Send-LiongardRequest -RequestToSend $Request -ApiVersion "v2") } Function Search-LiongardMetrics { [CmdletBinding()] Param( [Parameter(Mandatory=$false)] [int] $Page = 1, [Parameter(Mandatory=$false)] [int] $PageSize = 25, [Parameter(Mandatory=$false)] [array] $Filters, [Parameter(Mandatory=$false)] [array] $Sorting ) $QueryParams = @() if ($Page) { $QueryParams += "Page=$Page" } if ($PageSize) { $QueryParams += "PageSize=$PageSize" } if ($Filters) { foreach ($Filter in $Filters) { $FilterJson = $Filter | ConvertTo-Json -Compress $QueryParams += "Filters[]=$FilterJson" } } if ($Sorting) { foreach ($Sort in $Sorting) { $SortJson = $Sort | ConvertTo-Json -Compress $QueryParams += "Sorting[]=$SortJson" } } $Request = "metrics" if ($QueryParams.Count -gt 0) { $Request += "?" + ($QueryParams -join "&") } Return (Send-LiongardRequest -RequestToSend $Request -ApiVersion "v2") } Function Get-LiongardMetricsByFilter { [CmdletBinding()] Param( [Parameter(Mandatory=$false)] [ValidateSet('Name', 'UCK')] [string] $FilterBy, [Parameter(Mandatory=$false)] [ValidateSet('contains', 'does_not_contain', 'matches_exactly', 'starts_with', 'ends_with')] [string] $Operation, [Parameter(Mandatory=$false)] [string] $Value, [Parameter(Mandatory=$false)] [ValidateSet('ID', 'Name', 'UCK')] [string] $SortBy = 'ID', [Parameter(Mandatory=$false)] [ValidateSet('ASC', 'DESC')] [string] $Direction = 'ASC', [Parameter(Mandatory=$false)] [int] $Page = 1, [Parameter(Mandatory=$false)] [int] $PageSize = 25 ) $Filters = @() if ($FilterBy -and $Operation -and $Value) { $Filters += @{ FilterBy = $FilterBy Op = $Operation Value = $Value } } $Sorting = @(@{ SortBy = $SortBy Direction = $Direction }) Return (Search-LiongardMetrics -Page $Page -PageSize $PageSize -Filters $Filters -Sorting $Sorting) } |