ProxonProxon
Open Proxon
Documentation

Managed deployment on Windows

Push the Windows observer to a fleet with Intune, Group Policy, SCCM, or an RMM.

Push the Windows observer to a fleet with your device-management tool. Devices enroll with an enrollment token, and you attribute each one to a person by passing their email as USER_EMAIL.

Step 1: Turn on IT-managed distribution

Open Org Settings, then Data Collection, and choose IT-managed distribution. Onboarding asks the same question, so this is already set if you chose it there.

Step 2: Generate an enrollment token

Open Org Settings, then Devices, and choose Generate in the Enrollment tokens block. One token covers the whole fleet.

The token is shown once. Copy it before you close that dialog.

Step 3: Download the installer

Take ProxonObserver.msi from the tile below. You can also download from Org Settings, Data Collection.

Step 4: Run the silent install

Run the install with the token, pushed to each machine.

Silent install

bat
msiexec /i ProxonObserver.msi ENROLL_TOKEN=<token> /quiet /norestart

Replace <token> with the enrollment token you generated. To attribute the install to a specific person, add USER_EMAIL="ada@acme.com".

MSI properties

Property Detail
ENROLL_TOKEN Enrollment token, a secret. Required for a fleet push.
TENANT_ID Tenant or organization id, when the token does not already pin it.
USER_EMAIL The employee's email or UPN, for example ada@acme.com, to attribute the device to that person. Required for attribution on a fleet push - see How devices are attributed to people.
INGEST_URL Custom ingest endpoint. Omit to use the default.
UPDATE_CHANNEL Update track: stable, the default, beta, or canary. This is not a switch. To stop automatic updates, use the Disable automatic updates Group Policy instead.
POLICY_LOCK Set to 1 to lock enterprise mode so users cannot opt out.

Standard installer switches apply: /quiet, /qn, /norestart, /l*v install.log, and TRANSFORMS=.

Property names must be uppercase, and an empty value counts as absent, so the installer skips it rather than writing a blank.

How devices are attributed to people

Pass USER_EMAIL="ada@acme.com". It is sent as the enrollment's windows_upn, the backend maps that address to the person, and it is stored only in the admin-only enrollment.json, never the registry.

Pass USER_EMAIL on a fleet push. Without it the device still enrolls, holds its credential and captures normally, but it is attributed to nobody, and an unattributed device does not appear in the Live on Proxon view or against any person in Org Settings, Members - so a working rollout looks like a failed one.

This is a current limitation, not the intended behavior. The observer's service runs as the Windows SYSTEM account, which has no email of its own, so on a system-context install - which is what Intune, SCCM and an assigned GPO package all perform - it reports the computer's machine account rather than the signed-in employee. Automatic resolution of the signed-in user is being restored; until then USER_EMAIL is the supported way to attribute a device.

One thing that does not work around it: while its credential is healthy, an enterprise (token) install does not offer the tray sign-in wizard, so the employee cannot attribute the machine themselves.

Re-running the MSI with USER_EMAIL does not fix a device that already enrolled. The observer will not enroll a second time while it already holds a device credential, so the new value is written to disk and never sent. There are two paths that do work:

  • Set each device's owner in the console. An organisation owner or admin can do this with nothing to run on the machine, which makes it the quickest fix for a handful of devices. In Org Settings, open Devices, find the device under Enrolled devices, open the menu on its row, and choose Set owner. Search for the person by name or email, pick them, and choose Set owner to confirm. The row shows that person straight away, and the line under it about the last enrollment goes away. The people offered are those listed in Org Settings, Members, whether or not they have signed in to Proxon. This is one device at a time - there is no bulk action, so for a large fleet the scripted reset below may be less work. Remove owner, on the same menu, clears an owner that is wrong. An owner set this way stays until the device next enrolls with an address that resolves to a person; that person then replaces it.
  • Or reset the machine and re-push. On the device, run ProxonObserver.exe reset-enrollment from an Administrator shell, push the enrollment token again together with USER_EMAIL — the observer removes the token from enrollment.json once it has enrolled, so it has to be delivered a second time — then restart the ProxonObserver service.

Attribution is per machine, not per session. The enrollment that resolves a person binds the device, which suits a 1:1 laptop; a shared or kiosk machine cannot be split across the people who use it.

Push the .msi with the same properties through Intune, Group Policy, or SCCM, or run it from a NinjaOne script, or by hand on a single machine. Pick the channel your fleet already uses.

