cheat sheet

fsutil

Inspect and manage NTFS file system internals — query volume info, manage hard links, sparse files, reparse points, the USN journal, and the dirty bit — from an elevated command prompt.

fsutil — File System Utility

What it is

fsutil is a built-in Windows command that exposes low-level NTFS and ReFS file system features not accessible through Explorer or most GUI tools. Use it to query volume information, inspect hard links, create sparse files, manage reparse points, force a dirty-bit check, and control the USN change journal. The PowerShell equivalent for many operations is Get-Volume, Get-Item, and WMI/CIM cmdlets, but fsutil remains the only native CLI for some NTFS internals. Requires Administrator privileges for most sub-commands.

Availability

fsutil ships as C:\Windows\System32\fsutil.exe on Windows XP and later. Most features require NTFS volumes.

cmd
fsutil

Output:

arduino
---- FSUTIL Commands Supported ----

8dot3name         Manage the 8.3 short name behavior
behavior          Control file system behavior
dirty             Manage volume dirty bit
file              File specific commands
hardlink          Hardlink management
objectid          Object ID management
quota             Quota management
repair            Self healing management
reparsepoint      Reparse point management
resource          Transactional Resource Manager management
sparse            Sparse file control
tiering           Storage tiering
transaction       Transaction management
usn               USN management
volume            Volume management
wim               Wim Transparent File Compression Commands

Syntax

cmd
fsutil <command> <sub-command> [arguments]

Output: (varies by sub-command)

Essential sub-commands

Sub-commandMeaning
dirty query <vol>Report whether the dirty bit is set
dirty set <vol>Set the dirty bit (triggers chkdsk at next boot)
volume diskfree <vol>Show free, total, and available bytes
volume listList all mounted volumes
file queryvaliddata <file>Show the valid data length of a file
file createhardlink <new> <existing>Create an NTFS hard link
hardlink list <file>List all hard links for a file
sparse setflag <file>Mark a file as sparse
sparse queryrange <file>List allocated (non-zero) byte ranges in a sparse file
reparsepoint query <path>Show reparse tag and data for a path
reparsepoint delete <path>Remove a reparse point from a path
usn createjournal m=<max> a=<alloc> <vol>Create or resize the USN journal
usn queryjournal <vol>Show USN journal parameters
usn readjournal <vol>Read USN records from the journal

Volume information

fsutil volume reports disk space at byte granularity — more precise than dir or Explorer, useful in scripts that need exact available bytes.

cmd
fsutil volume diskfree C:

Output:

python
Total free bytes        :                 484,442,447,872 ( 451.1 GB)
Total bytes             :                 536,870,912,000 ( 500.0 GB)
Total quota free bytes  :                 484,442,447,872 ( 451.1 GB)
cmd
fsutil volume list

Output:

ruby
Volumes that are mounted:
\\?\Volume{a1b2c3d4-e5f6-7890-abcd-ef1234567890}\
\\?\Volume{f0e1d2c3-b4a5-6789-fedc-ba9876543210}\

Dirty bit

The dirty bit is an NTFS flag that signals the volume needs consistency checking. When set, chkdsk runs automatically at the next reboot before Windows loads. Use dirty query to check and dirty set to force a scheduled check.

cmd
fsutil dirty query C:

Output:

csharp
Volume - C: is NOT Dirty
cmd
rem Force chkdsk at next reboot for D:
fsutil dirty set D:

Output:

csharp
Volume - D: is now marked Dirty

An NTFS hard link is a second directory entry pointing to the same underlying file data — deleting either entry leaves the data accessible through the other. Hard links only work within the same volume. They are used by Windows SxS, DISM, and some package managers to avoid storing the same file bytes twice.

cmd
fsutil file createhardlink C:\Data\link_to_report.txt C:\Reports\report.txt

Output:

diff
Hardlink created for C:\Data\link_to_report.txt <<===>> C:\Reports\report.txt
cmd
fsutil hardlink list C:\Reports\report.txt

Output:

code
\Data\link_to_report.txt
\Reports\report.txt

Sparse files

A sparse file is an NTFS optimization where regions of zeros are not physically written to disk — only ranges containing non-zero data consume actual clusters. Useful for virtual disk images, databases, and log files that reserve a large address space but start mostly empty.

