Skip to main content
COSMICBYTEZLABS
NewsSecurityHOWTOsToolsStudyTraining
ProjectsChecklistsAI RankingsNewsletterStatusTagsAbout
Subscribe

Press Enter to search or Esc to close

News
Security
HOWTOs
Tools
Study
Training
Projects
Checklists
AI Rankings
Newsletter
Status
Tags
About
RSS Feed
Reading List
Subscribe

Stay in the Loop

Get the latest security alerts, tutorials, and tech insights delivered to your inbox.

Subscribe NowFree forever. No spam.
COSMICBYTEZLABS

Your trusted source for IT intelligence, cybersecurity insights, and hands-on technical guides.

429+ Articles
114+ Guides

CONTENT

  • Latest News
  • Security Alerts
  • HOWTOs
  • Projects
  • Exam Prep

RESOURCES

  • Search
  • Browse Tags
  • Newsletter Archive
  • Reading List
  • RSS Feed

COMPANY

  • About Us
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CosmicBytez Labs. All rights reserved.

System Status: Operational
  1. Home
  2. HOWTOs
  3. SentinelOne MSP Client Onboarding
SentinelOne MSP Client Onboarding
HOWTOAdvanced

SentinelOne MSP Client Onboarding

This runbook provides a standardized process for onboarding new MSP clients to SentinelOne Singularity Complete. Following this methodology ensures...

Dylan H.

Security Operations

February 11, 2026
27 min read

SCENARIO

This runbook provides a standardized process for onboarding new MSP clients to SentinelOne Singularity Complete. Following this methodology ensures consistent deployments, minimizes disruption to client operations, and establishes proper security baselines from day one.

Use this runbook when:

  • Onboarding a new managed services client
  • Migrating a client from another EDR/AV solution to SentinelOne
  • Upgrading a client from Control to Complete SKU
  • Re-deploying after a significant environment change
  • Standardizing an inconsistent existing deployment

Target Timeline: 2-4 weeks for full deployment (varies by client size)

Reference Documentation:

  • SentinelOne Seamless Onboarding Guide
  • SentinelOne GO Guided Onboarding
  • SentinelOne MSSP Partner Resources

REQUIREMENTS & ASSUMPTIONS

Prerequisites

MSP Console Access:

  • Global Admin or Account Admin role in multi-tenant console
  • Ability to create new Sites and Groups
  • API key with appropriate permissions (for automation)

Client Information Required:

InformationPurposeExample
Company nameSite naming"Contoso Ltd"
Primary contactNotifications & escalationsIT Manager
Endpoint countLicensing & planning150 endpoints
Endpoint typesPolicy planning120 workstations, 25 servers, 5 laptops
Current AV/EDRMigration planningSymantec Endpoint Protection
Domain structureDeployment methodSingle AD domain
RMM platformDeployment automationNinjaRMM
Critical applicationsExclusion planningQuickBooks, AutoCAD, custom LOB apps
Compliance requirementsPolicy configurationHIPAA, PCI-DSS
Business hoursDeployment schedulingM-F 8am-5pm CST

Technical Requirements:

  • Network access: HTTPS/443 outbound to *.sentinelone.net
  • Supported OS: Windows 10/11, Server 2016+, macOS 11+, Linux (RHEL, Ubuntu, etc.)
  • Minimum specs: 2GB RAM, 2GB disk space per endpoint
  • Local admin rights for installation (or RMM/GPO deployment)

Assumed Environment

  • Client has existing RMM agent (NinjaRMM, Datto, ConnectWise) for mass deployment
  • Client has Active Directory or Azure AD for group policy/Intune deployment
  • MSP has established change management process with client
  • SentinelOne Singularity Complete licensing is provisioned

PROCESS

Phase 1: Discovery & Planning (Days 1-3)

1.1 Conduct Client Discovery Call

Agenda Items:

  • Review endpoint inventory and types
  • Identify critical systems (servers, exec workstations, POS systems)
  • Document current security software installed
  • Identify line-of-business applications requiring exclusions
  • Discuss compliance requirements (HIPAA, PCI, SOC2, etc.)
  • Establish communication channels and escalation contacts
  • Define maintenance windows for deployment
  • Set expectations for pilot and full deployment timeline

Discovery Questions:

1. How many total endpoints need protection?
   - Windows workstations: ___
   - Windows servers: ___
   - macOS devices: ___
   - Linux servers: ___
 
2. What security software is currently installed?
   - Product name: ___
   - Managed or standalone: ___
   - Who manages removal: ___
 
3. What critical applications run in your environment?
   - ERP/Accounting: ___
   - Industry-specific: ___
   - Custom/LOB apps: ___
 
4. What compliance frameworks apply?
   - [ ] HIPAA
   - [ ] PCI-DSS
   - [ ] SOC2
   - [ ] NIST
   - [ ] Other: ___
 
5. Who are your pilot users? (2-5 users recommended)
   - Name/Department: ___
   - Endpoint type: ___
   - Technical proficiency: ___

1.2 Assess Current Security Posture

Run pre-deployment assessment on representative endpoints:

<#
.SYNOPSIS
    Pre-deployment assessment for SentinelOne onboarding
.DESCRIPTION
    Collects system information, identifies conflicting software, and validates requirements
#>
 
