Zoho Banner September 2011

Reading the post title you maybe wondering whether I’ve taken leave of my senses.  Why call Robocopy from Powershell to count files when Powershell has a perfectly good method of doing this natively? For example,

(Get-ChildItem e:\powershell -Recurse -force | ?{! $_.PSIsContainer} | Measure-Object).count

Well, the problem comes in when an individual file length exceeds 260 characters.  At this point Powershell throws an error similar to the one below.

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.

At E:\Powershell\CountFiles.ps1:243 char:32

+ $hcountpost = (Get-ChildItem e:\powershell -Recurse -force | Measure-Obj …

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+ CategoryInfo : ReadError: (\\myserver\homed… – blah blah:String) [Get-ChildItem], PathTooLongException

+ FullyQualifiedErrorId : DirIOError,Microsoft.PowerShell.Commands.GetChildItemCommand

The problem is not so much to do with Powershell as the underlying .NET APIs, as the following article succinctly explains.

http://blogs.msdn.com/b/bclteam/archive/2007/02/13/long-paths-in-net-part-1-of-3-kim-hamilton.aspx

This is where Robocopy comes in handy as it doesn’t suffer from the same limitations.  On the other hand Robocopy has its own output formatting that doesn’t play nicely with Powershell.  I came across a very handy code snippet from MVP Boe Prox that can help with this.  The only change I have made is to roll it up into a function (shown below for your pleasure).

Function Count-Files ($path) {
    $params = New-Object System.Collections.Arraylist
    $params.AddRange(@("/L","/S","/NJH","/BYTES","/FP","/NC","/NDL","/TS","/XJ","/R:0","/W:0"))
    $countPattern = "^\s{3}Files\s:\s+(?\d+).*"
    $sizePattern = "^\s{3}Bytes\s:\s+(?\d+(?:\.?\d+)).*"
    $return = robocopy $path NULL $params
    If ($return[-5] -match $countPattern) {
        $Count = $matches.Count
    } # end if
    else {
    $Count = 0
    } # end else
    Return $count
} # end Count-Files function

 

Enjoy.

 

7 Comments

  1. Yomodo says:

    Hi,

    PowerShell can easily be used with AlphaFS.dll to do actual file I/O stuff
    without the PATH TOO LONG hassle.

    For example:

    Import-Module

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

    Also, there are a couple of static methods to count folders and files.

  2. Lxlechat says:

    Hi yomodo,
    you are right, alphafs does the job.
    But you have to write a recursive function if i’m correct.
    I’ve tried both solution, and found robocpy way faster than alphaFs.

    Maybe i’m wrong…

  3. Yomodo says:

    AlphaFS has a couple of convenience methods like:
    Directory.CountDirectories() and Directory.CountFiles()

    So no need to write recursion your self, just call one of
    the overloaded methods to recurse, or not.

  4. firehaw says:

    Long Path Tool works well to copy or delete long path files, you may use it and I m sure you will love it.

  5. Iggy says:

    I got that error:
    parsing “^\s{3}Files\s:\s+(?\d+).*” – Unrecognized grouping construct.
    At line:7 char:9
    + If ($return[-5] -match $countPattern) {
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : OperationStopped: (:) [], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException

  6. Roksolana says:

    Long Path Tool help me a lot when i have an issue like file deleting or renaming the file. Also good to use if file name and file extension is too long.

  7. stepan raisa says:

    “Long Path Tool” is very helpful for this error !
    best solution for your problem.

Leave a Reply