Skip to main content
AI Watch deploys to Windows as a signed app (aiwatch.exe) installed once per device. Tenant config — host, a single organization API key, and the Enforcement / Sessions capability properties — is written to the registry by the MSI. The MSI also registers device-local Scheduled Tasks that run scans (all real user profiles) and assert hooks (SYSTEM) on a recurring schedule, so there are no Intune Remediations to create — this mirrors the macOS .pkg, which ships its own launchd jobs.

Prerequisites

  • Microsoft Intune admin with app upload rights. No Remediations (P2 / add-on) access required — scanning and hook assertion are scheduled device-locally by the MSI.
  • Devices running Windows 10 1809+ / 11, 64-bit, Microsoft Entra joined.
  • A single organization API key with the Shadow AI Scan role minted in Settings → Organization API keys (rl_org_...). The same key covers scanning, enforcement, and sessions.
Windows Home and S mode are not supported.

What you receive

The deployment package (aiwatch-<version>-intune-package.zip) contains:
FilePurpose
aiwatch-<version>-win-x64.intunewinApp package for Intune upload (installs aiwatch.exe + tenant registry and registers the device-local Scheduled Tasks)
custom-detection/detect-install.ps1Recommended detection rule — Intune custom detection script; reports installed only when aiwatch.exe (≥ packaged version) and the AIWatchScan task both exist (self-heals a wiped task folder; appends a diagnostic breadcrumb to C:\ProgramData\Runlayer\Logs\detect-install.log)
scripts/bootstrap.ps1Optional manual user-context one-shot (SCCM / GPO logon script) — not required for Intune
The scan + hook task scripts run inside the MSI (registered by its custom action); you don’t upload them to Intune. Contact your Runlayer account team if you don’t have the .zip yet.

Capability properties

The MSI install command carries tenant config and capability flags. Detect is always available after the app is installed; Enforce and Sessions are controlled by the optional properties below. All values write to HKLM\Software\Runlayer\AIWatch\ (Host / OrgApiKey as REG_SZ, Enforcement / Sessions / ProjectDepth / ProjectTimeout as REG_DWORD):
PropertyRequiredDefaultEffect
AIWATCH_HOSTYesNoneTenant host URL
AIWATCH_ORG_API_KEYYesNoneThe rl_org_... secret used for Detect scans, Enforce hooks, and Sessions telemetry
AIWATCH_ENFORCEMENTNo0Set 1 to install blocking hooks for unmanaged MCP sources and local tool policy checks
AIWATCH_SESSIONSNo1Set 0 to skip full event/session hooks; when both this and AIWATCH_ENFORCEMENT are 0, hook configs are removed while Detect scans continue
AIWATCH_PROJECT_DEPTHNo7Directory depth Detect scans walk under each user home (max 20; higher values are clamped, non-positive ignored)
AIWATCH_PROJECT_TIMEOUTNo60Per-scan time budget in seconds (max 300; higher values are clamped, non-positive ignored)
The MDM Configuration setup wizard renders the full install command from your capability toggles. Copy it before closing the dialog.

Phase 1 — Create the app

1

Open the Intune admin center

Go to intune.microsoft.comAppsWindowsAddWindows app (Win32).
2

Upload the package

Select the aiwatch-<version>-win-x64.intunewin file from the deployment package.
3

App information

FieldValue
NameRunlayer AI Watch
DescriptionRunlayer AI Watch agent for Shadow MCP detection and enforcement.
PublisherRunlayer Inc.
App VersionThe version from the deployment package (e.g. 1.0.0)
NotesstableAppId=com.runlayer.aiwatch
Click Next.
4

Program

FieldValue
Install commandmsiexec /i aiwatch-<version>-win-x64.msi /qn AIWATCH_HOST=https://<your-host>.runlayer.com AIWATCH_ORG_API_KEY=rl_org_... AIWATCH_ENFORCEMENT=1 AIWATCH_SESSIONS=1
Uninstall commandmsiexec /x aiwatch-<version>-win-x64.msi /qn
Install behaviorSystem
Device restart behaviorNo action
Use the install command rendered by the setup guide (SettingsMDM ConfigurationAdd new). For Detect-only, set AIWATCH_ENFORCEMENT=0 AIWATCH_SESSIONS=0. For a monitoring-only rollout, set AIWATCH_ENFORCEMENT=0.For full package, scheduled-task, and hook cleanup, see Remove AI Watch.Click Next.
5

Requirements

  • Operating system architecture: 64-bit
  • Minimum operating system: Windows 10 1809
Click Next.
6

Detection rules