function Get-PreDeploymentAssessment {
    param(
        [string]$OutputPath = "C:\Temp\S1-PreDeployment-Assessment.json"
    )
 
    $assessment = @{
        Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
        ComputerName = $env:COMPUTERNAME
        SystemInfo = @{}
        SecuritySoftware = @()
        Requirements = @{}
        Recommendations = @()
    }
 
    # System Information
    $os = Get-CimInstance Win32_OperatingSystem
    $assessment.SystemInfo = @{
        OSName = $os.Caption
        OSVersion = $os.Version
        OSArchitecture = $os.OSArchitecture
        TotalMemoryGB = [math]::Round($os.TotalVisibleMemorySize / 1MB, 2)
        FreeMemoryGB = [math]::Round($os.FreePhysicalMemory / 1MB, 2)
        FreeDiskSpaceGB = [math]::Round((Get-PSDrive C).Free / 1GB, 2)
        LastBootTime = $os.LastBootUpTime
        Domain = (Get-CimInstance Win32_ComputerSystem).Domain
    }
 
    # Detect Security Software
    try {
        $avProducts = Get-CimInstance -Namespace "root\SecurityCenter2" -ClassName AntiVirusProduct -ErrorAction SilentlyContinue
        foreach ($av in $avProducts) {
            $assessment.SecuritySoftware += @{
                Name = $av.displayName
                State = $av.productState
                Path = $av.pathToSignedProductExe
            }
        }
    } catch {
        $assessment.SecuritySoftware += @{ Name = "Unable to query SecurityCenter2" }
    }
 
    # Check for known conflicting products
    $conflictingProducts = @(
        "McAfee*", "Symantec*", "Norton*", "Trend Micro*", "CrowdStrike*",
        "Carbon Black*", "Cylance*", "Sophos*", "ESET*", "Kaspersky*",
        "Webroot*", "Malwarebytes*", "Bitdefender*"
    )
 
    $installedSoftware = Get-CimInstance Win32_Product | Select-Object Name, Version
    foreach ($pattern in $conflictingProducts) {
        $matches = $installedSoftware | Where-Object { $_.Name -like $pattern }
        foreach ($match in $matches) {
            $assessment.Recommendations += "REMOVE: $($match.Name) v$($match.Version) - conflicts with SentinelOne"
        }
    }
 
    # Validate Requirements
    $assessment.Requirements = @{
        DiskSpaceOK = $assessment.SystemInfo.FreeDiskSpaceGB -ge 2
        MemoryOK = $assessment.SystemInfo.TotalMemoryGB -ge 2
        OSVersionOK = [version]$os.Version -ge [version]"10.0"
        Architecture64Bit = $os.OSArchitecture -eq "64-bit"
    }
 
    # Test connectivity to SentinelOne
    $connectivityTest = Test-NetConnection -ComputerName "management-prod.sentinelone.net" -Port 443 -WarningAction SilentlyContinue
    $assessment.Requirements.ConnectivityOK = $connectivityTest.TcpTestSucceeded
 
    # Add recommendations
    if (-not $assessment.Requirements.DiskSpaceOK) {
        $assessment.Recommendations += "WARNING: Less than 2GB free disk space"
    }
    if (-not $assessment.Requirements.MemoryOK) {
        $assessment.Recommendations += "WARNING: Less than 2GB RAM installed"
    }
    if (-not $assessment.Requirements.ConnectivityOK) {
        $assessment.Recommendations += "CRITICAL: Cannot reach SentinelOne management servers - check firewall/proxy"
    }
 
    # Check proxy configuration
    $proxySettings = netsh winhttp show proxy
    if ($proxySettings -match "Direct access") {
        $assessment.SystemInfo.ProxyConfigured = $false
    } else {
        $assessment.SystemInfo.ProxyConfigured = $true
        $assessment.SystemInfo.ProxySettings = $proxySettings
    }
 
    # Export results
    $assessment | ConvertTo-Json -Depth 5 | Out-File $OutputPath -Encoding UTF8
 
    # Summary output
    Write-Host "`n=== Pre-Deployment Assessment Summary ===" -ForegroundColor Cyan
    Write-Host "Computer: $($assessment.ComputerName)"
    Write-Host "OS: $($assessment.SystemInfo.OSName)"
    Write-Host "Memory: $($assessment.SystemInfo.TotalMemoryGB) GB"
    Write-Host "Free Disk: $($assessment.SystemInfo.FreeDiskSpaceGB) GB"
    Write-Host "Connectivity: $(if($assessment.Requirements.ConnectivityOK){'PASS'}else{'FAIL'})"
 
    if ($assessment.SecuritySoftware.Count -gt 0) {
        Write-Host "`nDetected Security Software:" -ForegroundColor Yellow
        $assessment.SecuritySoftware | ForEach-Object { Write-Host "  - $($_.Name)" }
    }
 
    if ($assessment.Recommendations.Count -gt 0) {
        Write-Host "`nRecommendations:" -ForegroundColor Yellow
        $assessment.Recommendations | ForEach-Object { Write-Host "  - $_" }
    }
 
    Write-Host "`nFull report saved to: $OutputPath" -ForegroundColor Green
    return $assessment
}
 
# Run assessment
Get-PreDeploymentAssessment

1.3 Design Console Hierarchy

Recommended MSP Hierarchy Structure:

Account (MSP Level)
└── Site: [Client Name]
    ├── Group: Workstations
    │   ├── Sub-group: Standard Users
    │   ├── Sub-group: Power Users
    │   └── Sub-group: Executives (VIP)
    ├── Group: Servers
    │   ├── Sub-group: Domain Controllers
    │   ├── Sub-group: File Servers
    │   ├── Sub-group: Application Servers
    │   └── Sub-group: Database Servers
    ├── Group: Remote/Laptops
    └── Group: Pilot (temporary)

Naming Convention:

  • Site: [ClientCode]-[ClientName] (e.g., CNT-Contoso)
  • Groups: Descriptive, matching client terminology
  • Tags: client:[code], type:[workstation|server], location:[site]

1.4 Plan Policy Configuration

Policy Inheritance Strategy:

Account Policy (MSP Baseline)
    ↓ inherits
Site Policy (Client-specific overrides)
    ↓ inherits
Group Policy (Endpoint type specific)

Recommended Policy Settings by Endpoint Type:

SettingWorkstationsServersExecutives
Engine ModeProtectProtectProtect
Mitigation ModeProtectProtectProtect
Anti-TamperEnabledEnabledEnabled
SnapshotsEnabledEnabledEnabled
Deep VisibilityEnabledEnabledEnabled
Network QuarantineEnabledDisabled*Enabled
Remote ShellDisabledEnabledDisabled
Scan on WriteEnabledEnabledEnabled
Cloud ValidationEnabledEnabledEnabled

*Network quarantine on servers may cause service disruption - evaluate per client


Phase 2: Console Configuration (Days 2-4)

2.1 Create Site and Groups