cmd
rem Mark an existing file as sparse
fsutil sparse setflag C:\VMs\disk.vhd

Output:

csharp
(none — exits 0 on success)
cmd
rem Query which byte ranges are allocated (non-zero data)
fsutil sparse queryrange C:\VMs\disk.vhd

Output:

csharp
Allocated ranges in the file:
[0] Offset: 0x0000000000000000  Length: 0x0000000000200000
[1] Offset: 0x0000000040000000  Length: 0x0000000000100000

Reparse points

A reparse point is metadata attached to a file or directory that redirects I/O to a filter driver — the mechanism behind NTFS symbolic links, directory junctions, mount points, and OneDrive's cloud file placeholders. fsutil reparsepoint query reveals the reparse tag and raw data for any path that has one.

cmd
fsutil reparsepoint query C:\ProgramData\Application

Output:

yaml
Reparse Tag Value : 0x00000003
Tag value: Microsoft
Tag value: Name Surrogate
Tag value: Directory
Reparse Data Length: 0x00000028
Reparse Data:
0000: ...
cmd
rem Remove a stale reparse point (e.g. broken junction)
fsutil reparsepoint delete C:\OldLink

Output:

csharp
(none — exits 0 on success)

USN journal

The Update Sequence Number (USN) change journal is an NTFS log of every file system change on a volume — creations, deletes, renames, attribute changes. Antivirus engines, backup software, and search indexers use it to detect changes efficiently without full-volume scans.

cmd
fsutil usn queryjournal C:

Output:

yaml
Usn Journal ID   : 0x01d7b4a2c8ef1230
First Usn        : 0x0000000000000000
Next Usn         : 0x00000000012a4b80
Lowest Valid Usn : 0x0000000000000000
Max Usn          : 0x7fffffffffffffff
Maximum Size     : 0x0000000004000000
Allocation Delta : 0x0000000000800000
cmd
rem Create a journal with 64 MB max size and 16 MB allocation delta
fsutil usn createjournal m=0x4000000 a=0x1000000 D:

Output:

csharp
(none — exits 0 on success)

fsinfo — file system metadata

fsutil fsinfo is the canonical CLI source for low-level volume metadata: physical and logical sector sizes, alignment, TRIM and seek-penalty flags, NTFS version, and feature-support bits. Use it whenever a configuration tool needs to know whether the underlying device is an SSD, what the alignment is, or which NTFS features are enabled.

cmd
rem List every drive Windows can see (including network mounts)
fsutil fsinfo drives

Output:

makefile
Drives: C:\ D:\ E:\
cmd
rem What kind of drive is C:?
fsutil fsinfo drivetype C:

Output:

makefile
C: - Fixed Drive

Possible values: Unknown Drive, No such Root Directory, Removable Drive, Fixed Drive, Remote/Network Drive, CD-ROM Drive, RAM Disk.

cmd
rem Detailed NTFS info for a volume
fsutil fsinfo ntfsinfo C:

Output:

yaml
NTFS Volume Serial Number :       0xa1b2c3d4e5f67890
NTFS Version   :                  3.1
LFS Version    :                  2.0
Number Sectors :                  0x00000000003c5000
Total Clusters :                  0x000000001f3a8000
Free Clusters  :                  0x000000000c1bd400
Total Reserved :                  0x0000000000060000
Bytes Per Sector  :               512
Bytes Per Physical Sector :       4096
Bytes Per Cluster :               4096
Bytes Per FileRecord Segment    : 1024
Clusters Per FileRecord Segment : 0
Mft Valid Data Length :           0x00000000128c0000
Mft Start Lcn  :                  0x00000000000c0000
Mft2 Start Lcn :                  0x0000000000000000
Mft Zone Start :                  0x0000000007a90c00
Mft Zone End   :                  0x0000000007a92020
Resource Manager Identifier :     a1b2c3d4-e5f6-7890-abcd-ef1234567890
cmd
rem Per-sector physical layout — the same info defrag uses to detect SSD vs HDD
fsutil fsinfo sectorinfo C:

Output:

