IT Support & Help Desk Fundamentals Module 10 – Accounts, directories and access
Group Policy for support: apply, check, fix
Work out which GPO sets each setting on a Windows client with gpresult, force a refresh with gpupdate, and fix drive maps, printers and slow sign-ins.
What you will learn
- Explain how Group Policy objects are linked, inherited and processed
- Work out which setting wins when several GPOs apply to one user
- Check applied policy with gpresult and force a refresh with gpupdate
- Diagnose drive maps, printers and slow sign-ins delivered by policy
Before you start
What you’ll learn · Before you start
What you will learn
- Explain how Group Policy objects are linked, inherited and processed
- Work out which setting wins when several GPOs apply to one user
- Check applied policy with gpresult and force a refresh with gpupdate
- Diagnose drive maps, printers and slow sign-ins delivered by policy
Before you start
On this page
A caller says their H drive is missing after they moved from Finance to the Service Desk team. Their password works,
Outlook opens and no error appears: Group Policy simply did not map the drive on this sign-in. A technician who reads
the gpresult: A Windows command that displays the resultant set of policy that applied on a sign-in. /r prints a summary; /h writes an HTML report; on ARM64 only the gpresult in SysWow64 works with /h. summary (gpresult /r), finds the
Group Policy Preferences: A set of Group Policy client-side extensions that deliver preference settings such as drive maps, printers and files to domain-joined computers. Short name GPP. Each item can carry an item-level target that is checked on the client. item whose
item-level targeting: A per-item condition on a Group Policy Preferences item that decides whether the item applies on this sign-in. Microsoft's reference lists OU, group membership, IP range, computer name and WMI as targets. still names the old team, and has that target corrected
can prove the fix with gpupdate: A Windows command that refreshes Group Policy on the local PC. /force reapplies every setting rather than only changed ones; /logoff and /boot drain CSEs that run only at sign-in or startup; /sync marks the next foreground run synchronous. and a fresh sign-in within minutes.
Three things make that possible, and each has a section here: the fixed order in which Windows applies Group Policy to a PC and to a user, the rules that pick one winner when several GPOs set the same thing, and the two commands that show what a client has loaded and make it load again. A resolver you can run puts the rules to work on six layouts, and an exercise asks you to write it yourself.
A GPO reaches a PC only through a link, in a fixed order
A Group Policy object: Windows's way of pushing settings to many PCs and users at once. A container in Active Directory plus a template on each domain controller's SYSVOL share. Its short name is GPO. (a GPO) is Windows’s way of pushing settings to many PCs and users at once. Microsoft’s Group Policy overview splits it into two parts: a Group Policy container, kept in the domain partition of Active Directory, and a Group Policy template, a folder of files on every domain controller’s SYSVOL: A share on every Active Directory domain controller that stores the Group Policy templates and sign-in or startup scripts for the domain. Its contents replicate between domain controllers through DFSR. share. The two halves replicate by different routes, the container with Active Directory and the template through DFS Replication, so a fresh change can reach a domain controller in pieces.
A GPO on its own does nothing. It acts only as a linked GPO: A Group Policy object pointed at a site, a domain or an organisational unit by a link in the Group Policy Management Console. A GPO reaches a client only through a link, never by its own name., pointed at a container the user or computer belongs to: an Active Directory site, a domain, or an organisational unit: A container an administrator creates inside an Active Directory domain to hold users, computers and groups, so that Group Policy can be linked to it and control over its objects can be delegated. More in “Directory services and Active Directory basics” on the path to the object. The link, not the GPO, sets the scope, so one GPO can serve two OUs through two links, and deleting one of them leaves the other working.
Step through one laptop starting up and one user signing in, and watch which container is applied at each stage:
The drawing shows the whole scene; its 7 steps are listed below.
Every step as text
- The PC starts up. INDIA-LT-07 powers on in the Mumbai office. As it starts, the Group Policy service asks Active Directory which GPOs apply to the computer object: those linked to its site, its domain and the OUs above it.
- Local GPO. The local GPO on the laptop is applied first: settings made with gpedit.msc on the PC itself. Microsoft notes that every computer receives one, which is useful for computers that are not members of a domain.
- Site GPOs. Next come the GPOs linked to the PC's Active Directory site, Mumbai-Site. Microsoft's overview says few settings are applied at site level, and because the domain and OU links come after them, a site setting holds only where no later link sets the same thing.
- Domain GPOs. The PC then applies the GPOs linked to the domain corp.example.com. Microsoft's overview notes that some settings, password policies in particular, are applied at the domain level.
- OUs from parent to child. Finally, the PC applies the GPOs linked to each OU on the path to the computer object, from the shallowest down to the OU that holds the laptop itself. The article puts parent OUs before child OUs, so the OU closest to the laptop is applied last, and its settings override those applied earlier when both set the same setting.
- The user signs in. When Asha signs in, the Group Policy service builds a second list, this time for the user object. The same five containers are applied in the same order against the user's own path in the directory, so a user setting follows the user and a computer setting follows the computer.
- Refresh every 90 minutes. Microsoft's article says the client refreshes Group Policy every 90 minutes with a random offset of up to 30 minutes, so a change to a GPO reaches a running PC without a restart. Folder redirection and software installation wait for their start-up and sign-in events, and scripts run only on their own events.
The order is the one Microsoft’s Group Policy processing article gives: the local GPO first, then GPOs linked to the
site, then those linked to the domain, then those linked to each OU from the parent down to the child that holds the
object. Each later layer can overwrite what an earlier one set, so the OU closest to the user or computer has the last
word by default. For a user whose distinguished name is
CN=Asha Patel,OU=Service Desk,OU=IT,OU=Mumbai,DC=corp,DC=example,DC=com, the Mumbai OU is processed first and the
Service Desk OU last: the OU parts are read from right to left. Computer settings apply when the PC starts and user
settings when the user signs in, a first run Microsoft calls foreground processing. It is synchronous when the start
or the sign-in waits for policy to finish, and asynchronous when the desktop may appear first.
The local GPO still runs first
On a managed PC the local GPO is often empty, so it is easy to forget. Windows still processes it before every link,
and any later link can overwrite it, so a setting that shows up on one PC and on none of its neighbours is worth
checking in gpedit.msc on that PC.
Checkpoint
Check: Linking, inheritance and processing order
Which setting wins when several GPOs apply?
Two GPOs can set the same thing and disagree. On a ticket the useful question is not what somebody set but what the
PC applied, and three rules decide it. The resolver below applies them to six layouts of one setting, the screen saver
timeout ScreenSaverTimeOut, and prints each winner with the rule that picked it:
"""Resolve the winning value of one Group Policy setting across a list of
GPO links, following Microsoft's Group Policy processing article.
Each link is a dict with these keys:
scope one of "local", "site", "domain" or "ou"
ou_depth integer: 0 for the shallowest OU, 1 for its child, and so
on. Ignored for scopes other than "ou".
link_order the Group Policy Management Console link-order number
(the GPMC default starts at 1 and counts up).
The link with the LOWEST link_order has precedence
within one container.
enforced True when the link is marked enforced (sometimes called
"no override" in older documentation).
value the setting's value in that GPO
name an optional human name for the link, used in the output
The second argument of `winning_value` is a `block_inheritance_set`: a set
of ("scope", ou_depth) tuples naming the containers whose GPOptions mark
"Block Inheritance". The GP processing article says this stops local, site,
domain and higher OU levels from affecting that container, but that the
enforced option bypasses the block.
The resolver prints one row per layout: the layout id, the winning value and
a one-line reason. It never changes a policy and never bypasses one; it only
spells out which link the processing order makes the winner.
"""
SCOPE_RANK = {"local": 0, "site": 1, "domain": 2, "ou": 3}
def _position(link):
"""Return the link's position in the processing order.
Smaller tuples come earlier (local first, then site, then domain, then
OUs from the shallowest to the deepest). The tuple compares the way the
GP processing article describes: local < site < domain < OU parent
< OU child. The OU depth is counted from 0 at the shallowest OU.
"""
scope = link["scope"]
rank = SCOPE_RANK[scope]
depth = link.get("ou_depth", 0) if scope == "ou" else 0
return (rank, depth)
def _is_blocked_above(link, block_set):
"""True when an unenforced link should be dropped by Block Inheritance.
Block Inheritance is a container property. For each blocking container
in `block_set`, any link whose position is strictly higher in the
hierarchy is dropped, unless the link is enforced (enforced beats
block, per the GP processing article).
"""
if link["enforced"]:
return False
link_pos = _position(link)
for scope, depth in block_set:
blocker_pos = (SCOPE_RANK[scope], depth)
if link_pos < blocker_pos:
return True
return False
def winning_value(links, setting, block_inheritance_set=None):
"""Return (value, link_name) for the setting, or (None, reason).
The rules follow the Group Policy processing article:
* Enforced beats unenforced.
* Among enforced links, the highest in the hierarchy wins (the one in
the container closest to the root). Within one container, the link
with the lowest link_order wins.
* Among unenforced links, the deepest container wins. Within one
container, the link with the lowest link_order wins.
* Block Inheritance drops unenforced links that come from above the
blocking container.
"""
block = set(block_inheritance_set or set())
survivors = [link for link in links if not _is_blocked_above(link, block)]
if not survivors:
return None, "no link applies after Block Inheritance"
enforced = [link for link in survivors if link["enforced"]]
if enforced:
highest = min(_position(link) for link in enforced)
pool = [link for link in enforced if _position(link) == highest]
winner = min(pool, key=lambda link: link["link_order"])
reason = (
f"enforced link in {winner['scope']}"
+ (
f" depth {winner['ou_depth']}"
if winner["scope"] == "ou"
else ""
)
+ f", link order {winner['link_order']}"
)
return winner["value"], f"{winner.get('name', '(unnamed)')} ({reason})"
unenforced = [link for link in survivors if not link["enforced"]]
deepest = max(_position(link) for link in unenforced)
pool = [link for link in unenforced if _position(link) == deepest]
winner = min(pool, key=lambda link: link["link_order"])
reason = (
f"deepest container {winner['scope']}"
+ (
f" depth {winner['ou_depth']}"
if winner["scope"] == "ou"
else ""
)
+ f", lowest link order {winner['link_order']}"
)
return winner["value"], f"{winner.get('name', '(unnamed)')} ({reason})"
LAYOUTS = [
{
"id": "A: one domain-linked GPO",
"setting": "ScreenSaverTimeOut",
"links": [
{
"name": "Default Domain Policy",
"scope": "domain",
"ou_depth": 0,
"link_order": 1,
"enforced": False,
"value": "900",
},
],
"block_inheritance_set": set(),
},
{
"id": "B: two siblings at the same OU",
"setting": "ScreenSaverTimeOut",
"links": [
{
"name": "IT Baseline",
"scope": "ou",
"ou_depth": 2,
"link_order": 2,
"enforced": False,
"value": "900",
},
{
"name": "Service Desk Kiosk",
"scope": "ou",
"ou_depth": 2,
"link_order": 1,
"enforced": False,
"value": "300",
},
],
"block_inheritance_set": set(),
},
{
"id": "C: deeper OU overrides shallower OU",
"setting": "ScreenSaverTimeOut",
"links": [
{
"name": "Mumbai GPO",
"scope": "ou",
"ou_depth": 0,
"link_order": 1,
"enforced": False,
"value": "600",
},
{
"name": "Service Desk GPO",
"scope": "ou",
"ou_depth": 2,
"link_order": 1,
"enforced": False,
"value": "300",
},
],
"block_inheritance_set": set(),
},
{
"id": "D: enforced at domain beats deeper unenforced",
"setting": "ScreenSaverTimeOut",
"links": [
{
"name": "Corp Security Baseline",
"scope": "domain",
"ou_depth": 0,
"link_order": 1,
"enforced": True,
"value": "600",
},
{
"name": "Classroom override",
"scope": "ou",
"ou_depth": 2,
"link_order": 1,
"enforced": False,
"value": "1800",
},
],
"block_inheritance_set": set(),
},
{
"id": "E: Block Inheritance at an OU stops unenforced parent links",
"setting": "ScreenSaverTimeOut",
"links": [
{
"name": "Default Domain Policy",
"scope": "domain",
"ou_depth": 0,
"link_order": 1,
"enforced": False,
"value": "900",
},
{
"name": "Reception Lockdown",
"scope": "ou",
"ou_depth": 1,
"link_order": 1,
"enforced": False,
"value": "180",
},
],
"block_inheritance_set": {("ou", 1)},
},
{
"id": "F: two enforced links: highest in the hierarchy wins",
"setting": "ScreenSaverTimeOut",
"links": [
{
"name": "Corp Security Baseline",
"scope": "domain",
"ou_depth": 0,
"link_order": 1,
"enforced": True,
"value": "600",
},
{
"name": "Finance Enforced Override",
"scope": "ou",
"ou_depth": 1,
"link_order": 1,
"enforced": True,
"value": "300",
},
],
"block_inheritance_set": set(),
},
]
print(f"{'layout':<60} {'winner':>8} reason")
print("-" * 110)
for layout in LAYOUTS:
value, note = winning_value(
layout["links"],
layout["setting"],
layout["block_inheritance_set"],
)
print(f"{layout['id']:<60} {value!s:>8} {note}")
print()
print(
f"Resolved {len(LAYOUTS)} layouts against the GP processing rules "
f"(Microsoft's Group Policy processing article)."
) Output
layout winner reason -------------------------------------------------------------------------------------------------------------- A: one domain-linked GPO 900 Default Domain Policy (deepest container domain, lowest link order 1) B: two siblings at the same OU 300 Service Desk Kiosk (deepest container ou depth 2, lowest link order 1) C: deeper OU overrides shallower OU 300 Service Desk GPO (deepest container ou depth 2, lowest link order 1) D: enforced at domain beats deeper unenforced 600 Corp Security Baseline (enforced link in domain, link order 1) E: Block Inheritance at an OU stops unenforced parent links 180 Reception Lockdown (deepest container ou depth 1, lowest link order 1) F: two enforced links: highest in the hierarchy wins 600 Corp Security Baseline (enforced link in domain, link order 1) Resolved 6 layouts against the GP processing rules (Microsoft's Group Policy processing article).
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 gpo_winner.py
The six layouts are one link alone (A), two siblings on one OU (B), a shallow and a deep OU on one path (C), an enforced domain link (D), Block Inheritance on an OU (E) and two enforced links on one path (F). Answer the three questions about your own ticket in the table, and it rules out the layouts that do not match:
Answer the questions above: the table then marks what fits your case and says why the rest does not.
| Layout | Rule that decides | Winning value | When it fits |
|---|---|---|---|
| One link at domain | Good nothing competes, so the one link wins | Good 900 s, from the Default Domain Policy | Good early in a troubleshoot, when only one GPO is linked |
| Two siblings, same OU | Good same container, lowest link order wins | Good 300 s, from the sibling with link order 1 | Good two GPOs on the Service Desk OU argue, both unenforced |
| Deeper OU wins | Good closest container to the user or computer wins | Good 300 s, from the Service Desk OU, two levels deep | Good a shallow OU and a deep OU set the same setting both unenforced |
| Enforced at domain | Good enforced beats a deeper unenforced link | Good 600 s, from the domain Security Baseline | Good a wide policy must not be weakened by a lower link |
| Block Inheritance set | Mixed Block Inheritance drops unenforced parent links | Good 180 s, from the Reception Lockdown OU | Mixed an OU wants to ignore everything from above, no enforced parents |
| Two enforced in chain | Good among enforced, highest in the hierarchy wins | Good 600 s, from the domain, over the OU enforced link | Mixed two teams both marked a link enforced; the top one wins |
How the answers decide
- “Where is the setting defined in your case?” Only at the domain and “Is any link in play marked enforced?” No enforced links: rules out Two siblings, same OU, Deeper OU wins, Enforced at domain, Block Inheritance set and Two enforced in chain. One domain link is the only candidate, so the single-link layout is the match.
- “Where is the setting defined in your case?” In two or more OUs on the user path and “Is any link in play marked enforced?” No enforced links and “Does any container on the path have Block Inheritance set?” No Block Inheritance: adds a caveat to Two siblings, same OU. Two OUs on the same path mean the deeper one wins, unless the two links are actually siblings at the same OU.
- “Is any link in play marked enforced?” One enforced link: rules out One link at domain, Two siblings, same OU, Deeper OU wins, Block Inheritance set and Two enforced in chain. An enforced link beats an unenforced parent or child, so the enforced-at-the-top layout is the match.
- “Is any link in play marked enforced?” Two or more enforced links: rules out One link at domain, Two siblings, same OU, Deeper OU wins, Enforced at domain and Block Inheritance set. With two enforced links in the same chain, the highest in the hierarchy wins; that is the two-enforced layout.
- “Does any container on the path have Block Inheritance set?” Yes, at one OU and “Is any link in play marked enforced?” No enforced links: rules out One link at domain, Deeper OU wins, Enforced at domain and Two enforced in chain. Block Inheritance drops unenforced parents, so the blocked layout is the match; enforced parents would still get through.
These are the three rules, with the layouts that show each one:
- The container closest to the user or computer wins. A domain value is applied first and an OU value later, so the OU’s value stands, and among nested OUs the deepest wins. In layout C the Service Desk OU’s 300 seconds beats the Mumbai OU’s 600.
- Within one container, the link with the lowest link order wins. The Group Policy Management Console can hold many links on one OU, and Microsoft’s processing article gives precedence to the lowest number in its list of GPO links. In layout B, Service Desk Kiosk at link order 1 (300 seconds) beats IT Baseline at link order 2 (900).
- An enforced link: A Group Policy link marked enforced in GPMC, called no-override in older documentation. Microsoft's processing article says the highest enforced link in the chain wins over lower unenforced links and bypasses Block Inheritance. beats both. GPOs in lower containers cannot override an enforced one, so in layout D the domain’s enforced 600 seconds beats an OU’s 1,800, and when the domain and an OU are both enforced (layout F), the domain’s 600 still stands.
Block Inheritance: A property on a domain or OU that stops local, site, domain and higher OU Group Policy links from reaching that container. Enforced links in parent containers still pass through, so Block Inheritance is only partial. is set on a domain or an OU and stops unenforced links from above it. In layout E the Reception OU blocks inheritance, so the Default Domain Policy’s 900 seconds is dropped and the OU’s own 180 seconds applies. An enforced parent would still get through: the processing article calls enforced a link property that takes precedence over Block Inheritance, which is a property of the container.
Marking a GPO enforced to win an argument
Wrong: setting a link to enforced so that it beats another GPO. The value then lands on every OU below it, including
ones nobody meant to change. Right: read which link wins now with gpresult, agree with the GPO owners which policy
should win, and change the link that must not win, so the change lands only where it belongs.
Checkpoint
Check: Which setting wins across GPOs
gpresult shows what applied, gpupdate makes it apply now
A Group Policy ticket is about what one PC actually has. Microsoft’s gpresult page describes its report as the
resultant set of policy: the settings in force on that computer for a user, at that user’s sign-in. The command
will not run without an output option (/r, /v, /z, /x or /h), and four forms do the work on a desk:
gpresult /rprints a summary: the GPOs that applied, the GPOs filtered out with the reason, and the groups of the sign-in.gpresult /h report.html /fwrites a detailed HTML report and overwrites an older file of that name. On ARM64 Windows, Microsoft notes, only thegpresultinSysWow64works with/h.gpresult /scope user /ror/scope computer /rreports one half, so a user problem is not read through the computer’s settings.gpresult /user CORP\name /rnames the user to report on. From a prompt opened with another account, such as your own administrator account, it keeps the report on the caller’s sign-in rather than on the prompt’s account.
The parser below reads an invented gpresult /r transcript, written in the layout the command prints and with
placeholder names, and keeps the three fields a ticket note needs:
"""Summarise a `gpresult /r` transcript into Applied GPOs, Filtered GPOs
with their reason, and the sign-in's security groups.
`gpresult` itself runs only on Windows, and its `/r` summary is plain text,
so this script reads a hand-written transcript of typical output
(`gpresult_sample.txt`) whose field names and section headers follow the
`gpresult` documentation.
Every tenant, user name and host name in the sample is placeholder text.
The parser recognises three sections per scope (user and computer):
"Applied Group Policy Objects"
"The following GPOs were not applied because they were filtered out"
"The user is a part of the following security groups" (or "computer")
Within the filtered section, each GPO is followed by a `Filtering:` line
that names the reason. This script prints a tidy summary per scope that a
support technician would paste into a ticket, trimmed to the three fields
the lesson asks about and never the sign-in's full distinguished name.
"""
import re
from pathlib import Path
HERE = Path(__file__).resolve().parent
SCOPE_HEADERS = ("USER SETTINGS", "COMPUTER SETTINGS")
APPLIED_HEADER = "Applied Group Policy Objects"
FILTERED_HEADER = (
"The following GPOs were not applied because they were filtered out"
)
GROUPS_HEADER_RE = re.compile(
r"^\s*The (?:user|computer) is a part of the following security groups\s*$"
)
FILTER_RE = re.compile(r"^\s*Filtering:\s*(.*?)\s*$")
UNDERLINE_RE = re.compile(r"^\s*-{3,}\s*$")
BLANK_RE = re.compile(r"^\s*$")
def _split_by_scope(lines):
"""Return [(scope_name, lines)] for every USER SETTINGS and COMPUTER
SETTINGS section in the transcript.
"""
scopes = []
current = None
for line in lines:
stripped = line.strip()
if stripped in SCOPE_HEADERS:
if current is not None:
scopes.append(current)
current = (stripped.split()[0].lower(), [])
continue
if current is not None:
current[1].append(line)
if current is not None:
scopes.append(current)
return scopes
def _collect_items(lines, start, stop_headers):
"""Yield each non-blank, non-underline, non-dashed child line of a
section until a stop header or the end of the block.
"""
items = []
i = start
# Skip the underline right under the header.
while i < len(lines) and UNDERLINE_RE.match(lines[i]):
i += 1
while i < len(lines):
line = lines[i]
stripped = line.strip()
if stripped in stop_headers or GROUPS_HEADER_RE.match(line):
break
if not BLANK_RE.match(line) and not UNDERLINE_RE.match(line):
items.append(line)
i += 1
return items
def parse_scope(name, lines):
"""Return a dict for one scope with the three fields.
applied list of GPO names in the order gpresult printed them.
filtered list of (gpo name, reason) tuples.
groups list of group names.
"""
applied, filtered, groups = [], [], []
i = 0
while i < len(lines):
line = lines[i]
stripped = line.strip()
if stripped == APPLIED_HEADER:
items = _collect_items(
lines,
i + 1,
stop_headers={FILTERED_HEADER, APPLIED_HEADER},
)
applied = [item.strip() for item in items]
i += 1 + len(items)
continue
if stripped == FILTERED_HEADER:
# Collect raw lines until the groups header or end.
raw = []
j = i + 1
while j < len(lines) and UNDERLINE_RE.match(lines[j]):
j += 1
while j < len(lines):
if GROUPS_HEADER_RE.match(lines[j]):
break
raw.append(lines[j])
j += 1
# Pair each non-indented GPO name with the Filtering: line.
name_line = None
reason = None
for row in raw:
if BLANK_RE.match(row) or UNDERLINE_RE.match(row):
if name_line is not None:
filtered.append(
(name_line.strip(), reason or "(no reason given)")
)
name_line, reason = None, None
continue
match_f = FILTER_RE.match(row)
if match_f:
reason = match_f.group(1)
continue
# A GPO name line is non-blank, not a filter line, and not
# a trailing WMI detail line (which has "WMI" in it).
if name_line is None and "WMI" not in row:
name_line = row
if name_line is not None:
filtered.append(
(name_line.strip(), reason or "(no reason given)")
)
i = j
continue
if GROUPS_HEADER_RE.match(line):
items = _collect_items(lines, i + 1, stop_headers=set())
groups = [item.strip() for item in items]
i += 1 + len(items)
continue
i += 1
return {
"scope": name,
"applied": applied,
"filtered": filtered,
"groups": groups,
}
def summarise(text):
lines = text.splitlines()
return [parse_scope(name, body) for name, body in _split_by_scope(lines)]
def main():
text = (HERE / "gpresult_sample.txt").read_text(encoding="utf-8")
summary = summarise(text)
if not summary:
raise SystemExit("No USER SETTINGS or COMPUTER SETTINGS section found")
for scope in summary:
header = scope["scope"].upper() + " SETTINGS"
print(header)
print("-" * len(header))
print(f"Applied GPOs ({len(scope['applied'])}):")
for name in scope["applied"]:
print(f" {name}")
print(f"Filtered GPOs ({len(scope['filtered'])}):")
for name, reason in scope["filtered"]:
print(f" {name} -- {reason}")
print(f"Groups ({len(scope['groups'])}):")
for group in scope["groups"]:
print(f" {group}")
print()
totals = ", ".join(
f"{s['scope']}: {len(s['applied'])} applied, {len(s['filtered'])} filtered"
for s in summary
)
print(f"Totals -> {totals}")
if __name__ == "__main__":
main() Output
USER SETTINGS
-------------
Applied GPOs (4):
Service Desk - Browser Lockdown
IT - Mapped Drives
Default Domain Policy
Local Group Policy
Filtered GPOs (3):
Finance - Share Access -- Denied (Security)
Legacy - IE Trusted Sites -- Not Applied (Empty)
Developer - Dev Tools Allowed -- Denied (WMI Filter)
Groups (6):
Domain Users
Everyone
Authenticated Users
Mumbai-ServiceDesk
IT-All
Reception-Printer-Users
COMPUTER SETTINGS
-----------------
Applied GPOs (3):
Laptop Baseline
Default Domain Policy
BitLocker Required
Filtered GPOs (2):
Server Hardening -- Not Applied (Empty)
Finance Workstation Lockdown -- Denied (Security)
Groups (5):
Domain Computers
Mumbai-Laptops
IT-Laptops
BUILTIN\Users
Authenticated Users
Totals -> user: 4 applied, 3 filtered, computer: 3 applied, 2 filtered
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 gpresult_summarise.py
In the user half, four GPOs applied and three were filtered out, each with its own reason: Denied (Security), Not Applied (Empty) and Denied (WMI Filter). The groups list matters as much as the GPO list, because security filtering and the Security Group target of preference items both test group membership.
Policy also arrives without anyone asking. Walk through one PC’s day to see when each kind of setting lands and where
gpupdate shortens the wait:
- Start-up
Computer policy applies at start-up foreground
The PC powers on and the Group Policy service builds the list of computer-side GPOs; Microsoft says all policy processing must finish within 60 minutes. Software installation for the computer and startup scripts run only at this point, and when start-up processing is synchronous, the sign-in screen waits until computer policy is done.
- Sign-in
User policy applies at sign-in foreground
The user signs in and the same containers are read again along the user's own path. Folder redirection and user-targeted software installation get their turn, because they wait for a sign-in. When this run is asynchronous the desktop can appear before user policy has finished, so some settings land a moment after it; when it is synchronous the sign-in waits for them.
- +90 min
Background refresh after 90 minutes background
A background refresh comes about 90 minutes after the sign-in, with a random offset of up to 30 minutes, so one PC refreshes at 90 and the next at 118. A changed registry or security setting lands, but folder redirection and software installation wait for their own events, and scripts run only when their events come round.
- +180 min
Another background refresh background
The next refresh follows the same rule, 90 minutes plus a random offset of up to 30 minutes. By default a client-side extension reapplies its settings only when it detects a change to one of its GPOs or to its list of GPOs, a default Microsoft keeps for performance reasons.
- gpupdate
gpupdate /force reapplies every setting now on demand
A technician runs gpupdate /force. Microsoft's gpupdate page says /force reapplies all policy settings, not only the changed ones, which is why it helps when a setting seems stuck. /target:user and /target:computer narrow it to one half, while /wait sets the seconds to wait, with a default of 600.
- gpupdate /logoff
/logoff serves extensions that need a sign-in on demand
gpupdate /logoff signs the user out after the refresh. User-targeted Software Installation and Folder Redirection apply only at sign-in, so a change to either waits for the next sign-in; a technician who wants it now adds /logoff.
- gpupdate /boot
/boot serves computer policy that needs a restart on demand
gpupdate /boot restarts the computer after the refresh. Computer-targeted Software Installation applies at start-up only, so adding /boot makes the install happen on this restart rather than at the next one.
- gpupdate /sync
/sync makes the next foreground run synchronous on demand
gpupdate /sync marks the next start-up (or sign-in, with /target:user) as a synchronous foreground run, so that start or sign-in waits until policy has been applied: a slower sign-in in exchange for settings that are in place before the desktop. Microsoft says /force and /wait are ignored when /sync is set.
The timeline has 8 events, from Start-up to gpupdate /sync.
Left alone, a client refreshes every 90 minutes plus a random offset of up to 30, Microsoft’s processing article says.
gpupdate shortens that wait: /force reapplies every setting rather than only the changed ones, /logoff signs the
user out afterwards for the extensions that work only at sign-in (user-targeted Software Installation and Folder
Redirection, the gpupdate page says), /boot restarts the PC for computer-targeted Software Installation, and /sync
makes the next foreground run synchronous. /wait defaults to 600 seconds, which matters in a script that must act
after the refresh.
A background refresh skips some extensions
Microsoft’s processing article says folder redirection runs only at sign-in, software installation only at start-up
and sign-in, and scripts only on their own events. Microsoft’s Policy CSP reference lists the Drive Maps
preference extension with Software Installation and Folder Redirection among the extensions that need synchronous processing,
so a new drive map can wait for the next sign-in. When a change belongs to one of these, gpupdate /logoff or a
real sign-out is the dependable proof.
Checkpoint
Check: gpresult and gpupdate
Preference items decide drive maps and printers, extensions decide sign-in time
Drive maps and printers often arrive as Group Policy Preferences items rather than as policy settings. Microsoft’s preferences reference says each preference extension works through its items from the top of the list to the bottom, and that item-level targeting can stop an item from applying to this user or computer. That is the opening’s ticket: the drive map’s target still names the Finance group, so after the move the item no longer matches.
The table pairs five tickets a desk sees with what to read first:
| Ticket symptom | First thing to read | Cause to check first |
|---|---|---|
| Drive map missing for one user | gpresult /r, Applied GPOs |
An item-level target that still names the old group |
| Printer missing for one user | gpresult /r, Applied and Filtered GPOs |
An item-level target, or the whole GPO filtered out |
| Slow sign-in on a batch of PCs | The Group Policy Operational log of one slow sign-in | An extension that must finish before the desktop, now with new work |
| One odd setting on one PC | gpedit.msc, the local GPO |
A local policy left by a lab image or an earlier owner |
| User settings ignored on a classroom PC | The GPO linked to the PCs’ OU, Computer Configuration | Loopback not enabled, or the wrong mode |
Key idea
A drive map or a printer that disappears after a team move is a targeting question first: find the GPO that delivers the item, then read the item’s target, before you touch the share or the password.
On such a ticket, run gpresult /r for the caller. The Applied GPOs section names the GPO that carries the drive map,
and the Filtered GPOs section shows whether a security or WMI filter: A query on the client's Windows Management Instrumentation that gates whether a GPO applies to that PC. One GPO may have one WMI filter, and the filter is evaluated on the client during Group Policy processing. dropped the whole GPO
before any of its items was read. Only then open the GPO’s Drive Maps items in the Group Policy Management Console and
read each target.
Slow sign-ins are the other steady stream. Microsoft’s gpupdate page names user-targeted Software Installation and Folder Redirection as extensions that skip the background refresh and do their work at sign-in, and the Policy CSP reference lists the Drive Maps preference extension with them as needing synchronous processing. A GPO change that hands one of them new work, such as a package to install or folders to redirect, can make every sign-in it reaches wait. To see which client-side extension: A Group Policy component on a Windows client that reads one kind of setting out of a GPO and applies it. Short name CSE. Separate CSEs handle registry, security, folder redirection, scripts, drive maps and software installation. holds a slow sign-in up, Microsoft’s troubleshooting guide uses the Group Policy Operational log: each extension logs event 4016 when it starts and 5016 when it finishes, so the slow one shows as the widest gap between its pair.
One symptom only looks like a slow sign-in. Microsoft’s Policy CSP reference says that, unless the Configure Logon Script Delay setting says otherwise, the Group Policy client waits five minutes after sign-in before it runs logon scripts, to keep the desktop responsive. A drive that a logon script maps can therefore appear about five minutes after a desktop that arrived on time; the sign-in itself was not slow.
Loopback is for kiosks, labs and classrooms
loopback processing: A Group Policy mode that applies user settings based on the computer object rather than the user object, used on kiosks, labs, classrooms and reception PCs. The two modes are merge and replace. applies user settings by the computer, not by the user. Microsoft’s loopback article names computers in public areas, laboratories and classrooms, and the processing article adds kiosks and reception areas. Merge mode adds the computer’s GPO list after the user’s own, so the computer’s GPOs win a conflict; replace mode uses only the computer’s list. It is enabled under Computer Configuration in a GPO linked to the OU that holds those PCs.
A PC managed only by Microsoft Intune, with no on-premises domain, gets its settings from Intune policies instead, such as a settings catalog policy, and Intune’s Group Policy analytics can import an existing GPO and show which of its settings Intune supports. On such a PC, the MDM diagnostic report (the work account’s Info page under Settings > Accounts > Access work or school, then Create report) gives a summary of the MDM policies it holds. Domain-joined PCs still get Group Policy from their domain, so a desk that serves both kinds of PC reads both.
Checkpoint
Check: Preferences, drive maps and slow sign-ins
Practise: resolve the winning value yourself
The exercise gives you the same kind of link list the resolver read. Write winning_value so that it returns the
value of the link that wins for one setting, with enforced links, link order and Block Inheritance all in play. Its
sample tests run in your browser, from a lone domain link up to two enforced links on one path, and the first hint is
there if you get stuck.
Exercise · Medium · Python
Pick the winning GPO link
Write winning_value(links, setting, block_inheritance_set=None). It reads a list of Group Policy links and returns the winning value for one setting, following the processing order Microsoft's Group Policy processing article names.
Each link is a dict with these fields:
scope: one of"local","site","domain"or"ou".ou_depth: an integer counted from0at the shallowest OU, used only whenscopeis"ou".link_order: the GPMC link order (a positive integer). Within one container the link with the LOWESTlink_orderhas precedence.enforced: a boolean, True when the link is marked enforced.value: the setting's value if that link wins.
The second argument is a block_inheritance_set: a set of (scope, ou_depth) tuples naming the containers that have Block Inheritance on them.
Return the single value of the winning link, or None when no link applies.
Follow these rules:
- Enforced beats unenforced.
- Among enforced links, the one in the highest container (earliest in the processing order: local, then site, then domain, then OU parent, then OU child) wins. Within one container the lowest
link_orderwins. - Among unenforced links that survive Block Inheritance, the deepest container wins. Within one container the lowest
link_orderwins. - Block Inheritance drops an unenforced link whose position is strictly higher than any blocking container. Enforced links bypass Block Inheritance.
Return None when no link remains after Block Inheritance.
Starter code · winning_value.py
SCOPE_RANK = {"local": 0, "site": 1, "domain": 2, "ou": 3}
def winning_value(links, setting, block_inheritance_set=None):
"""Return the winning value for one Group Policy setting.
TODO: filter the links by Block Inheritance, pick the enforced winner when
one exists, otherwise pick the unenforced winner (deepest container, then
lowest link_order), and return its value. Return None when no link applies.
"""
return None The sample tests · test_gpo_winner.py
from winning_value import winning_value
def _link(scope, link_order, enforced, value, ou_depth=0):
return {
"scope": scope,
"ou_depth": ou_depth,
"link_order": link_order,
"enforced": enforced,
"value": value,
}
def test_single_domain_link_wins_by_itself():
"""one unenforced domain link, no competition"""
links = [_link("domain", 1, False, "900")]
assert winning_value(links, "ScreenSaverTimeOut") == "900"
def test_lower_link_order_wins_at_same_ou():
"""two sibling links at the same OU: lowest link_order wins"""
links = [
_link("ou", 2, False, "900", ou_depth=2),
_link("ou", 1, False, "300", ou_depth=2),
]
assert winning_value(links, "ScreenSaverTimeOut") == "300"
def test_enforced_at_domain_beats_deeper_unenforced():
"""enforced domain link beats a deeper OU link that is not enforced"""
links = [
_link("domain", 1, True, "600"),
_link("ou", 1, False, "1800", ou_depth=2),
]
assert winning_value(links, "ScreenSaverTimeOut") == "600"
def test_block_inheritance_stops_unenforced_parent():
"""Block Inheritance at an OU stops an unenforced domain link"""
links = [
_link("domain", 1, False, "900"),
_link("ou", 1, False, "180", ou_depth=1),
]
blocked = {("ou", 1)}
assert winning_value(links, "ScreenSaverTimeOut", blocked) == "180"
def test_block_inheritance_with_nothing_linked_below_leaves_it_unset():
"""Block Inheritance at the user's OU drops both unenforced parents; that OU links nothing"""
links = [
_link("domain", 1, False, "900"),
_link("ou", 1, False, "600", ou_depth=0),
]
blocked = {("ou", 1)}
assert winning_value(links, "ScreenSaverTimeOut", blocked) is None
def test_two_enforced_links_highest_wins():
"""two enforced links compete: the highest in the hierarchy wins"""
links = [
_link("domain", 1, True, "600"),
_link("ou", 1, True, "300", ou_depth=1),
]
assert winning_value(links, "ScreenSaverTimeOut") == "600" A hint
Walk the links once and sort them by (scope_rank, ou_depth) so you can compare their positions. Keep two groups: enforced and unenforced. Drop an unenforced link when its position is strictly higher than any (scope, ou_depth) in block_inheritance_set. Pick the enforced winner by the smallest position and the smallest link_order; pick the unenforced winner by the largest position and the smallest link_order. Return the chosen link's value.
Results of the sample tests
| Test | Result | Details |
|---|
What your code printed
The sample tests run on this device, in your browser (Pyodide): nothing is sent to mysmartcopilot.com. The first run downloads Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.
Then come the lesson’s own questions, one at a time across the four sections. Your weakest section so far is asked first, and every answer you pick tells you what it gets right or where it goes wrong:
Practice that adapts to you
Practise this lesson
8 questions about 4 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.
Interview questions
Warm-up (fresher): An administrator saved a Group Policy change an hour ago, but the user’s PC still behaves the old way. When does a GPO change reach a user?
A change reaches a user in three stages. First it must replicate to the domain controller the PC reads policy from.
The GPO’s container travels with Active Directory replication, which Microsoft says usually takes under a minute
between domain controllers in one site, while its template on SYSVOL travels separately through DFS Replication;
between sites, replication runs at intervals the site schedule sets, never shorter than 15 minutes. Second the PC must
refresh: every 90 minutes plus a random offset of up to 30, so one PC may refresh at 90 minutes and the next at 118.
Third the client-side extension must act, and a background refresh does not run them all: folder redirection waits
for a sign-in, software installation for a start-up or a sign-in, and scripts for their own events. gpupdate /force
shortens the wait, with /logoff when the change needs a sign-in.
Two harder tickets from the same estate come next: an archive server switched off with two drive maps gone, and a branch office whose sign-ins slowed after a new GPO. Settle on the first thing you would read for each before you open its page:
Model answers open with any pass: ₹79 for 1 week ($2.99), one payment that never renews.
-
Mid to senior
Since the old archive server was switched off on Monday, Service Desk staff have lost their S: and T: drives, yet H: still maps. One GPO delivers all four of their drives, listed H:, R: (the archive), S: and T:, and gpresult shows that GPO as applied. What is going on, and what do you change?
-
Mid to senior
On Monday a new GPO with user settings for an engineering tool was linked to the Pune OU. Since then the Welcome screen stays for about three minutes on every Pune PC, instead of under one. In the Group Policy Operational log of one slow sign-in, every client-side extension starts and finishes within seconds. Where is the time going?
Flashcards · 6 cards
Recall it, then check
Say the answer to yourself before you look: recalling it is what makes it stick.
-
How does a Group Policy object reach a PC?
Only through a link to a site, a domain or an OU. A GPO is a container in Active Directory plus a template on SYSVOL, so where it is linked matters as much as what it sets.
-
In what order does Windows apply Group Policy, and which level has the last word?
Local, then site, then domain, then OUs from parent to child, with computer settings at start-up and user settings at sign-in. By default the OU closest to the object wins.
-
Several GPOs set the same thing. Which one wins?
The closest container wins, and inside one container the lowest link order wins. An enforced link beats both and gets through Block Inheritance, which stops only the unenforced links from above.
-
Which gpresult and gpupdate switches does a technician use?
gpresult /r summarises the applied and filtered GPOs and the sign-in's groups, and /user keeps the report on the caller. gpupdate /force reapplies everything, with /logoff or /boot for extensions that work only at sign-in or start-up.
-
A mapped drive disappeared after a team move. Where do you look first?
At targeting: find the GPO that delivers the drive map and read the item's target, before you touch the share or the password.
-
Sign-in has been slow since a GPO change. What points at the cause?
An extension that must finish before the desktop appears. Its 4016 and 5016 events time how long it ran.
Key takeaways
- A GPO is a container in Active Directory plus a template on SYSVOL, and it reaches a client only through a link to a site, a domain or an OU, so where a GPO is linked matters as much as what it sets.
- Windows applies Group Policy local first, then site, domain and OUs from parent to child, computer settings at start-up and user settings at sign-in, so the OU closest to the object has the last word by default.
- The closest container wins, the lowest link order wins inside one container, and an enforced link beats both and gets through Block Inheritance, which stops only the unenforced links from above.
gpresult /rsummarises the applied and filtered GPOs and the sign-in’s groups,/userkeeps the report on the caller, andgpupdate /forcereapplies everything, with/logoffor/bootfor the extensions that work only at sign-in or start-up.- Drive maps and printers often come from preference items worked through top to bottom under item-level targets, and a slow sign-in after a GPO change points at an extension that must finish before the desktop, timed by its 4016 and 5016 events.
Terms in this lesson
- Block Inheritance
- A property on a domain or OU that stops local, site, domain and higher OU Group Policy links from reaching that container. Enforced links in parent containers still pass through, so Block Inheritance is only partial.
- client-side extension
- A Group Policy component on a Windows client that reads one kind of setting out of a GPO and applies it. Short name CSE. Separate CSEs handle registry, security, folder redirection, scripts, drive maps and software installation.
- enforced link
- A Group Policy link marked enforced in GPMC, called no-override in older documentation. Microsoft's processing article says the highest enforced link in the chain wins over lower unenforced links and bypasses Block Inheritance.
- gpresult
- A Windows command that displays the resultant set of policy that applied on a sign-in. /r prints a summary; /h writes an HTML report; on ARM64 only the gpresult in SysWow64 works with /h.
- gpupdate
- A Windows command that refreshes Group Policy on the local PC. /force reapplies every setting rather than only changed ones; /logoff and /boot drain CSEs that run only at sign-in or startup; /sync marks the next foreground run synchronous.
- Group Policy object
- Windows's way of pushing settings to many PCs and users at once. A container in Active Directory plus a template on each domain controller's SYSVOL share. Its short name is GPO.
- Group Policy Preferences
- A set of Group Policy client-side extensions that deliver preference settings such as drive maps, printers and files to domain-joined computers. Short name GPP. Each item can carry an item-level target that is checked on the client.
- item-level targeting
- A per-item condition on a Group Policy Preferences item that decides whether the item applies on this sign-in. Microsoft's reference lists OU, group membership, IP range, computer name and WMI as targets.
- linked GPO
- A Group Policy object pointed at a site, a domain or an organisational unit by a link in the Group Policy Management Console. A GPO reaches a client only through a link, never by its own name.
- loopback processing
- A Group Policy mode that applies user settings based on the computer object rather than the user object, used on kiosks, labs, classrooms and reception PCs. The two modes are merge and replace.
- SYSVOL
- A share on every Active Directory domain controller that stores the Group Policy templates and sign-in or startup scripts for the domain. Its contents replicate between domain controllers through DFSR.
- WMI filter
- A query on the client's Windows Management Instrumentation that gates whether a GPO applies to that PC. One GPO may have one WMI filter, and the filter is evaluated on the client during Group Policy processing.
References
- Group Policy processing (Microsoft)
- Group Policy overview (Microsoft)
- gpresult (Microsoft)
- gpupdate (Microsoft)
- Group Policy Preferences (Microsoft)
- Preference item-level targeting using the GPMC (Microsoft)
- ADMX_GroupPolicy Policy CSP (Microsoft)
- Loopback processing of Group Policy (KB 231287) (Microsoft)
- Applying Group Policy troubleshooting guidance (Microsoft)
- Import and analyze on-premises GPOs with Group Policy analytics in Microsoft Intune (Microsoft)
- Collect MDM logs (Microsoft)
- CompTIA A+ Core 2 (220-1202) exam objectives (CompTIA)
Report a problem with this lesson
Kept only in this browser. Your Learn progress