Recommended — custom detection script (self-healing): choose Use a custom detection script and upload custom-detection/detect-install.ps1 from the deployment package. Set Run script in 64-bit PowerShell host to Yes and Enforce script signature check to Yes for CI-built releases (leave it No for an unsigned local build). It reports installed only when aiwatch.exe (≥ the packaged version) and the AIWatchScan scheduled task both exist — so if the task folder is ever wiped, the app flips to not installed and Intune reinstalls, re-running the task-registration custom action. This also drives Supersedence upgrades.The #1 cause of a false not installed — especially when the breadcrumb log shows installed: — is STDERR contamination: Intune treats any bytes on STDERR as not-installed even with non-empty STDOUT + exit 0, and PowerShell maps the Warning / Verbose / Progress / Debug / Information streams onto STDERR. The shipped script silences and redirects all non-output streams to prevent this; confirm it in C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\AgentExecutor.log (non-empty captured STDERR is the smoking gun). Once STDERR is ruled out, check the execution context: Install behavior = System (so detection runs as SYSTEM and can read the \Runlayer tasks), Run script as 64-bit (the task + exe live under 64-bit paths), and signature check matching the signed/unsigned build. Each run appends one line to C:\ProgramData\Runlayer\Logs\detect-install.log (running identity + which check failed) — read it on a device that detects as not installed to pinpoint the branch.Alternative — file version rule: select Manually configure detection rulesAdd:
FieldValue
Rule typeFile
PathC:\Program Files\Runlayer\AIWatch
File or folderaiwatch.exe
Detection methodFile version
OperatorGreater than or equal to
ValueThe version you are deploying (e.g. 1.0.0)
A file-version rule also supports Supersedence upgrades but won’t self-heal a wiped task folder.Click OKNext.
7

Dependencies and Supersedence

  • Dependencies: skip (none required).
  • Supersedence: skip on first deploy. For upgrades, see Upgrade path below.
Click Next.
8

Return codes

Keep the defaults. They match the values expected by the MSI installer:
CodeResult
0Success
1707Success
3010Soft reboot
1641Hard reboot
1618Retry
Click Next.
9

Assignments

Select target device groups under Required or Available for enrolled devicesReview + create.

Phase 2 — Scheduling (automatic)

There is no Phase 2 to configure. When the MSI installs, a deferred SYSTEM custom action registers the device-local Scheduled Tasks and runs them once immediately. They live in a hidden, lock-down-secured \Runlayer Task Scheduler folder:
TaskRuns asWhat it doesSchedule
AIWatchScanSYSTEMaiwatch.exe scan --all-users — enumerates every real user profile and scans each in its own child process (see below)At boot, any-user logon, every 15 min
AIWatchHooksSYSTEMaiwatch.exe setup hooks install --mdm to assert hook configs (Enforce / Sessions)At boot + hourly
A single SYSTEM AIWatchScan task does the per-user fan-out inside the binary (not the scheduler): it enumerates real user profiles from HKLM\...\ProfileList (local S-1-5-21-... and Microsoft Entra S-1-12-1-...) and scans each profile in its own child aiwatch.exe scan --username <user> process:
  • Logged on → the child is launched as that user (token drop), so it reads their own %APPDATA% MCP client configs. This works for Entra users too — the token comes from their live session.
  • Logged off → the child runs as SYSTEM with USERPROFILE / APPDATA / LOCALAPPDATA pointed at the profile’s home directory, so the scanner still reads that user’s tree. (The SYSTEM file walk is hardened against junction/symlink traversal.)
Each profile is scanned independently — one failure can’t abort the run. A logged-on user (incl. Entra) is scanned as themselves; a logged-off user who has signed in at least once is still covered (as SYSTEM); a brand-new user with no profile yet is picked up on the next tick.
This single SYSTEM task replaces the legacy per-user AIWatchScanManager + AIWatchScan-<SID> fan-out, which used -LogonType Interactive and could not map an Entra S-1-12-1 SID (0x80070534) — so Entra users silently never got a scan task. The register custom action removes any leftover legacy tasks on upgrade. Logged-off Entra trade-off: privilege-drop needs a live session token and S4U is local/AD-only, so a logged-off Entra user is scanned as SYSTEM (paths pointed at their profile) rather than as themselves — coverage is preserved, only the privilege-drop is unavailable for that subset.
Because scans are scheduled on the device (not by Intune), “did it run” is reported by backend device last-seen plus Task Scheduler’s LastTaskResult / event log — there is no per-run Intune Remediations dashboard row. This matches the macOS launchd model.

Tamper resistance

The \Runlayer task folder and every task are hidden and carry a protected permission set: full control for SYSTEM and Administrators, read + execute only for standard users. A standard user attempting to modify or delete a task gets Access is denied; the register custom action re-asserts the tasks and the folder lockdown on each MSI repair/upgrade, and if the whole folder is wiped the recommended detect-install.ps1 detection rule flips the app to not installed so Intune reinstalls. A local administrator can still remove or uninstall the agent — the same trust boundary as uninstalling any managed app.

Phase 3 — Hooks (Enforce or Sessions)

Also automatic. The AIWatchHooks task (registered by the MSI, SYSTEM context) asserts hook configs hourly when AIWATCH_ENFORCEMENT=1 or AIWATCH_SESSIONS=1, and is a silent no-op when both are 0 (Detect-only). To stop enforcing, re-push the app with AIWATCH_ENFORCEMENT=0; if Sessions stays enabled, hooks remain installed for monitoring-only telemetry and aiwatch hook stops blocking on its next fire.

