PowerShell / PowerShell

PowerShell for every system!
https://microsoft.com/PowerShell
MIT License
44.71k stars 7.24k forks source link

Cannot use mapped network drive below drive h: #20861

Open DougChandler opened 10 months ago

DougChandler commented 10 months ago

Prerequisites

Steps to reproduce

Use subst to create a mapped network drive below drive h: (I tested from e: to g:), then attempt to set-location to the new drive. I attempted to map to my Box drive

subst e: c:\users\xxxxxx\Box\Files
e:

I have regressed to v7.3.10 as this works fine.

Expected behavior

In PowerShell v7.3.10 this works and the location is set as expected:
PS E:\>

Actual behavior

PS C:\> subst e: "C:\Users\xxxxxx\Box\Files"
PS C:\> e:
Set-Location: Cannot find drive. A drive with the name 'E' does not exist

Error details

Set-Location: Cannot find drive. A drive with the name 'E' does not exist

Environment data

PowerShell Code v7.4.0

Visuals

No response

DougChandler commented 10 months ago

With v7.4.0, using subst with a drive of h: or above also works.

mklement0 commented 9 months ago

Just a data point: I cannot repro the problem on my Windows 11 Pro 22H2 machine. Does running subst.exe without arguments list an E: drive. Does Get-PSDrive -PSProvider FileSystem reveal anything unusual?

DougChandler commented 9 months ago

Yes, subst on its own will list the e: drive. No, Get-PSDrive -PSProvider FileSystem does not list the e: drive. But [System.IO.DriveInfo]::getdrives() does list the e: drive. The other issue with PS not recognising the drive is that when you start PS, it gives an error: Attempting to perform the InitializeDefaultDrives operation on the 'FileSystem' provider failed Also important to note that the subst drive location needs to be a network location, a local location, e.g. c:\Windows works ok. For me it is the local Box drive which identifies as 'Network'.

DougChandler commented 9 months ago

So Box Drive maps to c:\Users\<username>\Box. There are two differences between:

subst e: c:\Users\<username>\Box
subst f: c:\Users\<username>

Drive f: will be accessible to PS, drive e: is not. Running [System.IO.DriveInfo]::getdrives() reveals that:

drive e: is DriveType=**Network**, DriveFormat=**FAT32**
drive f: is DriveType=**Fixed**, DriveFormat=**NTFS**

One of these two things must be causing the issue in PS 7.4.0

mklement0 commented 9 months ago

So it isn't about specific driver letters, but about the specific nature of the target directory, and it is somehow related to the target directory - though seemingly a local path - being a network path instead.

The question is what specific mechanism is used in the latter case; I do not see the problem when using subst with a network share explicitly (whether directly via a UNC path or indirectly via a regularly mapped drive).

Does Get-Item $HOME\Box | Format-List * reveal the specific NTFS reparse-point technology used (look for LinkType, LinkTarget and Attributes)?

DougChandler commented 9 months ago

This is the result of the cmdLet (on PS v7.3.10) Get-Item $HOME\Box | Format-List * (redacted):

PSPath              : Microsoft.PowerShell.Core\FileSystem::C:\Users\<username>\Box
PSParentPath        : Microsoft.PowerShell.Core\FileSystem::C:\Users\<username>
PSChildName         : Box
PSDrive             : C
PSProvider          : Microsoft.PowerShell.Core\FileSystem
PSIsContainer       : True
Mode                : l-r--
ModeWithoutHardLink : l-r--
BaseName            : Box
ResolvedTarget      : C:\Users\<username>\Box\
Target              : Volume{<guid>}\
LinkType            : Junction
Parent              : C:\Users\<username>
Root                : C:\
FullName            : C:\Users\<username>\Box
Extension           :
Name                : Box
Exists              : True
CreationTime        : 08/12/2023 13:36:11
CreationTimeUtc     : 08/12/2023 13:36:11
LastAccessTime      : 08/12/2023 13:36:12
LastAccessTimeUtc   : 08/12/2023 13:36:12
LastWriteTime       : 08/12/2023 13:36:11
LastWriteTimeUtc    : 08/12/2023 13:36:11
LinkTarget          : Volume{<guid>}\
UnixFileMode        : -1
Attributes          : ReadOnly, Directory, ReparsePoint
mklement0 commented 9 months ago

Thanks, @DougChandler.

So now we know that in your case it is an NTFS junction that points to a volume by GUID.

While I'm not sure how that is established, I have been able to reproduce one problem - which is at least part of the puzzle:

If the target of a subst.exe-established drive is removed or - presumably - unavailable, PowerShell inappropriately pretends that it doesn't even exist - irrespective of whether the target is a regular directory or an NTFS reparse point.

So, when you see the problem, is $HOME\Box actually accessible, with cmd /c dir $HOME\Box or Get-ChildItem $HOME\Box?

DougChandler commented 9 months ago

Thanks @mklement0. Yes, within PS 7.4.0, both of these commands work and list the directory contents. The subst'd drive works fine within Windows, just PS is not able to use it in this version.

DougChandler commented 8 months ago

It also works correctly as expected in PS v7.3.11, so appears it was introduced in 7.4.0.