Microsoft Intune (Win32 app)

Intune does not assign a .msi directly. Wrap it with the Microsoft Win32 Content Prep Tool to produce an .intunewin package first.

  1. Download the Win32 Content Prep Tool and extract IntuneWinAppUtil.exe.

  2. Put ProxonObserver.msi in its own source folder, then run the prep tool against it:

    IntuneWinAppUtil.exe -c C:\IntunePkg\ProxonObserver -s ProxonObserver.msi -o C:\IntunePkg\Output
  3. In the Intune admin center go to Apps, Windows, Add, choose Windows app (Win32), and upload ProxonObserver.intunewin.

  4. Set the Install command to the silent-install command above, with your token, plus any other properties you need.

  5. Set the Uninstall command. Pass the enrollment token, since that is the one uninstall form valid in every device state. See Uninstall and retire a device below for why a bare /x is refused on an enterprise install. Intune runs this from the package it already extracted, so naming the .msi keeps it pointed at the version that package installs, which is only the installed version while the device is actually on it. A fleet mid-upgrade, or a machine that missed a release, is on a different build, and /x against the wrong package returns 1605. See Troubleshooting, Common failure modes below.

    msiexec /x ProxonObserver.msi ENROLL_TOKEN=<token> /quiet /norestart

This command carries a secret. Intune stores it in the app configuration, shows it to any admin who opens the app, and every device writes it to AppEnforce.log when it runs. The installer masks the token in its own log, but that is all it can do. It does nothing for the copies your management tool keeps. Treat the uninstall command as a secret and rotate the token if it is exposed.

  1. Add a Detection rule. Prefer MSI product code detection, since Intune reads the product code out of the package you upload, so it is right for the version you are deploying. The product code is per-version, not stable. The installer declares only an UpgradeCode and no ProductCode, so every build gets a fresh product GUID, and UpgradeCode is the identifier that survives upgrades. Upload the new package each release and Intune re-populates the rule for you. Anything you hard-code from a product code has to be re-pointed by hand. Only fall back to a file-exists rule on %PROGRAMFILES%\Proxon\app-X.Y.Z\ProxonObserver.exe, and if you do, substitute the version you are deploying for X.Y.Z and re-point the rule on every upgrade. Set Requirements to Windows 10 or 11, x64.
  2. Assign it to your target device groups. Devices install on their next check-in, roughly every 8 hours by default, or force a sync from Company Portal, Settings, Sync. Track rollout under Apps, ProxonObserver, Device install status.

Transforms: Intune's Win32 wrapper cannot pass TRANSFORMS= on the command line the way a shell can. Intune supports command-line properties natively, so put the properties in the install command, or, if you must ship an .mst, pre-apply it to the MSI and repackage the result.

The install command is visible to admins in the Intune portal. Rotate the enrollment token after rollout, or use a short-lived one, but rotate the uninstall command with it. An uninstall only authorizes a device that still holds the token on its command line, so a rotation leaves the configured uninstall unable to retire the fleet it was configured for until you re-provision those devices onto the new token. See Re-provision or deprovision a device below.

Group Policy (GPO)

Group Policy does two separate jobs here. It pushes the MSI, and it manages the observer's update policy.

Pushing the MSI

  1. Copy ProxonObserver.msi to a network share every target machine can read, for example \\fileserver\software\proxon\.
  2. Open the Group Policy Management Console with gpmc.msc and create or edit a GPO linked to the target OU.
  3. Go to Computer Configuration, Policies, Software Settings, Software installation, then right-click, New, Package.
  4. Browse to the MSI by UNC path. A mapped drive will not work.
  5. Deploy it as Assigned. Machines install on their next Group Policy refresh plus reboot.

An assigned package takes no command-line properties, so this is the one channel where ENROLL_TOKEN= cannot simply be typed in. Put the properties into an .mst transform, which Orca or InstEd both author, attach it under the package's Modifications tab, and keep it on the same share. To test the transform on one machine first:

bat
msiexec /i ProxonObserver.msi TRANSFORMS=acme-corp.mst /quiet

Managing update policy (ADMX)

