From: Max Vilimpoc Date: Sat, 29 Aug 2026 16:43:11 +0000 (+0200) Subject: dotfiles: let a standard account collect ETW traces X-Git-Url: https://vilimpoc.org/repos/dotfiles/commitdiff_plain/99725a30bdb3eee44c38e1fd9a28c060341aa058?ds=inline;hp=99725a30bdb3eee44c38e1fd9a28c060341aa058 dotfiles: let a standard account collect ETW traces Windows Performance Analyzer is not a Visual Studio component -- VS's own Performance Profiler is a different, .diagsession-based tool that cannot open an .etl -- it ships with xperf and wpr in the Windows Performance Toolkit, either as an optional Windows SDK feature (OptionId.WindowsPerformanceToolkit) or inside the ADK, which bundles the same toolkit. The WPT step already installed it; it now detects the toolkit DIRECTORY rather than just xperf.exe, prints the version of each tool it found (wpa.exe included, since that is the one people come looking for), and re-asserts the machine PATH entry -- comparing with the trailing backslash trimmed, because the toolkit's own installer writes one and a second spelling of the same directory is just noise. Collection is the half that did not work for an ordinary account, and it fails in two distinct ways because two distinct things are missing: xperf -on base -> NT Kernel Logger: Access is denied. (0x5) wpr -start GeneralProfile -> Failed to enable the policy to profile system performance. Controlling ANY event tracing session -- a user-mode one naming a single provider included, which is the case that shows this is not only about the kernel -- is checked against the security descriptor ETW keeps per provider GUID, whose default grants the session-control rights to SYSTEM, Administrators, the service accounts and BUILTIN\Performance Log Users, and to nobody else. Switching on the kernel/system provider on top of that needs SeSystemProfilePrivilege, held by default only by Administrators and NT SERVICE\WdiServiceHost, and that is the one wpr names in its error. So grant the privilege to the GROUP and put the account in the group: membership alone becomes the switch, and enabling the next account is one net localgroup away with no policy edit. LsaAddAccountRights rather than a secedit round-trip -- it adds exactly one right to exactly one SID and is a no-op when already held, where secedit re-applies every user right on the box to fix one of them. SeDebugPrivilege is deliberately not granted: neither CPU sampling nor walking stacks in your own processes needs it, and it is equivalent to handing out administrator. setup-windows.bat passes -TraceUser across the UAC boundary. Accepting that prompt with an administrator's credentials runs the elevated half AS that administrator, so it cannot otherwise tell whose box this is. Two limits, both documented at the step and in the README. A privilege and a group membership are read into the access token at LOGON, so the account has to sign out and back in -- any new logon does, and an ssh login into the box is the quick way to check without dropping the desktop. And this only helps a NON-ADMIN account: UAC hands an administrator a filtered token keeping five harmless privileges, so an admin's ordinary shell still cannot trace however the policy reads. Analysis was never affected; wpa.exe opens an existing .etl as a plain user. Exercised under Windows PowerShell 5.1, which is what the batch file launches: the script parses, the LSA interop compiles under the in-box CodeDom compiler, the SID marshalling round-trips S-1-5-32-559, and LsaOpenPolicy fails cleanly with "Access is denied" from a non-elevated shell. Get-LocalGroup -SID resolves the localised group name, and the toolkit detection finds the SDK's WPT and correctly reports its PATH entry as already present. The grants themselves are unverified: they need an elevated run. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01YMh8i2QzkHNdE3MkKfcaT6 ---