I've been attempting to deploy the SentinelOne agent across our heterogeneous lab environment, which includes a non-trivial number of legacy Windows 10 builds (specifically versions 1809 and 1909). A standardized deployment script works flawlessly on our modern 22H2 systems, but fails consistently on these older builds. The failure is silent; the installer executes and exits with what appears to be a success code (0), but the agent service never appears, and the management console shows the host as uninstalled.
I have followed the documented silent install parameters, but the lack of verbose logging from the installer itself is a significant hurdle. My benchmark-driven mindset requires reproducible failure states and clear logs, which I am not getting. Here is the exact command sequence I'm running from an elevated PowerShell context, after verifying the system meets the stated minimum requirements:
```powershell
$InstallerPath = ".SentinelInstaller.exe"
$Token = ""
$SiteToken = ""
$Arguments = "/S /v`"/qn SENTINEL_TOKEN=$Token SITE_TOKEN=$SiteToken`""
# Execution and exit code capture
Start-Process -FilePath $InstallerPath -ArgumentList $Arguments -Wait -NoNewWindow
$ExitCode = $LASTEXITCODE
Write-Host "Installer exited with code: $ExitCode"
```
The process consistently returns exit code 0. Subsequent checks for the agent's presence are negative:
```powershell
# Check for service
Get-Service -Name "SentinelOne" -ErrorAction SilentlyContinue
# Check for driver
Get-WindowsDriver -Online | Where-Object {$_.Driver -like "*Sentinel*"}
# Check for installation directory
Test-Path "C:Program FilesSentinelOne"
```
All checks return null or false. I have attempted the following troubleshooting steps, treating each as an independent variable in the experiment:
* Disabled all third-party AV/EDR prior to installation (confirmed process).
* Verified Windows Installer service is running and functional.
* Attempted deployment using both the "Windows" and "Windows Legacy" agent packages from the console.
* Extracted the MSI from the wrapper and attempted a direct MSIEXEC install with enhanced logging. The log indicates a successful install, but the results on disk contradict this.
* Scanned for known incompatible software (particular old VPN clients, certain legacy security products). No conflicts were identified.
The core issue appears to be a gap between the installer's reported state and the actual system state post-execution. This is a critical flaw from a reproducibility standpoint.
Has anyone else encountered this specific failure mode on older Windows 10 feature releases? More importantly, does anyone have a methodology for extracting *meaningful* diagnostic logs from the SentinelOne installer to pinpoint the stage (driver injection, service registration, file placement) where the process is failing? I need data points beyond a simple exit code.
-- bb42
-- bb42
That's odd it returns success but doesn't show up. Have you checked if maybe the old systems have some leftover remnants from a previous AV? I ran into something similar once where a conflict caused the service to install but then immediately disable itself.
Hey, I've hit this exact wall with 1809 before. That exit code 0 is a total red herring. The installer's wrapper succeeds, but the actual MSI install can fail silently underneath.
You need to pull the real MSI logs. Try rerunning with msiexec explicitly and the /l*v flag. For me, the logs showed a prerequisite check failure for a specific C++ runtime on those older builds that the installer didn't flag. A manual install of the VC++ redist got it through.
Also, double-check those old systems for pending reboots from Windows updates. That'll ghost an install every time.
Happy customers, happy life.
The explicit msiexec approach user1037 mentioned is key, but you can integrate it directly into your script to maintain that reproducible benchmark you want. Instead of calling the .exe wrapper, extract the MSI first.
Add a step to extract the embedded MSI, then call msiexec with full verbose logging to a known path. This will give you the concrete failure logs.
```powershell
$MsiPath = [System.IO.Path]::ChangeExtension($InstallerPath, ".msi")
Start-Process -FilePath $InstallerPath -ArgumentList "/extract `"$MsiPath`"" -Wait -NoNewWindow
$LogPath = "C:TempSentinelInstall.log"
$MsiArgs = "/i `"$MsiPath`" /qn /l*v `"$LogPath`" SENTINEL_TOKEN=$Token SITE_TOKEN=$SiteToken"
Start-Process -FilePath "msiexec.exe" -ArgumentList $MsiArgs -Wait -NoNewWindow
```
Then you can programmatically check $LogPath for specific error codes. The 1809/1909 builds often fail on missing system components that aren't checked by the wrapper.
sub-100ms or bust
Great point about extracting the MSI for consistent logging. That's a solid method to cut through the wrapper's opacity. One small caveat from my experience - on some of those older builds, the temp path `C:Temp` might not exist or have restrictive permissions for the SYSTEM account if the script runs in that context. It's a good idea to add a `Test-Path` and `New-Item` step for the directory first to avoid a secondary silent failure.
The logs from this approach have been invaluable for us in the past, especially for pinpointing those missing prereqs.
Stay constructive
Ah, the classic silent failure with a success code. It's like the installer is gaslighting you. Been there with other agents.
That wrapper exit code 0 is basically meaningless. Like others said, the real action is in the MSI log. One thing I'd check *before* you even get to the extraction step is the installer's own log, which sometimes exists even when you don't ask for it.
Try adding a `%TEMP%` check after your installer runs. Look for a file named something like `S1_MSI*.log`. The wrapper sometimes dumps its own MSI log there, even on a "successful" run. It's a long shot, but it's saved me some extraction steps before.
Also, double-check your token and site token variables in that script. On some of those older builds, if there's a weird character or trailing space that gets pulled in from a config file, the MSI properties can be set incorrectly, leading to a silent rollback.
ship it
Good catch on checking for that wrapper-generated MSI log before jumping to extraction. It's an easy step to overlook in the script.
I'd add that the location of that log can shift depending on the user context the installer runs under - local temp vs system temp - so it's worth checking both directories if your deployment method changes context.
Keep it constructive.
You're missing the exit code capture and the logging. Here's what's happening:
Your `Start-Process` call doesn't actually capture the exit code from the wrapper. That's your first blind spot. The code you posted cuts off. You need to store the process object and check its `ExitCode` property.
But, that wrapper exit code is a lie. The real install happens in the MSI, and its failure is hidden. Run the install again with this tweak to get the true exit code from the wrapper process. It still won't show the MSI failure, but it's the right first step for your benchmark script.
```powershell
$proc = Start-Process -FilePath $InstallerPath -ArgumentList $Arguments -Wait -NoNewWindow -PassThru
$ExitCode = $proc.ExitCode
```
Now correlate that with the MSI log from `%TEMP%` or the explicit extraction method others posted. Without both data points, you're debugging with one hand tied behind your back.
Metrics don't lie.
Your script cuts off at a critical juncture, right where the exit code should be captured. The missing variable assignment for `$ExitCode` means you're not even logging the wrapper's misleading success code, which is a foundational data point for your benchmark.
I'd focus first on instrumenting the script to capture that wrapper exit code, as user634 suggests, but then immediately pivot to the MSI extraction method outlined by user181. The extracted MSI log will be your single source of truth. Given your environment, also validate the C++ runtime prerequisites on a sample 1809 machine before your next deployment cycle; it's a common, silent blocker that doesn't appear in minimum requirement docs.
Migrate slow, validate fast.
Yeah, that missing `$ExitCode` assignment in your script snippet is a big clue. Even if it's a misleading success code, not capturing it means you're losing a piece of the diagnostic chain.
Following that, the community has already surfaced the two most likely paths forward. Before you complicate the script, I'd manually test user1037's suggestion about checking for a leftover log in `%TEMP%` on one of the failing 1809 boxes. It's a quick, low-effort check that might save you the extraction step. If that's a dead end, then the explicit MSI extraction and logging method is your definitive next move. It'll give you the concrete error you need.
Keep it civil, keep it real.
Right, the missing `$ExitCode` assignment means you're not even capturing the misleading success signal. That's step zero for your benchmarks. The community's got the right idea - you need that wrapper exit code as a data point before moving to the real evidence.
The core problem is the wrapper/MSI disconnect. Since you're benchmark-driven, I'd test both diagnostic paths in sequence on a single 1809 machine. First, run your script with the corrected exit code capture. Immediately after, check both `%TEMP%` and `C:WindowsTemp` for any `S1_MSI*.log` file. If you find one, you've saved a step. If not, then move to the explicit MSI extraction method that user181 outlined. That extracted log will be your definitive, reproducible failure artifact.
Also, worth a quick manual check on one of those failing builds for pending reboots and the VC++ 2015-2022 redistributable, as user1037 mentioned. Those are common, silent prerequisites that'll tank the MSI even when the wrapper reports success.