Windows Server Administration

Registry und NTFS: Zustand, Typen und Zugriffsrechte

Windows hält seinen Zustand an zwei Orten: in der Registry und im Dateisystem. Beide sehen einfacher aus, als sie sind. Ein Pfad mit dem richtigen Inhalt kann am falschen Datentyp scheitern, derselbe Schlüssel je nach lesendem Programm auf zwei verschiedene Orte zeigen, und der Satz „Verweigern gewinnt immer“ ist bei NTFS-Rechten schlicht falsch. Dieses Modul ist die Werkzeugkunde für alles, was danach kommt — Dienste, Start, Patchstand und Freigaben liegen alle in einem dieser beiden Bäume.

Lehrtext · 12 Abschnitte · zuletzt geprüft: 2026-09-03

Zwei Orte, an denen Windows seinen Zustand hält

Wer von Linux kommt, sucht die Konfiguration in Textdateien unter /etc. Auf Windows liegt sie an zwei Orten: in der Registry und im Dateisystem. Beide sind hierarchisch, beide haben Berechtigungen nach demselben Modell, und beide werden von denselben Fehlannahmen falsch bedient. Dieses Modul ist die Werkzeugkunde für alles, was danach kommt: Dienste, Start, Patchstand und Freigaben liegen alle in einem dieser beiden Bäume.

HiveEine logische Gruppe von Schlüsseln, Unterschlüsseln und Werten mit eigenen Dateien auf der Platte, die beim Systemstart oder bei der Anmeldung geladen werden. Die meisten liegen unter %SystemRoot%\System32\config, der Benutzeranteil in Ntuser.dat im Profil.

Schlüssel und WertEin Schlüssel entspricht einem Ordner, ein Wert einer Datei darin. Ein Wert hat immer drei Teile: Name, Datentyp und Daten. Der Datentyp wird beim Lesen ausgewertet und ist keine Kosmetik.

Die praktische Konsequenz: Ein Wert am richtigen Ort mit dem falschen Datentyp ist kein halb richtiger Eintrag, sondern ein wirkungsloser. Warum das so ist, steht zwei Abschnitte weiter.

Die fünf Wurzeln — und welche davon echt sind

Der Registrierungs-Editor zeigt fünf Wurzeln. Nur zwei davon haben eigene Dateien; die anderen sind Sichten auf Teile davon. Wer das nicht trennt, sucht Werte an Orten, die es auf der Platte gar nicht gibt.

HKEY_LOCAL_MACHINE (HKLM)
Maschinenzustand. Eigene Hive-Dateien: SYSTEM, SOFTWARE, SAM, SECURITY unter System32\config.
HKEY_USERS (HKU)
Alle geladenen Benutzerprofile, je Profil eine Ntuser.dat.
HKEY_CURRENT_USER (HKCU)
Sicht auf HKU\<SID des angemeldeten Benutzers>. Kein eigener Ort.
HKEY_CLASSES_ROOT (HKCR)
Zusammengeführte Sicht aus HKLM\SOFTWARE\Classes und HKCU\SOFTWARE\Classes.
HKEY_CURRENT_CONFIG (HKCC)
Sicht auf das aktuelle Hardwareprofil unterhalb von HKLM\SYSTEM.
Warum das im Betrieb zähltHKCU ist die Sicht des gerade angemeldeten Benutzers. Ein Dienstkonto, ein geplanter Task oder ein Fernwartungswerkzeug hat ein anderes HKCU als du an der Konsole. Ein Skript, das unter deinem Konto funktioniert und als geplante Aufgabe nichts bewirkt, hat meistens genau hier seinen Fehler — es schreibt in ein anderes Profil, nicht in ein kaputtes.

`CurrentControlSet` ist ein Zeiger, kein Ort

