Hardened Environments
This guide is for admins who run AppLocker, App Control for Business (WDAC), Microsoft Defender Attack Surface Reduction (ASR) rules, a restrictive PowerShell execution policy, or other allow-listing controls on their Windows devices. It lists every location the Pckgr agent writes to and runs from, which of those files carry a code signature, and the rules and exclusions to put in place before you enroll devices.
It covers the Windows agent only. The macOS agent installs signed PKGs and does not run scripts from a work folder in the same way.
How the Agent Runs
- The agent is the Windows service PckgrAgent, running as Local System from
C:\Program Files\Pckgr\Agent\pckgr-agent.exe. - Every script runs through Windows PowerShell 5.1 (
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe). From agent 1.1.38 it is started aspowershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -Command "& '<script>' <arguments>; if ($?) { exit 0 }; if ($null -eq $LASTEXITCODE) { exit 1 }; exit $LASTEXITCODE"; User-context script jobs and collectors wrap that line incmd.exe /c ... 1> <stdout file> 2> <stderr file>. Agents before 1.1.38 usepowershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File <script>(see the language mode section for why that changed). If you validate process chains, or have EDR or AppLocker rules keyed on the-Fileform, re-validate them against the-Commandform before updating the agent. PowerShell 7 is not used. - Apps and scripts set to the System context run as Local System. Those set to the User context run as the signed-in user, from the same folders. For a User-context job the agent grants the built-in Users group read and execute on that job's folder only. Users are never granted write access to anything the agent runs.
- The agent starts every Windows tool it needs (
msiexec.exe,schtasks.exe,shutdown.exe,cmd.exe,powershell.exe) by its full path underC:\Windows\System32. It never uses WMI or PsExec to create processes. - Every package is checked against a SHA-256 hash from the API before it is extracted, and every script is checked the same way before it is written to disk. A mismatch fails the job.
Programs
| Path | What it is | Runs as |
|---|---|---|
C:\Program Files\Pckgr\Agent\pckgr-agent.exe | The service. The same executable runs as the screen-capture helper for remote desktop (a child process, Local System, in the console session) and is run once by the installer to enroll the device. | Local System |
C:\Program Files\Pckgr\Agent\pckgr-toast.exe | Shows deployment toast notifications. | Signed-in user |
C:\Program Files\Pckgr\Agent\update-watchdog.ps1 | Recovery script for agent self-update. A one-shot scheduled task, PckgrAgentUpdateWatchdog, runs it about five minutes after an update starts and then removes itself. | Local System |
C:\Program Files\Pckgr\Agent\collector-runner.ps1 (agent 1.1.28 and later) | Runs every custom-field collector. It defines the Set-PckgrField helper, then runs your collector script from its own file, so your script is never modified. Earlier agents add the helper to the top of the collector file instead. | Local System, or the signed-in user for User-context collectors |
C:\Program Files\Pckgr\Self-Service Portal\pckgr-self-service.exe | The Self-Service Portal, started by users from the Start menu. The agent installs and updates it; the MSI does not. | Signed-in user |
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe with -NoLogo -NoProfile, started by the service through ConPTY | The Remote Shell feature: an interactive PowerShell an Owner or Admin opens from the portal, recorded and audited. Only runs while Remote Shell is enabled for the tenant and a session is open. | Local System |
The Self-Service Portal is a single-file application. On first launch it unpacks its WebView2 loader into %LOCALAPPDATA%\Temp\.net\pckgr-self-service\ and keeps its browser data in %LOCALAPPDATA%\Pckgr\SelfServicePortal\WebView2\. The agent and the toast helper unpack nothing at run time.
Data Folder: C:\ProgramData\Pckgr
The agent creates this folder at enrollment with an access list of Local System and Administrators (Full Control) only. Standard users cannot read, create or change anything in it unless a row below says otherwise. The folder is shared with Pckgr for Intune, which writes its own PckgrPrivate_*.txt transcripts there.
| Path | Contents | Executed from here? | Who has access |
|---|---|---|---|
device.json, enrollment-result.json | Encrypted device identity and the enrollment result | No | SYSTEM, Administrators |
Logs\ | agent.log (rotates to agent.1.log and agent.2.log at 10 MB), agent-update-<version>.log, agent-update-watchdog-<version>.log, update-watchdog.log, screen-capture-helper.log | No | SYSTEM, Administrators |
Cache\policies.json | Cached policy assignments | No | SYSTEM, Administrators |
Work\<JobId>\ | One folder per deployment or script job (contents below). Deleted when the job finishes. | Yes | SYSTEM, Administrators. Users read and execute on this folder for User-context jobs only |
Work\collector-<ScriptId>\ | collector.ps1 for a custom-field collector, written byte for byte as you saved it, with its output files | Yes | As above |
Work\agent-update\ | pckgr-agent-<version>.msi and the watchdog's state files during a self-update | Yes, by msiexec.exe | SYSTEM, Administrators |
Work\portal-update\ | pckgr-self-service-<version>.exe while it is being copied to Program Files | No | SYSTEM, Administrators |
Scripts\pckgr-detect-<id>.ps1 | Detection scripts for apps in both install contexts. Written before each run and deleted after it. (Agents before 1.1.28 write the System-context ones to C:\Windows\Temp instead; see below.) | Yes | SYSTEM, Administrators. Users read and execute |
Inside a deployment job folder, Work\<JobId>\:
| File or folder | Purpose |
|---|---|
package.zip | The downloaded package, hash-verified before extraction |
extracted\Deploy-Application.exe | The PSADT launcher the agent starts. It starts powershell.exe with Deploy-Application.ps1. |
extracted\Deploy-Application.ps1 | The deployment script |
extracted\PSAppDeployToolkit\ | The PSAppDeployToolkit 4 module: PSAppDeployToolkit.psd1, PSAppDeployToolkit.psm1 and the assemblies under lib\ |
extracted\PSAppDeployToolkit.Extensions\ | Pckgr's extension module (.psd1 and .psm1) |
extracted\Config\config.psd1, extracted\Strings\<culture>\strings.psd1 | Toolkit configuration and dialog text |
extracted\Files\, extracted\SupportFiles\ | The application's installer and support files, run by the deployment script |
pre-install.ps1, post-install.ps1 | Your pre-install and post-install scripts, when the app has them |
script.ps1 | The script of a script job |
exec-stdout.txt, exec-stderr.txt, agent.log, result.json, <JobId>.zip | Output, the job log and the log bundle uploaded to the portal |
When an app runs in Interactive mode, PSADT starts a client process from the package's PSAppDeployToolkit folder in the signed-in user's session to show its dialogs (close-apps prompts, deferrals, progress).
Temp and Log Locations Outside the Data Folder
| Path | Written by | Notes |
|---|---|---|
C:\Windows\Temp\pckgr-detect-<id>.ps1 | Detection scripts for System-context apps, on agents before 1.1.28 only | The service's temp folder. Each script is written before the run and deleted after it. From agent 1.1.28 these go to ProgramData\Pckgr\Scripts like the User-context ones. |
C:\Windows\Temp\ for System installs, the user's %TEMP% for User installs | PSADT's own temporary files | As configured in each package |
C:\Windows\Logs\Software\<App>_<version>_Install.log | PSADT install and uninstall logs | Also collected into the job's log bundle |
Registry
| Key | Purpose |
|---|---|
HKLM\SOFTWARE\Pckgr\Agent | The agent's own marker values, for example the organization name it applied to PSADT dialogs |
HKLM\SOFTWARE\Policies\PSAppDeployToolkit\Config\Toolkit | CompanyName, set from your organization name so install dialogs carry it |
HKLM\SOFTWARE\PSAppDeployToolkit | PSADT deferral history, when an app allows deferrals |
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System | SoftwareSASGeneration, set to allow services to send Ctrl+Alt+Del during a remote desktop session, when the value is not already configured |
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PckgrSelfServicePortal | The Programs and Features entry for the Self-Service Portal |
Policy keys under HKLM\SOFTWARE\Policies and HKCU | Written by the Policies feature for the settings you assign |
The agent also creates the Start menu shortcut C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Pckgr\Self-Service Portal.lnk, the named pipes PckgrSelfService (Self-Service Portal) and PckgrScreenCapture-<id> (remote desktop), and the scheduled task PckgrAgentUpdateWatchdog for the duration of a self-update.
Code Signing
Publisher rules need a signature on the file that actually runs. This is the state today:
| File | Signed by |
|---|---|
pckgr-agent-<version>.msi (the installer) | Pckgr Pty Ltd. |
pckgr-self-service.exe | Pckgr Pty Ltd. |
pckgr-agent.exe, pckgr-toast.exe, update-watchdog.ps1, collector-runner.ps1 as installed | Pckgr Pty Ltd., from agent 1.1.28. Installs of earlier versions carry no signature on these files (only the MSI itself was signed), so keep a path rule on C:\Program Files\Pckgr\ until your fleet has updated. |
Deploy-Application.ps1 | Pckgr Pty Ltd. |
Deploy-Application.exe, PSAppDeployToolkit\ (manifest, module and lib\ assemblies) | The PSAppDeployToolkit publisher (Patch My PC) |
Config\config.psd1, Strings\<culture>\strings.psd1, PSAppDeployToolkit.Extensions\ | Not signed |
pckgr-detect-<id>.ps1, collector.ps1, script.ps1, pre-install.ps1, post-install.ps1 | Never signed by Pckgr. These are your own scripts, or the catalog's detection script, written out at run time. The agent writes them byte for byte, so a script you sign with your own certificate keeps its signature on the device (see below). |
The path rules below are safe because none of the folders they cover can be written to by a standard user (see the access column above). That is the property AppLocker and WDAC path rules depend on.
Signing your own scripts
Scripts, collectors, pre-install and post-install scripts and custom detection scripts reach the device exactly as you saved them in the portal, and each runs from its own file. Sign them with your organization's code-signing certificate before pasting them in (for example with Set-AuthenticodeSignature), add a publisher rule for that certificate, and they run without a path rule. From agent 1.1.28 a collector keeps its signature too, because the Set-PckgrField helper comes from the signed runner installed with the agent rather than being added to your file; earlier agents modify the collector file and break its signature, so those still need the Work path rule. Two things still need the path rules on Work and Scripts: the catalog's own detection scripts, and the package configuration and extension files until they are signed.
AppLocker
Deploy these in Audit only mode first, enroll a pilot device, and switch to Enforce once the event log is clean.
If your policy keeps the default rule that lets the Administrators group run anything, System-context deployments and scripts are already allowed, because Local System holds that group. You then only need the rules below for User-context apps and scripts, and for the toast helper and Self-Service Portal, which run as the user.
Executable rules
| Path condition | Apply to | Covers |
|---|---|---|
%PROGRAMFILES%\Pckgr\* | Everyone | The service, the toast helper and the Self-Service Portal |
%OSDRIVE%\ProgramData\Pckgr\Work\* | Everyone, or SYSTEM plus the groups that receive User-context apps | Deploy-Application.exe, the PSADT client process shown in the user's session, and the application installers under Files\ |
Publisher rules can replace the second row: one for the PSAppDeployToolkit publisher, plus one per software vendor whose installers you deploy. The path rule is simpler and no less safe, because the Work folder is not writable by users.
Script rules
| Path condition | Apply to | Covers |
|---|---|---|
%OSDRIVE%\ProgramData\Pckgr\Work\* | Everyone | Deploy-Application.ps1, the PSADT module and extensions, the configuration and strings data files, pre-install and post-install scripts, script jobs and collectors |
%OSDRIVE%\ProgramData\Pckgr\Scripts\* | Everyone | Detection scripts for apps in both install contexts |
%PROGRAMFILES%\Pckgr\Agent\*.ps1 | Everyone | The self-update watchdog (runs as SYSTEM) and the collector runner (runs as SYSTEM or the signed-in user). A publisher rule for Pckgr Pty Ltd. replaces this from agent 1.1.28. |
%WINDIR%\Temp\pckgr-detect-*.ps1 | NT AUTHORITY\SYSTEM only | Only while agents older than 1.1.28 remain: their System-context detection scripts run from here. Scope this rule to SYSTEM: standard users can create files in C:\Windows\Temp, so a rule for Everyone would let them run their own script under that name. Remove it once the fleet has updated. |
Windows Installer rules
| Path condition | Apply to | Covers |
|---|---|---|
%OSDRIVE%\ProgramData\Pckgr\Work\* | Everyone | The agent's own update MSI in Work\agent-update\, and MSI-based applications run from Files\ |
A publisher rule for Pckgr Pty Ltd. covers the agent update MSI on its own; MSI-based applications still need the path rule or a rule per vendor.
DLL rules
Only if you enforce them: %OSDRIVE%\ProgramData\Pckgr\Work\* for the PSADT lib\ assemblies, and a publisher rule for Microsoft Corporation for the WebView2 loader the Self-Service Portal unpacks into the user's temp folder.
Finding what was blocked
Open Event Viewer and go to Applications and Services Logs, Microsoft, Windows, AppLocker. EXE and DLL logs events 8003 (would have been blocked, audit) and 8004 (blocked). MSI and Script logs 8006 and 8007. A blocked script also shows in the job's log bundle in the portal as a PowerShell error saying the file cannot be loaded because its operation is blocked by policy.
App Control for Business (WDAC)
- Allow the publishers Pckgr Pty Ltd., the PSAppDeployToolkit publisher and Microsoft for the signed files in the table above.
- Add file path rules for
C:\Program Files\Pckgr\*,C:\ProgramData\Pckgr\Work\*andC:\ProgramData\Pckgr\Scripts\*. WDAC accepts a path rule only for a location standard users cannot write to; all three qualify. - With script enforcement on, PowerShell runs a script that no rule allows in Constrained Language Mode instead of blocking it. PSADT and most collector scripts do not work in that mode, so the
Workrule is required for deployments and collectors to run at all. - Agents before 1.1.28 run System-context detection scripts from
C:\Windows\Temp, which a WDAC path rule cannot cover, so on those agents they run in Constrained Language Mode until the agent updates. Registry and file checks work there; a detection script that calls .NET methods or usesAdd-Typedoes not.
PowerShell Execution Policy and Language Mode
- For script execution, the agent passes
-ExecutionPolicy Bypass. A machine-scope Group Policy (Turn on Script Execution) overrides that switch. Allow only signed scripts (AllSigned) stops every unsigned file in the tables above, which includes every detection, collector and pre-install and post-install script. Use Allow local scripts and remote signed scripts (RemoteSigned), or leave the policy unconfigured. - When an authorized admin opens Remote Shell, the service starts interactive
powershell.exe -NoLogo -NoProfileorcmd.exe /Dthrough ConPTY, as SYSTEM in Session 0 or, when the admin chooses, in the signed-in user's session under that user's token. It does not pass an execution-policy override. Validate this process chain against your approved AppLocker, WDAC and EDR policies before enabling remote shell. - Files the agent downloads carry no Mark of the Web, so RemoteSigned treats them as local and runs them.
- Constrained Language Mode breaks PSADT. Scripts that an AppLocker or WDAC rule allows run in Full Language mode, so the rules above are what keep deployments working. Forcing Constrained Language Mode on the whole device through the
__PSLockdownPolicyenvironment variable is not supported. - From agent 1.1.38 the agent starts every script file (script jobs, detection scripts, collectors through the runner, and a package's PSADT entry script when it runs as a
.ps1) by calling it, not with PowerShell's-Fileswitch. That matters on these devices: when the session starts in Constrained Language Mode, Windows PowerShell refuses to run a script that uses[CmdletBinding()]through-Fileeven though a rule allows it, and the run ends before the script starts withCannot dot-source this command because it was defined in a different language mode. Earlier agents hit that for every User-context run of such a script under AppLocker, the collector runner included, so User-context collectors there need agent 1.1.38; under WDAC script enforcement, where the session starts constrained for SYSTEM as well, it affected both contexts. - The restart and shutdown notifications the agent shows before a device command use an inline PowerShell command in the user's session. Under Constrained Language Mode that notification does not appear; the command itself still runs.
Attack Surface Reduction Rules
| Rule | Effect on Pckgr | What to do |
|---|---|---|
Block executable files from running unless they meet a prevalence, age, or trusted list criterion (01443614-cd74-433a-b99e-2ecdc07bfc25) | Can block a newly released agent version, the Self-Service Portal, or a vendor installer inside a package on the day it ships | Exclude C:\Program Files\Pckgr\ and C:\ProgramData\Pckgr\Work\ |
Use advanced protection against ransomware (c1db55ab-c21a-4637-bb3f-a12568109d35) | The same class of false positive on new installers | The same exclusions |
Block execution of potentially obfuscated scripts (5beb7efe-fd9a-4556-801d-275e5ffc04cc) | Can flag your own scripts or collectors if they are minified or encoded | Keep scripts readable. Exclude C:\ProgramData\Pckgr\Work\ if one is flagged. |
Block process creations originating from PSExec and WMI commands (d1e49aac-8f56-4280-b9ba-993a6d77406c) | None. The agent creates processes directly. | Nothing |
| Block persistence through WMI event subscription | None. Self-update recovery uses a scheduled task. | Nothing |
| Block credential stealing from LSASS, the Office and email rules, the USB rule, vulnerable signed drivers, Safe Mode reboots, copied system tools, Webshell creation | None | Nothing |
ASR exclusions are set per folder or file in Intune under Endpoint security, Attack surface reduction, and apply to every rule. Controlled folder access does not affect the agent unless you add its folders to the protected list.
Microsoft Defender Antivirus and SmartScreen
No antivirus exclusion is required. If real-time scanning slows the extraction of large packages, C:\ProgramData\Pckgr\Work\ is the folder to exclude; every package in it has already been verified against the catalog's hash. SmartScreen never prompts: the agent downloads packages itself, so no file carries a Mark of the Web.
Network
| Destination | Port | Used for |
|---|---|---|
api.pckgr.com | 443 (HTTPS) | Check-ins, job claims and results, and remote shell recording uploads. The agent also holds a WebSocket to the same host for pushed check-ins and remote desktop and remote shell signaling. If WebSockets are blocked, polling continues unchanged; only immediate check-ins, remote desktop and remote shell are affected. |
*.blob.core.windows.net | 443 (HTTPS) | Package downloads, agent and Self-Service Portal updates, and log uploads, through short-lived links issued by the API |
stun.l.google.com, stun1 to stun4.l.google.com | 19302 (UDP) | Remote desktop connectivity checks. The API announces the servers to use; this is the default set. |
turn.cloudflare.com | 3478 (UDP and TCP), 5349 (TLS) | Remote desktop and remote shell relay when no direct path between the admin's browser and the device exists |
The agent has no proxy settings of its own. Connections are made by the Local System account, so a proxy must apply to that account or be transparent on the network. If you inspect TLS, the inspecting certificate authority must be trusted in the device's machine store.
Rolling It Out
- Put AppLocker or WDAC in audit mode with the rules above, and set any ASR exclusions.
- Enroll one pilot device. Deploy one System-context app and one User-context app, run one script and one collector, and open a remote desktop session if you use it.
- Review the AppLocker or WDAC event log and the job log bundles in the portal for anything blocked.
- Switch to enforce and roll out.
Related
- Installing the Agent for the data folder overview and uninstall behavior
- Platform Security for how packages, scripts and device identity are protected in transit and at rest
- Scripts and Custom Fields for what runs from the work folder