2

I wrote a script to map a Network Drive (NAS) if not mapped, or unmap it if mapped.

# NAS.ps1
If (!(Test-Path N:)) {
    $User = "User"
    # Pwd in script will be removed later
    $Pwd = ConvertTo-SecureString -String "Password" -AsPlainText -Force
    
    $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $Pwd

    New-PSDrive -Name "N" -PSProvider "FileSystem" -Root "\\192.168.1.100\NAS" -Persist -Credential $Credential
} else {
    Remove-PSDrive -Name "N"
}

I edit it using the Windows Powershell ISE. When I run it, I see the drive appearing or disappearing in my Windows Explorer window. That's perfect.

Run with Powershell

However, when I right click NAS.ps1 > "Run with Powershell", the PS window quickly appear/disappear and the drive is neither mapped/unmapped (nothing changes).

Run Powershell, then ./NAS.ps1

If I try to run Powershell, cd to the folder with my scripts, and run it manually, it keeps mounting the drive:

PS C:\Users\User\Desktop> .\NAS.ps1

Name           Used (GB)     Free (GB) Provider      Root                                               CurrentLocation
----           ---------     --------- --------      ----                                               ---------------
N                1150.44       3201.81 FileSystem    \\192.168.1.100\NAS

PS C:\Users\User\Desktop> .\NAS.ps1

Name           Used (GB)     Free (GB) Provider      Root                                               CurrentLocation
----           ---------     --------- --------      ----                                               ---------------
N                1150.44       3201.81 FileSystem    \\192.168.1.100\NAS

Run Powershell as Admin., then ./NAS.ps1

If I launch Powershell as an administrator, and run my scripts, nothing is shown:

PS C:\Windows\system32> cd C:\Users\User\Desktop
PS C:\Users\User\Desktop> .\NAS.ps1
PS C:\Users\User\Desktop> .\NAS.ps1
PS C:\Users\User\Desktop> .\NAS.ps1

Using Get-PSDrive it appear as mounted, I can cd into it, but from the Win. Explorer window it does not appear

PermaChips
  • 51
  • 5
  • Probably due to the execution policy set on your system when you right click and runas. Try *dot sourcing* the ps1 first. `. .\NAS.ps1` – Abraham Zinala Jul 10 '21 at 11:36
  • As for running elevated (as admin): Unfortunately, drive mappings established while elevated are _not_ visible to the same account when _not_ elevated, so the behavior is expected. – mklement0 Jul 10 '21 at 13:17

2 Answers2

3

The solution was to use -Scope Global when mapping the drive, and to use net use to un map it.

Working code:

# NAS
Set-StrictMode -Version 2.0
If (!(Test-Path N:)) {

    $User = "user"
    $Pswd = ConvertTo-SecureString -String "Password" -AsPlainText -Force

    $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $Pswd

     New-PSDrive -Name "N" -Root "\\192.168.1.100\NAS" -Credential $Credential -PSProvider "FileSystem" -Persist -Scope Global
} else {
    Net Use "N:" /delete
}
PermaChips
  • 51
  • 5
  • Well done. That you cannot remove a persistent drive with `Remove-PSDrive` is a known, long-standing bug: see [GitHub issue #7829](https://github.com/PowerShell/PowerShell/issues/7829). To me, requiring `-Persist` to be combined with `-Scope Global` smells like a bug too - even though the behavior is [documented](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/new-psdrive?view=powershell-7.1&WT.mc_id=ps-gethelp): "[...] the Persist parameter doesn't persist the creation of a PSDrive beyond the scope in which the command is running." – mklement0 Jul 10 '21 at 15:00
  • 1
    Always thought PSDrive where visible only from PowerShell. Didn't know that persistent would map it on OS level, good to know! – Santiago Squarzon Jul 10 '21 at 15:03
  • 1
    @SantiagoSquarzon, yes, though the fact that `-Scope Global` is _also_ needed when calling from a script is both counterintuitive and logically extraneous. I've created [GitHub issue #15752](https://github.com/PowerShell/PowerShell/issues/15752) to propose removing this requirement (though _Windows PowerShell_ will never see this improvement either way). – mklement0 Jul 10 '21 at 19:27
1

Ok, the First question if you set the execution policy?

By default, execution of scripts is not allowed.

You can do it with this cmdlet.

# To configure execution policy
Set-ExecutionPolicy -ExecutionPolicy Unrestricted

# To check execution policy
Get-ExecutionPolicy -List

The second thing that looks bad is $pwd $pwd, a system default variable that defines the current path. Better user $Pass or $Pword or $Pswd etc.

And the final question, what for you are doing this New-PSDrive ?

Why I'm asking. Because as I know, PSDrive is mapping only for the current PowerShell session. This will not show you drive like a mapped drive. You can use it to copy files or doing an action. But when you close this PowerShell session, the mapping will be removed.

This is not the same as "net use" You actually can do it like

$net = new-object -ComObject WScript.Network
$net.MapNetworkDrive("n:", "\\192.168.1.100\NAS", $false, $User, $password)

Or the old fashion way:

$script = 'net use N: \\192.168.1.100\NAS /persistent:yes /u:' + $User + ' ' + $Password
Invoke-Expression $script
Puzo
  • 95
  • 3
  • Where did you hear that mapping a drive using `New-PSDrive` only stays mapped until the Powershell session is closed? That's not true at all. – Abraham Zinala Jul 10 '21 at 12:39
  • 1
    Good point re `$PWD`, but if the execution policy were the problem, wouldn't that affect elevated (run-as-admin) sessions too (the OP states it works there)? @AbrahamZinala, drives created with `New-PSDrive` are session-scoped by default, but do persist with the `-Persist` switch, which the OP _is_ using, so there is indeed no reason to avoid `New-PSDrive`. – mklement0 Jul 10 '21 at 13:15
  • P.S.: You can't invoke an entire command line stored in a string with `&` - and there's no need for such a string; just use `net use N: \\192.168.1.100\NAS /persistent:yes /u:$User $Password` – mklement0 Jul 10 '21 at 13:26
  • 1
    @mklement0, you need a youtube chanel! – Abraham Zinala Jul 10 '21 at 15:49
  • When you scope the command locally, without dot-sourcing, the Persist parameter doesn't persist in creating a PSDrive beyond the scope in which you run the command. If you run New-PSDrive inside a script and want the new drive to persist indefinitely, you must dot-source the script. And to force a new drive to persist, you must specify Global as the value of the Scope parameter and include Persist in your command. – Puzo Jul 10 '21 at 18:39
  • Thanks for updating, @Puzo (you didn't @-mention me, so I only noticed your comment now). However, while the updated command is now _functional_, the use of `Invoke-Expression` is unnecessary is this case (see previous comment for the simpler and safer alternative) and [should be avoided in general](https://stackoverflow.com/a/51252636/45375) – mklement0 Jul 11 '21 at 18:55