Powershell: Remove-PSDrive does not work correctly for Networked Drives created using -persist and -scope Global

Created on 20 Sep 2018  路  33Comments  路  Source: PowerShell/PowerShell

To be clear, all the above was done in PowerShell Core, however I can also reproduce this in PoSH. Almost Identical to #7193

Steps to reproduce

2 separate sessions required

Session 1

New-PSDrive -Name J -PSProvider FileSystem -Root "\\contoso.com\share" -Description Test -Scope Global -Persist

Session 2

> get-psdrive -name J

Name           Used (GB)     Free (GB) Provider      Root                                               CurrentLocation
----           ---------     --------- --------      ----                                               ---------------
J                   2.44      10237.44 FileSystem    \\contoso.com\share


> remove-psdrive -name J
> get-psdrive -name J

Name           Used (GB)     Free (GB) Provider      Root                                               CurrentLocation
----           ---------     --------- --------      ----                                               ---------------
J                   2.44      10237.44 FileSystem    \\contoso.com\share

Expected behavior

For it to actually delete J, similar to 'net use J: /delete'


Actual behavior

It does not delete J, or error. running

PS > net use J: /delete
J: was deleted successfully.

Works as expected

Environment data

> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      6.1.0
PSEdition                      Core
GitCommitId                    6.1.0
OS                             Microsoft Windows 10.0.14393
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Area-Cmdlets-Management Issue-Question

Most helpful comment

Just confirmed on 7.0.0 (OS Windows 10.0.17134)

New-PSDrive -Name J -PSProvider FileSystem -Root \\contoso.com\someshare -Scope Global -Persist

Works as intended. When you then open another powershell session, you can see it doing

Get-PSDrive -Name J

However, the following have no affect, the drive remains:

Get-PSDrive -Name J | Remove-PSDrive
Get-PSDrive -Name J | Remove-PSDrive -Force

Going back to the original session and running the above will work.

All 33 comments

Does it work using Remove-PSDrive -Scope Global?

@VortexUK,

Greatly Appreciate submitting this issue.
:)

To be clear *-PSDrive cmdlets are not using the same API as net use. You can't cross that boundary are far as I'm aware.

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/new-psdrive?view=powershell-6

I wasn't suggesting they are the same @thezim , it was more showing that it was possible to delete the drive using other tools.

@vexx32 - same issue:

> get-psdrive -name J

Name           Used (GB)     Free (GB) Provider      Root                                               CurrentLocation
----           ---------     --------- --------      ----                                               ---------------
J                   2.44      10237.44 FileSystem    \\contoso.com\share


>  remove-psdrive -name J -Scope Global
> get-psdrive -name J

Name           Used (GB)     Free (GB) Provider      Root                                               CurrentLocation
----           ---------     --------- --------      ----                                               ---------------
J                   2.44      10237.44 FileSystem    \\contoso.com\share

For those finding this. I went looking and found someone much smarter than I who knows how to do this properly. There are several ways to create network drives and Remove-PSDrive is not a catch all to remove them.

Source
https://blogs.msmvps.com/russel/tag/remove-psdrive/

Here is the code in case the link ever breaks

<#
.SYNOPSIS
Unmaps network drives
.DESCRIPTION
Unmapdrives removes all currently mapped network drives. It's smart enough to 
remove drives mapped with "net use", "New-SmbMapping" and "New-PSDrive". This 
cmdlet accepts no parameters and assumes -Force for all unmappings. 

.EXAMPLE
UnMapDrives 
Unmaps all currently mapped network drives 

.NOTES
    Author: Charlie Russel
 Copyright: 2015 by Charlie Russel
          : Permission to use is granted but attribution is appreciated
   Initial: 06/27/2015 (cpr)
   ModHist:
 :
#>
[CmdletBinding()]