Unter HKLM\SYSTEM liegen mehrere nummerierte Kontrollsätze: ControlSet001, oft ein ControlSet002. HKLM\SYSTEM\CurrentControlSet ist kein eigener Speicher, sondern ein Verweis auf den gerade aktiven — welcher das ist, steht in HKLM\SYSTEM\Select unter dem Wert Current. Dort stehen auch Default, Failed und LastKnownGood.

Solange das System läuft, ist das eine Trivialität: Man schreibt nach CurrentControlSet und trifft das Richtige. Interessant wird es, sobald ein System nicht läuft und man seine Registry von außen einhängt — etwa aus der Wiederherstellungsumgebung oder von einer angehängten virtuellen Festplatte.

Der Fehler, der offline entstehtIn einer eingehängten fremden Hive gibt es kein CurrentControlSet — nur die nummerierten Sätze. Wer dort blind ControlSet001 bearbeitet, ändert unter Umständen den Satz, der beim nächsten Start gar nicht gewählt wird. Der richtige Ablauf ist: erst Select\Current lesen, dann den Satz mit dieser Nummer bearbeiten. Der Eingriff sieht danach identisch aus — er wirkt nur eben, oder nicht.

Unter CurrentControlSet\Services liegt jeder Dienst mit seinem Starttyp, seinem Programmpfad und seinem Konto. Das nächste Modul arbeitet dort; hier ist wichtig, dass es sich um denselben Baum handelt, den sc.exe und Get-Service bedienen — die Werkzeuge sind eine Oberfläche über diesen Schlüsseln, keine eigene Datenbank.

Datentypen sind Verhalten, keine Beschriftung

REG_SZ
Zeichenkette. Wird genommen, wie sie dasteht.
REG_EXPAND_SZ
Zeichenkette mit unaufgelösten Umgebungsvariablen wie %SystemRoot%. Der Lesende löst sie auf.
REG_DWORD
32-Bit-Zahl. Der Standard für Schalter — 0 oder 1, nicht die Zeichenkette 1.
REG_MULTI_SZ
Folge von Zeichenketten, mit einer Leerzeichenkette abgeschlossen.
REG_BINARY
Rohdaten. Ohne Kenntnis des Formats nicht sinnvoll editierbar.
Der klassische FehlgriffEin Pfad wie %SystemRoot%\System32\dienst.exe als REG_SZ gespeichert wird nicht aufgelöst: Der Lesende bekommt die Zeichenkette mit dem Prozentzeichen und sucht nach einem Ordner dieses Namens. Der Eintrag sieht im Editor exakt richtig aus, denn dort steht dieselbe Zeichenfolge wie beim funktionierenden Nachbarn. Nur der Typ in der zweiten Spalte unterscheidet sich. Dasselbe gilt umgekehrt für einen Schalter, den ein Skript als REG_SZ mit dem Inhalt 1 anlegt, während die Software ein REG_DWORD erwartet: Sie liest keinen Wert, findet ihren Standard und macht weiter.

Die Registry aus PowerShell

PowerShell bildet die Registry als Laufwerk ab. Das ist bequem und erzeugt genau eine Verwechslung, die man einmal verstehen muss: In diesem Laufwerk sind Schlüssel die Elemente und Werte die Eigenschaften daran.

Get-ChildItem HKLM:\SYSTEM\Select
Listet Unterschlüssel — hier also nichts, denn Select hat keine.
Get-ItemProperty HKLM:\SYSTEM\Select
Liest die Werte: Current, Default, Failed, LastKnownGood.
New-ItemProperty -PropertyType DWord
Legt einen Wert mit ausdrücklichem Typ an.
Set-ItemProperty
Ändert einen vorhandenen Wert. Legt keinen Typ fest.
reg query <Pfad> /v <Name>
Dasselbe über reg.exe; zeigt den Typ in der Ausgabe mit an.

Der Ratschlag daraus ist kurz: Wer einen Wert anlegt, nennt den Typ ausdrücklich. Wer einen fremden Wert ändert, sieht ihn sich vorher mit reg query an — dort steht der Typ direkt neben den Daten und lässt sich nicht übersehen.