yaml
LogicalBytesPerSector :                                  512
PhysicalBytesPerSectorForAtomicity :                    4096
PhysicalBytesPerSectorForPerformance :                  4096
FileSystemEffectivePhysicalBytesPerSectorForAtomicity : 4096
Device Alignment :                                       Aligned (0x000)
Partition alignment on device :                          Aligned (0x000)
No Seek Penalty
Trim Supported
Not DAX capable
Not Thinly-Provisioned
cmd
rem ReFS-specific info
fsutil fsinfo refsinfo R:

Output:

yaml
REFS Volume Serial Number :       0x1234567890abcdef
REFS Version   :                  3.7
Number Sectors :                  0x00000000ffff8000
Total Clusters :                  0x00000000003ffe00
Free Clusters  :                  0x0000000000234bc8
Bytes Per Sector  :               512
Bytes Per Physical Sector :       4096
Bytes Per Cluster :               65536
Checksum Type:                    CHECKSUM_TYPE_CRC64
cmd
rem Statistics counters (great for diagnosing thrashing volumes)
fsutil fsinfo statistics C:

Output:

yaml
File System Type :     NTFS

UserFileReads          :         13456789
UserFileReadBytes      :      324567890123
UserDiskReads          :          1234567
UserFileWrites         :          4567890
UserFileWriteBytes     :       89012345678
UserDiskWrites         :           789012
MetaDataReads          :          5678901
MetaDataReadBytes      :       23456789012
MetaDataDiskReads      :           345678
MetaDataWrites         :          1234567
MetaDataWriteBytes     :        4567890123
MetaDataDiskWrites     :           234567
cmd
rem Lightweight, single-line volume info (FAT/exFAT/NTFS/ReFS)
fsutil fsinfo volumeinfo C:

Output:

vbnet
Volume Name : System
Volume Serial Number : 0xa1b2c3d4
Max Component Length : 255
File System Name : NTFS

Supports Case-sensitive filenames
Preserves the case of filenames
Supports Unicode in filenames
Preserves and Enforces ACL's
Supports file-based compression
Supports Disk Quotas
Supports Sparse files
Supports Reparse Points
Supports Object Identifiers
Supports the Encrypted File System
Supports Named Streams
Supports Transactions
Supports Hard Links
Supports Extended Attributes
Supports Open By FileID
Supports USN Journal
Is DAX volume               : No

8.3 short names

8.3 short names are the legacy FAT-style filename aliases (PROGRA~1) auto-generated for every long filename on NTFS. They are required by some 16-bit installers and by Windows itself for a few system paths, but disabling them speeds up directory enumeration on volumes with many files.

cmd
rem Show current per-volume policy
fsutil 8dot3name query C:

Output:

csharp
The volume state is: 0 (8dot3 name creation is enabled).
The registry state is: 2 (Per volume setting - the default).
cmd
rem Disable 8.3 generation for this volume going forward
fsutil 8dot3name set C: 1

Output:

csharp
Successfully disabled 8dot3name generation on C:
cmd
rem Strip existing 8.3 names from a folder (NTFS only)
fsutil 8dot3name strip C:\Apps

Output:

yaml
Scanning directories for files with 8dot3 names...
Successfully scanned 4012 files
Total 8dot3 names processed: 4012
Successfully stripped 8dot3 names from 4012 files
Registry stateMeaning
0Create 8.3 names on all volumes
1Disable on all volumes
2Per-volume setting (default)
3Disable on all volumes except the system volume

behavior — global NTFS knobs

fsutil behavior controls global NTFS settings: last-access timestamp updates, memory usage, link tracking, symlink evaluation, etc.

cmd
rem Query a single behavior
fsutil behavior query DisableLastAccess

Output:

ini
DisableLastAccess = 1 (User Managed, Disabled)
cmd
rem Query everything
fsutil behavior query

Output:

ini
DisableLastAccess = 1 (User Managed, Disabled)
DisableDeleteNotify  for NTFS = 0
DisableDeleteNotify  for ReFS = 0
EncryptPagingFile = 0
QuotaNotifyRate = 3600
SymlinkEvaluation:
        Local to local symbolic links are enabled.
        Local to remote symbolic links are enabled.
        Remote to local symbolic links are disabled.
        Remote to remote symbolic links are disabled.