Via SentinelOne Console:

  1. Navigate to Settings → Sites
  2. Click Add Site
  3. Configure:
    • Name: [ClientCode]-[ClientName]
    • Description: Client full name and contract reference
    • Account: Select MSP account
    • SKU: Singularity Complete
  4. Click Save
  5. Copy the Site Token and store securely in password manager

Create Groups:

  1. Navigate to Sentinels → Groups
  2. Click Add Group
  3. For each group:
    • Name: Descriptive name (e.g., "Workstations - Standard")
    • Site: Select client site
    • Description: Purpose and assignment criteria
  4. Repeat for all planned groups

Via API (PowerShell):

# SentinelOne API - Create Site and Groups
$apiToken = "YOUR_API_TOKEN"
$consoleUrl = "https://yourtenant.sentinelone.net"
$headers = @{
    "Authorization" = "ApiToken $apiToken"
    "Content-Type" = "application/json"
}
 
# Create Site
$siteBody = @{
    data = @{
        name = "CNT-Contoso"
        description = "Contoso Ltd - Contract #12345"
        accountId = "YOUR_ACCOUNT_ID"
        sku = "complete"
        siteType = "Paid"
    }
} | ConvertTo-Json
 
$site = Invoke-RestMethod -Uri "$consoleUrl/web/api/v2.1/sites" -Method POST -Headers $headers -Body $siteBody
$siteId = $site.data.id
 
Write-Host "Created Site: $($site.data.name) (ID: $siteId)"
 
# Create Groups
$groups = @(
    @{ name = "Workstations"; description = "Standard workstations" },
    @{ name = "Servers"; description = "Production servers" },
    @{ name = "Remote-Laptops"; description = "Remote and mobile devices" },
    @{ name = "Pilot"; description = "Pilot deployment group" }
)
 
foreach ($group in $groups) {
    $groupBody = @{
        data = @{
            name = $group.name
            siteId = $siteId
            description = $group.description
        }
    } | ConvertTo-Json
 
    $newGroup = Invoke-RestMethod -Uri "$consoleUrl/web/api/v2.1/groups" -Method POST -Headers $headers -Body $groupBody
    Write-Host "Created Group: $($newGroup.data.name) (ID: $($newGroup.data.id))"
}

2.2 Configure Security Policies

Create Site Policy:

  1. Navigate to Settings → Policies
  2. Click New Policy
  3. Scope: Select client site
  4. Configure Agent Settings:
# Recommended Singularity Complete Policy Configuration
 
Agent Mode:
  Engine: Protect
  Mitigation: Protect
 
Detection Engines:
  Static AI: Enabled
  Behavioral AI: Enabled
  Documents & Scripts: Enabled
  Lateral Movement: Enabled
  Anti-Exploitation: Enabled
 
Automated Actions:
  Threats:
    - Kill: Enabled
    - Quarantine: Enabled
    - Remediate: Enabled
  Suspicious: Alert Only (initially)
 
Deep Visibility (Complete Feature):
  Collection: Full
  Data Retention: 14 days
  Process Tracking: Enabled
  Network Tracking: Enabled
  File Tracking: Enabled
 
STAR Custom Rules:
  Default Rules: Enabled
  Custom Rules: Per client requirements
 
Remote Shell (Complete Feature):
  Enable: Per group policy
  Require Approval: Enabled
  Session Timeout: 30 minutes
 
Network Controls:
  Firewall Control: Enabled
  Device Control: Enabled
  Network Quarantine: Configurable per group
 
Anti-Tamper:
  Protection: Enabled
  Password: Set unique per client (store in password manager)
 
Agent UI:
  Tray Icon: Show
  User Notifications: Enabled
  Allow Local Upgrade: Disabled

2.3 Configure Baseline Exclusions

Pre-configure common exclusions using the Exclusions Catalog:

  1. Navigate to Settings → Exclusions
  2. Click Exclusions Catalog
  3. Enable recommended exclusions for:
    • Microsoft Windows (built-in)
    • Microsoft Office
    • Microsoft SQL Server (if applicable)
    • Microsoft Exchange (if applicable)
    • Backup software (Veeam, Datto, etc.)
    • RMM agent (NinjaRMM, Datto RMM, etc.)

Client-Specific Exclusions Template:

# Document all exclusions with justification
 
Exclusion Request Form:
  Client: [Client Name]
  Requested By: [Name]
  Date: [Date]
 
Exclusions:
  - Path: C:\Program Files\[Application]\
    Type: Path
    Scope: Site
    Justification: [Business application - vendor recommendation]
    Vendor Doc: [Link to vendor KB article]
 
  - Hash: [SHA256]
    Type: Hash
    Scope: Site
    Justification: [Custom internal application]
    Reviewed By: [Analyst name]
    Review Date: [Date]

Common MSP Client Exclusions:

ApplicationExclusion TypePath/Process
QuickBooksPathC:\Program Files\Intuit\*
SagePathC:\Program Files\Sage\*
AutoCADPathC:\Program Files\Autodesk\*
SQL ServerPathC:\Program Files\Microsoft SQL Server\*
Backup ExecProcessberemote.exe, beserver.exe
VeeamPathC:\Program Files\Veeam\*
NinjaRMMProcessNinjaRMMAgent.exe

2.4 Configure Notifications and Integrations

Email Notifications:

  1. Navigate to Settings → Notifications
  2. Configure alerts for:
    • New threats detected (High/Critical)
    • Agent offline > 24 hours
    • Agent health issues
    • Policy changes
    • Unresolved threats > 1 hour

Recipients:

  • MSP SOC team distribution list
  • Client IT contact (optional - discuss with client)

SIEM/Syslog Integration (if applicable):

  1. Navigate to Settings → Integrations
  2. Configure Syslog forwarding:
    • Server: Client SIEM IP
    • Port: 514 (UDP) or 6514 (TCP/TLS)
    • Format: CEF or LEEF

NinjaRMM Integration:

Configure custom fields in NinjaRMM to receive SentinelOne status:

  • s1_agent_status
  • s1_agent_version
  • s1_protection_status
  • s1_console_connectivity
  • s1_last_threat_date

Phase 3: Pilot Deployment (Days 5-10)

3.1 Select Pilot Endpoints

