Windows Reference (general)#

General Windows and PowerShell commands — the ones that get looked up, forgotten and looked up again.

Unverified by design — ordinary Windows/PowerShell commands, not checked against any build lane, so they do not carry the authority of Fresh Windows Host Bring-Up. Promotion rules: INDEX.md.

The Linux counterpart is Linux Reference.


Disk and files#

Largest files under a directory:

Get-ChildItem 'C:\path\to\folder' -Recurse -ErrorAction SilentlyContinue |
  Sort-Object Length -Descending |
  Select-Object FullName, @{Name='SizeMB'; Expression={ [math]::Round($_.Length / 1MB, 2) }} -First 10 |
  Format-Table -AutoSize

Folder sizes, recursively:

Get-ChildItem -Path $root -Directory -Recurse |
  ForEach-Object {
    $size = (Get-ChildItem -Path $_.FullName -Recurse -File -ErrorAction SilentlyContinue |
             Measure-Object -Property Length -Sum).Sum
    [PSCustomObject]@{ Folder = $_.FullName; SizeMB = [math]::Round($size / 1MB, 2) }
  } | Sort-Object SizeMB -Descending

Free space per volume:

Get-CimInstance Win32_LogicalDisk |
  Select-Object DeviceID,
    @{Name='FreeGB'; Expression={ [math]::Round($_.FreeSpace / 1GB, 2) }},
    @{Name='SizeGB'; Expression={ [math]::Round($_.Size / 1GB, 2) }}

Reclaiming space on a build host goes through windows\scripts\host\Clear-DiskSpace.ps1, which works from an allowlist and is report-only by default. Prefer it over ad-hoc recursive deletes.

Long paths are a build-host concern. Fresh Windows Host Bring-Up sets git’s core.longpaths and recommends the host switch as well. The switch, from an elevated shell (the image sets it the same way, in windows/scripts/build/Complete-Container.ps1):

Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -Value 1 -Type DWord

A tree that has already grown too deep to handle normally can still be moved with robocopy <source> <destination> /E /MOVE.

Running things and reading the result#

Scope an execution-policy bypass to the session, not the machine:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

Capture output to the console and a file, then check the real exit status — the first thing to do when an executable “just doesn’t start”:

.\yourapp.exe 2>&1 | Tee-Object -FilePath .\run_output.txt
Write-Output "exit code: $LASTEXITCODE"

$LASTEXITCODE is the native process’s code; $? is PowerShell’s own view and will not tell you what a crashing exe returned.

List a directory compactly:

Get-ChildItem -Path .\logs\ | Format-Table Name, Length

Count lines of code, skipping the usual noise:

Get-ChildItem -Recurse -File -ErrorAction SilentlyContinue |
  Where-Object { $_.FullName -notmatch '(\.git|node_modules|venv|build|dist|archive|ExternalLib|third_party)' } |
  Where-Object { $_.Extension -match '^\.(c|cpp|h|hpp|py|rs|java|js|ts|go|dart|sh|ps1)$' } |
  ForEach-Object { ([System.IO.File]::ReadLines($_.FullName) | Measure-Object -Line).Lines } |
  Measure-Object -Sum | Select-Object -ExpandProperty Sum

Swap a CSV delimiter:

(Get-Content input.csv) -replace ',', ';' | Set-Content output.csv -Encoding UTF8

Services and updates#

Get-Service | Where-Object Status -eq 'Running'
Restart-Service -Name <name>

Windows Update from a shell (needs the PSWindowsUpdate module):

Import-Module PSWindowsUpdate
Install-WindowsUpdate -AcceptAll -AutoReboot

Package management, Visual Studio updates and pinning an exact SDK version are in Fresh Windows Host Bring-Up § Appendix.

Restart, shutdown, recovery#

shutdown /r /t 0
shutdown /s /t 0
Restart-Computer -Force

To reach the recovery environment when the OS will not boot normally: start Windows and interrupt it during the load phase three times in a row. It then offers recovery options on the next boot.

PATH#

Temporarily, in a cmd session:

set PATH=C:\tools\bin;%PATH%

Picking up a machine-level PATH change in an already-open PowerShell session, without logging out, is in Fresh Windows Host Bring-Up § Appendix.

SSH into a Windows host#

Enable OpenSSH Server in Optional Features, then:

  • system-wide config: %ProgramData%\ssh\sshd_config

  • per-user config: %UserProfile%\.ssh\config

  • authorized keys: C:\Users\<user>\.ssh\authorized_keys

In sshd_config, uncomment what you actually want:

PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
Restart-Service sshd
Set-Service -Name sshd -StartupType Automatic

Turn PasswordAuthentication off once keys work. On a machine reachable from anything wider than your own LAN, password auth is the exposure, not the convenience.