Memory Usage = 2 (Standard)
Disable Compression = 0
Disable Encryption = 0
cmd
rem Allow remote-to-local symlinks (carefully — security implication)
fsutil behavior set SymlinkEvaluation R2L:1

Output:

css
This operation requires a reboot to take effect.
cmd
rem Stop NTFS from updating last-access timestamps (improves perf on busy volumes)
fsutil behavior set DisableLastAccess 1

Output:

ini
DisableLastAccess = 1
SettingEffect
AllowExtCharAllow extended-ASCII characters in 8.3 names
BugNTFS error-handling behaviour
DisableLastAccess0=enabled, 1=disabled, 2=managed by system (Win10+ default)
DisableDeleteNotify0=TRIM enabled, 1=TRIM disabled (per file system)
EncryptPagingFileEncrypt the page file
MftZoneMFT reservation size (1=12.5%, 2=25%, 3=37.5%, 4=50%)
QuotaNotifyRateDisk-quota notification interval in seconds
`SymlinkEvaluation L2L:01 L2R:0
Memory Usage1=conservative, 2=standard, 3=aggressive
Disable CompressionBlock use of NTFS compression
Disable EncryptionBlock use of EFS

File-level introspection

fsutil file exposes per-file metadata that NTFS tracks but Explorer hides — valid data length, file ID, layout, and zero-fill ranges.

cmd
rem Query the file ID (used by USN journal and Volume Shadow)
fsutil file queryfileid C:\Reports\report.txt

Output:

arduino
File ID is 0x0000000000000000000200000000a3b4
cmd
rem Reverse lookup — find a path from a file ID
fsutil file queryfilenamebyid C: 0x0000000000000000000200000000a3b4

Output:

csharp
A random link name to this file is [\\?\C:\Reports\report.txt]
cmd
rem Show valid-data length vs file size (sparse files report less VDL than size)
fsutil file queryvaliddata C:\VMs\disk.vhd

Output:

csharp
Valid Data Length is 0x0000000040100000
cmd
rem Pre-allocate a zero-filled file for benchmarking
fsutil file createnew C:\Temp\10gb.bin 10737418240

Output:

python
File C:\Temp\10gb.bin is created
cmd
rem Set the valid-data length on an existing file (e.g. for fast extend with no zeroing)
fsutil file setvaliddata C:\Temp\10gb.bin 10737418240

Output:

kotlin
Valid data length is changed
cmd
rem Layout details — extents, attributes, parent
fsutil file layout C:\Reports\report.txt

Output:

yaml
File reference number : 0x000200000000a3b4
Flags : 0x00000000
File attributes : 0x00000020
Stream :
        Name : :: $DATA
        Size : 0x000000000003e800
        Allocated Size : 0x0000000000040000
        Extents :
          Vcn : 0x0
          Lcn : 0x000000001a3b4567 Length : 0x40

fsutil hardlink rounds out into count and list, both essential for auditing how aggressively a tool (DISM, package managers) is using hard links to deduplicate data.

cmd
rem How many hard links point to this file?
fsutil hardlink count C:\Windows\System32\notepad.exe

Output:

csharp
Hardlink count is 1
cmd
rem List every hard link to a given file
fsutil hardlink list C:\Windows\System32\notepad.exe

Output:

code
\Windows\System32\notepad.exe
\Windows\WinSxS\amd64_microsoft-windows-notepad_31bf3856ad364e35_10.0.26100.1_none_a1b2c3d4\notepad.exe
powershell
# PowerShell hard-link creation (.NET 4.6+ / PowerShell 5+)
New-Item -ItemType HardLink -Path C:\Data\link.txt -Target C:\Reports\report.txt

Output:

diff
    Directory: C:\Data

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---l         5/25/2026   3:14 PM          15823 link.txt

objectid — NTFS object identifiers

NTFS can assign every file an Object ID (separate from its file reference) so distributed link tracking can find it even after moves and renames. fsutil objectid reads, sets, deletes, or creates these IDs.

cmd
fsutil objectid query C:\Reports\report.txt

Output:

yaml
Object ID :          a1b2c3d4e5f6789012345678901234567890abcd
Birth Volume ID :    aaaabbbbccccddddaaaabbbbccccdddd
Birth Object ID :    a1b2c3d4e5f6789012345678901234567890abcd
Domain ID :          00000000000000000000000000000000
cmd
rem Strip an Object ID (forces distributed-link-tracking refresh)
fsutil objectid delete C:\Reports\report.txt

Output:

code
The operation completed successfully.

quota — NTFS disk quotas

fsutil quota configures and inspects per-user disk quotas on NTFS. Quotas are tracked per-user-SID; the limit and warning level are global per volume, or per-user with explicit overrides.

cmd
rem Disable / enable / enforce per-volume
fsutil quota disable D:
fsutil quota track D:
fsutil quota enforce D:

Output:

code
The operation completed successfully.
The operation completed successfully.
The operation completed successfully.
cmd
rem Set a 10 GB quota and 9 GB warning for a domain user
fsutil quota modify D: 10737418240 9663676416 CORP\alicedev

Output:

code
The operation completed successfully.
cmd
rem Show all quota entries on a volume
fsutil quota query D:

Output:

ini
FileSystemControlFlags = 0x00000003
                Quotas are tracked and enforced on this volume
                Logging enabled when user exceeds their warning level
DefaultQuotaThreshold     = 0xffffffffffffffff
DefaultQuotaLimit         = 0xffffffffffffffff

SID Name = CORP\alicedev   (User)
Change time = Sunday, May 25, 2026  3:14:00 PM
Quota Used     = 5368709120
Quota Threshold = 9663676416
Quota Limit    = 10737418240

resource — NTFS Transactional Resource Manager

The Transactional Resource Manager (TxF) was the NTFS transaction subsystem. It is deprecated but still ships, and fsutil resource is how to query/start/stop a resource manager.

cmd
rem Inspect the default resource manager on a volume
fsutil resource info C:\

Output:

sql
Resource Manager Identifier :     a1b2c3d4-e5f6-7890-abcd-ef1234567890
KTM Log Path for RM:              \System Volume Information\Default{a1b2c3d4-...}TM
RM has been shut down cleanly.

Default Single Phase Commit transaction Timeout      :     60
Default Maximum Single Phase Commit transaction Wait :     30
Maximum number of transactions                       :   4096
Snapshot Mode                                        :  0x00 (None)

Microsoft recommends new code use MoveFileTransacted / TxF only when interop with existing transactional code is required; otherwise prefer application-level atomic file writes.

sparse — full sub-command reference

Sparse files have three operations beyond setflag / queryrange: removing the sparse flag, querying the flag state, and setting a zero range (which deallocates clusters).

cmd
rem Is this file sparse?
fsutil sparse queryflag C:\VMs\disk.vhd

Output:

csharp
This file is set as sparse
cmd
rem Deallocate a range of bytes (returns clusters to free space)
fsutil sparse setrange C:\VMs\disk.vhd 0x0 0x40000000

Output:

csharp
(no output — exits 0 on success)
cmd
rem Clear the sparse flag (file becomes a normal file again)
fsutil sparse setflag C:\VMs\disk.vhd 0

Output:

csharp
(no output — exits 0 on success)

reparsepoint — full sub-command reference

reparsepoint has a set sub-command for advanced uses — manually writing a reparse tag and payload — but most workflows only need query and delete. The companion CLI mklink is the right way to create symbolic links and junctions; fsutil reparsepoint is for inspection.

cmd
rem Is this path a reparse point?
fsutil reparsepoint query C:\Users\alice\OneDrive

Output:

yaml
Reparse Tag Value : 0x9000001a
Tag value: Microsoft
Tag value: Cloud
Tag value: Filter
Reparse Data Length: 0x00000040
Reparse Data:
0000:  03 00 00 00 04 00 00 00  4f 00 6e 00 65 00 44 00  ........O.n.e.D.
0010:  72 00 69 00 76 00 65 00  00 00 00 00 00 00 00 00  r.i.v.e.........
Reparse tag (hex)Meaning
0xA000000CNTFS symbolic link
0xA0000003Mount point / directory junction
0x80000005Hierarchical Storage Management
0x80000023App Execution Alias (Microsoft Store)
0x9000001AOneDrive Cloud Files placeholder
0x8000001BFilesystem Filter (Defender, FSRM)
cmd
rem Strip a stale reparse point — turns the directory back into an empty folder
fsutil reparsepoint delete C:\OldLink

Output:

csharp
(no output — exits 0 on success)

tiering — Storage Spaces tiering hints

On Storage Spaces tiered virtual disks, fsutil tiering controls per-file pinning to the SSD or HDD tier.

cmd
rem Inspect current tiering settings for a volume
fsutil tiering regionList F:

Output:

yaml
SSD Region size:        100 GB
HDD Region size:        900 GB
Heat tracking enabled:  Yes
Heat tracking version:  1
cmd
rem Set a per-file desired tier (1=SSD, 0=auto)
fsutil tiering setflags F:\HotData\db.mdf SSD-PIN

Output:

csharp
(no output — exits 0 on success)

usn — full sub-command reference

The USN journal is the foundation of every change-aware piece of Windows storage tooling: Indexing, File History, Volume Shadow Copy, OneDrive, modern backup software. fsutil usn is the way to enumerate it directly.

cmd
rem Read the journal — every record from the start
fsutil usn readjournal C:

Output:

yaml
USN Journal Records:
  USN              : 0x00000000012a4b80
  File ref#        : 0x000200000000a3b4
  ParentFile ref#  : 0x000100000000a3b3
  Reason           : 0x00000100 (USN_REASON_CLOSE)
  Time             : 5/25/2026 3:14:00 PM
  Source info      : 0x00000000
  Security Id      : 0x00000000
  File Attributes  : 0x00000020 (ARCHIVE)
  File Name        : report.txt
cmd
rem Read records past a starting USN
fsutil usn readjournal C: startusn=0x00000000012a4000 minmajorversion=2 maxmajorversion=3

Output:

csharp
USN Journal Records:
  USN              : 0x00000000012a4080
  File ref#        : 0x000200000000a3b5
  ...
cmd
rem Read records by file ID
fsutil usn readdata C:\Reports\report.txt

Output:

yaml
USN data:
  Major Version    : 0x2
  Minor Version    : 0x0
  FileRef#         : 0x000200000000a3b4
  Parent FRef#     : 0x000100000000a3b3
  Usn              : 0x00000000012a4b80
  File Attributes  : 0x00000020
  File Name Length : 0x14
  File Name Offset : 0x3c
  FileName         : report.txt
cmd
rem Delete the journal (use with care; antivirus and indexing will rebuild it)
fsutil usn deletejournal /d C:

Output:

csharp
Deleting USN journal on volume C:
cmd
rem Resize the journal — 256 MB max, 32 MB alloc delta
fsutil usn createjournal m=0x10000000 a=0x02000000 D:

Output:

csharp
(no output — exits 0 on success)
cmd
rem Enumerate every file currently tracked in the journal
fsutil usn enumdata 1 0 0 C:

Output:

python-repl
USN  : 0x0000000000000000
File ref#  : 0x000200000000a3b4
...
File name  : report.txt
USN  : 0x0000000000000020
...

volume — beyond diskfree

fsutil volume has additional sub-commands for forcing dismount, querying allocation, and inspecting volume layout — useful for diagnostics and pre-imaging gates.

cmd
rem Force a dismount (locks the volume, terminates open handles)
fsutil volume dismount D:

Output:

csharp
Volume - D: is dismounted
cmd
rem Show allocation-bitmap clusters in use vs free
fsutil volume allocationreport C:

Output:

yaml
File system : NTFS
Total allocated clusters     : 12000000
Total free clusters          : 100000000
Total reserved clusters      : 24576
Largest free chunk           : 99000000
cmd
rem Query the path that a volume GUID resolves to
fsutil volume querycluster D: 0x00000000

Output:

less
Cluster 0x0000000000000000 : NOT IN USE

PowerShell equivalents

Several fsutil operations have first-class PowerShell wrappers that produce object output. Prefer these in scripts that need cross-locale stability.

fsutil operationPowerShell
volume diskfreeGet-Volume (Size, SizeRemaining)
dirty query(Get-Volume).DriveLetter + fsutil dirty query (no native cmdlet)
fsinfo ntfsinfoGet-Volume + Get-Disk + Get-Partition
fsinfo sectorinfoGet-PhysicalDisk
fsinfo statisticsGet-StorageReliabilityCounter
file createhardlinkNew-Item -ItemType HardLink -Path link -Target target
file createnew (zero-fill)[System.IO.File]::Create('path').SetLength(N)
hardlink list(Get-Item path).LinkType + (Get-Item path).Target
reparsepoint query`Get-Item path
sparse setflagcompact /q /a /s file (related; closest native CLI)
usn readjournalNo direct cmdlet; use Get-WinEvent on FRS/Defender logs, or call DeviceIoControl
powershell
# Quick volume snapshot in one pipeline
Get-Volume | Where-Object DriveLetter |
    Select DriveLetter, FileSystemType, FileSystemLabel,
           @{n='SizeGB';e={[math]::Round($_.Size/1GB,1)}},
           @{n='FreeGB';e={[math]::Round($_.SizeRemaining/1GB,1)}}

