12

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. A suggestion I saw, that I thought would help, a couple of times was to create some non persistent PS Drives a couple of levels deep and query those.

Problem is when I use Get-ChildItem against the new PS Drives it is returning object with the full network path and not using the name I assigned it.

# Cycle the folders
Get-ChildItem $rootPath -Directory | select -first 1 | ForEach-Object{
    $target = $_

    # Create a PS Drive for each sub directory and get all the folders
    [void](New-PSDrive -Name $target.Name -PSProvider FileSystem $target.FullName)

    # Get the file objects. 
    Get-ChildItem "$($target.Name):\" -Recurse
}

I am sure that if I created some proper persistent network drives with a drive letter I would not have this issue.

Hopefully I just didn't miss it but Technet for New-PSDrive was not 100% clear about this scenario.

I am looking for a way to make ps-drive and reference there folders while returning paths relative to the new drive name. Consider the output from a psdrive I made (G:) then one of my mapped network drives (M:).

PS M:\> Get-ChildItem G:\

    Directory: \\server01\COMMON\Folder

Mode                LastWriteTime     Length Name                                                                                                            
----                -------------     ------ ----                                                                                                            
d----         6/18/2011   8:14 AM            Folder 1                                                                                                          
d----         6/18/2011   8:14 AM            Folder 2 

PS M:\> Get-ChildItem M:\

    Directory: M:\

Mode                LastWriteTime     Length Name                                                                                                            
----                -------------     ------ ----                                                                                                            
d----          5/8/2015  11:00 AM            Backup                                                                                                          
d----          5/8/2015  11:00 AM            covers                                                                                                          
d----          5/8/2015  11:00 AM            drop                                                                                                            
d----          5/8/2015  11:00 AM            Expense         

I am aware that multiple workarounds exists for my exact situation but I would like to understand the behavior that I am showing with New-PSDrive.

Matt
  • 45,022
  • 8
  • 78
  • 119
  • I feel silly for the bounty now but the issue is persistent drives. If i make a persistent one then I get the relative paths. I still need to find documentation to back that up.... If someone finds something concrete feel free to make that an answer. – Matt Jan 26 '16 at 18:48
  • This might not be what you are asking for, but what if the limit was not 260 characters, and it was 32,000? https://github.com/alphaleonis/AlphaFS – Micky Balladelli Jan 27 '16 at 20:59
  • @MickyBalladelli Yeah I ran into that as a recommendation several times. I wanted to remove the reliance on external libraries as I will be sharing this with people not as savvy. Thanks for the tip regardless. It might help someone else. This issue is just bugging so I am trying to figure out the reason behind it. – Matt Jan 28 '16 at 04:23

3 Answers3

7

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.

Matt
  • 45,022
  • 8
  • 78
  • 119
user4003407
  • 21,204
  • 4
  • 50
  • 60
  • Thanks PetSerAl. I had hoped you would see this. I new this was the problem but I _understand_ why that is the case now. – Matt Jan 31 '16 at 01:50
  • Using "-Persist" I get the following error: "New-PSDrive : The network resource type is not correct" – Segolas Feb 29 '16 at 08:17
  • @Segolas Network drive can refer to share: `\\Computer\Share` — but not to some folder `\\Computer\Share\Folder`. – user4003407 Feb 29 '16 at 08:44
1

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
Anthony Stringer
  • 1,981
  • 1
  • 10
  • 15
  • I'm still holding out to see why it does not work the way I expect but this is curious to know nonetheless. – Matt Jan 15 '16 at 15:21
-1

PS C:\Users\kamlesh> $cred = Get-Credential New-PSDrive -name "L" -PSProvider FileSystem -Root "\192.105.11.58\d$" -Credential $cred -Persist

  • This doesn't answer the question, which is already making use of `New-PSDrive` and has nothing to do with using alternate credentials. – Lance U. Matthews Dec 30 '21 at 22:43
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 31 '21 at 00:16