You do not have to find or stage the administrative templates. The MSI already installs them on every machine, at %SystemRoot%\System32\PolicyDefinitions\Proxon.admx and %SystemRoot%\System32\PolicyDefinitions\en-US\Proxon.adml. The only manual step is copying that pair from one installed machine into your domain controller's SYSVOL PolicyDefinitions central store, with the .admx at the top level and the .adml in its en-US subfolder.

Once it is there, the Proxon policies appear in the Group Policy editor under Administrative Templates, Proxon. The Updates category is the one most fleets touch, covering update channel, pinned version, the deferral window, maximum deferral days, and disabling automatic updates altogether. The templates also ship a Devices category, which sets the Proxon backend a machine enrolls against, and an Enrollment category, which sets how long a silently enrolling device waits for someone to sign in so it is attributed to that person instead of to the computer account. Capture settings are not Group Policy settings: they come from your Proxon organization. Browse the editor for the current, complete list. Intune can consume the same templates through imported administrative templates.

SCCM and ConfigMgr

Create an application deployment and put the silent-install command above into the Installation program field. Properties and transforms behave exactly as they do on a command line, so nothing else is Proxon-specific.

Uninstall program

Put the token-bearing form in the Uninstall program field. It is the one uninstall valid in every device state, see Uninstall and retire a device below, and ConfigMgr runs it from the deployment type's own content, so naming the .msi keeps it matched to the version that deployment type installs:

bat
msiexec /x ProxonObserver.msi ENROLL_TOKEN=<token> /quiet /norestart

That only holds while the deployment type actually delivers content for the uninstall. On its Content tab, leave Uninstall content settings at Same as install content. Set it to No uninstall content and the uninstall command runs with no package folder, so there is no ProxonObserver.msi for it to name. As with Intune, the package matches only a device that is on that version, and a fleet mid-upgrade earns a 1605. See Troubleshooting, Common failure modes below.

The same secret handling applies as in Intune. ConfigMgr stores this command in the application model, and each device writes it to AppEnforce.log. Rotate the token if it is exposed, and re-provision any device whose configured uninstall still carries the old one.

Detection method

Use a Windows Installer clause matched on the MSI's product code, but that code is per-version. The installer declares an UpgradeCode and no ProductCode, so WiX generates a fresh product GUID on every build, and only UpgradeCode is stable across releases. Update the clause each release with the code the new build actually installed. Read it off an installed machine, where IdentifyingNumber is the product code:

powershell
Get-CimInstance Win32_Product -Filter "Name LIKE 'Proxon%'" | Select-Object Name, Version, IdentifyingNumber

A file-path clause pinned to app-X.Y.Z\ has the same problem for the same reason, so neither clause is set-and-forget.

NinjaOne

NinjaOne is RMM-first, not an MDM. It deploys by running a script on the endpoint rather than by pushing a managed package. There is no Proxon app to add. Create a script or automation that runs the same silent install, and let it run with administrator rights.

powershell
# Replace the lookup on the next line with your NinjaOne custom-field accessor before running this.
$token = <your NinjaOne custom-field lookup>
msiexec /i ProxonObserver.msi ENROLL_TOKEN="$token" /quiet /norestart

Read the token from a NinjaOne custom field instead of hard-coding it, so one script covers the whole fleet. Substitute whatever field lookup your Ninja instance uses. Attribution needs nothing extra here, since the observer auto-detects the signed-in user's UPN. Add USER_EMAIL from a per-device custom field only where that detection is weak.

Whatever NinjaOne records about the script it ran will contain the token, so treat the script as a secret and rotate the token here if that changes.

Manual install

For one machine or a pilot, double-click the .msi or run it with a basic progress bar and no prompts:

bat
msiexec /i ProxonObserver.msi /qb

No token? Install without one and have the person sign in through the browser device-code flow, which is the self-serve path and needs no enrollment token at all. To pre-enroll instead, add ENROLL_TOKEN=<token> and any other properties to the same command.

Uninstall and retire a device

A device installed with a token refuses a bare msiexec /x at every point in its life, not just part of it. Two things mark it enterprise: the enrollment token sitting in enrollment.json before it enrolls, and the durable marker the observer writes into that same file the moment it does. One or the other is present from install until the device is properly retired, so a plain msiexec /x is blocked throughout and msiexec returns 1603.

On a successful enrollment the observer clears the single-use token from the file and stamps enterprise_enrolled_at in its place. That marker is what carries the device's enterprise status across restarts. Until it existed a freshly enrolled machine read back as self-serve and any local administrator could retire it with a bare /x, and that gap is closed. The same refusal covers the two states that were always blocked: a device that never finished enrolling, and one whose enrollment.json cannot be read while the machine still registers as enterprise.

