[CmdletBinding()] param( [Parameter(Mandatory)] [string]$EnrollmentTokenFile, [string]$Endpoint = 'https://app.syskeep.co.uk/api/v1/assets/ingest', [ValidateRange(15, 10080)] [int]$IntervalMinutes = 360, [ValidateRange(1, 10)] [int]$MaximumAttempts = 4, [ValidateRange(5, 300)] [int]$RetryDelaySeconds = 30 ) $ErrorActionPreference = 'Stop' $eventSource = 'SysKeep Agent' $executable = Join-Path $env:ProgramFiles 'SysKeep Agent\SysKeep.Agent.exe' $enrollmentMarker = Join-Path $env:ProgramData 'SysKeep\Agent\device-enrollment-v1' function Write-SysKeepEvent { param( [Parameter(Mandatory)][string]$Message, [Parameter(Mandatory)][ValidateSet('Information', 'Warning', 'Error')][string]$EntryType, [Parameter(Mandatory)][int]$EventId ) try { Write-EventLog -LogName Application -Source $eventSource -EntryType $EntryType -EventId $EventId -Message $Message -ErrorAction Stop } catch { # MSI registration or Event Log availability must not prevent enrollment. } } function Wait-ForRetry { param([int]$Attempt) $delay = [Math]::Min($RetryDelaySeconds * $Attempt, 300) Write-SysKeepEvent -EntryType Warning -EventId 4201 -Message "SysKeep Agent enrollment attempt $Attempt failed transiently; retrying in $delay seconds." Start-Sleep -Seconds $delay } if (-not $EnrollmentTokenFile.StartsWith('\\', [StringComparison]::Ordinal)) { throw 'EnrollmentTokenFile must be a UNC path on a separately secured deployment share.' } if (-not (Test-Path -LiteralPath $executable)) { exit 0 } if (Test-Path -LiteralPath $enrollmentMarker) { Start-Service SysKeepAgent -ErrorAction SilentlyContinue exit 0 } $service = Get-Service SysKeepAgent -ErrorAction SilentlyContinue $wasRunning = $service -and $service.Status -eq 'Running' $enrollmentToken = $null $enrolled = $false $serviceStopped = $false try { for ($attempt = 1; $attempt -le $MaximumAttempts; $attempt++) { try { $enrollmentToken = [System.IO.File]::ReadAllText($EnrollmentTokenFile).Trim() } catch [System.UnauthorizedAccessException] { Write-SysKeepEvent -EntryType Error -EventId 4301 -Message 'SysKeep Agent enrollment could not read the protected token file because access was denied.' throw 'SysKeep Agent enrollment token access was denied. Check the deployment share computer-group ACL.' } catch [System.IO.IOException] { if ($attempt -lt $MaximumAttempts) { Wait-ForRetry -Attempt $attempt continue } Write-SysKeepEvent -EntryType Error -EventId 4302 -Message "SysKeep Agent enrollment exhausted $MaximumAttempts attempts while waiting for the protected deployment share." throw 'SysKeep Agent enrollment could not reach the protected deployment share after bounded retries.' } if ([string]::IsNullOrWhiteSpace($enrollmentToken)) { Write-SysKeepEvent -EntryType Error -EventId 4301 -Message 'SysKeep Agent enrollment found an empty protected token file.' throw 'The SysKeep enrollment token file is empty.' } if ($wasRunning -and -not $serviceStopped) { Stop-Service SysKeepAgent $serviceStopped = $true } $enrollmentToken | & $executable enroll --endpoint $Endpoint --interval-minutes $IntervalMinutes $exitCode = $LASTEXITCODE $enrollmentToken = $null if ($exitCode -eq 0) { New-Item -ItemType File -Path $enrollmentMarker -Force | Out-Null $enrolled = $true Write-SysKeepEvent -EntryType Information -EventId 4100 -Message 'SysKeep Agent device enrollment completed successfully.' break } if ($exitCode -eq 3 -and $attempt -lt $MaximumAttempts) { Wait-ForRetry -Attempt $attempt continue } if ($exitCode -eq 2) { Write-SysKeepEvent -EntryType Error -EventId 4301 -Message 'SysKeep rejected device enrollment. The credential may be expired, revoked, exhausted or assigned incorrectly.' throw 'SysKeep rejected device enrollment. Replace the protected enrollment token and retry at computer startup.' } Write-SysKeepEvent -EntryType Error -EventId 4302 -Message "SysKeep Agent enrollment failed with exit code $exitCode." throw "SysKeep Agent enrollment failed with exit code $exitCode." } if (-not $enrolled) { Write-SysKeepEvent -EntryType Error -EventId 4302 -Message "SysKeep Agent enrollment exhausted $MaximumAttempts transient API attempts." throw 'SysKeep Agent enrollment exhausted its bounded retry allowance.' } } finally { $enrollmentToken = $null if ($enrolled -or $wasRunning) { Start-Service SysKeepAgent -ErrorAction SilentlyContinue } }