1

Trying to maintain a routine that uses Powershell Get-ChildItem to scan Windows directories, and lists the contents.

Since Powershell represents the next generation console accompanying Windows, you'd think file system traversal would be ironclad (the most fundamental computer function), but there have been several complications.

Symbolic links looping itemization was one issue (resolved by excluding -Attribute !ReparsePoints)

Another pesky issue has been very long file paths. For whatever reason, some Powershell configurations cannot list files when the path exceeds a certain character length.

Workarounds explored:

  • Using -LiteralPath instead of -Path, and placing \\?\ or \\?\UNC\ prefixes in the path Handling Path Too Long Exception with New-PSDrive

  • Mapping a portion of the longer path to a lettered PS-Drive to get in under the character limit (the lettered drive "workaround" allowed get-childItem commands to execute, but produced the same "path too long" error.

  • Installing Powershell 6 (CORE) in hopes that it somehow cured Powershell 5.1

To my surprise, I tested the routine on my desktop and it has no problem with the long paths, no special handlings was necessary at all. (longest path was 300 characters)

However, when I run the same on a Windows Server 2012 (virtual machine), it is still balking on the long paths.

Both machines are now running Powershell 5.1, here are the $PSVersionTable

DESKTOP Win7 INSTANCE (works without issue)

Name                           Value
----                           ----
PSVersion                      5.1.14409.1018
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0,4.0...}
BuildVersion                   10.0.14409.1018
CLRVersion                     4.0.30319.42000

SERVER 2012 INSTANCE (cannot handle long paths)

Name                           Value
----                           -----
PSVersion                      5.1.14409.1005
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.14409.1005
CLRVersion                     4.0.30319.36460

Any ideas how I can get the SERVER 2012 INSTANCE functional? I see that the build numbers for Powershell 5.1 are different, not sure how to align the builds identically, and do you think that is the root cause?

One other strange thing the 2012 Server is doing, is Powershell by default is not picking up mapped network drives from windows explorer. So if I map drive 'X:' to some other network location, the 2012 Server cannot by default see it in Powershell, and needs to have a PS-Drive mounted manually before it can "replicate" the mapped drive already in use by Windows Explorer.

Appreciate your help on this, just trying to keep track of some files! :D

mklement0
  • 382,024
  • 64
  • 607
  • 775
Khompewtur
  • 11
  • 1
  • @khompehur Are you running Powershell as administrator on the Windows server 2012 box ? If yes, I have a theory.... Try runnin powershell without Administrative priviledges and / or mapping the X drive for the system user too. I saw that happens to me at some point and it was because while the drive was mapped for me, when attempting anything, I was going through the "System" account (as administrator) and the drive was not mapped for the "System" user. – Sage Pourpre Jan 10 '19 at 01:11

2 Answers2

0

Windows 10 might or might not be working depending on a local group policy you can enable which is called Enable Win32 long paths

In order to set this policy, you will need to have installed beforehand:

  • Windows Management Framework 5.1 (which you'll have if Powershell 5.1 is installed)
  • .net Framework 4.6.2 or more recent.
  • At least windows server 2016 (1607) / Windows 10

The policy can be Enabled through:

#GPEdit location:  Configuration>Administrative Templates>System>FileSystem 
Set-ItemProperty 'HKLM:\System\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -value 1

To query it

$LongPathEnabled = (Get-ItemPropertyValue 'HKLM:\System\CurrentControlSet\Control\FileSystem\' -Name 'LongPathsEnabled') -eq 1
Write-host "LongPath policy configuration state: $LongPathEnabled"

If you enable it, you will be able to use long paths without specifying the Literal path notation described by that very intelligent answer from the first link you referenced.

However, according to the documentation I found, this policy won't be available on Windows Server 2012. I believe to support this "legacy" infrastructure, you would need to use the LiteralPath and specify the Unicode notation ( \?\UNC\ and '\?\c:\ )

Good to note

Even if you target RTM 1607 and more rececnt system, there is no guarantee that the policy will be enabled. If you are working on system where you cannot update the local policy as you see fit, the use of the LiteralPath and unicode notation will then again be your best bet. The Enable long path policy was only very recently introduced as part of the anniversary update.

References

Long Path Support In Powershell

Microsoft - Download Group Policy Settings Reference for Windows and Windows Server

Myself

Sage Pourpre
  • 9,932
  • 3
  • 27
  • 39
0

Your guidance is very appreciated, I would definitely want to further explore 'Enable Win32 long paths' performed via local group policy.

However, it looks like I was able to get it working on the Windows Server 2012 via a .NET update.

In an earlier thread researched, one responder mentioned .NET CLR versions: PathTooLong error with Get-ChildItem in PowerShell v3, but not v2

"One important difference between v2 and v3 of Powershell is the version of the .NET CLR it runs on top of. Powershell v2 ran using the .NET 2.0 CLR (not to be confused with .NET Framework v2.0) whereas Powershell v3 runs using the .NET 4.0 CLR (again, not to be confused with the .NET Framework 4.0). The 4.0 CLR is a LOT less forgiving about exceptions. – Matthew Brubaker Nov 9"

$PSVersionTable returns an entry for CLRVersion, and my desktop & server were not aligned. I checked .NET Framework versions and the desktop was using .NET 4.7.1, while the server was at .NET 4.5.

I had already installed .NET 4.7.1 on the server, but it didn't seem to be healthy so it was uninstalled & reinstalled, but that didn't work. Then I went to Microsoft and got a fresh installer for .NET 4.7.2.

Once .NET 4.7.2 installed, $PSVersionTable on the server aligned identical to the working desktop, and get-childitem was then able to parse very long paths without issue.

Name Value
---- -----
PSVersion 5.1.14409.1005
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14409.1005
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1

Khompewtur
  • 11
  • 1