# Build a dynamic list of currently mapped drives
$DriveList = Get-WMIObject Win32_LogicalDisk `
     | Where-Object { $_.DriveType -eq 4 }

# Don't bother running this if we don't have any mapped drives
 if ($DriveList) { 
    $SmbDriveList = $DriveList.DeviceID
 } else {
    Write-Host "No mapped drives found"
    Return
}

Write-host "Unmapping drive: " -NoNewLine
Write-Host $SmbDriveList
Write-Host " "

Foreach ($drive in $SmbDriveList) {
    $psDrive = $drive -replace ":" #remove unwanted colon from PSDrive name
    Remove-SmbMapping -LocalPath $Drive -Force -UpdateProfile
    If ( (Get-PSDrive -Name $psDrive) 2>$Null ) {
       Remove-PSDrive -Name $psDrive -Force
    }
}
Write-Host " "

# Report back all FileSystem drives to confirm that only local drives are present. 
Get-PSDrive -PSProvider FileSystem`

Any updates on this issue? It's affecting my build pipelines. I have to use a New-PSDrive to add and net use to remove Network Drives. This inconsistency in my pipeline doesn't look great.

@agoldenlife Thanks for the script. But geez. I think it's a lot less hassle to just add the extra line below in (addition to Remove-PSDrive. if necessary) to accomplish removing the drive completely. Pretty lame that they're interfering with one another.

NET USE /del \$Device 2>null

@mkanet I think you miss the point.

In the code above you simply type "unMapDrives" and all of them are now removed. I don't see how typing two commands (i.e. Remove-PSDrive and then net use /del $Device 2>null) is any easier.

The above code is written you so can load it into your powershell profile. Once that is set you can use it as much as you want. From then on out you just type the one command. It is also nice because it gives you feedback and makes checks to ensure it all worked properly. Your script outputs any errors to null so you have to check manually if it was successful or not. Of course that may be what you want so... ymmv.

The nice thing about scripting is there are many ways to accomplish the same thing! Thanks for commenting and showing what works for you.

@agoldenlife, I wasn't referring to the script you posted. I meant using native PowerShell and ad-hoc cases; referring to to the OP of this thread. Creating an UnMapDrives script, loading it, then execute the command would take significantly longer than just typing a couple of commands. But yeah, if unMapDrives is already loaded in memory, it would be even quicker.

Still broken on Windows 10 Enterprise 1809 build 17763.615

Hum! Although, it's broken in Windows PowerShell (no more changes here), and it hasn't been fix in PowerShell 7 (Core), there's a workaround.

Either install the SMB components in the client machine, which seems to work flawlessly when using the New/Remove-SMBMapping cmdlets, or use the following command line:

Get-PSdrive -Name t | Remove-PSDrive

Now, this one-liner will give an error:

ps> Get-PSdrive -Name t | Remove-PSDrive
Remove-PSDrive : Cannot find drive. A drive with the name 't' does not exist.
At line:1 char:23
+ Get-PSDrive -Name t | Remove-PSDrive
+                       ~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (t:String) [Remove-PSDrive], DriveNotFoundException
    + FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.RemovePSDriveCommand

Remove-PSDrive : Cannot find drive. A drive with the name 't' does not exist.
At line:1 char:23
+ Get-PSdrive -Name t | Remove-PSDrive
+                       ~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (t:String) [Remove-PSDrive], DriveNotFoundException
    + FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.RemovePSDriveCommand

GetPSDrive_01_2019-08-15_18-42-53

But, even with the error message, the drive is removed.

So, manually handle the error by including both the ErrorAction and ErrorVariable parameter to prevent the error to be displayed.

Get-PSdrive -Name t | Remove-PSDrive -ErrorAction SilentlyContinue -ErrorVariable rmDrive

GetPSDrive_02_2019-08-15_18-42-53

I know is just a workaround, and it does work in both versions of PowerShell (Windows and Core).

We'll have to wait for what the PowerShell Team decide to do about this one with PowerShell 7.

:)

Have you tried using the force? I had the same issue and found the answer in agoldenlife's script:
Remove-PSDrive -Name <drive_name> -Force

Just an FYI.

This works in PowerShell 7 Preview RC2, even without using the -Force parameter.

PS7_removeDrive_2020-02-19_11-52-18

And, it also works in PowerShell 6.2.4:
PS624_removeDrive_2020-02-19_11-52-18

None of this working in PowerShell 5.1
image

@ScriptingPro