Die 32-Bit-Sicht: `WOW6432Node`

Auf einem 64-Bit-Windows gibt es für Teile der Registry zwei Sichten. Ein 32-Bit-Prozess, der HKLM\SOFTWARE\Hersteller liest, wird transparent nach HKLM\SOFTWARE\WOW6432Node\Hersteller umgeleitet. Der Prozess merkt davon nichts — er sieht seine eigene, vollständige Welt.

  • reg query HKLM\SOFTWARE\Hersteller /reg:64 — die 64-Bit-Sicht ausdrücklich.
  • reg query HKLM\SOFTWARE\Hersteller /reg:32 — die umgeleitete Sicht ausdrücklich.
  • Ohne Angabe entscheidet die Bitness des aufrufenden Prozesses, nicht die des Systems.
Zwei Fallen auf einmalErstens: Ein 32-Bit-Installationsprogramm legt seine Einstellungen unter WOW6432Node ab, ein 64-Bit-Verwaltungsskript sucht sie darüber und findet nichts. Beide arbeiten korrekt. Zweitens: Schreibt ein 32-Bit-Prozess eine Zeichenkette mit %ProgramFiles%, ersetzt WOW64 das laut Dokumentation durch %ProgramFiles(x86)%. Der Wert, den du gleich danach ausliest, ist nicht der Wert, der geschrieben wurde. Wer die Sicht nicht ausdrücklich wählt, misst ein Ergebnis, das von seinem eigenen Werkzeug abhängt.

`.reg`-Dateien sind kein Änderungsverfahren

Ein Doppelklick auf eine .reg-Datei schreibt ihren Inhalt in die Registry. Das ist bequem und für einen kontrollierten Change aus drei Gründen ungeeignet.

  • Keine Transaktion. Bricht der Vorgang in der Mitte ab, bleibt die Hälfte stehen. Es gibt kein Zurück, das die Datei mitliefert.
  • Keine Prüfung. Ein Tippfehler im Pfad legt einen neuen Schlüssel an, statt eine Fehlermeldung zu erzeugen.
  • Löschen sieht harmlos aus. Ein Minuszeichen vor dem Schlüsselnamen in eckigen Klammern löscht den Schlüssel samt Unterschlüsseln. Eine Zeile, kein Hinweis.
reg export <Pfad> vorher.reg — den betroffenen Teilbaum sichern, bevor irgendetwas geschrieben wird.Die Änderung als Skript mit ausdrücklichen Typen schreiben, nicht als Datei zum Doppelklicken.reg query <Pfad> /v <Name> — den erwarteten Zustand danach zurücklesen, mitsamt Typ.Prüfen, ob die Anwendung den Wert überhaupt neu liest, oder ob ein Dienstneustart dazugehört.
Schritt 4 ist der, den man am häufigsten vergisst: Ein korrekt geschriebener Wert ist noch kein wirksamer Wert.

NTFS-Rechte, und warum „Verweigern gewinnt immer“ falsch ist

DACL und ACEJede Datei, jeder Ordner und jeder Registry-Schlüssel trägt eine DACL — eine Liste von Einträgen (ACE). Jeder Eintrag nennt einen Kontoinhaber und erlaubt oder verweigert ihm bestimmte Rechte.

Ein Eintrag ist entweder explizit am Objekt gesetzt oder vom übergeordneten Ordner geerbt. Diese Unterscheidung ist der Kern des nächsten Abschnitts — sie entscheidet, welcher Eintrag zuerst gefunden wird.

Geprüft wird gegen das Zugriffstoken des Zugreifenden. Darin stehen sein Konto und seine Gruppen — und zwar so, wie sie zum Zeitpunkt der Anmeldung waren. Wer jemanden einer Gruppe hinzufügt, ändert sein Token nicht: Die neue Mitgliedschaft wirkt erst nach einer neuen Anmeldung. whoami /groups zeigt, was im aktuellen Token wirklich steht — und beantwortet damit die Frage „ist die Gruppe schon drin“ ohne Raten.