Pilot Selection Criteria:

  • 3-5 endpoints representing different roles
  • Include at least one from each endpoint type (workstation, laptop, server)
  • Users who can provide constructive feedback
  • Non-critical systems (avoid exec assistants, finance during month-end)

Pilot Group Composition Example:

UserRoleEndpoint TypeReason
IT AdminTechnicalWorkstationCan identify technical issues
Sales RepStandardLaptopMobile worker, various networks
OperationsPower UserWorkstationHeavy application usage
Test ServerN/AServerValidate server policy

3.2 Remove Existing Security Software

Before SentinelOne installation, remove conflicting software:

<#
.SYNOPSIS
    Pre-deployment cleanup - removes conflicting security software
.DESCRIPTION
    Identifies and removes common AV/EDR products before SentinelOne deployment
#>
 
function Remove-ConflictingSecurity {
    param(
        [switch]$WhatIf
    )
 
    $removalTools = @{
        "McAfee" = @{
            Detection = "McAfee*"
            RemovalTool = "https://download.mcafee.com/molbin/iss-loc/SupportTools/MCPR/MCPR.exe"
            Instructions = "Run MCPR.exe with /silent switch"
        }
        "Symantec" = @{
            Detection = "Symantec*", "Norton*"
            RemovalTool = "CleanWipe utility from Symantec support"
            Instructions = "Download CleanWipe from Broadcom support portal"
        }
        "Trend Micro" = @{
            Detection = "Trend Micro*"
            RemovalTool = "Built-in uninstaller with password override"
            Instructions = "Use WFBS uninstall password or contact Trend support"
        }
        "CrowdStrike" = @{
            Detection = "CrowdStrike*"
            RemovalTool = "CsUninstallTool.exe"
            Instructions = "Requires maintenance token from CrowdStrike console"
        }
        "Sophos" = @{
            Detection = "Sophos*"
            RemovalTool = "Built-in uninstaller"
            Instructions = "May require tamper protection password"
        }
        "Webroot" = @{
            Detection = "Webroot*"
            RemovalTool = "wsasme.exe /uninstall"
            Instructions = "Requires removal password from Webroot console"
        }
    }
 
    Write-Host "Scanning for conflicting security software..." -ForegroundColor Cyan
 
    # Check installed products
    $installedProducts = Get-CimInstance Win32_Product |
        Where-Object { $_.Name -match "McAfee|Symantec|Norton|Trend|CrowdStrike|Sophos|Webroot|ESET|Kaspersky|Bitdefender|Malwarebytes" }
 
    # Check running services
    $securityServices = Get-Service |
        Where-Object { $_.DisplayName -match "McAfee|Symantec|Norton|Trend|CrowdStrike|Sophos|Webroot|ESET|Kaspersky|Bitdefender" }
 
    if ($installedProducts) {
        Write-Host "`nInstalled Security Products:" -ForegroundColor Yellow
        $installedProducts | ForEach-Object {
            Write-Host "  - $($_.Name) v$($_.Version)"
        }
    }
 
    if ($securityServices) {
        Write-Host "`nRunning Security Services:" -ForegroundColor Yellow
        $securityServices | ForEach-Object {
            Write-Host "  - $($_.DisplayName) [$($_.Status)]"
        }
    }
 
    if (-not $installedProducts -and -not $securityServices) {
        Write-Host "`n[PASS] No conflicting security software detected" -ForegroundColor Green
        return
    }
 
    if ($WhatIf) {
        Write-Host "`n[WHATIF] Would remove the above products" -ForegroundColor Cyan
        return
    }
 
    # Attempt removal
    foreach ($product in $installedProducts) {
        Write-Host "`nAttempting to remove: $($product.Name)" -ForegroundColor Yellow
 
        try {
            # Try standard MSI uninstall
            $result = $product.Uninstall()
            if ($result.ReturnValue -eq 0) {
                Write-Host "[SUCCESS] Removed $($product.Name)" -ForegroundColor Green
            } else {
                Write-Host "[WARNING] Standard uninstall returned code $($result.ReturnValue)" -ForegroundColor Yellow
                Write-Host "  Manual removal may be required - check vendor documentation"
            }
        } catch {
            Write-Host "[ERROR] Failed to remove: $($_.Exception.Message)" -ForegroundColor Red
            Write-Host "  Use vendor-specific removal tool"
        }
    }
 
    Write-Host "`n[INFO] Reboot recommended after security software removal" -ForegroundColor Cyan
}
 
# Run with -WhatIf first to preview
Remove-ConflictingSecurity -WhatIf
 
# Then run without -WhatIf to execute removal
# Remove-ConflictingSecurity

3.3 Deploy to Pilot Group

Deployment Method Selection:

MethodBest ForAutomation Level
Manual MSI1-5 endpoints, testingNone
RMM PushManaged endpointsHigh
GPODomain-joined, consistentHigh
IntuneAzure AD joined, modernHigh
SCCM/MECMEnterprise, existing infrastructureHigh

RMM Deployment (NinjaRMM Example):

  1. Upload SentinelOne MSI to NinjaRMM:

    • Navigate to Administration → Library → Software Repository
    • Upload SentinelInstaller_windows_64bit_vX.X.X.msi
  2. Create deployment script:

# NinjaRMM SentinelOne Deployment Script
# Deploy to: Pilot group devices
 
$installerPath = "C:\ProgramData\NinjaRMMAgent\SentinelInstaller.msi"
$siteToken = "YOUR_SITE_TOKEN_HERE"
$logPath = "C:\BIN\LOGS-$(Get-Date -Format 'yyyyMMdd')-SentinelOne-Install.log"
 
# Ensure log directory exists
New-Item -Path "C:\BIN" -ItemType Directory -Force -ErrorAction SilentlyContinue
 
# Check if already installed
$existingService = Get-Service -Name "SentinelAgent" -ErrorAction SilentlyContinue
if ($existingService -and $existingService.Status -eq "Running") {
    Write-Host "SentinelOne already installed and running"
    Ninja-Property-Set s1_agent_status "INSTALLED"
    exit 0
}
 
# Download installer from NinjaRMM repository (or use pre-staged path)
# This assumes installer is staged via NinjaRMM file distribution
 