Keep in mind! Windows PowerShell 5.1 is complete. So, any fixes are done against PowerShell 7 (or Greater).

No fixes will be done to Windows PowerShell 5.1. Only security updates.
:)

Aye. If it's already fixed in PS 7, we can close this one. 馃檪

I don't think this is actually fixed. Like @MaximoTrinidad I am able to remove the drive if I had created it _within the same session_. However, like OP, If I create the persisted drive in one session then try to remove it in _another_ session, it does not work.

Am I missing something?

> PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.0.0
PSEdition                      Core
GitCommitId                    7.0.0
OS                             Microsoft Windows 10.0.19041
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

@justinsantoro

I think it make sense that if the drive was created, and persisted, in session 1, that session 2 won't be able to remove it as it is still in use by session 1.

:)

If the first session is closed by the time session 2 tries to remove it, it should still be removable I would think. Is that the case @justinsantoro?

What a nightmare! (as Windows networking always seems to be)

You can also just right click on the drive in Explorer and click Disconnect :-)
You may need to reopen explorer.

I have just reproduced this issue with PowerShell 7.0.0.

@justinsantoro

I think it make sense that if the drive was created, and persisted, in session 1, that session 2 won't be able to remove it as it is still in use by session 1.

:)

That doesn't make sense at all. The drive is a _persistent_ mapped drive, meaning it will continue well after a session has gone, through log outs and reboots. Conversely a session is exactly that - something temporary. The drive should be un-mappable from any session you chose with the right command, but, as shown in the original post, it is not. Also I should have mentioned in the original post, but -force, -scope etc have no affect on this bug. It... persists.

I have just reproduced this issue with PowerShell 7.0.0.

This is really disappointing!

@vexx32 , can you please reopen this issue?
This is not fixed in 7.0.0

The issue still persists in pws 7.0.1.

@TheBlaide

Hum! It works for me! No issues at all.

PSDriveWorks_01_2020-06-05_10-28-14

PSDriveWorks_02_2020-06-05_10-28-14

PS C:\Users\max_t> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.0.1
PSEdition                      Core
GitCommitId                    7.0.1
OS                             Microsoft Windows 10.0.19041
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

PS C:\Users\max_t>

Windows 10 Pro Version 2004

Microsoft Windows [Version 10.0.19041.264]

:)

Reopening as some folks are still seeing this issue. Can we get environment data and exactly what code y'all are running to get the errors you're seeing as well, please? 馃檪

@vexx32

Sure! Here's my code to repo:

## - Create new mapped drive "W":
New-PSDrive -Name "W" -psprovider FileSystem `
    -root "\\SUN\MyWinSvrSharedFiles" -persist `
    -description "Server Shared folder" `
    -Credential (Get-Credential);

## - Display all Filesystem Drives including the new mapped drive:
Get-PSDrive -PSProvider FileSystem;

## - Remove mapped drive "W":
Get-PSDrive -Name "W" | Remove-PSDrive;

## - Display all Filesystem Drives but mapped drive was removed:
Get-PSDrive -PSProvider FileSystem;

:)

@MaximoTrinidad it looks like you're not using -Scope Global when you create that drive?

@MaximoTrinidad didn't read the original problem and created/deleted the drive in the same session. This is still an issue.

Seems to be the case. @VortexUK out of curiosity does the same reproduce without -Scope Global or is it specifically an issue with that switch in combination with the others?

It's been a while since I retested - I'll see if I can do it with the latest release I have and get back to you

Just confirmed on 7.0.0 (OS Windows 10.0.17134)

New-PSDrive -Name J -PSProvider FileSystem -Root \\contoso.com\someshare -Scope Global -Persist

Works as intended. When you then open another powershell session, you can see it doing

Get-PSDrive -Name J

However, the following have no affect, the drive remains:

Get-PSDrive -Name J | Remove-PSDrive
Get-PSDrive -Name J | Remove-PSDrive -Force

Going back to the original session and running the above will work.

@VortexUK

Just in case!
Can you try with the latest PowerShell GA is version 7.0.1?

:)

Was this page helpful?
0 / 5 - 0 ratings