Das System geht die Einträge der Reihe nach durch und hört auf, sobald der angeforderte Zugriff vollständig erlaubt oder ausdrücklich verweigert ist. Die Reihenfolge entscheidet also über das Ergebnis — und sie ist dokumentiert.

DACL · PRÜFUNG STOPPT BEIM ERSTEN TREFFER1 · explizit VERWEIGERNam Objekt gesetzt2 · explizit ZULASSENam Objekt gesetzt3 · geerbt VERWEIGERNvom übergeordneten Ordner4 · geerbt ZULASSENvom übergeordneten OrdnerTreffer → fertigExplizites Zulassen (2) wird vor geerbtem Verweigern (3) gefunden — und gewinnt.Kein Treffer bis zum Ende? Dann implizit verweigert.
Alle expliziten Einträge stehen vor allen geerbten; innerhalb jeder Gruppe Verweigern vor Zulassen.

Daraus folgt der Satz, den man sich merken muss: Verweigern gewinnt auf derselben Ebene, nicht über Ebenen hinweg. Ein am Ordner gesetztes Verweigern wird nach unten vererbt und landet damit in Gruppe 3. Ein direkt an der Datei gesetztes Zulassen steht in Gruppe 2 — es wird zuerst gefunden und beendet die Prüfung.

Kurzcheck

Ein Ordner verweigert der Gruppe Praktikanten das Lesen. Eine Datei darin hat ein direkt gesetztes Zulassen für dieselbe Gruppe. Was passiert beim Zugriff?

  • Der Zugriff gelingt — das explizite Zulassen wird vor dem geerbten Verweigern gefunden
  • Der Zugriff scheitert — ein Verweigern schlägt jedes Zulassen
  • Das Ergebnis ist unbestimmt und hängt von der Reihenfolge im Editor ab

Treffer. Richtig. Explizite Einträge stehen vollständig vor geerbten, und die Prüfung endet beim ersten Treffer.

Was das für die Praxis heißtEin Verweigern-Eintrag hoch im Baum ist keine verlässliche Sperre — irgendwo weiter unten kann ein explizites Zulassen ihn aushebeln, gesetzt von jemandem, der ein Zugriffsproblem schnell lösen wollte. Verlässlich sperrt man, indem man Zulassen-Einträge entfernt, nicht indem man Verweigern-Einträge hinzufügt.

`icacls`: sichern, setzen, vererben

icacls <Pfad>
Zeigt die DACL. Geerbte Einträge sind mit (I) markiert.
icacls <Pfad> /save <Datei> /t
Sichert die DACLs des Baums in eine Datei — der Rückweg vor jeder Änderung.
icacls <Ordner> /restore <Datei>
Spielt gesicherte DACLs zurück.
icacls <Pfad> /grant <Konto>:<Rechte>
Ergänzt ein Recht zu den vorhandenen expliziten Einträgen.
icacls <Pfad> /grant:r <Konto>:<Rechte>
Ersetzt die vorhandenen expliziten Einträge dieses Kontos.
icacls <Pfad> /inheritancelevel:r
Entfernt die Vererbung vom übergeordneten Ordner.
Der Unterschied, der zwei Zeichen groß ist/grant und /grant:r sehen fast gleich aus und tun Gegensätzliches. Ohne :r sammeln sich bei jedem Lauf eines Skripts weitere Einträge an — nach einem Jahr steht dort eine Liste, die niemand mehr erklären kann, und jeder Lauf war für sich erfolgreich. Mit :r ist der Lauf wiederholbar und das Ergebnis unabhängig davon, wie oft er lief.

Ein Sonderfall bleibt: Der Besitzer eines Objekts darf dessen Berechtigungen ändern, auch wenn die DACL ihm nichts erlaubt. Deshalb ist takeown der Ausweg aus einem Ordner, den sich niemand mehr zutraut — und deshalb ist der Besitzer eine Angabe, die man bei einer Rechteprüfung mitliest statt sie zu übergehen.

