Lawliet LAWLIET
Book a demo

12. Install agents on Windows

This guide describes Lawliet 1.5.13.s (the current release). Screens, commands and procedures may change in later versions; the usage guide is updated with each release. Check the version your server runs under Settings > Platform or with ./lawliet version, and see the Releases page for what changed.

This chapter covers every way to put the agent on Windows hosts:

MethodSectionUse it when
Copy-paste command12.2You can open PowerShell on the host, and it can reach the server
Offline package (ZIP)12.3The host cannot download anything
Group Policy: MSI by Software installation12.5A domain; you want every computer of an OU to install at boot
Group Policy: MSI by computer startup script12.6A domain; you prefer a startup script to Software installation
Remote deployment over WinRM12.8 and chapter 13The server logs in to the hosts with an account

For what the agent does, read chapter 10 first.

12.1 Before you start#

RequirementDetail
Windows64-bit Windows (x64). The x64 agent also runs on Windows on ARM
PowerShellWindows PowerShell 5.1 (powershell.exe, built into Windows). With -CaCert the installer refuses PowerShell 7
AccountA local Administrator, in an elevated PowerShell ("Run as administrator")
NetworkOutbound from the host to the server: 443/tcp (HTTPS mode) or 8000/tcp (lab mode)
ClockWithin 1 minute of the server (w32tm /resync)
DiskAt least 200 MB free on C: (remote deployment warns under 1 GB)

What the installer creates:

ItemValue
Program folderC:\Program Files\Lawliet Agent (SYSTEM and Administrators full control, Users read)
Data folderC:\ProgramData\Lawliet (token, state, log; SYSTEM and Administrators only)
Scheduled task LawlietAgentRuns the agent as SYSTEM at startup
Scheduled task LawlietWatchdogChecks every 20 seconds and starts the agent again; restores the program from its known-good copy
LogC:\ProgramData\Lawliet\lawliet-agent.log

The agent is a scheduled task, not a Windows service. The console's step text says "Windows service"; the installer uses the two scheduled tasks above.

For a server with a self-signed certificate, export it on the server and copy it to each host, for example to C:\path\to\lawliet-server.pem:

sudo ./lawliet tls --export          # on the server; writes ./lawliet-server.pem

12.2 Procedure: install with the copy-paste command#

Required permission (console): Manage agents. Four-eyes: no.

Risk: installs a SYSTEM task on the host. Rollback: uninstall (12.9).

  1. Get the command:
    • Console: Environment > Hosts > Install agent > Install command > Windows, then the copy button. Keep Self-signed certificate ticked when the server's certificate is self-signed.
    • Server: sudo ./lawliet token, section "Windows (PowerShell, as Administrator)".
  2. For a self-signed server, copy lawliet-server.pem to C:\path\to\lawliet-server.pem on the host, or edit that path in the command.
  3. Open Windows PowerShell as Administrator and paste the command. It is one line, starting powershell -NoProfile -ExecutionPolicy Bypass -Command "& {...}".

You cannot type this command: it contains the SHA-256 of the installer the server serves. It downloads install.ps1 into a new random folder under your %TEMP%, runs it only if its SHA-256 matches, removes the folder and exits with the installer's status.

What you see: the installer checks the server, downloads lawliet-agent.exe, checks it against the SHA-256 the server sends, starts it once to test it, registers the two scheduled tasks and waits up to 90 seconds for enrolment. The host appears on Environment > Hosts.

If it fails:

MessageMeaning and fix
"Refused: install.ps1 is missing or is not the installer this server published. Nothing was run."The download failed or was changed. Check the address and that the host reaches the server
A certificate verdictExport the certificate again and check the -CaCert path (see chapter 10.9)
HTTP 409 (exit 3)An older record of this host exists. Remove it in the console; the agent then enrols by itself
HTTP 401 (exit 3)Wrong enrolment secret. Copy the command again

Notes:

12.3 Procedure: install from an offline package (ZIP)#

Required permission: Deploy agents remotely. Four-eyes: yes in the console.

  1. Make the package: Environment > Hosts > Install agent > Offline package, Target Windows x64, Package ZIP, installed by hand on each host. Then follow the same steps as for Linux: chapter 11.3.1. On the server instead:

    sudo ./lawliet agent-package --os windows --hosts 20 --days 3 --label "Branch office"
  2. On a trusted machine, compare the ZIP's SHA-256 with the value shown when it was made:

    Get-FileHash -Algorithm SHA256 .\lawliet-agent-windows-amd64-offline-12.zip
  3. On the host, in Windows PowerShell as Administrator:

    Expand-Archive .\lawliet-agent-windows-amd64-offline-12.zip -DestinationPath C:\LawlietPackage
    cd C:\LawlietPackage\lawliet-agent-windows-amd64
    powershell -NoProfile -ExecutionPolicy Bypass -File .\install_windows.ps1 -OfflinePackage .

