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

3

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.

Chiton answered 15/1, 2016 at 13:38 Comment(3)
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.Chiton
This might not be what you are asking for, but what if the limit was not 260 characters, and it was 32,000? github.com/alphaleonis/AlphaFSAssyriology
@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.Chiton
S
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.

Solnit answered 31/1, 2016 at 0:38 Comment(3)
Thanks PetSerAl. I had hoped you would see this. I new this was the problem but I understand why that is the case now.Chiton
Using "-Persist" I get the following error: "New-PSDrive : The network resource type is not correct"Ponderous
@Ponderous Network drive can refer to share: \\Computer\Share — but not to some folder \\Computer\Share\Folder.Solnit
C
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
Compress answered 15/1, 2016 at 14:47 Comment(1)
I'm still holding out to see why it does not work the way I expect but this is curious to know nonetheless.Chiton
D
-1

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

Denticulation answered 30/12, 2021 at 22:19 Comment(2)
This doesn't answer the question, which is already making use of New-PSDrive and has nothing to do with using alternate credentials.Rightful
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.Felton

© 2022 - 2024 — McMap. All rights reserved.