Der Ordner, in den niemand mehr hineinkommt

Szenario

Ein Projektordner auf einem Dateiserver lässt sich von keinem Administrator mehr öffnen. Die Vererbung wurde irgendwann unterbrochen, und der einzige verbliebene Zulassen-Eintrag gehört einem Konto, das es nicht mehr gibt.

Anforderungen

  • Der Zugriff muss wiederhergestellt werden.
  • Der Zustand vorher muss belegbar bleiben.

Schritte

  1. icacls D:\Projekte\Alt /save C:\temp\alt.acl /t — den Ist-Zustand des Baums sichern. Das ist der Rückweg, und er entsteht vor dem ersten Eingriff.
  2. takeown /f D:\Projekte\Alt /r /d j — Besitz übernehmen. Der Besitzer darf Berechtigungen ändern, auch wenn ihm die Liste nichts erlaubt.
  3. icacls D:\Projekte\Alt — die Liste jetzt lesen und notieren, welche Einträge geerbt ((I)) und welche explizit sind.
  4. icacls D:\Projekte\Alt /grant:r "DOMAIN\Dateiserver-Admins":(OI)(CI)F — einen definierten Zugang setzen, mit :r, damit der Lauf wiederholbar bleibt.
  5. icacls D:\Projekte\Alt /inheritancelevel:e — die Vererbung wieder aktivieren, sofern das dem Sollzustand des Baums entspricht.

Merksatz: Der teure Teil war nicht die Reparatur, sondern die fehlende Sicherung: Ohne Schritt 1 lässt sich hinterher nicht mehr belegen, welche Rechte der Ordner vorher hatte — und ob die neue Liste enger oder weiter ist als die alte.

Verknüpfungen: drei Arten, ein Pfad

NTFS kennt drei Arten von Verweisen. Sie sehen im Explorer ähnlich aus, verhalten sich aber unterschiedlich — und genau eine davon braucht ein Sonderrecht.

Hardlink (mklink /h)
Zweiter Name für dieselbe Datei. Nur Dateien, nur innerhalb desselben Volumes.
Junction (mklink /j)
Verzeichnisverweis. Darf über lokale Volumes hinweg zeigen, aber nicht auf Netzwerkpfade.
Symbolische Verknüpfung (mklink, mklink /d)
Datei- oder Verzeichnisverweis, darf auch auf einen UNC-Pfad zeigen.
Das Recht, das den Unterschied machtSymbolische Verknüpfungen zu erstellen erfordert das Privileg SeCreateSymbolicLinkPrivilege, das standardmäßig nur Mitglieder der Administratoren-Gruppe haben. Junctions brauchen es nicht. Ein Bereitstellungsskript, das unter einem eingeschränkten Dienstkonto laufen soll und mklink /d benutzt, scheitert deshalb — und funktioniert, sobald jemand es „zum Testen“ als Administrator startet. Das ist der Grund, warum diese Sorte Fehler es bis in die Produktion schafft.

Ein Detail mit Betriebswirkung: Ein Hardlink ist kein Verweis auf eine Datei, sondern ein gleichberechtigter Name dafür. Das Löschen eines Hardlinks löscht die Daten nicht, solange noch ein anderer Name existiert. Ein Sicherungswerkzeug, das Dateien zählt, zählt dieselben Daten dabei mehrfach.

Was man in einer Datei nicht sieht

NTFS kann an eine Datei weitere, benannte Datenströme hängen. Der sichtbare Inhalt ist nur der unbenannte Strom; die anderen tauchen weder in der Größenangabe noch in einer normalen Auflistung auf.

  • dir /R zeigt die zusätzlichen Ströme einer Datei.
  • Get-Item <Datei> -Stream * listet sie in PowerShell.
  • Get-Content <Datei> -Stream Zone.Identifier liest einen davon.

