reg

reg is the command-line interface to the live registry — the running LCS store, reached through the registry system calls. Where regman reads shipped documentation and tells you what a key means, reg talks to the kernel and reads or writes what a key is. It is the everyday tool for scripting configuration: querying effective values, writing to layers, masking and hiding, managing security descriptors, watching for change, and taking backups.

reg <command> [options] <key> [value] [data]

reg is the read/write half of the registry toolset and regman is the lookup half. The division is exact:

To…Use…
Read or change what a value is set to, on this machine, right nowreg
Look up what a value means — its type, default, valid range, when it appliesregman

Consult regman first to learn the legal range for a knob, then use reg set to write a value inside it. reg never checks a value's meaning and regman never touches the live store; they are complementary.

How reg treats access and privilege #

Every reg operation goes through the kernel's access check against the single key it opens — the same access-control path as any other protected object, with no traversal check on the parent keys. reg performs no identity or membership checks of its own: it does not refuse a privileged operation up front. It attempts the operation and reports faithfully whatever the kernel returns. An operation that needs a privilege you lack (creating a link, a positive-precedence layer, a backup or restore, reading a SACL) simply fails with access denied (exit 3) rather than being blocked by the tool. A single reg command may legitimately span privilege tiers.

Addressing model #

Almost every subcommand shares one addressing scheme: a key path positional, and an optional value name positional. Understanding the split is most of understanding reg.

Key paths #

The key is a positional path argument. Both / and \ are accepted as separators — neither character is legal inside an LCS key component, so there is no ambiguity, and you may use whichever your shell quotes most comfortably:

reg get Machine/System/KMES
reg get 'Machine\System\KMES'      # identical

A leading separator is optional and ignored (/Machine/X is the same as Machine/X). Paths are compared case-insensitively. The first component is the hive:

PathMeaning
Machine\…The machine hive — system-wide configuration.
Users\<SID>\…A specific principal's hive.
CurrentUser\…A kernel alias, rewritten to the caller's own Users\<SID>\ at the syscall boundary.

On output, reg displays paths with a backslash by default. --sep=/ (or REG_SEP=/) switches display to forward slash for that invocation; this affects display only, never how a path is parsed.

The value-name positional #

The value name is a separate positional argument — it is never folded into the key path. This is deliberate: an LCS value name may itself contain / or \ (which a key component may not), so keeping them apart removes all ambiguity.

reg get Machine/System/KMES BufferCapacity
#       └──── key path ─────┘ └── value ──┘

The presence or absence of the value argument selects what the command targets:

  • No value argument ⇒ the command targets the key itself — its metadata, its values as a set, its security descriptor, its children.
  • A value argument ⇒ the command targets that one named value.
  • The default value (the empty-name value) is addressed by the literal token @ in the value-name position, mirroring .reg convention: reg get Machine\App @.

This split applies uniformly to get, set, del, mask, and unmask.

Value literals and types #

On set (and in a batch), the value's data is a single token whose registry type is either forced by a type: prefix or inferred from its shape. The registry value types and their literal syntax:

PrefixRegistry typeData syntax
sz:REG_SZUTF-8 string (rest of token, verbatim).
expand:REG_EXPAND_SZUTF-8 string, %VAR% left unexpanded on disk.
dword:REG_DWORD42 or 0x2A; must fit u32.
dword-be:REG_DWORD_BIG_ENDIAN42 or 0x2A; must fit u32.
qword:REG_QWORD42 or 0x2A; must fit u64.
multi:REG_MULTI_SZComma-separated; \, escapes a literal comma.
hex: / bin:REG_BINARYHex bytes; :, -, and space separators are ignored.
link:REG_LINKAn absolute key path (a symlink target).
none:REG_NONENo data (token must be empty after the prefix).