What this is. It stops the one-command removal: on an enrolled device msiexec /x on its own now fails, where before it succeeded. It is not a tamper-proof lock, and is not meant to be. An administrator can still remove the observer with FORCE_UNINSTALL=1 below, or by deleting enrollment.json, which the guard deliberately reads as self-serve so that a half-broken install can never become impossible to uninstall. Treat it as a deployment control that keeps a managed device managed, not as a guarantee against a local administrator who intends to remove it.

Devices enrolled before this release. The marker is written at enrollment, so a device that enrolled earlier gets one only if the observer can backfill it on its next start, and that needs both the device credential and a TENANT_ID recorded in enrollment.json. A fleet installed with only ENROLL_TOKEN, as the command above shows, has no tenant id recorded, so those devices are not backfilled and keep the old behavior, meaning a bare /x still retires them, until they re-enroll. Pass TENANT_ID at install, or re-enroll, if you need the block on an existing fleet.

Configure the token-bearing command in your MDM. It is the one form that works in every one of those states, so a command you set up once does not depend on which state a machine happens to be in when you retire it:

bat
msiexec /x ProxonObserver.msi ENROLL_TOKEN=<token> /quiet /norestart

The token has to match the one that device installed with, so a rotated token will not retire a device still holding the old one. Re-provision it first, see Re-provision or deprovision a device below. Once the device has enrolled there is no token left in enrollment.json to compare against, so the guard matches what you pass against the copy the MSI recorded at install time, which is why this command keeps working after enrollment. The command carries a secret, so whatever your management tool stores and logs, such as the Intune app configuration, the ConfigMgr application model, or AppEnforce.log on the device, will contain it.

Check the stored token before you rely on that command. A device that took an automatic update before this was fixed may have a blank stored token: the update ran as a token-less upgrade, which cleared the very copy the guard compares against, and nothing in the failing uninstall says so. Run proxon-observer show on the device, elevated, and read the Retirement Token line under Enrollment. It tells you which token, if any, will retire this device: the one it was installed with, the retained re-enrollment token instead, or neither, in which case retirement needs a manual restore or FORCE_UNINSTALL=1. It also calls out the case where the only token the device still holds contains characters the uninstall guard rejects, so no ENROLL_TOKEN can retire it at all. unknown means the check could not read the device's state, which is not the same as "no token", and usually means you ran it without elevation. proxon-observer show --json reports the same thing as enrollment.retirementAuthorization. It reports only which token applies; it never shows the value.

The one case that needs no manual step. If the device was deployed with a retained re-enrollment token, the optional reenroll_token an MDM can put in enrollment.json for headless recovery, the uninstall check will accept that token even though the installed-with copy is gone. Be precise about which token that is: the command that retires such a device is ENROLL_TOKEN=<retained re-enrollment token>, and the token it was originally installed with will not match. Nothing is copied anywhere to make this work; the retained token stays encrypted where it already lives and the check reads it there at uninstall time, so it is never exposed as a readable value on the device. Most fleets do not set reenroll_token at all, so for most affected devices the manual restore below is the route.

Restoring the value by hand. When the device holds no retained re-enrollment token and you still have the token it installed with, write it back directly and the token-bearing command works again:

bat
reg add "HKLM\SOFTWARE\Proxon" /v EnrollToken /t REG_SZ /d "<token>" /f

That command puts the token on a command line, so it lands in the shell's history and in whatever your management tool records. Prefer running it from a script your tooling already treats as sensitive, and clear the history afterwards on a machine other people can sign in to. An install pass that carries the token restores it too, and a fresh install always does; the direct write above is the one route that does not depend on which build the device is already on, which is why it is the one given here.

The override, when the matching token is unavailable:

bat
msiexec /x ProxonObserver.msi FORCE_UNINSTALL=1 /quiet /norestart

FORCE_UNINSTALL=1 bypasses policy, so keep it for one-off recovery, such as a lost token or a corrupted enrollment, not for fleet retirement.

Not available yet: the guard also accepts a .unenroll-authorized marker file on the device, valid for 7 days. Nothing writes that file today, so it is not a retirement path you can use, and it is not a way to avoid putting a token on the command line. The server side is not a substitute either. Deactivate, on the device's row under Org Settings, Devices, Enrolled devices, suspends the device so it stops reporting and cannot refresh its credential, but it does not authorize an uninstall on the machine.

