PowerShell and Batch Scripts to List Files in Folder and Subfolders, Handle Long Paths and Complex Filenames in Windows

These Windows batch and PowerShell scripts generate a list of all files in a specified folder and its subfolders. A script is preferable to the dir /s /b command from the command line because it more reliably handles long paths and filenames, even when the LongPathsEnabled registry value is not enabled.

In Windows, paths longer than about 260 characters can cause issues. The Windows API limits path length to 260 characters (MAX_PATH) though there are some exceptions. Although long paths and filenames are generally discouraged, they may appear in archive files or repositories created on other operating systems. The dir command and File Explorer may not list all files if there are long paths in the folder structure, which is why a PowerShell script is more reliable in these cases.

Includes support for Unicode characters in the generated .csv output file. Using Unicode encoding ensures filenames containing non-ASCII characters are preserved correctly in the CSV output.

NOTE: This example uses PowerShell version 7.x, which includes the pwsh executable. PowerShell versions 6 and later have built-in support for long paths by default.

For readers who want native long path support at the operating system level rather than relying on this script, the LongPathsEnabled registry value can be enabled at HKLM\SYSTEM\CurrentControlSet\Control\FileSystem, setting the LongPathsEnabled DWORD value to 1 and restarting the system. This affects native Windows API calls and File Explorer. It does not affect PowerShell 6 and later, which handle long paths independently of this setting.

Option 1: Batch File and PowerShell Script Combination

This method uses a batch file (list.cmd) to launch a PowerShell script (list.ps1). Windows blocks direct execution of PowerShell scripts by default, so the batch file provides a convenient command-line entry point that avoids requiring a change to the system execution policy.

  1. Create a file named list.cmd with the following batch script.
@echo off

pwsh -NoProfile -ExecutionPolicy Bypass -Command "& '.\list.ps1' '%~f1'"

exit /b 0
  1. Create a file named list.ps1 with the following PowerShell script.
param(
    [string]$folderPath
)

# Check if the folder path is provided
if (-not $folderPath) {
    Write-Host "ERROR: Please provide a folder path as an argument."
    exit 1
}

# Check if the provided folder path exists
if (-not (Test-Path -Path $folderPath -PathType Container)) {
    Write-Host "ERROR: The specified folder does not exist: $folderPath"
    exit 1
}

# Check if the path ends with a trailing backslash or forward slash
if ($folderPath.EndsWith('\') -or $folderPath.EndsWith('/')) {
    # Remove the trailing slash
    $folderPath = $folderPath.Substring(0, $folderPath.Length - 1)
}

# Generate timestamp with milliseconds
$timestamp = Get-Date -Format "yyyy_MM_dd_HH_mm_ss_fff"

# Create output list filename
$csvFileName = ".\index_$timestamp.csv"

# Get a recursive listing of all files in the folder and its subfolders
$files = Get-ChildItem -Path $folderPath -Recurse -File | Select-Object FullName

# Output the listing to the CSV file
$files | Export-Csv -Path $csvFileName -Encoding Unicode -NoTypeInformation

Write-Host "Directory listing saved to: $csvFileName"

exit 0
  1. From the command line, run list.cmd <path>, where <path> is the top-level folder targeted for the file listing.
  2. The script will generate a .csv file with the list of files from the folder and its subfolders.

Option 2: Batch File Only

This option uses a single batch file that directly calls the PowerShell command, eliminating the need for a separate PowerShell script. All argument validation is handled within the batch file.

  1. Create a file named list.cmd with the following batch script.
@echo off
setlocal enabledelayedexpansion

set folderPath=%~f1

REM Check if the folder path is provided
if "%folderPath%"=="" (
  echo ERROR: Please provide a folder path as an argument.
  exit /b 1
)

REM Check if the provided folder path exists
if not exist "%folderPath%" (
  echo ERROR: The specified folder does not exist: %folderPath%
  exit /b 1
)

REM Check if the path ends with a trailing backslash or forward slash
if "%folderPath:~-1%"=="\" (
  REM Remove the trailing backslash
  set folderPath=%folderPath:~0,-1%
)

if "%folderPath:~-1%"=="/" (
  REM Remove the trailing forward slash
  set folderPath=%folderPath:~0,-1%
)

REM Generate timestamp with milliseconds
for /f "tokens=2-4 delims=/ " %%a in ('date /t') do (
  set timestampDate=%%c_%%b_%%a
)

for /f "tokens=1-4 delims=:." %%a in ('echo %TIME%') do (
  if %%a LSS 10 (
    set timestampTime=0%%a_%%b_%%c_%%d
  ) else (
    set timestampTime=%%a_%%b_%%c_%%d
  )
)

set timestamp=%timestampDate%_%timestampTime%

REM Create output list filename
set csvFileName=.\index_%timestamp%.csv

REM Get a recursive listing of all files in the folder and its subfolders
REM Output the listing to the CSV file
pwsh -Command "& {Get-ChildItem -Path '%folderPath%' -Recurse -File | Select-Object FullName | Export-Csv -Path '%csvFileName%' -Encoding Unicode -NoTypeInformation}"

echo Directory listing saved to: %csvFileName%

exit /b 0
  1. From the command line, run list.cmd <path>, where <path> is the top-level folder targeted for the file listing.
  2. The script will generate a .csv file with the list of files from the folder and its subfolders.

NOTE: This script has two limitations to be aware of. The timestamp logic parses output from date /t and %TIME%, which is locale- and regional-format dependent. On systems configured with a non-US date or time format, the parsing may produce unexpected results. Additionally, because %folderPath% and %csvFileName% are interpolated directly into a single-quoted PowerShell command string, a folder path containing a single quote character will break the command. Option 1 avoids this second issue, since the path is passed as a script parameter rather than interpolated into a string.

Summary

Both options for Windows batch and PowerShell scripts provide a reliable way to generate a file list from a folder and its subfolders, even handling long paths and filenames that the dir command may exclude. The scripts also support Unicode and output the file list in a .csv format, ensuring compatibility with longer paths and complex filenames.