Client-side key handling — ssh-keygen, ssh-copy-id, the agent, clearing a stale host key after a reflash — is in Linux Reference § SSH and applies unchanged from a Windows client.

Wake-on-LAN#

Three layers all have to agree, which is why this fails silently so often.

1. Adapter — Device Manager → the NIC → Advanced:

Property

Value

Enable PME

Enabled

Energy Efficient Ethernet

Off

Wait for Link

On

Wake on Link Settings

Forced

Wake on Magic Packet

Enabled

Wake on Pattern Match

Enabled

2. Power options — disable Fast Startup, and disable sleep/hibernate if the machine must stay reachable.

3. Firmware — disable Fast Boot, enable UEFI, and enable whatever the board calls wake-from-PCIe. Observed here: WoL stopped working after a CPU swap, because the CMOS reset took “Power On by PCI-E” with it. If WoL worked and then stopped after any hardware change, check firmware before anything else.

Certificates and MSIX#

Generating and importing an MSIX signing certificate is owned by windows/scripts/certificates/ — GenerateCertificateMSIX.ps1 makes the certificate, and its README.md covers signing with it and importing it — and the WindowsMsix.* modules. One consumer-side step that is easy to miss: Developer Mode must be enabled (Settings → System → For developers) before Windows will install a self-signed .msix, even once the certificate is trusted.

Toolchain odds and ends#

Check which ABI a clang build targets — the clang-cl lane is MSVC-ABI, and a mingw-flavoured clang is not interchangeable with it:

#include <iostream>
int main() {
#ifdef _MSC_VER
    std::cout << "MSVC ABI\n";
#elif defined(__GNUC__)
    std::cout << "GNU ABI\n";
#endif
}
& "C:\Program Files\LLVM\bin\clang++.exe" -v test.cpp -o test.exe

Format Dart sources to the project’s line length, naming the source directories:

dart format --line-length 80 lib test

Never . on Windows: the walk enters .git/modules, a deep vendored submodule gitdir overruns MAX_PATH, and the listing throws before anything is formatted. The hub’s gates format tracked files only (Get-ProjectDartFiles in WindowsFormatting.Common.psm1; the Linux side is Code Quality Tooling § Dart file enumeration).

If dart format produces errors that make no sense, reinstall the SDK — a partially-extracted SDK fails here rather than at install time. The ARM variant of the same trap (a stale cache directory) is in Linux Host Setup § D2.

Phantom programs and drivers#

Removing a driver that will not uninstall (pnputil) is in Fresh Windows Host Bring-Up § Appendix.

A program that shows in the installed list but cannot be uninstalled has left an orphaned registry entry. Open regedit as admin and clear its key from whichever of these holds it:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

Removable media#

An SD card or USB stick reporting the wrong capacity usually has a leftover partition table from a flashed image. Rufus handles this with less risk of picking the wrong device; diskpart is the manual route:

diskpart
  list disk
  select disk X          ← identify by SIZE, and check twice
  clean
  create partition primary
  format fs=exfat quick
  exit

select followed by clean acts on whatever disk number you gave it, with no confirmation. Getting the number wrong destroys the wrong volume.

Media capture#

Enumerate DirectShow devices and what they support:

ffmpeg -list_devices true -f dshow -i dummy
ffmpeg -f dshow -list_options true -i video="<device name>"

Record from a device, and capture the screen:

ffmpeg -f dshow -video_size 1920x1080 -framerate 30 -pixel_format yuyv422 `
  -i video="<device name>" -c:v libx264 -preset veryfast -crf 23 out.mp4

ffmpeg -video_size 1920x1080 -framerate 30 -f gdigrab -rtbufsize 100M `
  -i desktop -c:v libx264 -preset ultrafast -crf 23 screen.mp4

Trim both ends without working out the duration by hand:

$duration = [double](ffprobe -v error -show_entries format=duration -of csv=p=0 "input.mp4")
$skip = 20
$tail = 7
$keep = [math]::Round($duration - ($skip + $tail), 3)
ffmpeg -ss $skip -i "input.mp4" -t $keep -c:v libx264 -c:a aac "output.mp4"

Resize an image, keeping aspect ratio:

ffmpeg -i "input.png" -vf "scale=800:-1" -y "output.png"

A quick local preview straight from a capture device, useful for confirming a camera works before wiring it into a pipeline:

gst-launch-1.0 mfvideosrc device-index=0 ! video/x-raw,width=1280,height=720,framerate=60/1 `
  ! videoconvert ! autovideosink sync=false

The full WebRTC and v4l2 pipelines are in Runtime Services.

Format conversion, trimming, frame extraction and OCR pre-processing are OS-agnostic and live in Linux Reference § Media and document conversion.