A self-serve install, one done without a token, carries no enterprise policy and uninstalls with no authorization at all.

Re-provision or deprovision a device

Enrollment is sticky on purpose. Once a device enrolls it holds a machine credential, and the observer skips enrollment for as long as that credential is there. Re-imaging the box, handing it to a new person, or issuing it a new token does not re-enroll it on its own. There are two separate levers:

  • reset-enrollment clears the credential the device is already holding, which reopens the enrollment gate. It runs on the machine, needs no reinstall, and keeps enrollment.json, meaning the tenant, ingest URL, and update channel you deployed with. It re-enrolls the device on its own only while that file still holds an unused enrollment token. Enrolling consumes the token, so on a device that has already enrolled, the reset leaves it with neither a credential nor a token, and it stops reporting until you deliver a fresh token. The command tells you which case you are in. It also deletes the captured traffic the device had not uploaded yet, both the relayer's queue and the observer's own, so it cannot reach whichever organization the device joins next. Stop the Proxon service before the reset when the device is changing hands, since a running service keeps capturing until it restarts. It also discards the capture policy the device had saved from its organization. Until the organization answers again after re-enrolling, the device collects metadata only, and anything the organization had switched off stays off.
  • WRITE_ENROLLMENT_ON_UPGRADE=1 is an install-time property. It re-stamps that enrollment file on an install pass that would otherwise preserve it, which is how a new token, tenant, or ingest URL reaches the device at all.

On a device that has already enrolled, the property on its own changes nothing about enrollment, since the freshly stamped token sits unread behind the credential that is still there. Reset the credential, deliver the new config, and restart. On a machine that never enrolled, such as a self-serve install you are adopting into the fleet, the install property alone is enough.

Reset enrollment in place

Run in PowerShell as Administrator on the device. The first line finds the installed executable, since it lives in a per-version folder and there is no fixed path to type.

powershell
$exe = (Get-ChildItem "$env:ProgramW6432\Proxon\app-*\ProxonObserver.exe" | Sort-Object LastWriteTime | Select-Object -Last 1).FullName
if (-not $exe) { throw "ProxonObserver.exe not found under $env:ProgramW6432\Proxon\app-*. Is the observer installed?" }
& $exe reset-enrollment

On its own this only re-enrolls a device that never consumed its token. The reset reopens the enrollment gate, but the service still needs a token in enrollment.json to walk through it, and a successful enrollment clears that token. So on a device that has already enrolled, a plain reset takes it off reporting until you deliver a fresh token, see Re-stamp the enrollment config below, and restart. The command says which case it left you in, either that it still carries an enroll token so the service will re-enroll on its next start, or that there is no enroll token because it was already consumed, so you must deliver a fresh one.

It prints what it cleared and is safe to run twice, since the second run is a no-op. If it reports that it could not remove the credential, or could not discard the saved capture policy, it exits non-zero, but it does not stop there. It goes on to clear device-credentials.json and the relayer routing env anyway, so the device is left partly cleared with the enrollment gate still shut. Re-run it from an elevated shell rather than deleting the registry key by hand. The only path that aborts leaving the device untouched is a --purge that cannot delete enrollment.json, described below.

Nothing takes effect until the service restarts. The reset does not stop or start the service, and a running service keeps using the credential it already loaded, so it can still report at the old target. It keeps the capture policy it already loaded too, and the command warns when it finds the service running. Before handing a machine to another organization, stop the service, run the reset, then start the service. This is the step whose absence turns a reset into a support ticket:

powershell
Restart-Service ProxonObserver

Re-stamp the enrollment config

To rotate an enrollment token, or to move an already self-serve machine onto one without uninstalling first, re-run the install with WRITE_ENROLLMENT_ON_UPGRADE=1. That forces the enrollment file to be re-stamped instead of preserved.

bat
msiexec /i ProxonObserver.msi ENROLL_TOKEN=<token> WRITE_ENROLLMENT_ON_UPGRADE=1 /quiet /norestart

Values you do not pass are kept, so pass every property you want changed.

To rotate a live device onto a new token, run these on the machine in order: reset-enrollment, re-run the install with the new token, then restart the service. The reset has to come first, or the freshly stamped token sits unread behind the credential that is still there.

