[CmdletBinding()] param( [string]$ManifestUrl = "https://gitea.officecom.cloud/officecom/oc-sentinel/raw/main/release/stable/version.json" ) $ErrorActionPreference = "Stop" $ProgressPreference = "SilentlyContinue" function Initialize-OCSentinelTls { $protocols = [Net.SecurityProtocolType]::Tls12 if ([Enum]::GetNames([Net.SecurityProtocolType]) -contains "Tls13") { $protocols = $protocols -bor [Net.SecurityProtocolType]::Tls13 } [Net.ServicePointManager]::SecurityProtocol = $protocols [Net.ServicePointManager]::Expect100Continue = $false } function Read-NinjaEnvironmentValue { param([Parameter(Mandatory)][string]$Name) $value = [Environment]::GetEnvironmentVariable($Name, "Process") if ($null -eq $value) { return "" } return $value.Trim() } Initialize-OCSentinelTls $installRoot = Join-Path $env:ProgramFiles "OCSentinel" $updaterPath = Join-Path $installRoot "scripts\update-ocsentinel.ps1" $monitorPath = Join-Path $installRoot "scripts\run-ocsentinel-monitor.ps1" $clientConfigPath = Join-Path $installRoot "config\ocsentinel-client.json" $secretPath = "C:\ProgramData\OCSentinel\secrets\ocsentinel-upload-secret.dat" foreach ($path in @($updaterPath, $clientConfigPath, $monitorPath)) { if (-not (Test-Path -LiteralPath $path)) { throw "OCSentinel installation is incomplete. Missing: $path" } } # The NinjaOne context exists only during this script execution. Upgrade first so # future scheduled scans restore the context from the local client configuration. $escapedUpdaterPath = $updaterPath.Replace("'", "''") $escapedManifestUrl = $ManifestUrl.Replace("'", "''") $updateCommand = @" `$protocols = [Net.SecurityProtocolType]::Tls12 if ([Enum]::GetNames([Net.SecurityProtocolType]) -contains 'Tls13') { `$protocols = `$protocols -bor [Net.SecurityProtocolType]::Tls13 } [Net.ServicePointManager]::SecurityProtocol = `$protocols [Net.ServicePointManager]::Expect100Continue = `$false & '$escapedUpdaterPath' -ManifestUrl '$escapedManifestUrl' exit `$LASTEXITCODE "@ & powershell.exe -NoProfile -ExecutionPolicy Bypass -Command $updateCommand | ForEach-Object { Write-Host $_ } if ($LASTEXITCODE -ne 0) { throw "OCSentinel updater exited with code $LASTEXITCODE" } $mappings = @( @{ EnvironmentName = "NINJA_ORGANIZATION_ID"; PropertyName = "ninjaOrganizationId"; Required = $true }, @{ EnvironmentName = "NINJA_ORGANIZATION_NAME"; PropertyName = "ninjaOrganizationName"; Required = $true }, @{ EnvironmentName = "NINJA_AGENT_MACHINE_ID"; PropertyName = "ninjaMachineId"; Required = $true }, @{ EnvironmentName = "NINJA_AGENT_NODE_ID"; PropertyName = "ninjaNodeId"; Required = $false }, @{ EnvironmentName = "NINJA_LOCATION_ID"; PropertyName = "ninjaLocationId"; Required = $false }, @{ EnvironmentName = "NINJA_LOCATION_NAME"; PropertyName = "ninjaLocationName"; Required = $false } ) $clientConfig = Get-Content -LiteralPath $clientConfigPath -Raw | ConvertFrom-Json $missing = @() $captured = 0 foreach ($mapping in $mappings) { $value = Read-NinjaEnvironmentValue -Name $mapping.EnvironmentName if ([string]::IsNullOrWhiteSpace($value)) { if ($mapping.Required) { $missing += $mapping.EnvironmentName } continue } $clientConfig | Add-Member -NotePropertyName $mapping.PropertyName -NotePropertyValue $value -Force $captured++ } if ($missing.Count -gt 0) { throw "NinjaOne did not provide required context: $($missing -join ', '). Run this only from a NinjaOne automation, not from an interactive PowerShell session." } $clientConfig | ConvertTo-Json -Depth 10 | Set-Content -LiteralPath $clientConfigPath -Encoding UTF8 Write-Host "OCSentinel NinjaOne context captured: $captured of $($mappings.Count) values." if ((Test-Path -LiteralPath $secretPath) -and -not [string]::IsNullOrWhiteSpace([string]$clientConfig.n8nWebhookUrl)) { Write-Host "Running an immediate status scan and upload with the refreshed NinjaOne context." & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $monitorPath ` -Mode status ` -ClientConfigPath $clientConfigPath ` -SecretPath $secretPath ` -UploadMode required ` -SuppressTriggerExit if ($LASTEXITCODE -ne 0) { throw "OCSentinel context refresh scan exited with code $LASTEXITCODE" } } else { Write-Warning "Context was stored, but the upload configuration or protected secret is missing. The next configured scan will use the stored context." } Write-Host "OCSENTINEL_NINJA_CONTEXT=updated"