Windows, PowerShell, and Long Paths

Windows, PowerShell, and Long Paths

I think you, like me, have often seen paths of the form !!! Important____New____!!! Do not delete!!! Order No. 98819-649-B dated February 30, 1985 on the appointment of Ivan Aleksandrovich Kozlov as the acting head of the department for supporting corporate VIP clients and organizing business meetings on the sidelines.doc.

And often you won’t be able to open such a document in Windows right away. Someone practices workaround in the form of disk mapping, someone uses file managers that can work with long paths: Far Manager, Total Commander and the like. And many more sadly watched how the PS script they created, in which a lot of work was invested and which worked with a bang in the test environment, in the combat environment, helplessly complained about an impossible task: 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.
As it turned out, 260 characters is enough "not only for everyone." If you are interested in going beyond the boundaries of what is permitted, I ask under cat.

Here are just a few of the unfortunate consequences of limiting file path length:

Slightly deviating from the topic, I note that for DFS Replication the problem considered in the article is not terrible and files with long names successfully travel from server to server (unless, of course, otherwise you done right).

I would also like to draw attention to a very useful utility that has helped me more than once robocopy. She, too, is not afraid of long paths, and she knows a lot. Therefore, if the task comes down to copying / transferring file data, you can stop at it. If you need to mess around with file system access control lists (DACLs), look away subinacl. Despite its considerable age, it showed itself perfectly on Windows 2012 R2. Here methods of application are considered.

I was also interested in learning how to work with long PowerShell paths. With him, almost like in a bearded joke about Ivan Tsarevich and Vasilisa the Beautiful.

Quick way

Switch to Linux and don't worry about Windows 10/2016/2019 and enable the appropriate group policy setting/registry tweak. I will not dwell on this method in detail, because. there are already many articles on the net on this topic, for example, this.

Considering that in most companies there are many, to put it mildly, not fresh versions of operating systems, this method is quick only for writing on paper, unless, of course, you are one of those lucky ones who have few legacy systems and Windows 10/2016/2019 reign .

long way

Here we immediately make a reservation that the changes will not affect the behavior of Windows Explorer, but will make it possible to use long paths in PowerShell cmdlets, such as Get-Item, Get-ChildItem, Remove-Item, etc.

First, let's update PowerShell. It's done one, two, three.

  1. We update the .NET Framework to a version of at least 4.5. The operating system must be at least Windows 7 SP1/2008 R2. The current version can be downloaded hereread more information here.
  2. Download the and install Windows Management Framework 5.1
  3. We reboot the machine.

The hard-working can do the above steps manually, the lazy ones can do it with the help of SCCM, policies, scripts and other automation tools.

The current version of PowerShell can be found from the variable $PSVersionTable. After the update it should look like this:

Windows, PowerShell, and Long Paths

Now when using cmdlets Get-ChildItem and others like him instead of the usual Path we will use literalPath.

The format of the paths will be slightly different:

Get-ChildItem -LiteralPath "?C:Folder"
Get-ChildItem -LiteralPath "?UNCServerNameShare"
Get-ChildItem -LiteralPath "?UNC192.168.0.10Share"

For the convenience of converting paths from the usual format to the format literalPath you can use this function:

Function ConvertTo-LiteralPath 
Param([parameter(Mandatory=$true, Position=0)][String]$Path)
    If ($Path.Substring(0,2) -eq "") {Return ("?UNC" + $Path.Remove(0,1))}
    Else {Return "?$Path"}
}

Please note that when setting the parameter literalPath wildcards cannot be used (*, ? etc.).

In addition to the parameter literalPath, in the updated PowerShell cmdlet Get-ChildItem received parameter Depth, with which you can set the nesting depth for recursive search, I used it a couple of times and was satisfied.

Now you can not be afraid that your PS-script will go astray from a long thorny path and will not see distant files. For example, this approach helped me a lot when writing a script to reset the β€œtemporary” attribute for files in DFSR folders. But this is another story, which I will try to tell in another article. I'm waiting for interesting comments from you and I suggest taking a survey.

Useful links:
docs.microsoft.com/en-us/dotnet/api/microsoft.powershell.commands.contentcommandbase.literalpath?view=powershellsdk-1.1.0
docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-5.1
stackoverflow.com/questions/46308030/handling-path-too-long-exception-with-new-psdrive/46309524
luisabreu.wordpress.com/2013/02/15/theliteralpath-parameter

Only registered users can participate in the survey. Sign in, you are welcome.

Is the problem of long paths relevant to you?

  • Yes

  • Was relevant, but already decided

  • Interferes, but not much

  • Didn't think about it, everything seems to be working

  • No

  • Other (specify in comments)

155 users voted. 25 users abstained.

Source: habr.com

Add a comment