To switch the device off server-side as well, which is worth doing on a compromised or reassigned device, do it first, before the three local steps above, so it is off even if they are interrupted. In Org Settings, open Devices, find the device under Enrolled devices, open the menu on its row, and choose Deactivate. If you can manage devices, every row carries that menu, including devices your management tool pushed, Unattributed rows, and devices whose owner has no Proxon account.

Deactivate suspends the device and its credential. The device stops reporting and cannot refresh its credential, but the credential is not revoked, and Reactivate on the same row restores that same credential. Re-enrolling the device with a token also turns it back on, which is what the three local steps above do, so a rotated device comes back without a second trip to the console. For a device that may be compromised, finish the re-enroll, which replaces the credential, rather than choosing Reactivate.

These cases apply only to a device that sends its data directly rather than through the local Proxon relayer. If that device was given a shared enrollment token as its retained re-enrollment token, it can re-enroll itself and come back on while deactivated. If it stays deactivated for more than about an hour, it resumes reporting after Reactivate only once its service restarts. If it stayed deactivated for more than about 90 days, its credential has been cleaned up and Reactivate cannot restore it: reset its enrollment and re-enroll it with an enrollment token.

On such a device, service log lines reading Transient re-enrollment failure (HTTP 429), or Event ID 2004 reporting re-enrollment unreachable, can mean the device is deactivated in the console, or that its owner was deactivated, which suspends their devices too. After the device was deleted, the log shows HTTP 400 (token_exhausted): deleting it used up its recovery token, which is not a sign of a replayed token.

Deleting a device, or removing its owner from Members, is permanent whether or not the device reports through the relayer. A deleted device comes back only through the three local steps above, reset-enrollment and a fresh enrollment token, and restoring a deleted person does not bring their devices back.

Do not reach for Revoke here. The only Revoke on this page is in the Enrollment tokens block, and it revokes the shared enrollment token, which stops every device from enrolling with it, not one machine. Deactivate is the per-device action. It suspends one device, and it does not authorize an uninstall on the machine.

Deprovision a device

Run in PowerShell as Administrator, as above, since the verb clears machine-wide credential state and refuses to run from an unelevated shell whichever flags you pass.

Add --purge when the machine is being handed to someone else or decommissioned. It does everything the reset does and also deletes enrollment.json, which is where the enroll token and the USER_EMAIL you attributed the device with live. The device will not enroll again until a fresh enrollment file is delivered.

powershell
$exe = (Get-ChildItem "$env:ProgramW6432\Proxon\app-*\ProxonObserver.exe" | Sort-Object LastWriteTime | Select-Object -Last 1).FullName
if (-not $exe) { throw "ProxonObserver.exe not found under $env:ProgramW6432\Proxon\app-*. Is the observer installed?" }
& $exe reset-enrollment --purge

The purge deletes enrollment.json first and stops there if it cannot, since a locked file aborts the whole reset rather than reopening enrollment while a usable token and someone's email are still on disk. Stop the service to free the lock and re-run.

There is an uninstall counterpart, uninstall --deprovision, which performs the same wipe as part of the observer's own uninstall:

powershell
# On an MSI-deployed device use reset-enrollment --purge instead, since this verb deletes files Windows Installer owns.
$exe = (Get-ChildItem "$env:ProgramW6432\Proxon\app-*\ProxonObserver.exe" | Sort-Object LastWriteTime | Select-Object -Last 1).FullName
if (-not $exe) { throw "ProxonObserver.exe not found under $env:ProgramW6432\Proxon\app-*. Is the observer installed?" }
& $exe uninstall --deprovision

Two things it is not. It is not an authorization, since the uninstall guard described above runs only from the MSI, this flag never reaches it, and it decides exactly one thing, which is whether the machine credential is deleted. And it is not the msiexec path, since an MSI uninstall never deprovisions, and this verb removes the installed files that Windows Installer owns. On an MSI-deployed fleet, run reset-enrollment --purge while the observer is still installed, then retire the device with the uninstall command above.

Troubleshooting

Check the service

powershell
Get-Service ProxonObserver

Start type must be Automatic. The status may read Running or Stopped straight after a silent install, and both are healthy. The installer does not start the service inside the install transaction, since a slow start there used to roll the whole install back. It registers the service to start automatically and then kicks off a best-effort start, so on a busy machine the service comes up moments later, or at the next boot. A service still Stopped after a reboot is the real fault, so read the service log below.

