Work with files and folders that have paths longer than 260 characters in PowerShell using AlphaFS

tree

If you try to use one of the built-in ‘item’ cmdlets (i.e. Get-Command *item* -Module Microsoft.PowerShell.Management) on the FileSystem provider with a path that is longer than 260 characters (actually > 248 characters on a folder and > 260 on a file), you will not be able to do it. For example running the line below in order to create a folder structure on c: that is longer than 260 characters :

1..60 | foreach {$folderTree = 'c:\'} {$folderTree += "test$_\"}
$folderTree.Length
mkdir $folderTree

Will result in an error message:
screenShotFilePath
This is not only a PowerShell deficiency but stems probably from the good old Dos days and applies as well to the underlying .Net methods. You can read more about it here if you fancy. While there are ways around it (e.g. using subst or \\?\ prefix), those are not really nice solution.
This is where AlphaFS can help. According to the description on the project’s webpage

The file system support in .NET is pretty good for most uses. However there are a few shortcomings, which this library tries to alleviate. The most notable deficiency of the standard .NET System.IO is the lack of support of advanced NTFS features, most notably extended length path support (eg. file/directory paths longer than 260 characters).

it’s a perfect fit for the problem at hand. Let’s see how we can use AlphaFS through PowerShell starting off by downloading and un-compressing the release version from the project’s github repository:

cd c:\
#download and unzip
mkdir 'AlphaFS'
$destFolder = 'C:\AlphaFS'
$url = 'https://github.com/alphaleonis/AlphaFS/releases/download/v2.0.1/AlphaFS.2.0.1.zip'
Invoke-WebRequest $url -OutFile "$destFolder\AlphaFS.zip"
$shFolder = (New-Object -ComObject Shell.Application).NameSpace($destFolder)
$shZip = (New-Object -ComObject Shell.Application).NameSpace('C:\AlphaFS\AlphaFS.zip')
$shFolder.CopyHere($shZip.Items(),16)
del "$destFolder\AlphaFS.zip"

Now we can load the library, explore it and start accessing its members (we’ll use the .net v4 version):

$alphaFS = Add-Type -Path $destFolder\lib\net40\AlphaFS.dll -PassThru
$alphaFS | where IsPublic | select Name, FullName
$alphaFS | where IsPublic | select Name, FullName | where Name -like *Directory*
[Alphaleonis.Win32.Filesystem.Directory] | Get-Member -Static
[Alphaleonis.Win32.Filesystem.Directory]::CreateDirectory
#let's try it again
1..60 | foreach {$folderTree = 'c:\'} {$folderTree += "test$_\"}
[Alphaleonis.Win32.Filesystem.Directory]::CreateDirectory($folderTree)
#worked!
#delete the folder tree recursively
[Alphaleonis.Win32.Filesystem.Directory]::Delete($folderTree, $true)

The library has support for many other useful features like:

  • Creation of Hardlinks
  • Accessing hidden volumes
  • Transactional file operations (similar to the registry provider in PowerShell)
  • Copying and moving files with progress indicator
  • NTFS Alternate Data Streams
  • Accessing network resources (SMB/DFS)

The full documentation for AlphaFS can be found here.
Update: Recently I also came across the PowerShell usage wiki on the project’s GitHub page.

shareThoughts


Photo Credit: ekarbig via Compfight cc

Advertisements

I'd love to hear what you think

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s