What you see: "Package contents match its checksum list (SHA256SUMS).", then the install. Nothing is downloaded. A host that cannot reach the server yet is installed anyway and enrols later, while the code is valid. The scheduled task LawlietEnrolCleanup removes the code from config.env once the agent has enrolled, then deletes itself. To check (prints nothing when the code is gone):

Select-String -Path 'C:\Program Files\Lawliet Agent\config.env' -Pattern '^LAWLIET_REGISTRATION_SECRET=.'

Revoke the code when you are done (Install agent > Offline package > Enrolment codes > Revoke).

12.4 Group Policy: make the rollout package#

The Group Policy methods (12.5 and 12.6) use the Windows MSI for Group Policy: the agent MSI plus a transform (.mst) made for one rollout. The MSI holds no server, code or certificate, so it is the same file everywhere and can carry an Authenticode signature. The transform holds the server address, an enrolment code and, for a self-signed server, the certificate.

Required permission: Deploy agents remotely. Four-eyes: yes.

  1. Open Environment > Hosts > Install agent > Offline package.

  2. Target Windows x64, Package Windows MSI for Group Policy. (The option appears when the server carries the MSI.)

  3. Fill in:

    FieldWhat to enter
    LabelFor example "OU Workstations rollout"
    Valid for (days, at most 30)Default 30 for a rollout. A computer that first boots after the expiry installs the agent but is not enrolled
    Computers in the OU (at most 1000)How many computers may enrol. Every computer that installs uses one, a reinstalled one too
    Server address the hosts reachFilled in; change if needed
  4. Click Request package. A second administrator approves it (the approver reads "Group Policy rollout (Windows MSI + transform)").

  5. Click Check again, then Create package. Note the Package SHA-256 and download the ZIP (the link works once, for 15 minutes).

On the server instead (root, no second signature, audited as made through the CLI):

sudo ./lawliet agent-package --os windows --gpo --hosts 400 --label "OU Workstations"

The ZIP contains:

FileWhat it is
lawliet-agent-windows-amd64.msiThe agent MSI of this release
lawliet-rollout-<id>.mstThe transform with the enrolment code
README.txtThe SHA-256 of both files, the MSI product code, and the Group Policy steps
SHA256SUMSChecksums of the other files

Before deploying:

  1. Compare the ZIP's SHA-256 with the value shown (Get-FileHash -Algorithm SHA256 .\<file>.zip).
  2. Unpack it. If README.txt says the MSI is Authenticode-signed, check it: Get-AuthenticodeSignature .\lawliet-agent-windows-amd64.msi must say Valid.
  3. If your policy requires your own signature, sign the MSI (not the transform) with signtool before you add it to Group Policy. Its SHA-256 then changes; note the new one.

Where the enrolment code ends up (read this first)#

So: restrict the share, apply Security Filtering to the GPO before you add the package, and revoke the code when the rollout is done. The console reminds you while a rollout's code is active ("Group Policy rollout still active").

12.5 Procedure: Group Policy with Software installation (MSI)#

On a domain controller or an admin workstation with Group Policy Management (RSAT).

Risk: installs the agent as SYSTEM on every computer of the OU at its next boot. Rollback: remove the package from the GPO (below); for protected agents turn protection off first.

  1. Share. Copy the MSI and the .mst to a share every target computer reaches by UNC path, for example \\fileserver\LawlietDeploy$. Share and NTFS permissions: Read for Domain Computers, Full control for the admins who manage it, nothing for Authenticated Users or Everyone. A mapped drive letter or a local path does not work.
  2. GPO. Group Policy Management > the OU holding the computers > Create a GPO in this domain, and Link it here (for example "Lawliet Agent").
  3. Security Filtering (required). Select the GPO > Scope > Security Filtering:
    • remove Authenticated Users;
    • add a group of only the target computers (recommended), or Domain Computers (simplest, but then any computer of the domain can read the code).

    Then Delegation > Advanced: that group has Read and Apply group policy. Keep the default entries (Domain Admins, Enterprise Admins, ENTERPRISE DOMAIN CONTROLLERS, SYSTEM). Give Read to no one else. Check it: as an ordinary domain user, dir \\<domain>\SYSVOL\<domain>\Policies\{<GPO id>}\Machine must be refused.

  4. Edit the GPO. Computer Configuration > Policies > Software Settings > Software installation > right-click > New > Package. Give the UNC path of the MSI. Choose Advanced.
  5. Transform. In the properties: Modifications tab > Add > the UNC path of lawliet-rollout-<id>.mst. A transform can only be added now, not later. Deployment tab: Deployment type Assigned. OK.
  6. Recommended: Computer Configuration > Policies > Administrative Templates > System > Logon > Always wait for the network at computer startup and logon: Enabled.
  7. Restart a computer of the OU. gpupdate /force alone does not install software; Windows installs it during the next boot, before the logon screen.

