Collect Windows event logs in Logsign without installing an agent, using Windows' built-in Event Forwarding mechanism. Only the user interface on the Logsign side, PowerShell on the Windows side.
Screenshots come from a sample environment; machine names, IP addresses, definition names and the CA name will differ in yours. Replace the
<angle-bracket>placeholders in the text with your own values. Field and button names are written exactly as they appear in the product interface.
Purpose
Collect the event logs of Windows machines (Security, Application, System, Sysmon, PowerShell…) centrally in Logsign without installing any agent, using Windows' built-in Event Forwarding (WEF) mechanism.
This document describes two setup paths. Both are completed entirely through the user interface and PowerShell commands on the Windows side:
- Path A — Logsign PKI: Logsign issues the certificates; you install one package on each machine. For organisations without a PKI and for small fleets.
- Path B — Windows certificates: the collector's own server certificate + client certificates distributed automatically by your enterprise AD CS; deployment through Group Policy. For domain-wide fleets.
If you are unsure, start with Path A on a single machine. You can move to Path B later.
How it works
The Windows machine connects to Logsign; Logsign never connects to Windows. Microsoft calls this a "source-initiated subscription". The WinRM service already installed on every machine dials the collector address it has been given over 5986/tcp, asks "what should I send?" (it receives a subscription) and delivers its logs itself. The machine proves its identity with a client certificate; there is no username or password anywhere in this flow.
Windows (WinRM) ──HTTPS 5986──▶ Logsign WEF collector ──▶ parser → search screen
On the Logsign side the model has two layers. First you create a definition: a name, an IP scope, default channels, a default data policy, a health check and a certificate mode. When a machine inside the scope reaches the collector for the first time, it appears in the definition's Clients table as pending (amber). When you click Enable on that row, a source record specific to that machine is created, one device licence slot is consumed and the row turns enabled (green). Only from that moment does the machine receive a subscription and start sending logs.
Natural consequences of that direction:
- 5986/tcp must be open on the Logsign side, not on the Windows machines.
- Logsign cannot "test the connection" to a machine — there is nothing to connect to. You verify the setup by looking at what arrives.
- A machine that has never connected does not appear in the Clients table. That is why the order matters: set up the Windows side first, let the machine reach the collector, then Enable it.
Three certificates, three different jobs:
| Certificate | Lives on | Answers the question |
|---|---|---|
| Server certificate | Logsign | "Is this really the collector?" Windows checks it; the address inside it must match exactly the address Windows dials. Logsign issues it on both paths. |
| CA certificate | Both sides | "Do we trust each other's certificates?" Logsign uses it to verify client certificates; Windows must trust this CA and know its fingerprint. Path A: Logsign's CA on both sides. Path B: Windows trusts Logsign's CA (Trusted Root) and your enterprise CA (IssuerCA); Logsign trusts your enterprise CA. |
| Client certificate | Each Windows machine | "Which machine is this?" One per machine. Arrives with the package on Path A; distributed automatically by AD CS on Path B. |
Prerequisites
-
A Logsign user: an account with device management permission that can see the
Settings → Integrations → Windows Event Forwardingpage. Enable needs the device management permission; Disable and Forget delete the machine's source record, so the profile also needs the device deletion permission (delete_settings_device_list) — without it the action fails with HTTP 403 "…needs the delete_settings_device_list permission". For certificate renewal (Regenerate) the signed-in user must be a super admin; the password alone is not enough. The warning dialog appears when you click Save. - The address the Windows machines will use to reach Logsign: an IP or a DNS name. In a cluster this is the shared (float/VIP) address, not a single node. This address is written into the server certificate and must be used identically everywhere afterwards.
-
Network path: every Windows machine must be able to reach
<collector-address>:5986/tcp. Do not test this port before Step 1 — the port stays closed until the certificates are generated, and being closed is normal. Testing early returnsTcpTestSucceeded : Falseand sends you hunting for a firewall for nothing. - Windows permissions: local administrator on the machine for Path A; Domain Admin (GPO, SYSVOL and AD CS template rights) plus administrator on the CA server for Path B.
-
Windows version: Windows Server 2016 and later / Windows 10 and later (PowerShell 5.1). Server 2012 R2 has no
Get-LocalGroupMember/Add-LocalGroupMember; do the same job withnet localgroup "Event Log Readers"(on a localised Windows, with the group's local name). -
Licensing: every machine you enable consumes one device slot.
pendingrows consume nothing. Once the quota is full, Enable is refused in the interface with the message "Maximum device limit reached". Check how many free slots you have before onboarding a fleet. - Start with one machine and do not touch Group Policy until it works. A small fleet (a handful of servers) can be set up in one go; in a large environment link the GPO to a test OU first (3B.3) and widen the scope only after one machine has passed Step 5.
============================================================
Step 1 — Collector certificate
On both paths Logsign issues the collector's server certificate. This step is independent of any definition and is done once. Until it is complete, port 5986 stays closed.
Open the Settings → Integrations → Windows Event Forwarding page. With no definitions yet the page reads "No WEF definitions yet."; the Certificates panel on the page shows a Generate certificates button.
The Certificates panel (sample environment, after setup): Collector address, the button, Issuer CA Thumbprint (SHA1) and the unlabeled subscription line. On a first install the button reads Generate certificates and the thumbprint is empty.
1.1 · Check and correct the Collector address field
The Collector address field is mandatory and comes pre-filled with the hostname from your browser's address bar. Replace it with the address the Windows machines will use to reach Logsign — the IP or DNS name you chose under Prerequisites. This value:
- is written into the server certificate's CN/SAN (Windows compares the address it dials against the address in the certificate);
- is the source of the subscription line — the line that tells Windows "come here" is derived from it.
Choose the address correctly, then do not change it. If the machines will reach the collector by IP, enter the IP; if by DNS name, enter the DNS name. A wrong address produces no error whatsoever on the Windows side — the forwarder simply never enrolls. Changing the address later means a new certificate, and therefore a new CA (see If the collector address changes).
1.2 · Generate certificates → Save
Click Generate certificates. On its own this button produces nothing; it only records the intent. The certificates are generated and written when you click the Certificates panel's Save button. In the panel's own words: "Save writes the new certificates. Nothing changes before that." The only visible result of clicking Generate is that the button turns orange and Save becomes enabled; in the dark theme the warning band underneath is hard to read.
Click Save. Within roughly 15 seconds the collector opens port 5986.
You should see: after Save, two new values appear in the panel — Issuer CA Thumbprint (SHA1) (the fingerprint of Logsign's CA, 40 hex characters) and, right under it, an unlabelled read-only box holding the subscription line: it starts with
Server=https://…:5986/wsman/SubscriptionManager/WEC,Refresh=60,IssuerCA=…and carries the hint "Set this value in Group Policy: Computer Configuration → …" (there is no label called "Subscription URL" in the UI). The button is now labelled Regenerate certificates. From a Windows machine,Test-NetConnection <collector-address> -Port 5986now returnsTcpTestSucceeded : True.
1.3 · Note the expiry date
The lifetime of the PKI Logsign issues is fixed: the CA lasts 10 years, the server certificate and the client certificates 825 days. There is no renewal mechanism and no expiry warning. When it expires, every machine goes silent at the same time. The only interface path to renew the server certificate is Regenerate — and that means a new CA: the whole fleet is set up again.
Add 825 days to today's date; put the result in your calendar as a reminder at least one month in advance. If you want to check from a Windows machine, once the machine has enrolled:
Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.Issuer -like '*Logsign WEF CA*' } | Select-Object Subject, NotAfterThis command shows the client certificate on Path A machines; on Path B it returns nothing, because the client certificates come from your enterprise CA. The collector's server certificate is valid for 825 days; count its expiry from the day you did Generate + Save and put it in the calendar.
1.4 · Regenerate certificates: when, and why it is dangerous
⚠ Do not click Regenerate after the setup is done.
Regenerate certificates + Save produces a new CA and a new server certificate. Every client certificate issued by the old CA becomes invalid at that instant: every machine goes silent and the fleet is rebuilt from scratch (on Path A a new package is installed on every machine. On Path B the client certificates do not change; take the new Logsign CA from the package (
ca.crt) as in 3B.2 and repeat 3B.4 — delete the old Logsign CA in the Trusted Root GPO and write the new one — thengpupdate /forceon the machines).The product guards this with two gates: while enrolled clients exist, clicking Save after Regenerate shows a warning — "Generating a new CA will break the N enrolled WEF client(s)…" — and asks for the super admin password to proceed; the signed-in user must be a super admin. When you see that warning, stop; unless you are performing a deliberate migration, cancel.
The panel does not look at the definition's certificate mode: even if you use Path B (Windows certificates) the button is visible and works. On Path B too, the server certificate is Logsign's; Regenerate replaces it, and the Logsign CA the Windows machines trust has changed.
You should see: in the Certificates panel a filled-in Collector address, an Issuer CA Thumbprint (SHA1), the read-only subscription line under it, and a button labelled Regenerate certificates. You will come back to this panel only for a planned certificate renewal.
============================================================
Step 2 — Create a WEF definition
A definition is a template for an IP scope: the machines that fall inside the scope are listed under this definition and inherit its defaults when they are enabled. On the same page, click New definition.
The create dialog (sample environment) asks for three fields: Name, Scope, Default channels. The certificate mode is not here; it is chosen on the definition's form after saving.
2.1 · The create dialog: Name, Scope, Default channels
| Field | Value | Note |
|---|---|---|
Name |
<definition-name> | Must be unique (case-insensitive). This name becomes the first part of every machine's source description on the search screen: <definition-name> <ip>. Choose something short and meaningful, and do not change it later. |
Scope |
<scope> | A single IP (10.100.100.10), a CIDR block (10.100.100.0/24) or a "from - to" range (10.100.100.10 - 10.100.100.50). Hostnames and comma-separated lists are rejected. For the first setup enter only the test machine's IP; you widen the scope later. |
Default channels |
Security, Application, System | The field comes pre-filled with Security, Application, System; type only to add an extra channel. A suggestion list opens as you type, and the text you typed also appears in that list as a free-form item — click the real channel name in the list; do not press Enter. A half-typed name such as Secur is added as a channel and that subscription drops (ID=107). Do not click the tags in the field or the × next to them — a click removes that channel from the list. Before clicking New definition, confirm that all three tags (Security, Application, System) are still in the field. |
Scope overlap is not checked. Two definitions may cover the same subnet; the product does not prevent it. A machine appears as
pendingin the Clients table of every definition whose scope it falls into. Enable it only in the definition you want: the first Enable binds the machine to that definition; an Enable attempt in another definition is refused with "belongs to another definition", and the machine keeps showing aspendingthere (harmless).0.0.0.0/0is also a valid scope — do not type it by accident.
Narrowing the scope later is refused if it would leave an
enabledordisabledmachine outside: "Scope <scope> leaves N client(s) outside the definition: <ip…>. Disable and delete them first." Although the message says "Disable and delete", the correct action is Forget — a disabled machine still counts as outside the scope. Move those machines topendingwith Forget first, then narrow the scope.
Click the New definition button at the bottom of the dialog (the button is not labelled Save). The definition appears in the list. Click its name; the real settings and the Clients table live on the definition's own form.
The definition form (sample environment): in Logsign PKI mode the Windows enrollment package section is visible.
2.2 · Fields on the definition form
| Field | What it does |
|---|---|
Default channels |
Copied only to newly enabled clients. In the form's own words: "New clients start with these channels. A client keeps its own channels after that." It does not change an existing machine's list. |
Default data policy |
The data policy a new client inherits. The drop-down comes up empty — pick Default from the list; do not leave it blank. Typing into the list to filter it does not work, and Enter selects the first highlighted policy (a wrong policy is saved silently). The list is long and unsorted; the Default row may sit further down — scroll the list if needed. Click the Default row with the mouse and, before saving, verify that the field shows Default. |
Health check + period |
The health check and its period (minutes) a new client inherits. Can be left off; it can be turned on later from the machine's card. |
Certificate mode |
Logsign PKI (Path A) or Windows certificates (Path B). See below. |
Inheritance is one-way. Changing the definition's defaults later does not affect existing machines. To roll a new channel out to the fleet you either update each machine from its own card (see Day-to-day operations), or Disable→Enable them — which also resets every per-machine setting back to the defaults.
2.3 · Certificate mode: Path A or Path B?
Path A — Logsign PKI
|
Path B — Windows certificates
|
|
|---|---|---|
| Server certificate | Issued by Logsign (Step 1) | Issued by Logsign (Step 1) — the same |
| Client certificates | Issued by Logsign's CA; one package per machine | Distributed automatically by your enterprise AD CS (autoenrollment) |
| Work per machine | Copy the ZIP + install.ps1 | A restart, or a one-off SYSTEM task (3B.10) |
| Logsign's role | Issues and verifies | Issues the server certificate, verifies clients against your enterprise CA |
| Suited to | No PKI, small fleet, machines outside the domain | Organisations with AD CS, domain-wide fleets |
If you chose Path A: leave the Certificate mode field on Logsign PKI, save the form and go to Step 3A.
If you chose Path B: for now leave the Certificate mode field on Logsign PKI as well, and save the form. Do not switch the mode yet: you switch it to Windows certificates in 3B.2, after downloading Logsign's CA from the enrollment package section — which is shown only in Logsign PKI mode. When the mode is switched, a Windows CA certificate (PEM) field appears on the form; there you paste, in PEM format, the certificate of the enterprise CA that issues the client certificates — also in 3B.2. In 2.4 you only prepare that PEM and its SHA1 fingerprint.
Path B (sample environment): the Windows CA certificate (PEM) field that appears once Certificate mode = Windows certificates is selected in 3B.2 — shown with the PEM pasted and saved; you fill it in 3B.2.
You should see: a new row in the definitions list —
Name,Scope,Pending 0,Enabled 0,Disabled 0. On the definition's form the Clients table is still empty: no machine has reached the collector yet. That is normal. On both paths the definition is saved in Logsign PKI mode at this point; on Path B the mode is switched in 3B.2. Go to Step 3A for Path A; for Path B do 2.4 first, then Step 3B.
2.4 · Path B only: prepare the enterprise CA certificate (PEM) and its SHA1 fingerprint
In this step you only prepare two things and save them to files: the enterprise CA certificate as PEM (pasted into the definition in 3B.2) and its SHA1 fingerprint (written into the GPO in 3B.5). Nothing is pasted into the definition yet.
On the CA server, in an elevated PowerShell:
# -f overwrites an existing file; with a stale ca.der/ca.pem left behind you would fingerprint the wrong CA New-Item -ItemType Directory C:\Temp -Force | Out-Null cmd /c "certutil -f -ca.cert C:\Temp\ca.der" Get-Content C:\Temp\ca.der -TotalCount 1
While it runs, certutil prints a PEM-style dump with a -----BEGIN CERTIFICATE----- line to the console; do not be misled — that is only screen output, the file itself is DER. That is why the check line looks at the first line of the file, not at the screen. Look at the output of the last command:
- If the output is unreadable characters, the file is DER. Convert it to PEM:
cmd /c "certutil -encode C:\Temp\ca.der C:\Temp\ca.pem" - If the output is
-----BEGIN CERTIFICATE-----, the file is already PEM. Do not encode it — a second encode wraps the PEM in base64 again and Logsign cannot read the certificate. Copy the file as-is toca.pem.
The
cmd /cwrapper is mandatory. If you runcertutil -ca.certdirectly from PowerShell, the dotted switch is split apart and you get "Expected no more than 1 args / Too many arguments". The message does not reflect the real cause; run the command insidecmd /c "…".
Now get the enterprise CA's SHA1 fingerprint — this is the IssuerCA value you will write into the GPO on Path B (not the thumbprint shown in the Logsign panel):
# Language-independent: Get-PfxCertificate reads DER as well as PEM; Thumbprint is already upper-case, 40 hex characters $tp = (Get-PfxCertificate C:\Temp\ca.der).Thumbprint; $tp $tp | Set-Content C:\Temp\ca-sha1.txt # keep it for the SubscriptionManager line in 3B.5
In a two-tier PKI (Root → Issuing) use the certificate and fingerprint of whichever CA issues the client certificates — usually the Issuing CA. Not the Root's. The Windows machine selects the certificate it presents by the
IssuerCAvalue; with the wrong CA written there, the machine reports "I have no certificate".
Keep C:\Temp\ca.pem and the fingerprint at hand. Do not paste the PEM into the definition yet: the Windows CA certificate (PEM) field exists only in Windows certificates mode, and you switch to that mode in 3B.2 — after downloading Logsign's CA, which is offered only while the definition is still in Logsign PKI mode. The fingerprint goes into the SubscriptionManager line in 3B.5.
============================================================
Step 3A — Path A: one package per machine + install.ps1
If you use Path B, skip this step and go to Step 3B.
3A.1 · Download the package
Open the definition (click its name in the list). The Windows enrollment package section is on the definition's form — not in the Certificates panel — and it is shown only while Certificate mode = Logsign PKI. Under its heading there is an unlabelled box with the placeholder text WIN-SRV-01 and a Download package button. Type the machine's computer name into the box (not its IP; the name the hostname command returns on Windows) and click Download package. If the box is left empty you get "Enter the computer name". The browser downloads wef-<machine>.zip.
Download a separate package for every machine. The client certificate inside is that machine's identity. If you download the package for the same machine a second time, the browser names the file something like wef-<machine> (1).zip. Always use the newest package; if you did Regenerate + Save in the Certificates panel, the ca.crt/client.pfx in older packages belong to the old CA and will not work — delete the old ones.
| File | What |
|---|---|
ca.crt |
Logsign's CA → goes into Trusted Root |
client.pfx |
The machine's identity (certificate + private key). Its password is in README.txt, randomly generated per package
|
install.ps1 |
The setup script — what it does and does not do is described below |
README.txt |
Subscription line, PFX password, notes. Its notes carry sentences from the old model ("the device page lists the machine once its first events arrive", Eventlog-ForwardingPlugin); this guide takes precedence — do not use README.txt as a guide |
Package generation only looks for Logsign's CA. If you see either of these two messages:
- "No collector-managed CA is available. Generate a PKI first" → Step 1 (Generate + Save) has not been done.
- "Save the certificate change first. A package made now would carry the old CA." → there is an unsaved change in the Certificates panel. Save first (or discard the change), then download. The package is produced with the CA in effect at that moment.
The ZIP is a credential. Move it over a secure channel and delete it from the machine once the install finishes. Do not put it on shared folders, especially ones readable domain-wide.
3A.2 · Run install.ps1
Copy the ZIP to the machine, log in at the console or over RDP, and run it from an elevated (Run as administrator) PowerShell:
Expand-Archive -Force C:\wef-<machine>.zip C:\wef-setup cd C:\wef-setup powershell -ExecutionPolicy Bypass -File .\install.ps1
The script prints its steps in order:
[1/6] Importing the CA into Trusted Root...
[2/6] Importing the client certificate...
Imported: <client-certificate-thumbprint>
[3/6] Granting NETWORK SERVICE read access to the private key...
[4/6] Granting access to the Security channel...
[5/6] Pointing the forwarder at the collector...
Server=https://<collector-address>:5986/wsman/SubscriptionManager/WEC,Refresh=60,IssuerCA=<logsign-ca-thumbprint>
[6/6] Restarting WinRM...
Done. CA thumbprint: <logsign-ca-thumbprint>Run the script from a file, and verify afterwards. Copy the ZIP into the RDP session (clipboard or a mapped drive) and run
install.ps1from an elevated PowerShell on the machine with-File, as shown above. If you run it remotely and non-interactively (PowerShell Remoting, an RMM tool, a remote console), prefix the commands with$ProgressPreference='SilentlyContinue';or run the script as a scheduled task under the SYSTEM account; in a non-interactive session the progress bar (notablyExpand-Archive's) can stall the script. Always verify after the run:reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows\EventLog\EventForwarding\SubscriptionManager"(Get-Service WinRM).Status
The channel hint on the script's last line is out of date. On completion
install.ps1tells you to look at theEventlog-ForwardingPluginpath in Event Viewer. That path does not exist on modern Windows. The correct channel isMicrosoft-Windows-Forwarding/Operational. Look there for errors.
3A.3 · What install.ps1 does, and does not do
| Does | Does not — you complete it |
|---|---|
| Installs Logsign's CA into Trusted Root |
Does not grant Event Log Readers membership, and does not grant access to channels other than Security. For the three default channels (Security, Application, System) no extra group action is needed: [4/6] grants NETWORK SERVICE access to the Security channel through its SDDL (the channel's access-descriptor string), and Application and System are readable anyway — on member machines and on Domain Controllers alike. Only if you are going to collect a non-default channel (Sysmon, PowerShell/Operational, DNSServer/Audit…) add (A;;0x1;;;NS) to that channel's SDDL (wevtutil sl <channel> /ca:…; on a Domain Controller this is the only way, there is no local group) or, on a member machine, grant it through group membership (language-independent, by SID):Add-LocalGroupMember -SID 'S-1-5-32-573' -Member 'S-1-5-20'Restart-Service WinRM -ForceDoes not install the software that produces a channel. If Sysmon is in the channel list, Sysmon must be installed on the machine. Does not change the WinRM service's startup type. On Windows Server WinRM is already Automatic; just check it: Get-Service WinRM | Select-Object Status, StartType. On Windows 10/11 clients the default is Manual: Set-Service WinRM -StartupType Automatic; Start-Service WinRM
|
Imports client.pfx into the LocalMachine\My store | |
| Grants NETWORK SERVICE read access to the private key | |
Adds (A;;0x1;;;NS) to the access list (SDDL) of the Security channel only
| |
| Writes the SubscriptionManager policy | |
Restarts WinRM (Restart-Service WinRM) |
A machine must not hold more than one Logsign client certificate. If another machine's package was installed by mistake, the forwarder picks a different identity each time, the subscription never settles and not a single event arrives. Check:
Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.Issuer -like '*Logsign WEF CA*' }— exactly one certificate should remain; remove extras withRemove-Item Cert:\LocalMachine\My\<thumbprint> -DeleteKey.
If a channel in the channel list does not exist on the machine (e.g. Sysmon not installed), the forwarder raises error
5004for that channel and keeps creating and tearing down the subscription. Either install the software that provides the channel (Sysmon64.exe -accepteula -i), or after Step 4 remove the channel from that machine's channel list — the definition'sDefault channelsdoes not affect an existing client.
Is the install complete? Run this on the machine. At this stage you will see ID=105 with code 2150859023 (0x8033810F) — that is normal, the machine has not been Enabled yet; one ID=100 per channel arrives after Step 4:
wevtutil qe Microsoft-Windows-Forwarding/Operational /c:10 /rd:true /f:text
You should see: on Windows,
Done. CA thumbprint: …; the SubscriptionManager registry key populated; WinRMRunning. In Logsign, when you refresh the definition's form, the machine's IP appears in the Clients table aspending(the view is cached for 30 seconds; if it is not there immediately, wait half a minute and refresh). Now Step 4.
============================================================
Step 3B — Path B: deployment with a GPO
If you use Path A, skip this step.
3B.0 · Design: the collector's own certificate + enterprise client certificates
On Path B two PKIs work together, with strictly separated roles. This is the recommended and supported path:
| What | Who issues it | Who trusts it, and how |
|---|---|---|
| The collector's server certificate | Logsign (Step 1). There is no interface path to upload a server certificate from your enterprise CA. | Windows machines → Logsign's CA is distributed to Trusted Root by GPO (3B.2 and 3B.4) |
| The machines' client certificates | Your enterprise AD CS, by autoenrollment from the Computer (Machine) template | Logsign → the Windows CA certificate (PEM) on the definition (prepared in 2.4, pasted in 3B.2) |
On the Windows machine a single line ties the two together, the SubscriptionManager policy: its Server= part points at the collector (Logsign's certificate), its IssuerCA= part at the enterprise CA (the criterion by which the machine selects its own certificate).
Revoking the certificate at the AD CS does not silence a machine. The collector does not consult revocation lists; it validates the chain only. The place to stop a machine from forwarding is Logsign: Disable in the definition's Clients table (see the destructive-action warning in Step 4).
There are eight parts; all sit under Computer Configuration and the order matters:
| Order | Part | Mechanism | If missing |
|---|---|---|---|
| 0 | Create the GPO + link it at the domain root | GPMC / PowerShell | Nothing is applied |
| a | Logsign's CA → Trusted Root | Public Key Policies | The machine does not trust the collector's certificate and never enrolls; no error either |
| b | SubscriptionManager | Registry | The forwarder does not know the collector and never connects |
| b2 | Autoenrollment (AEPolicy=7) |
Registry | The machine never requests a certificate — even with correct template rights |
| c | Event Log Readers membership | Restricted Groups | The Security channel cannot be read — Application/System arrive, Security does not (the script also establishes the membership itself; the GPO is for persistence) |
| c2 | WinRM service = Automatic | System Services | On some installs WinRM does not run; nothing is collected, no error |
| d | Private-key permission + enrollment trigger | Startup script |
0x80090016 — the certificate exists but cannot be presented; no channel arrives |
| last | CSE list (Client-Side Extension — the list that tells the client which parts of the GPO to apply) + version number | AD attribute | The startup script sits in SYSVOL, never reaches the client, no error |
3B.1 · AD CS preparation: the Computer template and the Autoenroll right
Client certificates come from the built-in Computer template (AD name Machine). Three conditions:
- The template must be published on the CA (it usually is on enterprise CAs).
- The
Domain Computersgroup must hold the Enroll and Autoenroll rights on the template. Enroll is there by default; you grant Autoenroll. - Autoenrollment must be turned on on the machines (
AEPolicy=7in the GPO, 3B.5).
Is it published? On the CA server, as an administrator:
certutil -CATemplates # the list must contain a "Machine: Computer" line (a trailing "Auto-Enroll: Access is denied." on it is normal)
If you run this command on a member server or under a local account you get "Access is denied". That is normal, not a fault — run the command on the CA server as a domain administrator. An
Auto-Enroll: Access is denied.suffix at the end of a line is something else: it says that template does not grant autoenroll to your user account — it appears even on the CA server as Domain Admin, and is not a fault. What you are looking for is that theMachine: Computerline is present. If the template is not in the list:certsrv.msc→ Certificate Templates → right-click → New → Certificate Template to Issue → Computer.
The Security tab of the Computer template (sample environment). Because the built-in template is an old schema version, the Autoenroll row is not drawn here; the right is granted with PowerShell.
Do not look for the Autoenroll checkbox in the GUI — it is never drawn. The built-in Computer template is an old schema version;
certtmpl.mscdoes not show an Autoenroll row on its Security tab. The right is granted directly in AD. The block below is run once; running it again does not add a second entry.
On the DC, in a domain-administrator PowerShell:
Import-Module ActiveDirectory
$templateDN = "CN=Machine,CN=Certificate Templates,CN=Public Key Services,CN=Services," +
(Get-ADRootDSE).configurationNamingContext
# Domain Computers SID = domain SID + "-515"
$sid = New-Object System.Security.Principal.SecurityIdentifier(((Get-ADDomain).DomainSID.Value + "-515"))
$autoenroll = [GUID]"a05b8cc2-17bc-4802-a710-e7c15ab866a2"
$acl = Get-Acl "AD:$templateDN"
$already = $false
foreach ($a in $acl.Access) {
$ss = $null
try { $ss = $a.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]).Value } catch { }
if ($ss -eq $sid.Value -and $a.ObjectType -eq $autoenroll -and $a.AccessControlType -eq 'Allow') { $already = $true }
}
if (-not $already) {
$acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
$sid, "ExtendedRight", "Allow", $autoenroll)))
Set-Acl -AclObject $acl -Path "AD:$templateDN"; "Autoenroll right added"
} else { "Autoenroll right already present - untouched" }Verification — msPKI-Enrollment-Flag tells you whether the template is marked for autoenrollment, but it does not prove the access right itself; for the Autoenroll ACE the second command must return a row:
# In a new window, run the $templateDN lines of the block above first, then this $sid line
$sid = New-Object System.Security.Principal.SecurityIdentifier(((Get-ADDomain).DomainSID.Value + "-515"))
Get-ADObject -Identity $templateDN -Properties msPKI-Enrollment-Flag | Select-Object msPKI-Enrollment-Flag
# the 0x20 bit (32) must be SET in the value. 0x8 is something else entirely.
# Autoenroll ACE check - must return a row for Domain Computers (by SID: the name "Domain Computers" differs on a localised DC)
(Get-Acl "AD:$templateDN").Access | Where-Object { $_.ObjectType -eq 'a05b8cc2-17bc-4802-a710-e7c15ab866a2' -and $_.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]).Value -eq $sid.Value }Immediately after Set-Acl the ACE check can come back empty in the same session; wait a few seconds and run it again in a new PowerShell window (re-run the first three lines of the block that define $templateDN first). The block above is idempotent — running it twice does no harm and does not add a second entry.
You should see:
Autoenroll right added(or already present), andMachine: Computerin thecertutil -CATemplatesoutput (with or without theAuto-Enroll: Access is denied.suffix).
3B.2 · Get Logsign's CA (ca.crt), then switch to Windows certificates and paste the PEM
For the Windows machines to trust the collector's server certificate, they must see Logsign's CA in Trusted Root. The way to obtain Logsign's CA from the interface is the enrollment package, and the package section is shown only while the definition is in Logsign PKI mode. That is why the order inside this step matters: download ca.crt first, switch the mode afterwards. Changing the mode is free of consequences while the definition has no enabled clients.
First, while the definition is still in Logsign PKI mode:
- Open the definition (click its name in the list).
Certificate modeis still Logsign PKI — the default from Step 2 — and the Windows enrollment package section is visible on the form. (If you changed the mode earlier, set it back to Logsign PKI: the package section appears as soon as the mode is selected, before Save; save the definition anyway.) - Type any name into the box (e.g.
gpo-ca) → Download package. - Take only the
ca.crtfile out of the ZIP. The rest of the ZIP (client.pfx,install.ps1) is not used on Path B — delete it; client certificates come from AD CS. - Copy
ca.crtto the DC asC:\Temp\logsign-ca.crt. Cross-check: the file's fingerprint must equal the Issuer CA Thumbprint (SHA1) shown in the panel:
(Get-PfxCertificate C:\Temp\logsign-ca.crt).Thumbprint
Then, on the same form:
- Set
Certificate mode= Windows certificates. The Windows enrollment package section disappears and the Windows CA certificate (PEM) field appears. - Open the
ca.pemfile from 2.4 in a text editor, copy all of it (including theBEGINandENDlines) and paste it into the Windows CA certificate (PEM) field. - Save the form.
Switching the mode empties the PEM field. A PEM pasted before the switch from Logsign PKI to Windows certificates is discarded by the switch. If you paste the PEM first and then switch the mode back and forth, the field is emptied and the machines cannot be validated — that is why the PEM is pasted after
ca.crthas been downloaded and the mode has been set for the last time. Paste the PEM in this step, after selecting the mode, and check that the field still holds it before you Save.
⚠ Changing the
Windows CA certificate (PEM)field while enabled machines exist is saved WITHOUT any warning, and the client-verification pool changes immediately: machines holding a certificate from the old CA start being refused at that instant. If you are going to change the CA, first prepare the machines so that they obtain a certificate from the new CA. (The guard exists only for Generate/Regenerate in the Certificates panel, not here.)
This definition's CA joins the client-verification pool. The pool is not a single certificate: it is Logsign's own CA plus the enterprise CA of every definition in Windows certificates mode. If you later delete this definition, its CA leaves the pool and machines holding certificates from that CA — even ones attached to a different definition — are rejected. If you use more than one enterprise CA, plan definition deletions accordingly.
3B.3 · (0) Create and link the GPO
On the DC, in an elevated PowerShell with domain-admin rights: $SYSVOL is a local file path, so this block and the following ones must run on a DC. All the settings below are written into an existing GPO; create the GPO and link it at the root or at a test OU first. For the first setup it is safer to link only the OU that contains the test machine, not the root; once the fleet is verified you move the link to the root.
Import-Module GroupPolicy, ActiveDirectory
$gpo = New-GPO -Name 'Logsign WEF Collection' -Comment 'WEF forwarding + certificate autoenrollment'
# In a large environment link a test OU first: -Target '<test-ou-dn>' ; link the root only after Step 5 has passed
New-GPLink -Guid $gpo.Id -Target (Get-ADDomain).DistinguishedName -LinkEnabled Yes # or the DN of the test OU
$GUID = "{$($gpo.Id.ToString().ToUpper())}"
$SYSVOL = "C:\Windows\SYSVOL\sysvol\$((Get-ADDomain).DNSRoot)\Policies\$GUID"
if (-not (Test-Path "$SYSVOL\GPT.INI")) { throw "Wrong SYSVOL path: $SYSVOL" } # safeguard: with a wrong path the later blocks build a fake tree with New-Item -Force and the GPO silently applies empty
$GPODN = "CN=$GUID,CN=Policies,CN=System,$((Get-ADDomain).DistinguishedName)"
"GPO: $GUID"; "SYSVOL: $SYSVOL"
# If the session was closed, re-derive the variables (only these four lines; do not repeat New-GPO):
$gpo = Get-GPO -Name 'Logsign WEF Collection'; $GUID = "{$($gpo.Id.ToString().ToUpper())}"
$SYSVOL = "C:\Windows\SYSVOL\sysvol\$((Get-ADDomain).DNSRoot)\Policies\$GUID"
$GPODN = "CN=$GUID,CN=Policies,CN=System,$((Get-ADDomain).DistinguishedName)"
$sec = Join-Path $SYSVOL 'Machine\Microsoft\Windows NT\SecEdit'The $SYSVOL, $GPODN, $GUID and $sec variables are used in the following steps; stay in the same PowerShell session. If the session was closed, run only the four lines after the comment (starting with Get-GPO) in the new session; do not repeat New-GPO.
3B.4 · (a) Distribute Logsign's CA to Trusted Root
In GPMC (gpmc.msc) edit the Logsign WEF Collection GPO: Computer Configuration → Policies → Windows Settings → Security Settings → Public Key Policies → Trusted Root Certification Authorities → right-click → Import → C:\Temp\logsign-ca.crt.
Or with PowerShell, in the same session as 3B.3 — this writes the certificate blob into the same GPO setting that the GPMC import produces:
$gpo = Get-GPO -Name 'Logsign WEF Collection'
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2('C:\Temp\logsign-ca.crt')
$blob = [byte[]]([byte[]](0x20,0,0,0,0x01,0,0,0) + [BitConverter]::GetBytes([int]$cert.RawData.Length) + $cert.RawData)
Set-GPRegistryValue -Guid $gpo.Id -Key "HKLM\SOFTWARE\Policies\Microsoft\SystemCertificates\Root\Certificates\$($cert.Thumbprint)" -ValueName 'Blob' -Type Binary -Value $blob
# verify on a client, after gpupdate:
Get-ChildItem Cert:\LocalMachine\Root | Where-Object Thumbprint -eq '<logsign-ca-thumbprint>'"Already distributed" is not a timing guarantee. If a machine's Root store does not hold the relevant CA — a clean image, or a machine previously removed from WEF — trust fails silently. Do not confuse two separate cases:
(1) Logsign's CA is missing from Trusted Root. Symptom: the machine never appears in the Clients table and
startup.logis silent (the script does not check Logsign's CA). Fix: repeat 3B.4, thengpupdate /forceon the machine and, if needed, the SYSTEM task (3B.10); if it is urgent, temporarily by hand on the machine:certutil -addstore -f Root C:\Temp\logsign-ca.crt.(2) The line
WARNING: a certificate was issued but it does not chain to the target CA… RESULT: no suitable certificate.instartup.log. This is an enterprise chain problem: the Issuing CA's root/intermediate certificate is missing from the machine's Root/CA store, or the expected CA is not the one issuing the certificate; adding Logsign's CA does not fix it. Your enterprise CA's own certificate is normally already distributed in an AD CS environment; this step (3B.4) is for Logsign's CA only.
3B.5 · (b, b2) SubscriptionManager and autoenrollment
(b) Point the forwarder at the collector — on the DC, in an elevated PowerShell with domain-admin rights (or with GPMC). Take the value from the Logsign panel: copy the subscription line (the read-only box under the Issuer CA Thumbprint) from the Certificates panel. On Path B, in the IssuerCA= part of that line you write not the Logsign thumbprint the panel shows but the SHA1 fingerprint of your enterprise CA obtained in Step 2.4 (the machine selects its own autoenrolled certificate by it). The result must look like this:
Server=https://<collector-address>:5986/wsman/SubscriptionManager/WEC,Refresh=60,IssuerCA=<enterprise-ca-sha1>
With GPMC: Computer Configuration → Policies → Administrative Templates → Windows Components → Event Forwarding → Configure target Subscription Manager → Enabled → Show → add the line. Or with PowerShell:
$SM = 'Server=https://<collector-address>:5986/wsman/SubscriptionManager/WEC,Refresh=60,IssuerCA=<enterprise-ca-sha1>' Set-GPRegistryValue -Name 'Logsign WEF Collection' ` -Key 'HKLM\SOFTWARE\Policies\Microsoft\Windows\EventLog\EventForwarding\SubscriptionManager' ` -ValueName '1' -Type String -Value $SM
⚠ Do not omit the trailing
\SubscriptionManager. If you write the key path one level too shallow (just…\EventForwarding) the command appears to succeed silently, but the key never materialises on the client and the forwarder does not know the collector.
Thumbprint traps: (1) 40 hex characters, no colons and no spaces. (2) It is the fingerprint of the CA that issues the client certificates — not the one in the Logsign panel, not the collector's server certificate. Written wrongly it yields
ID=105 / 0x80338082and you will believe "there is no certificate". (3) In a two-tier PKI, the Issuing CA. To read what the policy actually says on a machine:(Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\EventForwarding\SubscriptionManager').'1'
(b2) Turn on autoenrollment. Template rights alone are not enough; the machine has to ask for the certificate:
Set-GPRegistryValue -Name 'Logsign WEF Collection' ` -Key 'HKLM\SOFTWARE\Policies\Microsoft\Cryptography\AutoEnrollment' ` -ValueName 'AEPolicy' -Type DWord -Value 7 # verify on the client (after gpupdate): (Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\AutoEnrollment').AEPolicy # -> 7
3B.6 · (c) Event Log Readers membership
This step cannot be skipped: the __Members line below REPLACES the membership on every machine in scope (DCs included) with the list you provide here; accounts missing from the inventory (monitoring, backup) drop out of Event Log Readers. The forwarder runs as NETWORK SERVICE and cannot read the Security channel by default. The GPO's Restricted Groups mechanism solves this by SID, language-independently. The file is GptTmpl.inf and you write it; the block that writes the INF runs on the DC, in an elevated PowerShell with domain-admin rights (the inventory commands run on every machine).
⚠ TAKE AN INVENTORY FIRST —
__Membersis an authoritative list, not an addition.The line
*S-1-5-32-573__Members = *S-1-5-20reduces the group's membership to exactly this list; every member not on it is removed. With the GPO linked at the domain root the effect covers every machine, Domain Controllers included. In enterprise environments the Event Log Readers group usually contains a monitoring account, a backup account or an operations group — all of them are silently dropped and the damage surfaces late (Security settings are re-applied every 16 hours).The additive
__Memberofform looks intuitively right but is not applied forS-1-5-20; you have to use the authoritative__Membersform. That is why you add the existing members to the list.# on member machines Get-LocalGroupMember -SID S-1-5-32-573 | Select-Object Name, @{n='SID';e={$_.SID.Value}} # If the group holds an unresolvable (deleted) SID, Get-LocalGroupMember fails ENTIRELY; then use: net localgroup "$((Get-LocalGroup -SID S-1-5-32-573).Name)" # a DC has no local groups: Get-LocalGroupMember fails with "Group S-1-5-32-573 was not found" - that is normal, look at the AD group Get-ADGroupMember -Identity 'S-1-5-32-573' | Select-Object Name, SIDIf different machines hold different members, take the union of all of them — the GPO applies a single list. If the group holds an unresolvable SID (a deleted account),
Get-LocalGroupMemberfails entirely; on that machine take the list with thenet localgroupline in the block.
A DC has no local groups (see the note in the block); if there are no members, $existing stays empty and the block carries on. Put the members from the inventory into the $existing list and generate the INF file (the block below is not INF text; it is the command that writes it):
# 1. SIDs of the existing members from the inventory (other than S-1-5-20). Leave empty if there are none.
$existing = @() # example: @('S-1-5-21-…-1105', 'S-1-5-21-…-1203')
$Extra = if ($existing) { ',' + (($existing | ForEach-Object { "*$_" }) -join ',') } else { '' }
# 2. Write the GptTmpl.inf file
$sec = Join-Path $SYSVOL 'Machine\Microsoft\Windows NT\SecEdit'
New-Item -Path $sec -ItemType Directory -Force | Out-Null
@"
[Unicode]
Unicode=yes
[Version]
signature="`$CHICAGO`$"
Revision=1
[Group Membership]
*S-1-5-32-573__Memberof =
*S-1-5-32-573__Members = *S-1-5-20$Extra
"@ | Set-Content -Path (Join-Path $sec 'GptTmpl.inf') -Encoding Unicode
# 3. VERIFY - look at the written line with your own eyes; $Extra must really have expanded
Get-Content (Join-Path $sec 'GptTmpl.inf') | Select-String '__Members'Three details are mandatory. (1) The here-string (
@"…"@): INF is multi-line;$Extramust expand, while`$CHICAGO`$must stay literal. (2)-Encoding Unicode(UTF-16LE) is required — aGptTmpl.infwritten as UTF-8 is silently ignored. (3) INF files do not expand variables: if you copy the text by hand instead of running the block, the file literally contains$Extraand the membership is never applied. Do not skip the verification in step 3.
Do not address the group by name.
net localgroup "Event Log Readers"will not find that name on a localised Windows (Turkish "Olay Günlüğü Okuyucuları"); the command appears to succeed and does nothing. GPO Restricted Groups and commands with a-SIDparameter work through SIDs and are correct in every language.
The setup works even if this part fails: the startup script also establishes the membership through its own SID-based branch. The GPO part is the persistence safeguard.
3B.7 · (c2) Set the WinRM service to Automatic
Append to the same GptTmpl.inf file, after 3B.6. The order is critical: the Set-Content in 3B.6 writes the file from scratch; if you run this block before it, it is wiped out. On Windows Server WinRM is already Automatic; this line is a persistence safeguard and is really needed for Windows 10/11 clients (default Manual).
# Safeguard: stop if 3B.6 was not done in this session
if (-not (Test-Path variable:existing)) { throw 'Do the 3B.6 inventory first and define the $existing variable (even if it is just @())' }
$sec = Join-Path $SYSVOL 'Machine\Microsoft\Windows NT\SecEdit'
Add-Content -Path (Join-Path $sec 'GptTmpl.inf') -Encoding Unicode -Value @"
[Service General Setting]
"WinRM",2,"D:AR(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)"
"@
# verify on the client:
Get-Service WinRM | Select-Object Status, StartType
# -> Running Automatic3B.8 · (d) Startup script: LogsignWEF-Prepare.ps1
By default only SYSTEM and Administrators can read the private key of a certificate delivered by AD CS. NETWORK SERVICE cannot; the forwarder cannot present the certificate during the TLS handshake. There is no built-in GPO setting that grants this permission. The solution is a startup script. The script does the following:
- Reads the target CA from the
IssuerCA=value of the machine's own SubscriptionManager policy — no IP, domain or CA name is embedded in it. - If no suitable client certificate exists, triggers enrollment: first
certutil -pulse, then polls for at most 45 seconds; if the certificate still has not arrived, enrolls manually withcertreq. - Grants NETWORK SERVICE (
S-1-5-20) read access to the certificate's private key. - Checks the Event Log Readers membership and adds it if missing.
- Restarts WinRM if anything changed (
Restart-Service WinRM -Force). If everything is in place, it touches nothing. - Writes every step to
C:\ProgramData\LogsignWEF\startup.log.
| Parameter | Default | When to change it |
|---|---|---|
-Template |
Machine |
If you use your own template (the AD name, not the display name) |
-IssuerThumbprint |
read from the policy | To override the value in the policy by hand |
-EnrollRetryHours |
24 |
Minimum interval between manual enrollment attempts; 0 = no limit |
-AutoEnrollWaitSeconds |
45 |
Increase on slow CAs; below 10 is pointless |
-RequireTemplateMatch |
off | To allow only a certificate issued from the specified template (see the security note below) |
-LogPath |
%ProgramData%\LogsignWEF\startup.log |
To change where the log goes |
Do not assume autoenrollment does its work immediately at boot.
certutil -pulsedoes not produce a certificate; it only triggers a scheduled task, and that task runs delayed and asynchronously after boot. That is why the script polls for a bounded period and falls back tocertreqif needed. The log tells you which branch did the work:after pulse (polled for up to 45s): N— ifNis 0, the certificate was obtained by thecertreqfallback, not by autoenrollment. Both are valid outcomes.
Security note — which private keys does the script open up?
The script takes as candidates the certificates that chain to the target CA and are valid for client authentication. Two special cases:
1. If the CA and the DC are the same machine, the CA's own certificate sits in the same store with its private key. The script filters out CA certificates and logs it:
SECURITY: CA certificate EXCLUDED from candidates: <thumbprint>.2. On a Domain Controller there is no certificate from the Machine template; a DC uses its Domain Controller Authentication and Kerberos Authentication certificates. Both carry client authentication and become the script's candidates → NETWORK SERVICE is granted read access to the DC's authentication keys. If you find that unacceptable, issue a dedicated template for DCs and run the script with
-Template <name> -RequireTemplateMatch, or leave DCs out of WEF.
If you run the script by hand, trigger it as SYSTEM. For diagnostics, run it from the console/RDP under a domain account, or trigger it with a
schtasks /ru SYSTEMtask as in 3B.10 — that is the same context as at boot (the machine identity).
Put the script in SYSVOL. The full source is in the expandable box below; copy it and save it on the DC as C:\Temp\LogsignWEF-Prepare.ps1 (copy the file into the RDP session — clipboard or a mapped drive). After pasting, verify that the file has 576 lines ((Get-Content C:\Temp\LogsignWEF-Prepare.ps1).Count) and that its first and last lines match the box; a missing line silently results in "no script".
$startup = Join-Path $SYSVOL 'Machine\Scripts\Startup' New-Item -Path $startup -ItemType Directory -Force | Out-Null Copy-Item C:\Temp\LogsignWEF-Prepare.ps1 $startup -Force # The file name is psscripts.ini (NOT scripts.ini - that is a different file). # The encoding MUST be UTF-16LE; written as UTF-8 the file is SILENTLY ignored. $ini = Join-Path $SYSVOL 'Machine\Scripts\psscripts.ini' "[Startup]`r`n0CmdLine=LogsignWEF-Prepare.ps1`r`n0Parameters=" | Set-Content -Path $ini -Encoding Unicode (Get-Item $ini -Force).Attributes = 'Hidden' # VERIFY - the first four bytes must be 255 254 91 0 (UTF-16LE BOM + '[') [System.IO.File]::ReadAllBytes($ini)[0..3] -join ' '
If you want to pass parameters (e.g. your own template), put them on the 0Parameters= line: 0Parameters=-Template CorporateComputer -RequireTemplateMatch.
LogsignWEF-Prepare.ps1 — download the script from the attachment LogsignWEF-Prepare.ps1 (576 lines, PowerShell 5.1; SHA-256 2897577558a92a057886a79469bcd875ea4dea7123de903b1e4d4f7f9007903b). Save it with exactly this file name; the first line is <# and the last line starts with if ($failed.
3B.9 · (last) CSE list and version number
⚠ This step goes LAST — after the startup script is in SYSVOL. Run it on the DC, in an elevated PowerShell with domain-admin rights, in the same session as 3B.3 (
$GPODN,$SYSVOL). An attribute in AD tells the client which components of the GPO to process. The work you did through GPMC (3B.4, 3B.5) updates it by itself, and values written withSet-GPRegistryValue(the PowerShell alternatives in 3B.4 and 3B.5) get the Registry CSE added automatically too; only the parts written to files —GptTmpl.infandpsscripts.ini(3B.6–3B.8: Security and Scripts) — do not, and that is what this step is for. If this step is skipped, the script sits in SYSVOL, the GPO reports as applied, but on the machine it never runs and produces no error.
The list must be sorted ASCENDING by GUID. If you append to the end, Windows sees a broken order and silently skips the remaining components. The block below keeps the existing entries, adds the three and sorts them.
$CSE_REG = '{35378EAC-683F-11D2-A89A-00C04FBBCFA2}{D02B1F72-3407-48AE-BA88-E8213C6761F1}' # Registry
$CSE_SCR = '{42B5FAAE-6536-11D2-AE5A-0000F87571E3}{40B6664F-4972-11D1-A7CA-0000F87571E3}' # Scripts
$CSE_SEC = '{827D319E-6EAC-11D2-A4EA-00C04F79F83A}{803E14A0-B4FB-11D0-A0D0-00A0C90F574B}' # Security
# Merge while KEEPING the existing entries (otherwise the PKI/Registry entries GPMC wrote are lost)
$cur = (Get-ADObject -Identity $GPODN -Properties gPCMachineExtensionNames).gPCMachineExtensionNames
$have = @()
if ($cur) { $have = @([regex]::Matches($cur,'\[[^\]]+\]') | ForEach-Object { $_.Value.Trim('[',']') }) }
# the @(...) wrapper is mandatory - with a single entry the result is a string and "+" concatenates text instead of appending
$all = @($have)
foreach ($e in $CSE_REG, $CSE_SCR, $CSE_SEC) {
$cse = $e.Substring(0,38) # {CSE-GUID} = the first 38 characters; leave it alone if the same CSE is already there (GPMC may have written it with a different tool GUID)
if (-not ($all | Where-Object { $_.StartsWith($cse) })) { $all += $e }
}
$all = $all | Sort-Object
Set-ADObject -Identity $GPODN -Replace @{ gPCMachineExtensionNames = (($all | ForEach-Object { "[$_]" }) -join '') }
# verify immediately after writing
$v = (Get-ADObject -Identity $GPODN -Properties gPCMachineExtensionNames).gPCMachineExtensionNames
"CSE entry count: " + ([regex]::Matches($v,'\[[^\]]+\]')).Count + " (must be at least 3)"
# bump the version - AD and GPT.INI TOGETHER; otherwise clients consider the GPO unchanged
$cur = (Get-ADObject -Identity $GPODN -Properties versionNumber).versionNumber
$new = $cur + 3
Set-ADObject -Identity $GPODN -Replace @{ versionNumber = $new }
"[General]`r`nVersion=$new`r`n" | Set-Content -Path (Join-Path $SYSVOL 'GPT.INI') -Encoding Ascii3B.10 · Apply and verify
On the test machine, in an elevated PowerShell:
gpupdate /force
The startup script runs by itself at every boot from the copy in the GPO. To run it now, without waiting for a boot, run it once under the machine identity — the same context it has at startup. First copy LogsignWEF-Prepare.ps1 to C:\Windows\Temp on the machine from the copy in SYSVOL — the full UNC path is \\<domain>\SYSVOL\<domain>\Policies\{<gpo-guid>}\Machine\Scripts\Startup\LogsignWEF-Prepare.ps1, where the GUID is what (Get-GPO -Name 'Logsign WEF Collection').Id prints (the folder name is in braces) — or, if that path is not reachable from the machine, with the RDP clipboard: the UNC path needs a session signed in with a domain account; from a local account or a remote management tool you get Cannot find path — that is not a fault. Then, in the same elevated PowerShell (the schtasks commands work unchanged there):
schtasks /create /tn LogsignWEFOnce /tr "powershell -ExecutionPolicy Bypass -NoProfile -File C:\Windows\Temp\LogsignWEF-Prepare.ps1" /sc once /st 23:59 /ru SYSTEM /rl HIGHEST /f schtasks /run /tn LogsignWEFOnce Start-Sleep -Seconds 90
Read startup.log with a separate command (item 5 of the verification block below); its last line must be done (changes: …, errors: …). Do not run schtasks /delete before you have seen that line — that is, before the task has finished; the delete command sits at the end of the verification block (item 7).
Once the task has finished, in the same elevated PowerShell, check in order:
# 1. Was the GPO applied? gpresult /r /scope:computer | Select-String 'Logsign WEF' # 2. Is the policy correct? (Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\EventForwarding\SubscriptionManager').'1' (Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\AutoEnrollment').AEPolicy # -> 7 # 3. Is Logsign's CA in Root? Get-ChildItem Cert:\LocalMachine\Root | Where-Object Thumbprint -eq '<logsign-ca-thumbprint>' # 4. Did the client certificate arrive? (Issuer = enterprise CA) Get-ChildItem Cert:\LocalMachine\My | Where-Object Issuer -like '*<enterprise-ca-name>*' | Select-Object Subject, NotAfter, Thumbprint # 5. Did the startup script run, and what did it do? Get-Content C:\ProgramData\LogsignWEF\startup.log -Tail 30 # 6. Membership and service Get-LocalGroupMember -SID S-1-5-32-573 # S-1-5-20 must appear (Get-ADGroupMember on a DC) Get-Service WinRM | Select-Object Status, StartType # 7. If the log shows the "done" line, delete the temporary task schtasks /delete /tn LogsignWEFOnce /f
You should see: Logsign WEF Collection in the
gpresultoutput; the SubscriptionManager value is your line;AEPolicy = 7; Logsign's CA in Root; a certificate issued by your enterprise CA in the My store; the certificate thumbprint and the permission line instartup.log, ending withdone (changes: N, errors: 0)— on a member serverN= 1 (2 if the Event Log Readers membership had not yet arrived from the GPO and the script added it too), on a DC 2 (two identity certificates: Kerberos Authentication + Domain Controller Authentication); what matters iserrors: 0; WinRMRunning / Automatic. In Logsign, the machine's IP in the definition's Clients table aspending. Now Step 4. Before widening the fleet, verify this single machine end to end with Step 5; then move the GPO link to the root (or the target OUs) and widen the definition's Scope.Normal
startup.logoutput on a first run:after pulse (polled for up to 45s): 0, thentrying manual enrollment (template: Machine)and acertreq … has been issuedline. That is normal, not a fault: the autoenrollment task runs delayed after boot, so the script falls back tocertreq; the certificate still comes from your enterprise CA.
============================================================
Step 4 — Enable the machines
When a machine inside the scope reaches the collector, it appears in the Clients table on the definition's form as pending. In that state it sends no logs: the machine reaches the collector but is turned away (per-machine counters of refused requests are not shown in the interface in this version; see 5.2). The Enable button on the row creates that machine's own source record, consumes one device slot, and collection starts. Before Enable, seeing ID=105 / code 2150859023 (0x8033810F, collector 403) in Microsoft-Windows-Forwarding/Operational on this machine is normal; after Enable, one ID=100 per channel arrives within 1–2 minutes.
The Clients table (sample environment): machines arrive as pending first; Enable at the end of the row.
| State | Meaning | Has a record | Consumes a slot |
|---|---|---|---|
pending (amber) |
Reached the collector, not approved | no | no |
enabled (green) |
Being collected | yes | yes |
disabled (red) |
Deliberately stopped; the machine is refused | no — it is deleted | no |
Click Enable one row at a time. There is no confirmation dialog and no notification; the row turns enabled (green) by itself within a few seconds. If it does not change, read the red error box under the row. Disable and Forget are equally unconfirmed — a wrong click deletes the machine's settings.
⚠ Enable, Disable and Forget are DESTRUCTIVE — per-machine settings are lost. Disable and Forget do not park the record; they actually delete it. When you Enable again, the record is rebuilt from scratch out of the definition's defaults at that moment: the channel list, data policy, health check and Offset you gave that machine are gone. If you are silencing a noisy machine temporarily, write down the settings on its machine card first. Forget returns the machine to
pending; Disable marks itdisabledand refuses the machine's requests.
Licensing: once the quota is full, Enable is refused in the interface with the message "Maximum device limit reached".
pendingrows consume no slot; as many machines as you like can wait.
A machine that has never connected does not appear in the list. Rows come from the collector's 7-day machine registry: a machine must have reached the collector at least once. If the machine you expect as
pendingis not there, the problem is not in Logsign but on the Windows side (the SubscriptionManager policy, reachability of 5986, WinRM). Apendingmachine that has not connected for 7 days drops off the list;enabled/disabledrows are always shown.
Channels are copied at the moment of Enable. The definition's
Default channelsfield is copied to the new client only at that instant. A channel you add to the definition after enabling does not reach existing machines; you add it from the machine card (see Day-to-day operations). This is the cause of the "the channel I added does not arrive, but Application+Security+System flow" symptom.
When does the first event arrive? The machine receives its subscription at its next poll (at most 60 seconds, Refresh=60). After that, delivery works per channel with two triggers: when the envelope reaches 512 KB, or when 60 seconds elapse. A busy machine (a DC) sends within seconds; on a quiet machine the first event takes ~1 minute. To speed it up, generate events on the machine:
1..25 | ForEach-Object { eventcreate /T INFORMATION /ID 999 /L APPLICATION /SO WefTest /D "test" | Out-Null }You should see: the row turns
enabled; theEnabledcounter in the definitions list goes up by 1. Within a minute or two the row'sReceivedcolumn (events received in the last 30 minutes) starts climbing andEPSrises above zero. On Windows, oneID=100per channel appears in theMicrosoft-Windows-Forwarding/Operationalchannel.
============================================================
Step 5 — Verify
5.1 · Logsign: the definitions list counters
The definitions list on the Windows Event Forwarding page shows Pending, Enabled and Disabled counters for every definition. Once the fleet is complete you should see Pending 0 and Enabled = the number of machines.
The definitions list (sample environment): Name, Scope, Pending, Enabled, Disabled and Actions columns.
After setup (sample environment): three machines enabled, none pending.
5.2 · Logsign: the Clients table columns
| Column | Meaning | On a healthy machine |
|---|---|---|
State |
pending / enabled / disabled | enabled |
Computer / IP
|
The computer name the machine reports, and its IP. While pending, the Computer column shows -; the FQDN fills in after Enable and the first data — not a fault |
— |
EPS |
Events per second | Above 0 on a busy machine |
Received |
Number of events received in the last 30 minutes — not a running total. On a quiet machine it falls back to 0 after 30 minutes; that is not a fault | climbs while events arrive |
First seen / Last seen
|
First and most recent time it reached the collector |
Last seen within the last few minutes |
Actions |
Enable / Disable / Forget | — |
The view is cached for 30 seconds; if a counter does not change immediately, wait half a minute and refresh.
Error counters: the Clients table has no error columns, and per-machine error counters (refused / unregistered requests) are not shown in the interface in this version. Whether a machine is being turned away you tell from the Microsoft-Windows-Forwarding/Operational events on the Windows side (5.4) and — if you have console access — from the Dropping request from unregistered source lines in 5.5. The machine's card on Settings → Data Collection is only for editing its settings (card menu ☰ → Edit) and for Source Stats (menu → Stats).
5.3 · Logsign: the search screen
On the Search screen set the time range to today (or the last hour) and search:
EventSource.Collector:"wef" # all WEF traffic EventSource.Description:"<definition-name> <ip>" # a single machine (the client source's description has this form) EventSource.Collector:"wef" AND EventSource.HostName:"<machine-fqdn>" # by machine name
If you see a time difference: if there is a constant offset of whole hours between an event's Generated and Received times, the machine's time zone differs from Logsign's. It is corrected with the Offset field on the machine card (see Day-to-day operations).
5.4 · Windows: was the subscription created?
On the machine, in an elevated PowerShell:
wevtutil qe Microsoft-Windows-Forwarding/Operational /c:20 /rd:true /f:text
The line you are looking for, one per channel:
Event ID 100: The subscription LogsignWEFCollector-Security is created successfully. Event ID 100: The subscription LogsignWEFCollector-Application is created successfully. Event ID 100: The subscription LogsignWEFCollector-System is created successfully.
ID=104"connected" does not mean done. The real signature isID=100, and there must be as many as there are channels. If one channel is missing, check that channel's name and permissions (Troubleshooting → 5004). Not seeing events in Logsign right afterID=100is not a fault — on a quiet machine the first event takes ~1 minute.
5.5 · Advanced — Logsign console (SSH)
This box is optional; the main flow does not depend on it. If you can log in to the Logsign server over SSH, the collector's own log shows in real time what happens while a machine enrolls:
journalctl -u logsign-wef-collector -f | grep -E 'HANDSHAKE-OK|SUBSCRIPTION-LIVE|Dropping' [HANDSHAKE-OK] Subscription policies delivered to <ip>:... [SUBSCRIPTION-LIVE] First event received from <ip>:... — events are flowing
SUBSCRIPTION-LIVEmeans events are actually flowing;HANDSHAKE-OKonly says the policy was delivered.TLS handshake error … EOFlines are normal: Windows opens a throwaway probe connection before every real one. They matter only alongside another symptom.Dropping request from unregistered source <ip>→ the machine ispendingordisabled, or inside no definition's scope. Do not read "unregistered" literally; read "not approved". These lines are throttled to one per IP per minute; the suppressed count is reported at the end of the line asskipped_since_last=N— few lines does not mean few attempts.
You should see:
Pending 0in the definitions list;Receivedclimbing for every machine in the Clients table; no new error event inMicrosoft-Windows-Forwarding/Operationalon Windows; on Search,EventSource.Collector:"wef"returning events from today; on Windows, as manyID=100as there are channels. The setup is complete.
============================================================
Day-to-day operations
Adding a machine
- Does the machine's IP fall inside the definition's
Scope? If not, widen the scope (widening is always allowed) or create a new definition. - Set up the Windows side: on Path A a new package +
install.ps1; on Path B, if the machine is in the OU the GPO is linked to,gpupdate /force+ the SYSTEM task (3B.10) is enough. - When the machine shows up as
pending, Enable.
Removing a machine
- Temporary silencing: Clients → Disable. The machine is refused, the slot is freed, the settings are deleted (write them down first). Enable to bring it back.
-
Permanent removal: Disable, then clean the Windows side (see Removal). If you want to narrow the scope, move the machine to
pendingwith Forget first; a scope change that leaves an enabled/disabled machine outside is refused with "Scope <scope> leaves N client(s) outside the definition: <ip…>. Disable and delete them first." — despite the wording, the action that clears it is Forget, not Disable; a disabled machine also counts as out of scope. - On Path B, revoking the certificate at the CA does not silence the machine; silencing is Disable.
Changing channels, data policy and health check
Every enabled machine appears with its own card on the Settings → Data Collection page; the card is named <definition-name> <ip>. The channel list, data policy and health check are edited from this card, per machine: open the card menu (☰) → Edit. The card is for two things only — that Edit, and Source Stats (menu → Stats); the card has no error counter or machine table. The card's host and type fields and its link to the definition are protected; they cannot be changed.
Data Collection (sample environment): typing the definition name in the search box lists only that definition's machine cards; every enabled machine is one card.
-
Rolling a new channel out to the fleet: add it to the definition's
Default channels(for future machines) and to the card of every existing machine. Changing the definition does not reach existing machines. -
Channel name: verify it exactly on the machine with
wevtutil el | Select-String <fragment>. A wrong name drops that channel's subscription (ID=107); because the other channels keep flowing, the error goes unnoticed. - Removing a channel: remove it from that machine's card only. The machine picks up the new list at its next poll (≤60 s).
Offset (time difference)
If a machine's events arrive with a constant offset (e.g. always 3 hours behind), enter the difference in the Offset field on the machine card. It is per machine; the definition has no such field.
Certificate lifecycle
| Certificate | Lifetime | On expiry | Renewal |
|---|---|---|---|
| Logsign CA | 10 years | Everything stops | Regenerate = new CA, fleet rebuilt |
| Collector server certificate | 825 days | Every machine goes silent at once (on both paths) | Only Regenerate = new CA, fleet rebuilt. No warning is given; calendar |
| Path A client certificates | 825 days | That machine goes silent | Download a new package + install.ps1 |
| Path B client certificates | Template validity (Computer: 1 year) | — | AD CS renews automatically; the startup script re-grants the key permission at every boot |
If you are doing a planned renewal (Regenerate): pick a maintenance window; pass the warning and the super admin password; Save; on Path A install a new package on every machine; on Path B the client certificates do not change; take the new Logsign CA from the package (ca.crt) as in 3B.2 and repeat 3B.4 (delete the old Logsign CA in the Trusted Root GPO and write the new one), then gpupdate /force on the machines.
If the collector address changes
The server certificate is bound to the address. When the address changes you must update the Collector address and do Regenerate + Save — that is a new CA, and the planned-renewal procedure above applies. The SubscriptionManager line on the Windows side (a new package on Path A, the GPO on Path B) is also updated to the new address. This is why choosing the address correctly in Step 1 matters; in a cluster always use the shared address.
Definition deletion rules
- Deletion is refused while
enabledclients exist: "This definition still has N enabled client(s)… Disable them first" (In some versions the banner text is not visible in the dark theme; an empty red banner means exactly this.). - Deleting a definition clears its
disabledmarks without warning and removes the definition's enterprise CA from the client-verification pool — machines holding certificates from that CA are rejected, even if they belong to another definition. - Even after the definition is deleted, 5986 stays open; every request is refused. Closing the port (removing the PKI) cannot be done from the interface → Logsign support.
============================================================
Troubleshooting
Almost every WEF failure is visible on the Windows side. Logsign only tells you "nothing arrived"; Windows tells you why.
| # | Where to look first | What it tells you |
|---|---|---|
| 1 | Logsign: definition form → Clients table | Is the machine visible, in which state, is Received climbing (last 30 minutes). There are no per-machine error counters in the interface in this version; for refusals use row 2 and, with console access, 5.5 |
| 2 | Windows: Microsoft-Windows-Forwarding/Operational
|
The primary source. Was the subscription created, with which error code |
| 3 | Windows: C:\ProgramData\LogsignWEF\startup.log (Path B) |
Did the startup script run, who obtained the certificate, was the permission granted |
| 4 | Windows: Microsoft-Windows-GroupPolicy/Operational (Path B) |
Was the GPO applied, which components ran |
Symptom → cause → fix
| Symptom | Cause | Fix |
|---|---|---|
| The machine never appears in the Clients table | It never reached the collector: no policy, 5986 closed/unreachable, WinRM not running, no trust in the certificate — or the IP is inside no definition's scope | On Windows check the SubscriptionManager value, Test-NetConnection <collector-address> -Port 5986, Get-Service WinRM and the Forwarding/Operational channel; compare Scope against the IP |
Machine pending, Last seen updating |
Not enabled | Enable |
Machine enabled, Received 0
|
Subscription not created, or a quiet machine | Is there an ID=100 on Windows? If so, wait 1–2 min and generate events. If not, see the ID/code tables |
Machine enabled, Received 0, and an ID=105 certificate error on Windows |
The machine's certificate is not from a trusted CA (Path A: a package from an old CA; Path B: wrong/missing enterprise CA PEM, or the wrong certificate is being selected on the machine) | Path A: install a new package. Path B: check the PEM on the definition and the IssuerCA thumbprint |
| The whole fleet went quiet at once | Somebody clicked Regenerate certificates and saved; or the server certificate reached its 825 days | Certificate lifecycle procedure |
| Application+System arrive, Security does not | NETWORK SERVICE cannot read Security (no Event Log Readers membership, or the token was not refreshed) |
Add-LocalGroupMember -SID 'S-1-5-32-573' -Member 'S-1-5-20' + Restart-Service WinRM -Force (on a DC this cmdlet does not exist/fails: Add-ADGroupMember -Identity 'S-1-5-32-573' -Members 'S-1-5-20', or the channel SDDL wevtutil sl Security /ca:…); on Server 2016 stop-wait-start, or add (A;;0x1;;;NS) to the channel SDDL (Timing traps → 2 below) |
| The channel I added does not arrive, but App+Sec+Sys flow | The machine was enabled with the default channels; a channel added to the definition afterwards does not reach an existing client | Add the channel on the machine's Data Collection card |
| One particular channel produces nothing | The channel name does not match exactly (ID=107), or the channel does not exist / cannot be read on the machine (5004) |
Verify the name with wevtutil el; the 5004 table |
| Events arrive with a constant time offset | The machine's time zone | Offset on the machine card |
| Search returns nothing | Time range, or the wrong source name | Set the range to today; start with EventSource.Collector:"wef", then narrow down |
| Enable refused with "Maximum device limit reached" | Device quota full | Remove unused devices or extend the licence; pending machines can wait |
| Download package: "No collector-managed CA is available" | Step 1 not done | Generate certificates + Save |
| Download package: "Save the certificate change first" | Unsaved change in the panel | Save first (or discard), then download |
| Saving the definition: narrowing the scope is refused with "Scope … leaves N client(s) outside the definition … Disable and delete them first." | An enabled/disabled machine would be left outside | Forget those machines (not Disable — a disabled machine still counts as outside), then narrow |
| Deleting the definition is refused | Enabled clients exist | Disable all of them, then Delete |
| SubscriptionManager still populated on the machine after removal | A Local Group Policy leftover (surfaces once the domain GPO is deleted; gpupdate does not clear it) |
gpresult /r /scope:computer → if Local Group Policy is present, remove the EventForwarding entry from the local registry.pol: gpedit.msc → Computer Configuration → Administrative Templates → Windows Components → Event Forwarding → Configure target Subscription Manager → Not Configured (see Removal) |
Windows Event ID reference (Microsoft-Windows-Forwarding/Operational)
| ID | Meaning | What to do |
|---|---|---|
| 100 | Subscription created ✅ | One per channel. This is the line you want |
| 101 | Subscription created, but one channel could not be read | The others flow; check that channel |
| 102 | Subscription could not be created, code usually 5004
|
The 5004 table |
| 103 | Unsubscribed | Normal — policy change / WinRM restart |
| 104 | Connected to the collector | ⚠ Not the same as done — the real signature is 100 |
| 105 | Communication/certificate problem; the code decides | The error code table |
| 106 | Policy changed | Normal |
| 107 | Policy invalid | Usually a mistyped channel name — or 0x80090016 (Keyset does not exist): the private-key permission is not there yet; on Path B the preparation script has not run yet, and it clears once the script has run and WinRM has restarted |
Error code reference
The text of the ID=105 event itself carries the explanation; read the event before looking up the code. Also: winrm helpmsg 0x<code>.
| Decimal | Hex | Actual cause | Fix |
|---|---|---|---|
| 2150858882 | 0x80338082 |
The certificate is not in the store, or IssuerCA points at the wrong CA |
Path A: was the package installed? Path B: did autoenrollment deliver, is IssuerCA the enterprise CA? |
| 995 | 0x3E3 |
A transient HTTP error while talking to the subscription manager — the collector settings were just saved (certificate mode/CA changed), or the machine has not been Enabled yet |
Transient; the machine retries every 60 seconds. It disappears within 1–2 minutes after Enable and gives way to one ID=100 per channel |
| 2148073494 |
0x80090016 "Keyset does not exist" |
The certificate is there, the private key cannot be read (no NETWORK SERVICE permission); seen under ID=105 or ID=107
|
Path B: the startup script did not run (the CSE/version step?). By hand: "private key permission" below |
| 2150859102 | 0x8033815E |
IssuerCA empty or malformed |
Fix the SubscriptionManager line (40 hex, no spaces) |
| 2150858770 | 0x80338012 |
The collector cannot be reached | Was Step 1 done (the port opens with the certificate)? Firewall? Is the address correct? |
| 2150859023 | 0x8033810F |
The collector returned HTTP 403: the machine has not been Enabled in Logsign yet (pending), or it has been Disabled
|
Step 4 — Enable the machine in the Clients table. Before Enable this code is normal; afterwards one ID=100 per channel arrives within 1–2 minutes |
| 5004 | — | A channel could not be read (WEF-specific) | The table below |
Two codes, the same sentence.
0x80338082and0x80090016produce the same message ("cannot find the certificate that was requested"). Whoever reads only the message concludes "no certificate" and pokes at the wrong place — the code is what separates them;…0016(a permission problem) is by far the more common one.certutil -error 5004returns an unrelated explanation; 5004 is WEF-specific.
Granting the private-key permission by hand (install.ps1 grants it on Path A; the script grants it on Path B; for emergencies): certlm.msc → Personal → Certificates → right-click the certificate → All Tasks → Manage Private Keys → Add → NETWORK SERVICE → Read. Then Restart-Service WinRM -Force.
Manage Private Keys (sample environment).
Read permission for NETWORK SERVICE (sample environment).
The two causes of 5004
wevtutil gl "Microsoft-Windows-Sysmon/Operational"
| Result | Cause | Fix |
|---|---|---|
| The command errors, no such channel | The software producing the channel is not installed (e.g. Sysmon) | Install the software or remove the channel from the machine's card (not the definition's Default channels) |
| The channel exists, subscription still 5004 | NETWORK SERVICE cannot read that channel | Event Log Readers membership (by SID) + WinRM restart; on Server 2016 stop-wait-start, or add (A;;0x1;;;NS) to the channel SDDL (Timing traps → 2) |
This failure is silent. Even when Security drops, Application and System keep flowing — the machine looks "connected",
Receivedclimbs, but the most valuable channel has been cut. Count theID=100lines per channel.
Timing traps — the "installed but not working" illusion
1. The first event from a quiet machine can take up to a minute. Delivery is a separate subscription per channel and has two triggers: when the envelope reaches 512 KB, or when 60 seconds elapse. The heartbeat is 900 seconds and is not a delivery trigger. There is no count-based trigger; a machine cannot flush early on "I have collected 20 events". Keep your verification window at 2–3 minutes at least, and generate events if needed (the command in Step 4).
2. On Server 2016,
Restart-Service WinRMmay not be enough. If the Event Log Readers membership was added during that same boot, the new group does not enter the existing WinRM token and Security fails withID=102/5004. On Server 2019 and later a service restart is sufficient. On Server 2016 stop WinRM, wait 10 seconds and start it again:Stop-Service WinRM -Force; Start-Sleep 10; Start-Service WinRM. If it is still5004, add(A;;0x1;;;NS)to the channel's SDDL (wevtutil sl <channel> /ca:…) — this requires no restart. The preventive route: distribute the membership via GPO ahead of time (Path B does this).
3. Autoenrollment is delayed at boot (Path B). If you do not see the certificate after the first run of the script, look at the
after pulseline instartup.log; the script may have used the fallback. If there is still no certificate after running the SYSTEM task once more (3B.10), check in order: is the enterprise CA in the Root store, is the template published, is the Autoenroll right granted, isAEPolicy=7.
Old/unpatched Windows: the certificate can never be obtained (Path B)
An unpatched Windows cannot obtain a certificate from a modern CA server (Server 2022/2025). The cause is DCOM hardening: the server side demands a higher authentication level than the client offers, and on Server 2022/2025 that cannot be turned off. The client-side compliance shipped with the June 2021 cumulative update.
The symptom and the cause live on different machines. All the client shows is
0x800706BA "The RPC server is unavailable"— which reads like a network/port problem and sends people hunting through firewalls for hours. The real explanation is in the CA server's System log:Get-WinEvent -FilterHashtable @{LogName='System'; Id=10036} -MaxEvents 5 -ErrorAction SilentlyContinue | Format-List TimeCreated,Message # "The server-side authentication level policy does not allow the user <domain>\<machine>$ ... to activate DCOM server"
The distinguishing test (on the client, with a domain account): certutil -ping -config "<ca-server-fqdn>\<enterprise-ca-name>". A healthy machine returns "interface is alive"; a broken one is refused with 0x800706ba within milliseconds — a fast rejection, not a slow timeout. Run the same command on a working machine too; if it succeeds there, the CA is healthy and the problem is specific to that client.
| Fix | Note |
|---|---|
| 1. Patch the machine | The only real fix. For Server 2016, the June 2021 or a later cumulative. A machine far behind will not get there in one pass; Windows Update advances in stages |
| 2. If it cannot be patched | Use Path A for that machine — the Logsign package does not touch DCOM. (For mixed use within the same definition, create a separate definition: Logsign PKI mode, with only those machines' IPs.) This machine also shows as pending in the Path B definition's scope; do not Enable it there. |
| 3. Turning off hardening on the CA | ❌ Do not try — it has been removed as of Server 2022 |
In a "some machines arrive, some never do" picture, check the patch level of the ones that don't:
(Get-CimInstance Win32_OperatingSystem).BuildNumber.ToString() + "." + (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion').UBR
If you need a clean slate: full cleanup on the Windows side
# On Path B do the GPO removal in the Removal section + gpupdate /force FIRST, then this block (while the GPO is linked the settings come back; New-GPO stops on the existing name)
# 1. SubscriptionManager - do NOT delete the whole key; there may be several numbered entries (a second collector)
# On Path B the key is already gone once the GPO is removed and gpupdate /force has run: reg export then fails with "...key or value" - harmless. This step is for Path A (or when you wrote the entry by hand).
$SM = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\EventForwarding\SubscriptionManager'
reg export "HKLM\SOFTWARE\Policies\Microsoft\Windows\EventLog\EventForwarding" C:\wef-backup.reg /y
Get-ItemProperty $SM -EA SilentlyContinue | Format-List # READ THIS FIRST
(Get-ItemProperty $SM -EA SilentlyContinue).PSObject.Properties |
Where-Object { $_.Name -match '^\d+$' -and $_.Value -like "*<collector-address>*" } |
ForEach-Object { Remove-ItemProperty -Path $SM -Name $_.Name -EA SilentlyContinue }
# 2a. Path A certificates (Logsign PKI) - filtered by ISSUER: leaves the Logsign Agent's O=Logsign certificate alone
Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.Issuer -like '*Logsign WEF CA*' } | ForEach-Object { Remove-Item ("Cert:\LocalMachine\My\"+$_.Thumbprint) -DeleteKey }
Get-ChildItem Cert:\LocalMachine\Root | Where-Object { $_.Subject -like '*Logsign WEF CA*' } | ForEach-Object { Remove-Item ("Cert:\LocalMachine\Root\"+$_.Thumbprint) }
Remove-Item C:\wef-setup -Recurse -Force -EA SilentlyContinue # the package folder: the PFX and its password in README.txt
# On a Windows 10/11 client put WinRM back to its old state (on a server it was Automatic already; leave it): Set-Service WinRM -StartupType Manual
# 2b. Path B - the client certificate belongs to your enterprise CA and serves other purposes too: do NOT delete it (on a DC it is the Kerberos Authentication / Domain Controller Authentication certificate).
# The only thing to undo is NETWORK SERVICE's private-key permission: certlm.msc -> Personal -> Certificates -> the certificate -> All Tasks -> Manage Private Keys -> remove NETWORK SERVICE;
# or by the key-file path from the "PERMISSION GRANTED:" line in startup.log (SID form, language-independent):
icacls "<key-file>" /remove "*S-1-5-20"
Remove-Item "Cert:\LocalMachine\Root\<logsign-ca-thumbprint>" -ErrorAction SilentlyContinue # already gone once the GPO is removed
# 3. Script leftovers, Security channel permission and group membership (S-1-5-20 only)
Remove-Item C:\ProgramData\LogsignWEF -Recurse -Force -EA SilentlyContinue
# remove the (A;;0x1;;;NS) part that install.ps1 (Path A) or you added by hand from the Security channel SDDL; if it is not there nothing changes
$ca = (wevtutil gl Security | Select-String '^channelAccess:').Line -replace '^channelAccess:\s*',''
if ($ca) { $ca = $ca -replace '\(A;;0x1;;;NS\)',''; wevtutil sl Security /ca:$ca }
Remove-LocalGroupMember -SID 'S-1-5-32-573' -Member 'S-1-5-20' -EA SilentlyContinue # on a DC: Remove-ADGroupMember -Identity 'S-1-5-32-573' -Members 'S-1-5-20'
Restart-Service WinRM -Force============================================================
Removal
Order matters: Logsign first, then the GPO, then the clients. If you clean a client while the GPO is still in place, everything comes back at the next boot.
1 · Logsign side
-
Settings → Integrations → Windows Event Forwarding→ click the definition → Disable every machine in the Clients table. - Return to the definitions list → Delete in the row's Actions column. If enabled clients remain it is refused; Disable all of them and try again. Delete opens a confirmation dialog (Enable/Disable/Forget do not); once you confirm, the definition and its settings are gone for good.
This much stops collection. No machine can obtain a subscription; every incoming request is refused. Port 5986 stays open — the listener depends on the collector's server certificate, not on the definitions. That is expected, and nothing is collected. Closing the port as well (removing the PKI) cannot be done from the interface; do it together with Logsign support.
2A · Windows — Path A
On every machine, steps 1, 2a and 3 of the block in the “If you need a clean slate: full cleanup on the Windows side” box in Troubleshooting (the box is collapsed; click its title to open it). The filter in 2a selects only the certificate issued by Logsign WEF CA; if the Logsign Agent is installed on the same machine, its O=Logsign certificate is left untouched.
2B · Windows — Path B
On the DC:
Import-Module GroupPolicy, ActiveDirectory
$gpo = Get-GPO -Name 'Logsign WEF Collection'
Remove-GPLink -Guid $gpo.Id -Target (Get-ADDomain).DistinguishedName -EA SilentlyContinue # or the OU you linked
Remove-GPO -Guid $gpo.Id
# the SYSVOL folder goes with Remove-GPO; if it remains, delete it by hand:
$GUID = "{$($gpo.Id.ToString().ToUpper())}"
Remove-Item "C:\Windows\SYSVOL\sysvol\$((Get-ADDomain).DNSRoot)\Policies\$GUID" -Recurse -Force -EA SilentlyContinue
# Optional: revoke the Autoenroll right on the template (only if you granted it for WEF alone; if anything else relies on the Computer template's autoenrollment, skip these lines)
$templateDN = "CN=Machine,CN=Certificate Templates,CN=Public Key Services,CN=Services," +
(Get-ADRootDSE).configurationNamingContext
$sid = New-Object System.Security.Principal.SecurityIdentifier(((Get-ADDomain).DomainSID.Value + "-515"))
$acl = Get-Acl "AD:$templateDN"
$acl.Access | Where-Object { $_.ObjectType -eq 'a05b8cc2-17bc-4802-a710-e7c15ab866a2' -and $_.AccessControlType -eq 'Allow' -and $_.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]).Value -eq $sid.Value } | ForEach-Object { [void]$acl.RemoveAccessRule($_) }
Set-Acl -AclObject $acl -Path "AD:$templateDN"If you want to revoke the Autoenroll right on the template, run the optional lines at the end of the block (only if you granted it for WEF alone; if anything else relies on the Computer template's autoenrollment, leave it).
On every client: gpupdate /force, then steps 1, 2b and 3 of the block in the “If you need a clean slate: full cleanup on the Windows side” box in Troubleshooting.
⚠ Avoid four destructive mistakes during removal.
1. Do not delete every certificate. A filter of
Issuer -like '*CA*'means "everything this CA ever issued". On Path A the filter goes by issuer (Logsign WEF CA); on Path B the client certificate belongs to your enterprise CA and is not deleted — on a DC it is the Kerberos Authentication / Domain Controller Authentication certificate, and deleting it breaks the DC; the only thing to undo is NETWORK SERVICE's private-key permission (2b in the block).2. Do NOT delete
%windir%\System32\GroupPolicy. That is not the domain GPO cache; it is the local Group Policy object, where your hardening baseline lives, andgpupdate /forcewill not bring it back. If SubscriptionManager is still populated after removal, checkgpresult /r /scope:computerfor a Local Group Policy entry; back up the EventForwarding entry in the localregistry.poland remove only that:gpedit.msc → Computer Configuration → Administrative Templates → Windows Components → Event Forwarding → Configure target Subscription Manager → Not Configured.3. Do not delete the whole
EventForwardingkey. There may be several numbered entries under SubscriptionManager (a second collector). Read first; delete only the entry containing your own collector address.4. Do not empty the Event Log Readers group. Remove only
S-1-5-20; the other members from your inventory stay.