Der wichtigste dieser Ströme heißt Zone.Identifier. Windows hängt ihn an Dateien aus dem Internet; der Wert 3 steht für die Internet-Zone. Er ist der Grund, warum ein heruntergeladenes PowerShell-Skript unter der Ausführungsrichtlinie RemoteSigned nicht startet, obwohl es lokal auf der Platte liegt und der Inhalt korrekt ist. Unblock-File entfernt genau diesen Strom — es ändert nichts am Skript selbst.

Warum das keine Randnotiz istEin Kopiervorgang, der Datenströme nicht mitnimmt, entfernt diese Kennzeichnung stillschweigend. Ein Archiv, das nur den Hauptstrom auspackt, ebenso. Wer eine Datei über mehrere Zwischenstationen auf einen Server bringt, kann deshalb nicht mehr sagen, ob die fehlende Sperre eine Entscheidung war oder ein Nebeneffekt des Transportwegs.

Lange Pfade: der Schalter, der allein nichts tut

Die klassische Obergrenze der Windows-API für einen Pfad ist MAX_PATH260 Zeichen, das abschließende Nullzeichen eingerechnet. Auf einem Dateiserver mit gewachsenen Ordnerbäumen ist das keine theoretische Grenze: Dateien werden unkopierbar, Sicherungen melden Fehler, und der Explorer weigert sich, einen Ordner zu löschen.

Wichtig ist, worauf sich die Grenze bezieht: auf den gesamten Pfad vom Laufwerksbuchstaben an, nicht auf den Dateinamen. Dieselbe Datei ist deshalb unerreichbar, solange sie tief im Baum liegt, und wieder erreichbar, sobald ein übergeordneter Ordner umbenannt oder der Teilbaum weiter oben eingehängt wird. Das erklärt auch, warum ein Problem nur beim Kopieren auf den Server auftritt und nicht auf dem Arbeitsplatz: Der Zielpfad ist länger als der Quellpfad.

HKLM\SYSTEM\CurrentControlSet\Control\FileSystem, Wert LongPathsEnabled als REG_DWORD auf 1 — oder dieselbe Einstellung per Gruppenrichtlinie.Die Anwendung muss in ihrem Manifest longPathAware deklarieren.Neustart, weil der Wert je Prozess zwischengespeichert und danach nicht neu gelesen wird.
Fehlt einer der beiden ersten Schritte, ändert sich für die betroffene Anwendung gar nichts.
Die häufigste FehldiagnoseDer Registry-Wert allein wirkt nicht. Die Dokumentation sagt ausdrücklich, dass er nur Anwendungen betrifft, die dafür angepasst wurden — und dass der Wert je Prozess zwischengespeichert wird und während dessen Laufzeit nicht neu gelesen wird. Wer den Wert setzt, den Explorer denselben Ordner noch einmal probieren lässt und daraus schließt, die Einstellung sei wirkungslos, hat zwei Dinge gleichzeitig nicht geprüft. Der Weg, der unabhängig davon immer funktioniert, ist das Präfix \\?\ vor dem absoluten Pfad — es umgeht die Grenze auf API-Ebene, nicht über eine Einstellung.

Jetzt anwenden

Diesen Stoff gibt es als Modul mit bewerteten Entscheidungs-Checks — dieselbe Einführung, danach die Übungen.

Zum Modul →
Quellen & Aktualität12 Primärquellen · zuletzt geprüft:
  1. 01Registry Hives
  2. 02Registry Value Types
  3. 03Registry Redirector
  4. 04Order of ACEs in a DACL
  5. 05How DACLs Control Access to an Object
  6. 06icacls
  7. 07mklink
  8. 08Hard links and junctions
  9. 09Create symbolic links (security policy setting)
  10. 10Maximum Path Length Limitation
  11. 11Unblock-File (Microsoft.PowerShell.Utility)
  12. 12Get-Item (Microsoft.PowerShell.Management)