What you see: the computer appears on Environment > Hosts. On the computer, gpresult /r /scope computer lists the GPO, and the Application event log has an event from source Lawliet Agent Setup (table below).

12.6 Procedure: Group Policy with a computer startup script#

The same rollout package, installed by a startup script instead of Software installation. The script only names the files on the share, so the enrolment code is not written into the GPO's SYSVOL folder; it is still in the .mst on the share. Apply the same share permissions and Security Filtering as in 12.5 (steps 1 to 3).

Risk and rollback: as 12.5.

  1. Do steps 1 to 3 of 12.5 (share, GPO, Security Filtering).

  2. Edit the GPO. Computer Configuration > Policies > Windows Settings > Scripts (Startup/Shutdown) > Startup > Properties > Add.

  3. Script Name: C:\Windows\System32\msiexec.exe Script Parameters (one line, your share and rollout id):

    /i \\fileserver\LawlietDeploy$\lawliet-agent-windows-amd64.msi TRANSFORMS=\\fileserver\LawlietDeploy$\lawliet-rollout-<id>.mst /qn
  4. OK, close the editor, and restart a computer of the OU.

The script runs at every boot as SYSTEM. On a computer where the agent is installed, running the MSI again changes nothing.

To test on one computer by hand first, as Administrator, with both files in the current folder:

msiexec /i lawliet-agent-windows-amd64.msi TRANSFORMS=lawliet-rollout-<id>.mst /qn

Do not add /l*v (verbose logging) unless support asks: a verbose Windows Installer log records the enrolment code. If you used it, delete the log afterwards.

12.7 MSI results, upgrades and removal#

Event log#

Application log, source Lawliet Agent Setup:

EventLevelMeaning
1000InformationInstalled and enrolled
1001InformationInstalled; not enrolled yet, keeps trying while the code is valid
1002WarningInstalled, but the server refused the enrolment (expired or used-up code, or 409: delete the old record)
1003InformationA newer agent was already installed; it was kept
1004InformationThe cached transform copies are restricted to SYSTEM and Administrators
1100ErrorNot installed; the reason is in the event
1101ErrorThe MSI was run without the transform on a computer with no enrolled agent
1104WarningThe cached transform could not be restricted yet; retried
2000InformationRemoved
2001ErrorNot removed: the agent is protected and no valid authorisation was given
2100ErrorRemoval failed

msiexec exit codes#

CodeMeaning
0Done
1603The Lawliet action failed (events 1100, 1101, 2001, 2100); nothing changed
1624The transform could not be read (wrong path, or the computer account cannot read the share)
1618Another installation was running; Group Policy retries at the next boot
1638Another version is installed; use an upgrade

Upgrade#

The agent keeps its identity and history. An older MSI than the installed one is refused.

Removal#

The MSI removes the agent only when the agent accepts the removal (self-protection):

Then remove the host in the console (chapter 10.7).

What you see: msiexec exit code 0 and an Application event from Lawliet Agent Setup (see the tables above); the host goes offline in the console.

12.8 Preparing hosts for remote deployment over WinRM#

Remote deployment (chapter 13) logs in to Windows hosts over WinRM. The host needs a listener, a firewall rule and an administrator account.

Account#

In PowerShell as Administrator on the host:

  1. See the listeners. If WinRM is not running, start it with Enable-PSRemoting -SkipNetworkProfileCheck -Force first.

    winrm enumerate winrm/config/listener
  2. With AD Certificate Services: let the computers get a computer certificate by auto-enrolment, then on each host:

    winrm quickconfig -transport:https

    Paste your AD CS root (and any intermediate) certificate as WinRM server CA on the credential in the console.

  3. Without AD CS: a self-signed certificate per host. Set $ip to the address you will enter in Lawliet:

    $ip = '<host IP>'
    $c = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -Subject "CN=$env:COMPUTERNAME" -TextExtension @("2.5.29.17={text}IPAddress=$ip&DNS=$env:COMPUTERNAME") -NotAfter (Get-Date).AddYears(3)
    New-Item -Path WSMan:\localhost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $c.Thumbprint -Force
    New-NetFirewallRule -DisplayName "WinRM HTTPS 5986" -Direction Inbound -Protocol TCP -LocalPort 5986 -Action Allow -RemoteAddress <Lawliet server address>
    Export-Certificate -Cert $c -FilePath "$env:TEMP\winrm.cer"
    certutil -f -encode "$env:TEMP\winrm.cer" "$env:TEMP\winrm.pem"
    Get-Content "$env:TEMP\winrm.pem"

    Paste the printed PEM as WinRM server CA on the credential. For several hosts, paste their PEMs one after another in the same field.