Verification

After devices sync with Intune (and, for Enforce, a user logon):
# 1. App installed; registry has Host + OrgApiKey (+ Enforcement / Sessions)?
Get-ItemProperty "HKLM:\Software\Runlayer\AIWatch"

# 2. Scheduled Tasks registered? (hidden \Runlayer folder — expect AIWatchScan + AIWatchHooks)
Get-ScheduledTask -TaskPath "\Runlayer\" | Format-Table TaskName, State

# 3. The all-users scan task's last result, and per-profile outcomes?
Get-ScheduledTaskInfo -TaskPath "\Runlayer\" -TaskName "AIWatchScan" |
  Select-Object LastRunTime, LastTaskResult
# Orchestrator summary + per-profile result lines (all_users_*) land here:
Get-Content "C:\ProgramData\Runlayer\Logs\scheduled-task.log" -Tail 40
# Detailed per-profile child-scan output lives in each scanned user's profile:
#   C:\Users\<username>\.runlayer\logs

# 4. (Enforce or Sessions) hook configs current where supported?
& "C:\Program Files\Runlayer\AIWatch\aiwatch.exe" setup hooks check --mdm
# Expect exit 0.

# 5. (Enforce or Sessions) hook configs on disk?
Get-Content "C:\ProgramData\Cursor\hooks.json"
# Claude Code hooks currently live in the console user's settings.json:
Get-Content "$env:USERPROFILE\.claude\settings.json"
In the Runlayer dashboard, go to SettingsMDM Configuration and confirm Detect data is arriving (device last-seen advances each scan tick). There is no Intune Remediations dashboard row to check — task health is read from LastTaskResult / the Task Scheduler event log on the device.

Upgrade path

The MSI uses MajorUpgrade with RemoveExistingProducts before InstallFinalize — it uninstalls the old C:\Program Files\Runlayer\AIWatch\ tree then installs the new one. Registry values in HKLM\Software\Runlayer\AIWatch survive because they are owned by a separate component keyed on a registry value, not a file. The task-registration custom action re-runs on the upgrade install (re-asserting the \Runlayer tasks with the new scripts), and the unregister action is gated to a true uninstall so tasks are not torn down mid-upgrade.
1

Download the new package

Download the new aiwatch-<version>-intune-package.zip and extract the .intunewin.
2

Create a new app

Follow Phase 1 again. The install command must still include AIWATCH_HOST and AIWATCH_ORG_API_KEY (plus your capability properties) — re-writing the same registry values is a no-op, but the MSI requires both mandatory properties.
3

Set the detection rule + Supersedence

Set the detection rule to File version >= <new version>. On the new app’s Supersedence page, add the previous version and select Supersede, then assign to the same device groups. Retire the old app once the new one is assigned.

Troubleshooting

  • Ensure the device is Microsoft Entra joined (not just registered)
  • Check that the Intune Management Extension service is running
  • Verify the install command has the correct host and API key
  • Review logs in C:\ProgramData\Microsoft\IntuneManagementExtension\Logs
The install command is missing a mandatory property. Both AIWATCH_HOST and AIWATCH_ORG_API_KEY are required — the MSI’s launch conditions refuse a half-configured registry write. Re-run with both set.
  • The task-registration action gates on OrgApiKey. Confirm Get-ItemProperty "HKLM:\Software\Runlayer\AIWatch" shows OrgApiKey, then trigger an app repair/reinstall.
  • Check the task-registration lines (tagged [register]) in C:\ProgramData\Runlayer\Logs\scheduled-task.log.
  • A user who has never signed in has no profile yet, so they aren’t scanned until the next AIWatchScan tick (logon / boot / 15 min) after their first sign-in.
  • Verify the organization API key is correct and not revoked (SettingsOrganization API keys), and that the device can reach your Runlayer instance over HTTPS.
The single SYSTEM AIWatchScan task runs aiwatch.exe scan --all-users and scans each real profile in a child process. Check its LastTaskResult and tail C:\ProgramData\Runlayer\Logs\scheduled-task.log for the orchestrator summary (all_users_scan_complete) and per-profile lines (all_users_profile_scan_*) — a non-zero task result means at least one profile’s child scan failed, and the log names the SID/username. (The detailed per-profile child-scan output lands in each scanned user’s own profile at C:\Users\<username>\.runlayer\logs — the child scan’s USERPROFILE is pointed at that profile — not in scheduled-task.log.) Confirm the profile has a real ProfileImagePath under HKLM\...\ProfileList (local S-1-5-21-... / Entra S-1-12-1-...; service SIDs S-1-5-18/19/20 are skipped by design). A logged-off Entra user is scanned as SYSTEM (env-pointed at their profile), not privilege-dropped — expected and documented; they are scanned as themselves once logged on.
Expected. The \Runlayer folder and tasks are hidden and locked to SYSTEM + Administrators (full control) with read + execute only for standard users. Use an elevated session to inspect or change them.