John Dalesandro

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. You might wonder why a script is necessary when you can use the dir /s /b command from the command line. While the output is similar, the script more reliably handles long paths and filenames, even if 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 aren’t generally recommended, 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.

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

Option 1: Batch File and PowerShell Script Combination

This method uses a batch file (list.cmd) to run a PowerShell script (list.ps1), which is required because Windows blocks direct execution of PowerShell scripts by default.

  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 from which you want to generate a 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
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 from which you want to generate a file listing.
  2. The script will generate a .csv file with the list of files from the folder and its subfolders.

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.