Output:

yaml
DriveLetter FileSystemType FileSystemLabel SizeGB FreeGB
----------- -------------- --------------- ------ ------
C           NTFS           System           475.0  234.8
D           NTFS           Data            1862.4  843.2
R           ReFS           DataLake        4000.0 2200.0

Cross-references: where fsutil fits in the toolchain

ToolWhen to use
fsutilNTFS/ReFS internals — the only built-in CLI for many of them.
chkdsk / Repair-VolumeVolume integrity. See sections/windows/chkdsk.
defrag / Optimize-VolumeDefragmentation, retrim, slab consolidation. See sections/windows/defrag.
diskpart / Get-DiskPartition-level operations. See sections/windows/diskpart.
mountvolMount-point management. See sections/windows/mountvol.
dism /Online /Get-DriversDriver inventory linked from fsutil reparsepoint output. See sections/windows/dism.
compact /Q /A /SNTFS file/folder compression report.
cipher /WWipe free space on encrypted volumes.
df / du / duf (Linux)Cross-platform space accounting via WSL. See sections/linux/df-du-duf.

Common pitfalls

  1. Most operations require elevation — run cmd.exe as Administrator; unprivileged calls return "Access is denied".
  2. dirty set means chkdsk runs at every reboot until the bit is cleared — only use it when you intend a scheduled check; a clean chkdsk /F clears the bit automatically.
  3. Hard links don't work across volumesfsutil file createhardlink fails if source and destination are on different drives.
  4. Sparse query output is byte offsets not GB — convert hex offsets with printf "%d" 0xABC in PowerShell or a calculator; the raw output is in hexadecimal.
  5. Deleting a reparse point does not delete the filefsutil reparsepoint delete removes only the reparse data; the directory entry (and any real content) remains.
  6. 8dot3name strip cannot undo itself — once stripped, 8.3 names can only be restored by recreating the files; back up before stripping production volumes.
  7. behavior set DisableDeleteNotify 1 cripples SSD performance — that flag disables TRIM; only set it when troubleshooting drives that misbehave on TRIM.
  8. Disabling last-access via DisableLastAccess breaks some backup/audit tooling — verify that nothing relies on access timestamps before flipping.
  9. usn deletejournal /d is synchronous and locks the volume — running it on the system drive can stall services that depend on the journal; do it during maintenance windows.
  10. tiering only does anything on tiered Storage Spaces virtual disks — on regular volumes the commands return success but have no effect.
  11. file setvaliddata requires SeManageVolumePrivilege — by default only Administrators have it; non-admin batch runs fail with Access is denied.
  12. resource (TxF) is deprecated — write new code against MoveFileEx or app-level atomic writes; the resource manager will eventually be removed.
  13. fsinfo statistics counters reset on every reboot — to track trends, sample periodically and diff; don't read them as cumulative-since-install.
  14. 8.3 generation policy needs rebootfsutil 8dot3name set changes the setting but pending operations may continue to create 8.3 names until next boot.

