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, Mode, legacy Enforcement, Sessions, and optional discovery settings — is written to the registry by the MSI. The MSI also registers device-local Scheduled Tasks that run scans (all real user profiles), assert hooks, and install managed AI Watch updates as 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, sessions, and managed updates.
Windows Home and S mode are not supported.

What you receive

The deployment package (aiwatch-<version>-intune-package.zip) contains: The scan, hook, and update 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 settings. Project and client-config detection is always available after installation; endpoint mode, Sessions, optional runtime discovery, managed updates, and scan tuning are controlled by the properties below. All values write to HKLM\Software\Runlayer\AIWatch\: Host, OrgApiKey, and Mode as REG_SZ; boolean and scan-tuning settings as REG_DWORD. The MDM Configuration setup wizard renders the full install command from the selected mode, Sessions setting, and scan settings. 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

Click Next.
4

Program

Use the install command rendered by the setup guide (SettingsMDM configurationAdd new). For Detect-only, use AIWATCH_MODE=monitor AIWATCH_ENFORCEMENT=0 AIWATCH_SESSIONS=0 and leave both AIWATCH_DETECT_* properties at 0. For a Monitor rollout, set AIWATCH_MODE=monitor and keep Sessions enabled. Managed self-update is on by default; add AIWATCH_AUTO_UPDATE=0 only when your organization needs to opt out.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), AIWatchScan, and AIWatchUpdate exist — so a wiped folder or isolated failure to register either mandatory task flips the app to not installed and Intune reinstalls, re-running the task-registration custom action. AIWatchHooks is intentionally optional. 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: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: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. It starts the scan and hook tasks once immediately; the update task waits about 67 minutes for its first trigger so it cannot overlap the MSI transaction that created it. All three live in a hidden, lock-down-secured \Runlayer Task Scheduler folder: 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 with protected permissions. The folder, AIWatchScan, and AIWatchHooks grant full control to SYSTEM and Administrators and read + execute to standard users. AIWatchUpdate and its transient installer handoff are stricter: only SYSTEM and Administrators have access, so a standard user cannot trigger the SYSTEM installer. The register custom action re-asserts these permissions on each MSI repair/upgrade, and if AIWatchScan or AIWatchUpdate is missing the recommended detect-install.ps1 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 (Protect, Enforce, or Sessions)

Also automatic. The AIWatchHooks task refreshes the linked backend settings and asserts hook configs hourly when Mode is Protect/Enforce or Sessions is enabled. It is a silent no-op for Monitor + Sessions disabled. To stop applying endpoint decisions, use SettingsMDM configurationManage settings and select Monitor; if Sessions stays enabled, hooks remain installed for telemetry. Re-push AIWATCH_MODE only when intentionally changing the registry fallback.

Verification

After devices sync with Intune (and, for Protect or Enforce, a user logon):
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. For updates, LastTaskResult = 0 on the parent task means the policy check completed or a detached handoff was accepted. It is not the final MSI result. Compare the installed Version with the expected backend target and inspect aiwatch-update.log after the handoff has had time to finish.

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. On scheduler-equipped devices, AIWatchUpdate performs that upgrade automatically: it creates and locks the Runlayer update directory, copies the backend-selected MSI into it, rehashes and verifies that staged file, and only then queues a one-shot SYSTEM install after the running updater exits. No API key or MSI property is put on the task command line; the MSI recovers existing tenant settings through its AppSearch chain.
The first automatic update cannot install its own scheduler. Devices on an older MSI need one manual Intune/MDM push to a version that includes AIWatchUpdate; subsequent updates are automatic unless AutoUpdate is 0.
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 mode, Sessions, and scan 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. Standard users have read + execute only for the \Runlayer folder, AIWatchScan, and AIWatchHooks, and no access to AIWatchUpdate or its transient handoff. Use an elevated session to inspect or change them.