1 minute read

A while ago I created a Path Length Checker tool in C# that has a “nice” GUI, and put it up on CodePlex. One of the users reported that he was trying to use it to scan his entire C: drive, but that it was crashing. Turns out that the System.IO.Directory.GetFileSystemEntries() call was throwing a permissions exception when trying to access the “C:\Documents and Settings” directory. Even when running the app as admin it throws this exception. In the meantime while I am working on implementing a workaround for the app, I wrote up a quick PowerShell script that the user could use to get all of the path lengths. That is what I present to you here.

# Output the length of all files and folders in the given directory path.
[CmdletBinding()]
param
(
    [Parameter(HelpMessage = 'The directory to scan path lengths in. Subdirectories will be scanned as well.')]
    [string] $DirectoryPathToScan = 'C:\Temp',

    [Parameter(HelpMessage = 'Only paths this length or longer will be included in the results. Set this to 260 to find problematic paths in Windows.')]
    [int] $MinimumPathLengthsToShow = 0,

    [Parameter(HelpMessage = 'If the results should be written to the console or not. Can be slow if there are many results.')]
    [bool] $WriteResultsToConsole = $true,

    [Parameter(HelpMessage = 'If the results should be shown in a Grid View or not once the scanning completes.')]
    [bool] $WriteResultsToGridView = $true,

    [Parameter(HelpMessage = 'If the results should be written to a file or not.')]
    [bool] $WriteResultsToFile = $false,

    [Parameter(HelpMessage = 'The file path to write the results to when $WriteResultsToFile is true.')]
    [string] $ResultsFilePath = 'C:\Temp\PathLengths.txt'
)

# Ensure output directory exists
[string] $resultsFileDirectoryPath = Split-Path $ResultsFilePath -Parent
if (!(Test-Path $resultsFileDirectoryPath)) { New-Item $resultsFileDirectoryPath -ItemType Directory }

# Open a new file stream (nice and fast) to write all the paths and their lengths to it.
if ($WriteResultsToFile) { $fileStream = New-Object System.IO.StreamWriter($ResultsFilePath, $false) }

$filePathsAndLengths = [System.Collections.ArrayList]::new()

# Get all file and directory paths and write them if applicable.
Get-ChildItem -Path $DirectoryPathToScan -Recurse -Force |
    Select-Object -Property FullName, @{Name = "FullNameLength"; Expression = { ($_.FullName.Length) } } |
    Sort-Object -Property FullNameLength -Descending |
    ForEach-Object {

    $filePath = $_.FullName
    $length = $_.FullNameLength

    # If this path is long enough, add it to the results.
    if ($length -ge $MinimumPathLengthsToShow)
    {
        [string] $lineOutput = "$length : $filePath"

        if ($WriteResultsToConsole) { Write-Output $lineOutput }

        if ($WriteResultsToFile) { $fileStream.WriteLine($lineOutput) }

        $filePathsAndLengths.Add($_) > $null
    }
}

if ($WriteResultsToFile) { $fileStream.Close() }

if ($WriteResultsToGridView) { $filePathsAndLengths | Out-GridView -Title "Paths under '$DirectoryPathToScan' longer than '$MinimumPathLengthsToShow'." }

Happy coding!

Comments

Kieran

Hi Daniel, Thanks for the script - it is exactly what I’m looking for, but I find when I run it, as soon as it comes up against the 260+ pathlenghts I get the usual error: “Get-ChildItem : The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.”

When I look at the output log it starts at 259 characters as the 260+ ones fail. I’m using PowerShell 4 on server 2012 R2.

Thanks for any help. Kieran.

deadlydog

@Kieran I tried to setup some test data to let me try and recreate this issue to find a fix for it, but I can’t get Windows to allow me to create a path longer than 260 characters, so I’m not able to test any workarounds :(

helper

http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath

there is somthing about to get over 260 characters .. hope it help

Yomodo

Hi, this WILL help you. Get AlphaFS.dll: https://alphafs.codeplex.com/SourceControl/list/changesets

PowerShell:

Import-Module [Alphaleonis.Win32.Filesystem.Directory]::Delete($path, $True)

Stefan

I updated your script to scan for paths longer than f.e. 260.

$pathToScan = “P:" # The path to scan (sub-directories will be scanned as well). $MaxLength = “260” # the maximum path length $outputFilePath = “C:\temp\PathsLongerThan260_at_P.txt” # This must be a file in a directory that exists and does not require admin rights to write to. $writeToConsoleAsWell = $false # Writing to the console will be much slower.

Open a new file stream (nice and fast) and write all the paths and their lengths to it.

$outputFileDirectory = Split-Path $outputFilePath -Parent if (!(Test-Path $outputFileDirectory)) { New-Item $outputFileDirectory -ItemType Directory } $stream = New-Object System.IO.StreamWriter($outputFilePath, $false) Get-ChildItem -Path $pathToScan -Recurse -Force | Where-Object {$.FullName.Length -gt $MaxLength} | Select-Object -Property FullName, @{Name=”FullNameLength”;Expression={($.FullName.Length)}} | Sort-Object -Property FullNameLength -Descending | ForEach-Object { $filePath = $.FullName $length = $.FullNameLength $string = “$length : $filePath”

# Write to the Console.
if ($writeToConsoleAsWell) { Write-Host $string }

#Write to the file.
$stream.WriteLine($string) } $stream.Close()

Leave a Comment

Your email address will not be published. Required fields are marked *

Loading...