The certificate must name the host as you enter it in Lawliet (its DNS name or its address).

WinRM over plain HTTP on 5985 (insecure)#

winrm quickconfig alone creates only an HTTP listener on 5985. When agents are needed before HTTPS listeners exist, a credential can use WinRM connection: HTTP 5985 (insecure).

Warning. This is not protected by TLS. With Kerberos the messages are encrypted by Kerberos and the host proves its identity. With NTLM the login can be captured and cracked offline, or relayed, and the host's identity is not verified. Use it only on a trusted network, temporarily, then switch back to HTTPS or use Group Policy (12.5).

What Lawliet always does on HTTP: every message is encrypted with the login's session key; Basic authentication and unencrypted sessions are never used; client-certificate credentials cannot use HTTP. Creating or switching a credential to HTTP needs a second administrator. While a credential uses HTTP, the review queue shows "Insecure WinRM in use - switch back to HTTPS".

Risk: as in the warning above. Rollback: switch the credential back to HTTPS (13.7) and remove the HTTP listener when it is no longer needed.

  1. On the host, as Administrator, run winrm quickconfig (creates the HTTP listener on 5985) and allow TCP 5985 from the Lawliet server only in the host firewall.
  2. In the console, add or edit the credential with WinRM connection: HTTP 5985 (insecure) (13.2) and have it approved.
  3. Test it against the host (13.3). What you see: the checklist passes; the credential shows the insecure chip and the review queue shows "Insecure WinRM in use - switch back to HTTPS".
  4. Deploy, then switch back to HTTPS as soon as listeners exist.

Kerberos (for domains that restrict NTLM)#

A WinRM password credential logs in with Kerberos when the account's domain is listed under Kerberos realms in the console (chapter 13.4). Requirements:

12.9 Procedure: uninstall the agent#

Risk: the host stops being monitored. Rollback: install it again.

  1. If the agent is protected, get an uninstall code: Environment > Hosts > the host > Self-protection > Issue uninstall code (four-eyes; valid 1 hour, this host only).

  2. A host installed by the MSI: remove it as in 12.7.

  3. Any other host: in Windows PowerShell as Administrator, run the installer the server serves (agents\install_windows.ps1 from the bundle):

    powershell -NoProfile -ExecutionPolicy Bypass -File .\install_windows.ps1 -Uninstall
    powershell -NoProfile -ExecutionPolicy Bypass -File .\install_windows.ps1 -Uninstall -Code '<code>'   # protected agent
  4. Remove the host in the console.

What you see: "Lawliet agent removed from this host. Remove it in the console too ...".

If it fails: "This agent is protected. Removing it needs an authorization code from the console ..." - issue a code for this host and run again.

12.10 Installer parameters (install_windows.ps1)#

Add the parameters to the command from 12.2 (or 12.3) and run it in an elevated PowerShell. What you see: the installer prints each step and ends with the agent running; the host appears in Environment > Hosts.

ParameterPurpose
-Server URLServer address
-Token SECRETEnrolment secret
-Name NAMEName shown in the console (default: computer name)
-CaCert PATHTrust and pin this server certificate (self-signed server)
-Sha256 HASHCheck the agent against a hash you got separately
-LocalBinary PATHInstall this lawliet-agent-windows-amd64.exe; needs -Sha256
-OfflinePackage PATHInstall from an offline package (ZIP or unpacked folder)
-PythonInstall the Python fallback agent
-UninstallRemove the agent
-Code CODEWith -Uninstall: an uninstall code for a protected agent
-RecoveryKey KEYWith -Uninstall: the installation's recovery key
-RefreshCaWith -CaCert: give the installed agent a new server certificate
-InsecureAllow a plain-HTTP server. Lab only

Managing the agent on the host:

Get-ScheduledTaskInfo -TaskName LawlietAgent                              # last and next run, last result
Get-Content "$env:PROGRAMDATA\Lawliet\lawliet-agent.log" -Tail 50 -Wait  # live log
Stop-ScheduledTask -TaskName LawlietAgent; Start-ScheduledTask -TaskName LawlietAgent   # restart

Run these in an elevated PowerShell. With self-protection on, the watchdog starts a stopped agent again within 20 seconds; turn protection off in the console first if you need it stopped (chapter 16). To repair a damaged installation, run the installer again with the same command (12.2 or 12.3): it upgrades in place and keeps the host's identity.

More detail: Windows Group Policy reference, offline packages and remote deployment reference.