Sources

References consulted while writing this article. Links open in a new tab.

  • Microsoft Learn — fsutil command reference — Authoritative flag list and parameter semantics used to build the Essential options table.
  • SS64 — fsutil — Cross-version comparison and historical syntax notes.

Real-world recipes

Check exact free bytes in a script

cmd
for /f "tokens=3" %A in ('fsutil volume diskfree D: ^| findstr "Total free"') do set FREE=%A
echo Free bytes on D: %FREE%

Output:

csharp
Free bytes on D: 1,073,741,824
cmd
for %F in (C:\Reports\*.txt) do @fsutil hardlink list "%F" 2>NUL | find /c "\" > NUL && echo %F

Output:

makefile
C:\Reports\report.txt
C:\Reports\summary.txt

Detect whether a path is a reparse point

cmd
@echo off
fsutil reparsepoint query C:\SomeDir >NUL 2>&1
if %ERRORLEVEL% EQU 0 (
    echo C:\SomeDir is a reparse point.
) else (
    echo C:\SomeDir is a regular directory.
)

Output:

vbnet
C:\SomeDir is a reparse point.

Heat report for an MFT-heavy volume

Surface volumes likely to benefit from MFT zone expansion.

powershell
$rows = Get-Volume | Where-Object { $_.DriveLetter -and $_.FileSystemType -eq 'NTFS' } | ForEach-Object {
    $letter = "$($_.DriveLetter):"
    $info   = (cmd /c "fsutil fsinfo ntfsinfo $letter") -join "`n"
    if ($info -match 'Mft Valid Data Length\s+:\s+(0x[0-9a-fA-F]+)') {
        $mft = [Convert]::ToInt64($Matches[1], 16)
        [PSCustomObject]@{
            Drive    = $letter
            SizeGB   = [math]::Round($_.Size / 1GB, 1)
            FreeGB   = [math]::Round($_.SizeRemaining / 1GB, 1)
            MFT_MB   = [math]::Round($mft / 1MB, 1)
        }
    }
}
$rows | Sort-Object MFT_MB -Descending | Format-Table -AutoSize