# Install SentinelOne
$arguments = "/i `"$installerPath`" /qn SITE_TOKEN=`"$siteToken`" /l*v `"$logPath`""
$process = Start-Process msiexec.exe -ArgumentList $arguments -Wait -PassThru -NoNewWindow
 
# Wait for service to start
$maxWait = 120
$waited = 0
while ($waited -lt $maxWait) {
    $service = Get-Service -Name "SentinelAgent" -ErrorAction SilentlyContinue
    if ($service -and $service.Status -eq "Running") {
        Write-Host "SentinelOne installed successfully"
        Ninja-Property-Set s1_agent_status "HEALTHY"
        Ninja-Property-Set s1_install_date (Get-Date -Format "yyyy-MM-dd")
        exit 0
    }
    Start-Sleep -Seconds 5
    $waited += 5
}
 
# Installation failed
Write-Error "SentinelOne service failed to start"
Ninja-Property-Set s1_agent_status "INSTALL_FAILED"
exit 1
  1. Deploy to pilot devices:
    • Target pilot group/devices
    • Schedule during maintenance window
    • Monitor deployment status

3.4 Validate Pilot Deployment

Pilot Validation Checklist:

## Pilot Deployment Validation
 
Client: _______________
Date: _______________
Technician: _______________
 
### Console Verification
- [ ] All pilot agents appear in console
- [ ] Agents assigned to correct site
- [ ] Agents in correct groups
- [ ] Policy applied correctly (verify settings)
- [ ] Agent version matches expected
- [ ] All agents show "Connected" status
 
### Endpoint Verification (per device)
Device: _______________
- [ ] SentinelAgent service running
- [ ] System tray icon visible
- [ ] No user-reported issues
- [ ] Application compatibility verified
- [ ] Performance acceptable (no slowdown complaints)
- [ ] Network connectivity maintained
 
### Threat Detection Test
- [ ] EICAR test file detected and blocked
- [ ] Alert visible in console
- [ ] Threat auto-remediated (if configured)
- [ ] Notification received (if configured)
 
### Complete Features Validation (Singularity Complete)
- [ ] Deep Visibility data populating
- [ ] Process timeline visible
- [ ] Network connections logged
- [ ] Remote Shell accessible (if enabled)
- [ ] STAR rules active
 
### Issues Identified
1. _______________
2. _______________
3. _______________
 
### Exclusions Required
1. _______________
2. _______________
3. _______________
 
### Sign-off
Pilot Validated: [ ] Yes [ ] No - Issues to resolve
Ready for Full Deployment: [ ] Yes [ ] No

EICAR Test Procedure:

# Create EICAR test file to validate detection
# IMPORTANT: This is a harmless test file recognized by all AV products
 
$eicarString = 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*'
$testPath = "$env:USERPROFILE\Desktop\eicar-test.txt"
 
Write-Host "Creating EICAR test file..."
Write-Host "Expected behavior: SentinelOne should detect and block this file"
Write-Host ""
 
try {
    Set-Content -Path $testPath -Value $eicarString -ErrorAction Stop
    Write-Host "[WARNING] File was created - SentinelOne may not be protecting" -ForegroundColor Yellow
} catch {
    Write-Host "[SUCCESS] File creation blocked - SentinelOne is protecting" -ForegroundColor Green
}
 
# Check if file exists (should be quarantined immediately)
Start-Sleep -Seconds 2
if (Test-Path $testPath) {
    Write-Host "[WARNING] Test file still exists - check SentinelOne status" -ForegroundColor Yellow
    Remove-Item $testPath -Force -ErrorAction SilentlyContinue
} else {
    Write-Host "[SUCCESS] Test file was quarantined" -ForegroundColor Green
}

3.5 Pilot Feedback Collection

Collect feedback after 3-5 business days:

## Pilot User Feedback Form
 
User: _______________
Device: _______________
Pilot Duration: ___ days
 
### Performance
1. Have you noticed any slowdown since installation?
   [ ] No change [ ] Slight slowdown [ ] Significant slowdown
 
2. Application startup times:
   [ ] Same [ ] Slightly slower [ ] Much slower
 
3. Boot/login time:
   [ ] Same [ ] Slightly slower [ ] Much slower
 
### Compatibility
4. Any applications not working correctly?
   [ ] No [ ] Yes - List: _______________
 
5. Any error messages observed?
   [ ] No [ ] Yes - Details: _______________
 
### User Experience
6. Frequency of notifications:
   [ ] None [ ] Occasional [ ] Too many
 
7. Any disruption to your work?
   [ ] No [ ] Minor [ ] Significant
 
### Additional Comments
_______________________________________________

Phase 4: Full Deployment (Days 10-21)

4.1 Wave-Based Deployment Schedule

Recommended Deployment Waves:

WaveEndpointsTimelineDescription
1PilotDays 5-10Validation complete
2Standard Workstations (25%)Days 11-12Low-risk endpoints
3Standard Workstations (50%)Days 13-14Continue workstations
4Standard Workstations (remaining)Days 15-16Complete workstations
5Laptops/RemoteDays 17-18Mobile devices
6Non-Critical ServersDays 19-20File servers, print servers
7Critical ServersDay 21+Domain controllers, DB servers

Between Each Wave:

  • Validate deployment success
  • Review alerts for false positives
  • Add required exclusions
  • Collect user feedback
  • Address any issues before proceeding

4.2 Mass Deployment Script

<#
.SYNOPSIS
    Mass SentinelOne deployment orchestration script
.DESCRIPTION
    Deploys SentinelOne to multiple endpoints with progress tracking and error handling
.PARAMETER ComputerList
    Array of computer names or path to text file
.PARAMETER SiteToken
    SentinelOne site token
.PARAMETER WaveSize
    Number of concurrent deployments
#>
 
param(
    [Parameter(Mandatory=$true)]
    [string[]]$ComputerList,
 
    [Parameter(Mandatory=$true)]
    [string]$SiteToken,
 
    [Parameter(Mandatory=$true)]
    [string]$InstallerShare,
 
    [int]$WaveSize = 10,
 
    [string]$LogPath = "C:\BIN\LOGS-S1-MassDeployment-$(Get-Date -Format 'yyyyMMdd-HHmmss').csv"
)
 
