Field notes

Field note: a screen lock GPO with an exemption group, and the Kerberos ticket that has to come first

An audit required a 30-minute screen lock on every domain PC, except the dispatch consoles. Linking the GPO at the domain root with a deny for an exemption group worked, but only after the exempt machines picked up their new group membership.

An audit required every domain PC at a small agency to lock after 30 minutes of inactivity. Reasonable, except for the dispatch consoles. Those screens have to stay up, and a console locking in the middle of a call is not an option.

So the job was: lock everything, except a handful of specific machines. Two things made it more interesting than it sounds.

What it looked like

The first problem was where the computers lived. Plenty of active PCs were still sitting in the default Computers container, the place new machines land when they join the domain. That’s a container, not an OU, and Group Policy can’t be linked to it. A GPO linked to an OU would never reach those machines.

The obvious fix is to move them into OUs. The trouble is that the OUs they’d go into already had other GPOs linked, and moving a pile of machines just to get one setting would drag a lot of unrelated policy along with it.

The fix

I created a new GPO with one computer-side setting: Interactive logon: Machine inactivity limit set to 1800 seconds (30 minutes). It lives under Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options, and it writes the InactivityTimeoutSecs value on the PC.

I linked it at the domain root, so it reaches every computer no matter which container or OU it’s in.

For the exceptions, I made a security group, put the dispatch console computer accounts in it, and added a Deny entry for that group on the GPO’s Apply Group Policy permission. Under the hood that’s the Apply-Group-Policy extended right, GUID edacfd8f-ffb3-11d1-b41d-00a0c968f939, in case you’re setting it with a script instead of clicking. In the Group Policy Management Console it’s on the GPO’s Delegation tab under Advanced. (Microsoft’s own steps for an exception group deny Read as well.)

Why not block inheritance?

I considered putting the consoles in their own OU with Block Inheritance turned on. I rejected it because block inheritance doesn’t block just one GPO. It stops everything linked above that OU from applying, except links marked Enforced. The consoles would have lost the screen lock and every other domain-level policy they were supposed to get. A deny entry on one GPO only affects that one GPO.

The step that matters: refresh the exempt machines first

This is the part that’s easy to miss. A computer only picks up a new group membership when it gets a new Kerberos ticket, which normally happens at restart. Add a console to the exemption group and link the GPO right away, and that console still has its old ticket, doesn’t know it’s exempt yet, and applies the screen lock anyway.

So before linking the GPO, I ran this on each exempt machine through the RMM tool:

klist -li 0x3e7 purge
echo n | gpupdate /force

klist -li 0x3e7 purge clears the cached Kerberos tickets for the computer’s own (SYSTEM) logon session, so the next request gets a fresh ticket with the new group in it. The echo n | answers “no” if gpupdate asks to log off or restart, so the command doesn’t sit waiting in a remote session nobody’s watching.

Then I confirmed each one:

gpresult /r /scope computer

Once each exempt machine listed the exemption group among its computer security groups, I linked the GPO.

Microsoft’s documentation for this setting notes that a change takes effect after a restart, so plan on the lock showing up on the other PCs after their next reboot, not the moment you link it.

A confusing detail in PowerShell

When I checked the GPO’s permissions with Get-GPPermission, the exemption group showed up as GpoCustom with Denied set to False. That looks like the deny didn’t take. It did. A deny-only entry just doesn’t map onto any of the cmdlet’s standard permission levels, so it gets lumped into “custom.” Look at the GPO’s actual access list (the Advanced view on the Delegation tab) to see the deny.

What I took away from it

  • When machines are scattered, link at the root instead of moving them into OUs that bring unrelated GPOs with them.
  • A deny entry beats block inheritance when you need to exclude a few machines from one GPO. Block inheritance takes everything else away too.
  • Refresh the machine’s Kerberos ticket before the deny matters. Group membership changes don’t reach a computer until it gets a new ticket.
  • Don’t trust Get-GPPermission alone for deny entries. “GpoCustom” with Denied False can still mean a working deny. Check the access list.

Sources

All articles