Launch OpenRGB on login

Script to create a task in Windows Task Sheduler to launch OpenRGB with admin rights and any profile of your choosing. It also allows you to restore a config folder if you have it stored somewhere.
 avatar
unknown
powershell
a month ago
6.7 kB
41
Indexable
#Requires -Version 5.1
[CmdletBinding()]
param()

# Self-elevate if not admin
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)) {
    $cmd = "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`""
    Start-Process -FilePath "powershell.exe" -ArgumentList $cmd -Verb RunAs
    exit
}

# UI
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

function Select-OpenRGBExe {
    $dlg = New-Object System.Windows.Forms.OpenFileDialog
    $dlg.Title = "Select OpenRGB.exe"
    $dlg.Filter = "Executable (*.exe)|*.exe"
    $dlg.FilterIndex = 1
    $dlg.CheckFileExists = $true
    $dlg.CheckPathExists = $true
    $dlg.RestoreDirectory = $true
    $dlg.FileName = "OpenRGB.exe"

    $candidates = @(
        (Join-Path $PSScriptRoot ''),
        (Join-Path $env:ProgramFiles 'OpenRGB'),
        (Join-Path ${env:ProgramFiles(x86)} 'OpenRGB'),
        (Join-Path $env:LOCALAPPDATA 'Programs\OpenRGB')
    ) | Where-Object { $_ -and (Test-Path $_) }

    if ($candidates.Count -gt 0) { $dlg.InitialDirectory = $candidates[0] }

    while ($true) {
        $res = $dlg.ShowDialog()
        if ($res -ne [System.Windows.Forms.DialogResult]::OK) { return $null }
        if ((Split-Path -Leaf $dlg.FileName) -ieq 'OpenRGB.exe') { return $dlg.FileName }
        [System.Windows.Forms.MessageBox]::Show(
            "Please select OpenRGB.exe.",
            "Wrong file",
            [System.Windows.Forms.MessageBoxButtons]::OK,
            [System.Windows.Forms.MessageBoxIcon]::Warning
        ) | Out-Null
    }
}

function Select-OpenRGBBackupFolder {
    $dlg = New-Object System.Windows.Forms.FolderBrowserDialog
    $dlg.Description = "Select your OpenRGB BACKUP folder (the folder named 'OpenRGB' that contains openrgb.json, Profiles, Plugins, etc.)"
    $dlg.ShowNewFolderButton = $false

    $candidates = @(
        (Join-Path $PSScriptRoot 'OpenRGB'),
        (Join-Path $PSScriptRoot ''),
        (Join-Path $env:USERPROFILE 'Documents'),
        (Join-Path $env:USERPROFILE 'Desktop')
    ) | Where-Object { $_ -and (Test-Path $_) }
    if ($candidates.Count -gt 0) { $dlg.SelectedPath = $candidates[0] }

    $res = $dlg.ShowDialog()
    if ($res -ne [System.Windows.Forms.DialogResult]::OK) { return $null }
    return $dlg.SelectedPath
}

# Pick OpenRGB.exe
$openrgbExe = Select-OpenRGBExe
if (-not $openrgbExe) { [System.Windows.Forms.MessageBox]::Show("Selection cancelled.","Cancelled"); exit 1 }
if (-not (Test-Path $openrgbExe)) {
    [System.Windows.Forms.MessageBox]::Show("Selected file not found. Try again.","Not Found") | Out-Null
    exit 1
}

# Optional: pick backup config folder (user may cancel)
$backupFolder = Select-OpenRGBBackupFolder

# Destination config path: %APPDATA%\OpenRGB
$destConfig = Join-Path $env:APPDATA 'OpenRGB'
if (-not (Test-Path $destConfig)) {
    New-Item -ItemType Directory -Path $destConfig | Out-Null
}

# If a backup was chosen, restore it; if not, continue without copying
if ($backupFolder) {
    & robocopy "$backupFolder" "$destConfig" /E /COPY:DAT /R:1 /W:1 | Out-Null
    $rc = $LASTEXITCODE
    if ($rc -ge 8) {
        Write-Error "Robocopy failed with exit code $rc"
        exit 1
    }
    Write-Host "Backup restored to $destConfig"
} else {
    Write-Host "No backup folder selected. Using existing %APPDATA%\OpenRGB configuration."
}

# Enumerate .orp profiles in %APPDATA%\OpenRGB
$profilesPath = $destConfig
$profiles = @()
if (Test-Path $profilesPath) {
    $profiles = Get-ChildItem -Path $profilesPath -Filter "*.orp" -File | Sort-Object Name
}

$selectedProfile = $null
if ($profiles.Count -gt 0) {
    Write-Host "`nFound $($profiles.Count) profile(s) in $profilesPath :"
    for ($i = 0; $i -lt $profiles.Count; $i++) {
        Write-Host "  [$($i+1)] $($profiles[$i].Name)"
    }
    Write-Host "  [0] Skip - do not load a profile at startup"
    
    $choice = $null
    while ($true) {
        $input = Read-Host "`nEnter the number of the profile to load at startup (or 0 to skip)"
        if ($input -match '^\d+$') {
            $num = [int]$input
            if ($num -eq 0) {
                Write-Host "No profile will be loaded at startup."
                break
            }
            if ($num -ge 1 -and $num -le $profiles.Count) {
                $selectedProfile = $profiles[$num - 1].BaseName  # Use BaseName (without .orp extension)
                Write-Host "Selected profile: $selectedProfile"
                break
            }
        }
        Write-Host "Invalid selection. Please enter a number from 0 to $($profiles.Count)." -ForegroundColor Yellow
    }
} else {
    Write-Host "`nNo .orp profiles found in $profilesPath. Skipping profile selection."
}

# Build arguments: start minimized + optional profile
$arguments = '--startminimized'
if ($selectedProfile) {
    $arguments += ' --profile "' + $selectedProfile + '"'
}

# Ensure Task Scheduler folder named after computer exists
$sched = New-Object -ComObject "Schedule.Service"
$sched.Connect()
$root = $sched.GetFolder("\")
try { $root.CreateFolder($env:COMPUTERNAME) } catch {}

# Create elevated logon task
Import-Module ScheduledTasks -ErrorAction Stop

$taskName       = 'Launch OpenRGB'
$taskFolderPath = "\" + $env:COMPUTERNAME
$description    = 'Start OpenRGB elevated at user logon'

# Remove existing task if present
try { Unregister-ScheduledTask -TaskName $taskName -TaskPath $taskFolderPath -Confirm:$false -ErrorAction SilentlyContinue } catch {}

$action    = New-ScheduledTaskAction -Execute $openrgbExe -Argument $arguments
$trigger   = New-ScheduledTaskTrigger -AtLogOn -User $env:USERNAME
$principal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -LogonType Interactive -RunLevel Highest
$settings  = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -ExecutionTimeLimit (New-TimeSpan -Seconds 0)

Register-ScheduledTask -TaskName $taskName -TaskPath "$taskFolderPath\" -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Description $description -Force | Out-Null

$summaryMsg = "Config location:`n$destConfig`n`nScheduled task created:`n$taskFolderPath$taskName`n`nOpenRGB will start minimized and elevated at user logon."
if ($selectedProfile) {
    $summaryMsg += "`n`nProfile to load: $selectedProfile"
}
[System.Windows.Forms.MessageBox]::Show($summaryMsg,"Done") | Out-Null
Editor is loading...
Leave a Comment