# If ComputerList is a file path, read contents
if ($ComputerList.Count -eq 1 -and (Test-Path $ComputerList[0])) {
    $ComputerList = Get-Content $ComputerList[0]
}
 
Write-Host "=== SentinelOne Mass Deployment ===" -ForegroundColor Cyan
Write-Host "Target: $($ComputerList.Count) computers"
Write-Host "Wave Size: $WaveSize"
Write-Host "Installer: $InstallerShare"
Write-Host ""
 
$results = @()
$completed = 0
 
# Process in waves
for ($i = 0; $i -lt $ComputerList.Count; $i += $WaveSize) {
    $wave = $ComputerList[$i..([Math]::Min($i + $WaveSize - 1, $ComputerList.Count - 1))]
    $waveNumber = [Math]::Floor($i / $WaveSize) + 1
 
    Write-Host "`nWave $waveNumber - Deploying to $($wave.Count) computers..." -ForegroundColor Yellow
 
    $waveResults = $wave | ForEach-Object -ThrottleLimit $WaveSize -Parallel {
        $computer = $_
        $siteToken = $using:SiteToken
        $installerShare = $using:InstallerShare
 
        $result = [PSCustomObject]@{
            ComputerName = $computer
            StartTime = Get-Date
            EndTime = $null
            Status = "Pending"
            Message = ""
            ServiceRunning = $false
        }
 
        try {
            # Test connectivity
            if (-not (Test-Connection -ComputerName $computer -Count 1 -Quiet)) {
                $result.Status = "Offline"
                $result.Message = "Computer not reachable"
                return $result
            }
 
            # Check if already installed
            $service = Invoke-Command -ComputerName $computer -ScriptBlock {
                Get-Service -Name "SentinelAgent" -ErrorAction SilentlyContinue
            } -ErrorAction SilentlyContinue
 
            if ($service -and $service.Status -eq "Running") {
                $result.Status = "AlreadyInstalled"
                $result.Message = "Agent already running"
                $result.ServiceRunning = $true
                return $result
            }
 
            # Copy installer
            $remotePath = "\\$computer\C$\Temp\SentinelInstaller.msi"
            Copy-Item -Path $installerShare -Destination $remotePath -Force
 
            # Install remotely
            $installResult = Invoke-Command -ComputerName $computer -ScriptBlock {
                param($token)
 
                $process = Start-Process msiexec.exe -ArgumentList "/i C:\Temp\SentinelInstaller.msi /qn SITE_TOKEN=`"$token`" /l*v C:\Temp\S1-install.log" -Wait -PassThru -NoNewWindow
 
                # Wait for service
                $attempts = 0
                while ($attempts -lt 24) {
                    $svc = Get-Service -Name "SentinelAgent" -ErrorAction SilentlyContinue
                    if ($svc -and $svc.Status -eq "Running") {
                        return @{ Success = $true; ExitCode = $process.ExitCode }
                    }
                    Start-Sleep -Seconds 5
                    $attempts++
                }
                return @{ Success = $false; ExitCode = $process.ExitCode }
            } -ArgumentList $siteToken
 
            if ($installResult.Success) {
                $result.Status = "Success"
                $result.Message = "Installed successfully"
                $result.ServiceRunning = $true
            } else {
                $result.Status = "Failed"
                $result.Message = "Service not running after install (Exit: $($installResult.ExitCode))"
            }
 
            # Cleanup
            Remove-Item -Path $remotePath -Force -ErrorAction SilentlyContinue
 
        } catch {
            $result.Status = "Error"
            $result.Message = $_.Exception.Message
        }
 
        $result.EndTime = Get-Date
        return $result
    }
 
    $results += $waveResults
    $completed += $wave.Count
 
    # Display wave results
    $waveResults | ForEach-Object {
        $color = switch ($_.Status) {
            "Success" { "Green" }
            "AlreadyInstalled" { "Cyan" }
            "Failed" { "Red" }
            "Error" { "Red" }
            default { "Yellow" }
        }
        Write-Host "  $($_.ComputerName): $($_.Status) - $($_.Message)" -ForegroundColor $color
    }
 
    Write-Host "Progress: $completed / $($ComputerList.Count) ($([Math]::Round($completed/$ComputerList.Count*100))%)"
 
    # Brief pause between waves
    if ($i + $WaveSize -lt $ComputerList.Count) {
        Start-Sleep -Seconds 10
    }
}
 
# Export results
$results | Export-Csv -Path $LogPath -NoTypeInformation
 
# Summary
Write-Host "`n=== Deployment Summary ===" -ForegroundColor Cyan
Write-Host "Total: $($results.Count)"
Write-Host "Success: $(($results | Where-Object { $_.Status -eq 'Success' }).Count)" -ForegroundColor Green
Write-Host "Already Installed: $(($results | Where-Object { $_.Status -eq 'AlreadyInstalled' }).Count)" -ForegroundColor Cyan
Write-Host "Failed: $(($results | Where-Object { $_.Status -eq 'Failed' }).Count)" -ForegroundColor Red
Write-Host "Errors: $(($results | Where-Object { $_.Status -eq 'Error' }).Count)" -ForegroundColor Red
Write-Host "Offline: $(($results | Where-Object { $_.Status -eq 'Offline' }).Count)" -ForegroundColor Yellow
Write-Host "`nResults exported to: $LogPath"

4.3 Server Deployment Considerations

Pre-Deployment Server Checklist:

## Server Deployment Checklist
 
Server: _______________
Role: _______________
Criticality: [ ] Low [ ] Medium [ ] High [ ] Critical
 
### Pre-Deployment
- [ ] Maintenance window scheduled
- [ ] Change management approval obtained
- [ ] Backup verified (within last 24 hours)
- [ ] Rollback plan documented
- [ ] Stakeholders notified
 
### Server-Specific Exclusions
Application exclusions added:
- [ ] SQL Server (if applicable)
- [ ] Exchange Server (if applicable)
- [ ] IIS/Web applications (if applicable)
- [ ] Backup software (if applicable)
- [ ] Line-of-business applications
 
### Policy Configuration
- [ ] Network Quarantine: DISABLED (production servers)
- [ ] Remote Shell: ENABLED (for investigation)
- [ ] Scan exclusions for high-I/O paths
 
### Deployment
- [ ] Agent installed successfully
- [ ] Service running
- [ ] Console connectivity verified
- [ ] Assigned to correct group
- [ ] Policy applied correctly
 
### Post-Deployment Validation
- [ ] All services started normally
- [ ] Application functionality verified
- [ ] No excessive alerts generated
- [ ] Performance within acceptable range
- [ ] Monitoring systems show healthy
 
### Sign-off
Deployed By: _______________
Date/Time: _______________
Post-Deployment Check: [ ] Pass [ ] Fail

Phase 5: Post-Deployment (Ongoing)

5.1 Deployment Completion Verification

Final Validation Script:

<#
.SYNOPSIS
    Post-deployment validation for SentinelOne rollout
.DESCRIPTION
    Verifies all endpoints are protected and reports deployment status
#>
 
function Get-S1DeploymentStatus {
    param(
        [Parameter(Mandatory=$true)]
        [string]$ApiToken,
 
        [Parameter(Mandatory=$true)]
        [string]$ConsoleUrl,
 
        [Parameter(Mandatory=$true)]
        [string]$SiteId
    )
 
    $headers = @{
        "Authorization" = "ApiToken $ApiToken"
        "Content-Type" = "application/json"
    }
 
    # Get all agents for the site
    $agents = @()
    $cursor = $null
 
    do {
        $url = "$ConsoleUrl/web/api/v2.1/agents?siteIds=$SiteId&limit=1000"
        if ($cursor) { $url += "&cursor=$cursor" }
 
        $response = Invoke-RestMethod -Uri $url -Headers $headers -Method GET
        $agents += $response.data
        $cursor = $response.pagination.nextCursor
    } while ($cursor)
 
    Write-Host "=== SentinelOne Deployment Status ===" -ForegroundColor Cyan
    Write-Host "Site ID: $SiteId"
    Write-Host "Total Agents: $($agents.Count)"
    Write-Host ""
 
    # Status breakdown
    $statusGroups = $agents | Group-Object -Property isActive
    $connected = ($statusGroups | Where-Object { $_.Name -eq "True" }).Count
    $disconnected = ($statusGroups | Where-Object { $_.Name -eq "False" }).Count
 
    Write-Host "Connection Status:" -ForegroundColor Yellow
    Write-Host "  Connected: $connected" -ForegroundColor Green
    Write-Host "  Disconnected: $disconnected" -ForegroundColor $(if($disconnected -gt 0){"Red"}else{"Green"})
 
    # Protection status
    $protectionGroups = $agents | Group-Object -Property infected
    $clean = ($protectionGroups | Where-Object { $_.Name -eq "False" }).Count
    $infected = ($protectionGroups | Where-Object { $_.Name -eq "True" }).Count
 
    Write-Host "`nProtection Status:" -ForegroundColor Yellow
    Write-Host "  Clean: $clean" -ForegroundColor Green
    Write-Host "  Active Threats: $infected" -ForegroundColor $(if($infected -gt 0){"Red"}else{"Green"})
 
    # Agent versions
    Write-Host "`nAgent Versions:" -ForegroundColor Yellow
    $agents | Group-Object -Property agentVersion | Sort-Object Count -Descending | ForEach-Object {
        Write-Host "  $($_.Name): $($_.Count)"
    }
 
    # OS Distribution
    Write-Host "`nOS Distribution:" -ForegroundColor Yellow
    $agents | Group-Object -Property osName | Sort-Object Count -Descending | ForEach-Object {
        Write-Host "  $($_.Name): $($_.Count)"
    }
 
    # List disconnected agents
    if ($disconnected -gt 0) {
        Write-Host "`nDisconnected Agents (requires attention):" -ForegroundColor Red
        $agents | Where-Object { -not $_.isActive } | ForEach-Object {
            Write-Host "  - $($_.computerName) (Last seen: $($_.lastActiveDate))"
        }
    }
 
    # Return summary object
    return [PSCustomObject]@{
        TotalAgents = $agents.Count
        Connected = $connected
        Disconnected = $disconnected
        Clean = $clean
        ActiveThreats = $infected
        DeploymentComplete = ($disconnected -eq 0 -and $infected -eq 0)
    }
}
 
# Usage:
# $status = Get-S1DeploymentStatus -ApiToken "YOUR_TOKEN" -ConsoleUrl "https://tenant.sentinelone.net" -SiteId "SITE_ID"

5.2 Configure Ongoing Monitoring

NinjaRMM Health Check Integration:

Add the existing Check-SentinelOne-Health.ps1 script as a scheduled task in NinjaRMM:

  • Frequency: Every 4 hours
  • Alert on: s1_agent_status not equal to "HEALTHY"

Create SentinelOne Monitoring Dashboard:

Configure NinjaRMM dashboard widgets for:

  • Agent status distribution
  • Threat detection trends
  • Disconnected agents
  • Version compliance

5.3 Establish Ongoing Procedures

Weekly Tasks:

  • Review threat detections and ensure resolution
  • Check for disconnected agents
  • Review exclusion requests
  • Monitor Deep Visibility alerts

Monthly Tasks:

  • Review and tune policies
  • Audit exclusion list (remove unnecessary)
  • Check for agent updates
  • Generate client security report
  • Review STAR rule effectiveness

Quarterly Tasks:

  • Comprehensive policy review
  • Agent version standardization
  • Exclusion audit and cleanup
  • Client security posture presentation
  • Training refresh for SOC team

VERIFICATION

Deployment Success Criteria:

MetricTargetMeasurement
Agent Coverage100%All endpoints have agent installed
Agent Connectivity>98%Agents connected to console
Policy Compliance100%Correct policy applied to all agents
Version Currency>95%Running current GA version
Active Threats0No unresolved threats
False Positive Rate`<5%Minimal tuning required

Client Sign-Off Checklist:

## SentinelOne Deployment Sign-Off
 
Client: _______________
Deployment Date Range: _______________ to _______________
MSP Engineer: _______________
 
### Deployment Metrics
- Total endpoints deployed: ___
- Agent coverage: ___%
- Policy compliance: ___%
- Outstanding issues: ___
 
### Deliverables Completed
- [ ] All endpoints protected
- [ ] Policies configured per requirements
- [ ] Exclusions documented and applied
- [ ] Notifications configured
- [ ] Integration with RMM completed
- [ ] Client documentation provided
- [ ] Client contacts added to notifications (if requested)
 
### Training Provided
- [ ] Console navigation overview
- [ ] Threat response procedures
- [ ] Escalation process
 
### Outstanding Items
1. _______________
2. _______________
 
### Client Acceptance
I confirm that the SentinelOne deployment has been completed satisfactorily.
 
Client Signature: _______________
Date: _______________
 
MSP Signature: _______________
Date: _______________

TROUBLESHOOTING

Common Deployment Issues

Issue: Agent not appearing in console after installation

# Verify agent status locally
$sentinelCtl = Get-Item "C:\Program Files\SentinelOne\Sentinel Agent*\SentinelCtl.exe" | Select-Object -First 1
& $sentinelCtl.FullName status
 
# Check connectivity
$consoleHost = (Get-ItemProperty "HKLM:\SOFTWARE\SentinelOne\Sentinel Agent").ManagementServerUrl
Test-NetConnection -ComputerName ([Uri]$consoleHost).Host -Port 443
 
# Check for proxy issues
netsh winhttp show proxy
 
# Force reconnection
Restart-Service -Name "SentinelAgent" -Force

Issue: High CPU/Memory usage after installation

# Check if initial scan is running
& "C:\Program Files\SentinelOne\Sentinel Agent*\SentinelCtl.exe" is_scan_in_progress
 
# Review agent activity
& "C:\Program Files\SentinelOne\Sentinel Agent*\SentinelCtl.exe" create_agent_analyzer_report -o "C:\Temp\S1-analyzer.txt" -m 60
 
# Common cause: Initial scan and cloud verification
# Wait 30-60 minutes for initial activities to complete

Issue: Application blocked incorrectly (false positive)

  1. Identify the blocked file/process in console
  2. Navigate to Activity → Threats
  3. Find the detection and click for details
  4. If false positive:
    • Click Actions → Mark as Threat → False Positive
    • Create exclusion based on path, hash, or certificate
  5. Document exclusion with justification

Issue: Agent fails to install (Error 1603)

# Check installation log
$logPath = Get-ChildItem "C:\Temp" -Filter "*SentinelOne*Install*.log" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
Select-String -Path $logPath.FullName -Pattern "error|failed|return value 3" -Context 2,5
 
# Common causes:
# - Conflicting security software not fully removed
# - Insufficient disk space
# - Corrupted installer
# - Group Policy blocking installation

COMMANDS/SCRIPTS

Quick Reference Commands

# Check agent status
cd "C:\Program Files\SentinelOne\Sentinel Agent*"
.\SentinelCtl.exe status
 
# Check if scan is running
.\SentinelCtl.exe is_scan_in_progress
 
# Generate diagnostic report
.\SentinelCtl.exe create_agent_analyzer_report -o "C:\Temp\S1-diag.txt" -m 60
 
# Get agent UUID
.\SentinelCtl.exe uuid
 
# Check protection status
.\SentinelCtl.exe protection_status
 
# View agent log
Get-Content "C:\ProgramData\SentinelOne\Logs\Agent.log" -Tail 50
 
# Restart agent service
Restart-Service -Name "SentinelAgent" -Force
 
# Check agent version
(Get-Item "C:\Program Files\SentinelOne\Sentinel Agent*\SentinelAgent.exe").VersionInfo.FileVersion

API Quick Reference

# Set up API headers
$apiToken = "YOUR_API_TOKEN"
$consoleUrl = "https://yourtenant.sentinelone.net"
$headers = @{
    "Authorization" = "ApiToken $apiToken"
    "Content-Type" = "application/json"
}
 
# List all sites
Invoke-RestMethod -Uri "$consoleUrl/web/api/v2.1/sites" -Headers $headers
 
# List agents for a site
Invoke-RestMethod -Uri "$consoleUrl/web/api/v2.1/agents?siteIds=SITE_ID" -Headers $headers
 
# Get threat summary
Invoke-RestMethod -Uri "$consoleUrl/web/api/v2.1/threats?siteIds=SITE_ID" -Headers $headers
 
# Get Deep Visibility events (Complete feature)
Invoke-RestMethod -Uri "$consoleUrl/web/api/v2.1/dv/events?siteIds=SITE_ID&query=YOUR_QUERY" -Headers $headers

RELATED DOCUMENTATION

  • HOWTO- SentinelOne Deploy Agent Manual Installation
  • HOWTO- SentinelOne Deploy Agent via Group Policy
  • HOWTO- SentinelOne Create and Manage Exclusion Policies
  • HOWTO- SentinelOne Threat Investigation Workflow
  • HOWTO- SentinelOne PowerShell API Automation

REVISION HISTORY

VersionDateAuthorChanges
1.02026-01-08CosmicBytezInitial creation - Singularity Complete focus

Related Reading

  • SentinelOne Control vs Complete Feature Comparison
  • SentinelOne Policy Configuration Best Practices
  • SentinelOne Deep Visibility Threat Hunting
#sentinelone#edr#Security#threat-hunting#deployment#policy#automation#api#incident-response#detection-rules#device-control#firewall

Related Articles

SentinelOne Control vs Complete Feature Comparison

This document provides a comprehensive comparison between SentinelOne Singularity Control and Singularity Complete SKUs to help MSP teams understand the...

17 min read

SentinelOne Policy Configuration Best Practices

This guide provides comprehensive best practices for configuring SentinelOne policies in MSP environments managing multiple client sites with Singularity...

38 min read

SentinelOne Deep Visibility Threat Hunting

Deep Visibility is SentinelOne's EDR telemetry engine that provides comprehensive endpoint data collection for threat hunting, incident investigation, and...

22 min read
Back to all HOWTOs