When the substring before the first : is not a recognised keyword (for example http://host), the token is not treated as typed and inference applies:

Token shapeInferred type
all decimal digits, fits u32REG_DWORD
all decimal digits, fits u64 but not u32REG_QWORD
0x… hex, ≤ 8 significant hex digitsREG_DWORD
0x… hex, ≤ 16 significant hex digitsREG_QWORD
anything else (including empty)REG_SZ

Inference is intentionally broad, so any all-digit token becomes a number — a PIN, a zip code, or 007 becomes a REG_DWORD and loses its textual form. To force a string, prefix it with sz: (sz:007 stores the string 007; sz:dword:42 stores the literal string dword:42). Because the coercion is a known trap, reg set always echoes the resolved type on success, so a surprising conversion is never silent even under --quiet.

Global options #

Every subcommand accepts the following. Each behavioural toggle also has an environment-variable equivalent, so it can be set per-invocation (the flag) or once per shell or script (the variable). The flag wins over the variable, which wins over the built-in default.

OptionEnv varEffect
--jsonREG_JSON=1Emit structured JSON instead of human text. watch emits JSON-lines.
-v, --verboseREG_VERBOSE=1More detailed output.
-q, --quietSuppress non-essential output. (A surprising type coercion is still reported.)
--sep=CHARREG_SEPPath display separator: \ (default) or /.
--helpPrint help for the command and exit 0.
--versionPrint the version and exit 0.

Mutating subcommands additionally accept:

OptionEnv varEffect
--layer NAMEREG_LAYERTarget layer for the write (default: the base layer).
-y, --yesREG_ASSUME_YES=1Skip the confirmation prompt on a destructive command.

Destructive commands (del -r, restore, layer del) prompt for confirmation when standard input is a terminal, and auto-proceed when it is not — so interactive use is guarded while scripts are never blocked. Set -y/--yes or REG_ASSUME_YES=1 to skip the prompt explicitly.


Reading #

reg get <key> [value] #

Read the effective (resolved) value. With a value, prints that value's data; with no value, lists the key's effective values (the default @ value first, then named values sorted case-insensitively) — a shorthand for ls --values-only.

OptionEffect
-L, --layersAnnotate the value with the layer it resolved from and its sequence number.
--rawWrite the value's raw bytes to standard output verbatim — for piping REG_BINARY data.
--no-followOperate on a symlink key itself rather than following it to its target.

The single-value default form prints data bare (no quotes; one element per line for REG_MULTI_SZ) so it pipes cleanly. -L shows the winning layer's provenance:

$ reg get Machine\System\KMES BufferCapacity
4194304

$ reg get Machine\App Theme -L
Theme = REG_SZ "dark"   (layer: policy, seq 7)

Only the winning value is shown; the full shadowed stack beneath it is not yet exposed by any client ABI (the -L flag will render the whole stack unchanged once that primitive lands). See Layers for what "effective" resolves against.

reg ls <key> #

One-level listing of a key's immediate subkeys and values.

OptionEffect
-l, --longLong form: for subkeys, child and value counts; for values, type and byte size.
--keys-onlyList subkeys only.
--values-onlyList values only.
$ reg ls Machine\System\KMES -l
BufferCapacity = REG_QWORD 4194304   (8 bytes)
MaxEventSize   = REG_DWORD 65536   (4 bytes)

reg tree <key> #

Recursively list the subkey tree rooted at key.

OptionEffect
--depth NLimit recursion to N levels.
--valuesInclude each node's values, not just its keys.
$ reg tree Machine\System --depth 2

reg info <key> #

Print a key's metadata: leaf name, subkey and value counts, last-write time, hive generation, security-descriptor size, and the volatile and symlink flags.

OptionEffect
--no-followInspect a symlink key itself rather than its target.
$ reg info Machine\System\KMES
path             Machine\System\KMES
name             KMES
subkeys          0
values           4
last_write_ns    1717243800000000000
hive_generation  42
sd_size          164
volatile         false
symlink          false

Writing #

reg set <key> <value> <data> #

Create or update a value. The value name (or @) and the data token are both required. Writes are tagged with --layer (default: base). See value literals for the data syntax.

OptionEffect
--layer NAMEWrite into layer NAME instead of the base layer.
-p, --parentsCreate any missing ancestor keys.
--expected-seq NCompare-and-swap guard: apply only if the value's current sequence is N; a mismatch exits 6 without writing.
$ reg set Machine\App Build 4096
set Machine\App Build = REG_DWORD 4096   (layer: base)

$ reg set Machine\App Servers multi:alpha,beta --layer policy

--expected-seq supports lock-free read-modify-write: read the value with -L to learn its sequence, then write back with --expected-seq set to that number; if another writer changed it in between, your write fails cleanly instead of clobbering theirs.

reg new <key> #

Create a key with no values. Reports whether the key was created or already existed.

OptionEffect
--layer NAMECreate the key in layer NAME.
-p, --parentsCreate any missing ancestor keys.
--volatileCreate a volatile (RAM-only) key that does not survive a reboot.
$ reg new Machine\App\Cache --volatile
created Machine\App\Cache   (layer: base)

reg del <key> [value] #

Delete a value, or a key. (Alias: delete.)

With a value, deletes this layer's entry for that value only — lower-layer entries resurface, because a per-layer delete is not a tombstone (use mask for that). With no value, deletes the key, which must be empty unless -r is given.

OptionEffect
--layer NAMEDelete from layer NAME.
-r, --recursiveDelete the key and all its descendants (walks and removes children).
-y, --yesSkip the confirmation prompt (recursive deletes prompt on a terminal).
$ reg del Machine\App Legacy
deleted value Legacy from Machine\App

$ reg del Machine\App\Temp -r
Recursively delete key Machine\App\Temp and all its contents? [y/N] y
deleted Machine\App\Temp (3 keys)

See Deleting keys and values for how a per-layer delete differs from a tombstone.


Masking and hiding #

These commands expose LCS's tombstone and hide primitives, which mask lower-precedence state rather than removing a layer's own entry — the distinction that makes layers revertible. The layer is chosen with --layer (default: base).

reg mask <key> [value] / reg unmask <key> [value] #

mask sets a tombstone: a per-value marker in the target layer that hides that value from all layers below it. unmask clears it.

OptionEffect
--layer NAMEThe layer that carries the tombstone.
--allBlanket tombstone: mask all lower-layer values on the key (no value argument).

A value is required unless --all is given.

$ reg mask Machine\App ApiKey --layer policy
set tombstone on Machine\App ApiKey (layer: policy)

$ reg mask Machine\App --all --layer policy
set blanket tombstone on Machine\App (layer: policy)

reg hide <key> / reg unhide <key> #

hide installs a HIDDEN path entry in the target layer, masking the key's existence in that layer and below. unhide removes that layer's path entry, letting the key reappear.

OptionEffect
--layer NAMEThe layer that hides (or unhides) the key.
$ reg hide Machine\App\Debug --layer policy
hid Machine\App\Debug (layer: policy)

Layers #

reg layer ls #

List layers with name, precedence, enabled state, and (informational) owner SID, ordered by descending precedence.

OptionEffect
-l, --longLong form.
$ reg layer ls
policy                   prec=100    enabled   owner=S-1-5-32-544
base                     prec=0      enabled

reg layer new <name> #

Create a layer by writing its metadata key under Machine\System\Registry\Layers\.

OptionEffect
--precedence NPrecedence (higher wins). A precedence above 0 requires SeTcbPrivilege; the tool attempts it and reports any denial.
--owner SIDRecord an informational owner SID.
--disabledCreate the layer disabled.
$ reg layer new policy --precedence 100 --owner S-1-5-32-544
created layer policy (precedence 100, enabled)

reg layer set <name> #

Modify an existing layer's metadata.

OptionEffect
--precedence NChange the precedence.
--enable / --disableEnable or disable the layer.
--owner SIDChange the informational owner SID.

reg layer del <name> #

Delete a layer — removes its metadata key; LCS tears down the layer's entries. Prompts for confirmation on a terminal.

$ reg layer del policy
Delete layer policy and all its entries? [y/N] y
deleted layer policy

Managing per-process private layer views is out of scope for reg; see private hives and layers.


Security descriptors #

reg sd <key> #

Show or set a key's security descriptor as SDDL, using the same codec as the sd tool, so its output is consistent. With no scope flags, the default is owner + group + DACL (a SACL requires the privileged ACCESS_SYSTEM_SECURITY right).

OptionEffect
--set SDDLApply the given SDDL. Without it, sd prints the current descriptor.
--ownerScope to the owner.
--groupScope to the group.
--daclScope to the DACL.
--saclScope to the SACL (needs ACCESS_SYSTEM_SECURITY).
$ reg sd Machine\App
O:BAG:BAD:(A;;KA;;;BA)(A;;KR;;;WD)

$ reg sd Machine\App --set 'O:BAG:BAD:(A;;KA;;;BA)' --owner --dacl
set security descriptor on Machine\App

A security-descriptor change takes effect on future opens only (existing handles keep the access mask they were granted). Security changes are not layered and are not undone by layer removal — they mutate the key object directly. See Access control on keys.


Create a symlink key pointing at the absolute target key path. This creates a key with the immutable symlink flag and a default REG_LINK value holding the target. Requires KEY_CREATE_LINK and SeTcbPrivilege/Administrator; the tool attempts it and reports any denial.

OptionEffect
--layer NAMECreate the link key in layer NAME.
$ reg link Machine\App\CurrentConfig Machine\App\Config\v3
linked Machine\App\CurrentConfig -> Machine\App\Config\v3 (layer: base)

get and info follow symlinks to their target by default; pass --no-follow to inspect the link key itself. See Advanced: registry links.


Watching #

reg watch <key> #

Arm a change watch and stream one event per change until interrupted (or until --count events). Each event faithfully means "something under the filter changed — re-read"; reg does not decode the change records' contents. With --json, emits one JSON object per line.

OptionEffect
--subtreeWatch descendant keys too, not just this key.
--filter LISTComma-separated subset of value, subkey, sd (default: all).
--count NExit after N events.
$ reg watch Machine\System\KMES --subtree --filter value
changed: Machine\System\KMES
changed: Machine\System\KMES

See Watching for changes for why a service watches instead of polling.


Batch, export, backup, and restore #

Two paths move a subtree around: export/apply are the portable, reviewable path (a diffable text or JSON document); backup/restore are the exact, privileged path (an opaque kernel snapshot).

reg apply <file> #

Apply a batch of operations to one hive in a single transaction — all-or-nothing. All operations must target one hive (a cross-hive batch fails with exit 4). - reads standard input.

OptionEffect
--dir DIRApply every batch file in DIR (sorted), each as its own transaction. A missing or empty directory applies nothing and succeeds.
--once-deleteDelete each batch file after it applies successfully (a drain).
-y, --yesSkip confirmation.

The batch format is JSON (canonical and exact) or a line-oriented text format; apply auto-detects (a leading { or [ means JSON). Text-format input is not yet implemented — supply JSON, or generate one with reg export --json. Text export works for review.

$ reg export --json Machine\App - | reg apply -
applied 4 keys

reg export <key> [file] #

Dump a subtree to the batch format. Omit file (or pass -) to write to standard output. Human-readable text by default; --json emits the canonical exact form.

OptionEffect
--layer NAMEExport one layer's view (default: the effective state).
$ reg export Machine\App app-config.reg

reg backup <key> <file> #

Write an opaque, exact, binary kernel snapshot of a key and its subtree to file. Requires SeBackupPrivilege.

$ reg backup Machine\System\KMES kmes.snap
backed up Machine\System\KMES -> kmes.snap

reg restore <key> <file> #

Replace a key and its entire subtree from a snapshot, in one transaction. Requires SeRestorePrivilege. Prompts for confirmation on a terminal.

$ reg restore Machine\System\KMES kmes.snap
Replace key Machine\System\KMES and its entire subtree from kmes.snap? [y/N] y
restored Machine\System\KMES from kmes.snap

See Backup and restore for when to reach for each path.


Output formats #

Default output is terse, human-readable, and grep-friendly. --json switches every command to structured output — a single self-contained JSON document, except watch, which emits JSON-lines (one object per event). In any value listing, the default (@) value is emitted first, then named values sorted case-insensitively.

Type formatting on read:

Registry typeHuman formJSON form
REG_SZ / REG_EXPAND_SZthe string{"type":"sz","data":"…"}
REG_DWORD / REG_QWORDdecimal{"type":"dword","data":42}
REG_MULTI_SZone element per line{"type":"multi","data":["a","b"]}
REG_BINARYhex{"type":"binary","data":"deadbeef"}
REG_LINKthe target path{"type":"link","data":"…"}

Exit status #

CodeMeaningTypical cause
0Success.
1Usage error.Bad arguments; a required option missing.
2Key or value not found.ENOENT.
3Access denied.EACCES, EPERM — the kernel refused the operation.
4Invalid specification.Bad path, type, or literal; a cross-hive batch; a name too long (EINVAL, EXDEV, ENAMETOOLONG).
5Syscall or source failure.EIO, ETIMEDOUT, ENOSPC, ENOMEM.
6Compare-and-swap conflict.EAGAIN — an --expected-seq guard did not match; the value changed under you.

A denial (3) reports the operation, the target, and, where relevant, the access that was required — in the style of the sd and token tools.

See also #

  • regman — the registry manual: what a key or value means, as opposed to what it is set to. Consult it before you reg set.
  • Keys, values, and types — the data model reg addresses.
  • Layers — what "effective" resolves against, and what --layer, mask, and hide operate on.
  • Access control on keys — the check every reg operation goes through.

Edit this page