Output:

yaml
Drive SizeGB FreeGB MFT_MB
----- ------ ------ ------
D:    1862.4  843.2 2934.6
C:     475.0  234.8  297.4

USN journal tail in PowerShell

A simple poller that prints new USN entries every few seconds — handy for debugging which process is touching files.

powershell
$drive = 'C:'
$last  = (cmd /c "fsutil usn readjournal $drive" 2>$null |
    Select-String -Pattern '^\s*USN\s+:\s+(0x[0-9a-fA-F]+)' |
    Select-Object -Last 1).Matches.Groups[1].Value

while ($true) {
    Start-Sleep -Seconds 3
    $records = cmd /c "fsutil usn readjournal $drive startusn=$last" 2>$null
    if ($records) {
        $records | Select-String -Pattern 'File Name|Reason'
        $last = ($records | Select-String -Pattern '^\s*USN\s+:\s+(0x[0-9a-fA-F]+)' |
                 Select-Object -Last 1).Matches.Groups[1].Value
    }
}

Output:

yaml
  Reason           : 0x00000102 (USN_REASON_DATA_OVERWRITE | USN_REASON_CLOSE)
  File Name        : app.log
  Reason           : 0x00000100 (USN_REASON_CLOSE)
  File Name        : sessions.dat

Volume integrity precheck before a backup

Compose fsutil dirty query, Repair-Volume -Scan, and Get-PhysicalDisk into a single gate.

powershell
function Test-VolumeReady {
    param([Parameter(Mandatory)][string]$Drive)
    $dirty = (cmd /c "fsutil dirty query ${Drive}:" 2>$null) -match 'is Dirty\s*$'
    if ($dirty) { return @{Ok=$false; Reason='Dirty bit set'} }

    $scan  = Repair-Volume -DriveLetter $Drive -Scan
    if ($scan -ne 'NoErrorsFound') { return @{Ok=$false; Reason="Scan: $scan"} }

    $disk = Get-Partition -DriveLetter $Drive | Get-Disk |
            Get-PhysicalDisk | Select -First 1
    if ($disk.HealthStatus -ne 'Healthy') {
        return @{Ok=$false; Reason="Disk health: $($disk.HealthStatus)"}
    }
    return @{Ok=$true; Reason='Healthy'}
}

Test-VolumeReady -Drive D

Output:

sql
Name                           Value
----                           -----
Ok                             True
Reason                         Healthy