Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I wrote a powershell script to strip R/H/S attributes off all files in a specified set of root paths. The relevant code is:

$Mask = [System.IO.FileAttributes]::ReadOnly.Value__ -bor [System.IO.FileAttributes]::Hidden.Value__ -bor [System.IO.FileAttributes]::System.Value__
Get-ChildItem -Path $Paths -Force -Recurse -ErrorAction SilentlyContinue | ForEach-Object {
    $Value = $_.Attributes.value__
    if($Value -band $Mask) {
        $Value = $Value -band -bnot $Mask
        if($PSCmdlet.ShouldProcess($_.FullName, "Set $([System.IO.FileAttributes] $Value)")) {
            $_.Attributes = $Value
        }
    }
}

This works fine, but when processing one very large folder structure, I got a few errors like this:

Exception setting "Attributes": "Could not find a part of the path 'XXXXXXXXXX'."
At YYYYYYYYYYGrant-FullAccess.ps1:77 char:17
+                 $_.Attributes = $Value
+                 ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationException
    + FullyQualifiedErrorId : ExceptionWhenSetting

I find this strange because the FileInfo object being manipulated is guaranteed to exist, since it comes from a file search.

I can't give the file names because they are confidential, but I can say:

  • they are 113-116 characters long
  • the unique set of characters involved are %()+-.0123456789ABCDEFGIKLNOPRSTUVWX, none of which are illegal in a file name
  • the % character is there due to URL-encoded spaces (%20)

Do you have any suggestions as to what may be causing this? I assume that if the full path was too long, or I didn't have write permissions to the file, then a more appropriate error would be thrown.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
939 views
Welcome To Ask or Share your Answers For Others

1 Answer

As stated in your own answer, the problem turned out to be an overly long path (longer than the legacy limit of 259 chars.)

In addition to enabling long-path support via Group Policy, you can enable it on a per-computer basis via the registry as follows, which requires running with elevation (as admin):

# NOTE: Must be run elevated (as admin).
# Change will take effect in FUTURE sessions.
Set-ItemProperty HKLM:SYSTEMCurrentControlSetControlFileSystem LongPathsEnabled 1

Pass 0 to turn support off.


However, even with long-path supported turned OFF (as is invariably the case on pre-Windows 10 versions) it is possible to handle long paths:

  • In Windows PowerShell (PowerShell up to version 5.1), you must use the long-path opt-in prefix, \?, as discussed below.

  • In PowerShell [Core] v6+, no extra work is needed, because it always supports long paths - you neither need to turn on support system-wide nor do you need the long-path prefix discussed below.

    • Caveat: While you may use \? in PowerShell [Core] as well in principle, support for it is inconsistent as of v7.0.0-rc.2; see this GitHub issue.

Important: Prefix \? only works under the following conditions:

  • The prefixed path must be a full (absolute), normalized path (must not contain . or .. components).

    • E.g., \?C:pathofoo.txt works, but \?.foo.txt does not.
    • Furthermore, if the path is a UNC path, the path requires a different form:
      • \?UNC<server><share>...;
      • E.g., \server1share2 must be represented as \?UNCserver1share2

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...