How can I query a temporary PS-Drive while returning files with a name relative to the drive?

后端 未结 2 1320
旧时难觅i
旧时难觅i 2020-12-20 12:41

I am trying to create a script where I will be searching the file servers for non inherited permissions. I have run into the 260 character limit for file names as a result.

相关标签:
2条回答
  • 2020-12-20 13:30

    haven't tested, but if you're not opposed to using 'subst' something like this might work for you

    function Get-FreeDriveLetter {
        $drives = [io.driveinfo]::getdrives() | % {$_.name[0]}
        $alpha = 65..90 | % { [char]$_ }
        $avail = diff $drives $alpha | select -ExpandProperty inputobject
        $drive = $avail[0] + ':'
        $drive
    }
    
    $file = gi 'C:\temp\file.txt'
    $fullname = $file.FullName
    
    if ($fullname.length -gt 240) {
        $drive = Get-FreeDriveLetter
        $path = Split-Path $fullname
        subst $drive $path
        $subst = $true
        rv path
        $fullname = Join-Path $drive $(Split-Path $fullname -Leaf)
    }
    
    $fullname
    
    0 讨论(0)
  • 2020-12-20 13:33

    Looks like you are mixing up two different things: PowerShell path and Provider path. PowerShell paths are not visible outside of PowerShell.

    New-PSDrive X FileSystem C:\Windows
    (Get-Item X:\System32\notepad.exe).get_Length() #OK
    ([IO.FileInfo]'X:\System32\notepad.exe').get_Length() #Error
    

    But Get-Item X:\System32\notepad.exe managed to create a FileInfo object, which represents some file. So, what file is represented by the resulting FileInfo object?

    (Get-Item X:\System32\notepad.exe).FullName
    # C:\Windows\System32\notepad.exe
    

    Since the FileInfo object knows nothing about PowerShell drive X:, it has to store a path, which internally uses the file system API which it can understand. You can use Convert-Path cmdlet to convert PowerShell path to Provider path:

    Convert-Path X:\System32\notepad.exe
    # C:\Windows\System32\notepad.exe
    

    Same happens when you create the PowerShell drive, which point to some network path:

    New-PSDrive Y FileSystem \\Computer\Share
    Get-ChildItem Y:\
    

    Returned FileInfo and DirectoryInfo objects know nothing about Y:, so they can not have paths relative to that PowerShell drive. Internally used file system API will not understand them.

    Things changes when you use the -Persist option. In that case real mapped drives will be created, which can be understood by file system API outside of PowerShell.

    New-PSDrive Z FileSystem \\Computer\Share -Persist|Format-Table *Root
    # Root        : Z:\
    # DisplayRoot : \\Computer\Share
    

    As you can see, the Root will be not \\Computer\Share as you ask in New-PSDrive cmdlet, but Z:\. Since Z: is a real drive in this case, FileInfo and DirectoryInfo objects returned by Get-Item or Get-ChildItem cmdlet can have paths relative to it.

    0 讨论(0)
提交回复
热议问题