Verify enrollment and attribution

Run this in PowerShell as Administrator, since the file is readable only by LocalSystem and Administrators, so an ordinary shell cannot open it.

powershell
Get-Content "$env:ProgramData\Proxon\enrollment.json"

Before a device enrolls, an enterprise install shows the token, tenant, and, if you passed it, user_email, which is what the device is attributed by. After it enrolls the token reads null and enterprise_enrolled_at is set instead: that is a healthy enrolled device, not a self-serve one. A self-serve install shows nulls throughout, which is correct for that path. The file lives at %PROGRAMDATA%\Proxon\enrollment.json and is readable only by LocalSystem and Administrators.

Read the service log

Run this in PowerShell as Administrator. The logs folder is readable only by LocalSystem and Administrators, so an ordinary shell gets Access Denied.

powershell
Get-Content "$env:ProgramData\Proxon\logs\service.log" -Tail 50

%PROGRAMDATA%\Proxon\logs\service.log is the observer's own log and the first place to look when the service installs but nothing ever reports. A script that runs as SYSTEM, which is how most management tools run one, reads it unchanged.

Upgrading a device from a build before the log folder was locked down deletes the older service logs, once, on that device. Later upgrades keep them, and only a full uninstall removes them. On a device you are investigating, collect a debug bundle first. It is redacted and safe to send to Proxon support, and it must be produced from an elevated shell or from the tray's Diagnostics screen: a bundle collected without elevation leaves the service log out. The verb is debug-bundle, run the same way as the commands above, which resolve the executable in its per-version folder. The bundle is written to %PROGRAMDATA%\Proxon\support.

The install itself failed

Check Event Viewer, Windows Logs, Application, for MsiInstaller errors, then re-run with verbose logging and search install.log for the failing custom action.

bat
msiexec /i ProxonObserver.msi ENROLL_TOKEN=<token> /l*v install.log /quiet

Verbose logs written before this fix contain your enrollment token in plain text, and masking is not retroactive. Any install.log still sitting on a device, anything already attached to a support ticket, and anything your management tool archived will have the token in the clear. Delete those logs, or rotate the token if you cannot account for where they went.

There is one case where a new log can still capture it: upgrading a device that was installed by a build from before this fix. An upgrade runs the old package's uninstall as part of the same operation and writes it to the same file, and that older package does not mask anything. So if you turn on /l*v while upgrading an affected fleet, treat the resulting logs as containing the token too.

Before sharing any log, search it for the token value first.

Common failure modes

  • enrollment.json missing after install: the MSI has to run elevated. Check the obvious impostor first, since Access Denied on the verify command above means your shell is not elevated, not that the file is missing or that the install needs re-running across the fleet. Re-read it from an elevated PowerShell before concluding anything. If it really is absent, check free space under %PROGRAMDATA% and whether antivirus quarantined files the installer wrote, then allow-list ProxonObserver.exe and %PROGRAMDATA%\Proxon\.
  • A property did not land: the installer ignores empty values, so ENROLL_TOKEN="" counts as absent, and lowercase property names are dropped by Windows Installer. Search install.log for the property name. ENROLL_TOKEN is masked, so you see ********** rather than the value. That is expected, not a failure: you are checking that the property arrived, not reading it back. To confirm the token itself landed, read it from the registry instead with Get-ItemProperty "HKLM:\SOFTWARE\Proxon" -Name EnrollToken.
  • Installed but never reports: the MSI does not validate the token or the endpoint, since that happens at first service start. Confirm the token is still active in the Enrollment tokens block, and that the machine can reach your ingest host on port 443.
  • Intune deployment stuck: the detection rule has to match the real install path, and the version in app-X.Y.Z\ changes on upgrade. Force a sync from the device, then read C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\IntuneManagementExtension.log on that machine.
  • The uninstall returns 1605, meaning the action is only valid for products that are currently installed. This is not the authorization block, which is 1603. It means the product you targeted is not the one on the machine. Every build gets a fresh product code, so a hard-coded GUID goes stale at the next release, and running msiexec /x ProxonObserver.msi against a different version's .msi fails the same way. Point it at the installed version's package, or read the installed product code with the command under SCCM and ConfigMgr, Detection method above.

Verify that enrolled devices appear in the Enrolled devices list.