Mapping Drives Revisited
September 4th, 2016 by Charlie Russel and tagged $Profile, Map Drives, net use, PowerShell v5, PSDrive
In my old drive mapping post, I was forced to do some fairly ugly stuff because I had to call the old net use command. Yech. Eventually, we got New-PSDrive, and that helped, but in PowerShell v5 (Windows 10’s version), we get New-SmbMapping and it actually works. (New-SmbMapping was added earlier, but there were issues. Those appear to be resolved in the final version of v5.)
When New-PSDrive finally had persistent drive mappings, I replaced my my old MapDrives.cmd file with a new MapDrives.ps1 that used the New-PSDrive syntax:
New-PSDrive -Name I -root \\srv2\Install -Scope Global -PSProv FileSystem -Persist
A bit awkward, but it works. However, it sometimes ran into problems with drives that were mapped with net use, so I was glad when we finally got a useful version of New-SmbMapping. Now the syntax for mapping my I: drive to \\srv1\install is:
New-SmbMapping -LocalPath I: -RemotePath \\srv2\Install -Persistent $True
Great. But it doesn’t have a -Force parameter, so I can’t tell it to override any maps that already exist. That requires cleaning up the old maps before I make new ones. For that, we have Remove-SmbMapping and Remove-PsDrive.
function Remove-myMaps () { $DriveList = (Get-SmbMapping).LocalPath write-verbose "Removing drives in DriveList: $drivelist" Foreach ($drive in $DriveList) { $psDrive = $drive -replace ":" #remove unwanted colon from PSDrive name Write-Verbose "Running Remove-SmbMapping -LocalPath $Drive -Force -UpdateProfile" Remove-SmbMapping -LocalPath $Drive -Force -UpdateProfile If ( (Get-PSDrive -Name $psDrive) 2>$Null ) { Write-Verbose "Running Remove-PsDrive -Name $psDrive -Force " Remove-PSDrive -Name $psDrive -Force } } write-host " " $DriveList = (Get-SMBMapping).LocalPath Write-Verbose "The drive list is now: $DriveList" }
As you might have noticed, PsDrives don’t have a colon, and SmbMapping drives do. But PowerShell gives us the useful -replace operator, allowing us to simply remove the stray colon from the drive letter that SmbMapping has.
So, here’s the entire script. Feel free to use it as the basis for your own mappings, but please, respect the copyright and don’t republish it but link to here instead. Thanks. :)
Charlie.
<# .Synopsis Maps network drives to drive letters .Description Map-myDrive is used to map network resources to local drive letters. It can use SmbMapping or PsDrive to do the mapping, but defaults to simple PsDrives for historical reasons. (SmbMapping was buggy when it was first introduced!) .Example Map-myDrive Performs a standard drive mapping on the local machine using New-PsDrive syntax. .Example Map-MyDrive -SMB Performs a standard drive mapping on the local machine using New-SmbMapping syntax. .Example Map-MyDrive -SMB -Force Performs a standard drive mapping on the local machine using New-SmbMapping syntax, and forces an unmapping of any existing drive maps before remapping. .Example Map-MyDrives -SMB -Force -AtHome $False Performs a standard drive mapping on the local machine using New-SmbMapping syntax, and forces an unmapping of any existing drive maps before remapping. The script assumes that it is NOT being run in my home domain, and therefore does only local mappings. .Parameter SMB When set, Map-myDrive uses SMB syntax to do the drive mappings .Parameter Force When set, Map-myDrive completely unmaps any existing drive mappings, and then remaps them. .Parameter AtHome When True, Map-myDrive assumes that it has connectivity to the home domain resources. When False, it assumes no home domain resources are available and maps to local shares. .Inputs [switch] [switch] [switch] [Boolean] .Notes Author: Charlie Russel Copyright: 2016 by Charlie Russel : Permission to use is granted but attribution is appreciated Initial: 10 June, 2012 ModHist: 26 June, 2012 A single, cleaner, call to GWMI : 26 April,2015 Cleaned up smb unmapping failures, and added Verbose : 27 June, 2015 New unmapping function : 04 Sept, 2016 Added AtHome Boolean to override environment, Force switch to force unmapping/remapping : #> [CmdletBinding(SupportsShouldProcess=$True)] Param ([Parameter(Mandatory=$false)][Switch]$SMB, [Parameter(Mandatory=$false)][Switch]$Force, [Parameter(Mandatory=$false)][Boolean]$AtHome=$True) # Write-Verbose "Running mapdrives.ps1 with SMB set to $SMB" Write-Verbose "Athome is set to $AtHome" Write-Verbose "Force is $Force" $Psh = Get-Process PowerShell # Start by checking for mapped drives $DriveList = $Null $PSDriveList = $Null #$DriveList = Get-WMIObject Win32_LogicalDisk | Where-Object { $_.DriveType -eq 4 } $DriveList = (Get-SMBMapping).LocalPath write-verbose "The DriveList is: $DriveList" if ($DriveList) { $PSDriveList = $DriveList -replace ":" write-verbose "The PSDrivelist is: $PSDriveList" } # Unmap any lingering ones Function Remove-myMaps () { write-verbose "Removing drives in DriveList: $drivelist" Foreach ($drive in $DriveList) { $psDrive = $drive -replace ":" #remove unwanted colon from PSDrive name Write-Verbose "Running Remove-SmbMapping -LocalPath $Drive -Force -UpdateProfile" Remove-SmbMapping -LocalPath $Drive -Force -UpdateProfile If ( (Get-PSDrive -Name $psDrive) 2>$Null ) { Write-Verbose "Running Remove-PsDrive -Name $psDrive -Force " Remove-PSDrive -Name $psDrive -Force } } write-host " " $DriveList = (Get-SMBMapping).LocalPath Write-Verbose "The drive list is now: $DriveList" } Function Map-myPSDrive () { New-PSDrive -Name I -root \\server\Install -Scope Global -PSProv FileSystem -Persist New-PSDrive -Name J -root \\server\Download -Scope Global -PSProv FileSystem -Persist New-PSDrive -Name S -root \\server\SharedDocs -Scope Global -PSProv FileSystem -Persist New-PSDrive -Name W -root \\server\Working -Scope Global -PSProv FileSystem -Persist New-PSDrive -Name H -root \\server2\Download -Scope Global -PSProv Filesystem -Persist New-PSDrive -Name K -root \\server2\Kindle -Scope Global -PSProv FileSystem -Persist New-PSDrive -Name M -root \\server2\Music -Scope Global -PSProv FileSystem -Persist New-PSDrive -Name N -root \\server2\Audible -Scope Global -PSProv FileSystem -Persist New-PSDrive -Name P -root \\server2\Pictures -Scope Global -PSProv FileSystem -Persist New-PSDrive -Name T -root \\labserver\Captures\70-742 -Scope Global -PSProv FileSystem -Persist } # Map using SMBMapping. It's more robust Function New-mySMBMaps () { New-SmbMapping -LocalPath I: -RemotePath \\server\Install -Persistent $True New-SmbMapping -LocalPath J: -RemotePath \\server\Download -Persistent $True New-SmbMapping -LocalPath S: -RemotePath \\server\SharedDocs -Persistent $True New-SmbMapping -LocalPath W: -RemotePath \\server\Working -Persistent $True New-SmbMapping -LocalPath H: -RemotePath \\server2\Downloads -Persistent $True New-SmbMapping -LocalPath K: -RemotePath \\server2\Kindle -Persistent $True New-SmbMapping -LocalPath M: -RemotePath \\server2\Music -Persistent $True New-SmbMapping -LocalPath N: -RemotePath \\server2\Audible -Persistent $True New-SmbMapping -LocalPath P: -RemotePath \\server2\Pictures -Persistent $True New-SmbMapping -LocalPath T: -RemotePath \\labserver\Captures\70-742 -Persistent $True } Function Map-myLocal () { New-SmbMapping -LocalPath K: -RemotePath \\localhost\Kindle -Persistent $False New-SmbMapping -LocalPath T: -RemotePath \\localhost\Captures\70-742 -Persistent $False } if(! $PSDriveList ) { if ($Force) { Remove-myMaps } Write-Verbose "SMB is set to $SMB" if ($SMB) { If ($AtHome) { New-mySMBMaps } else { Map-myLocal } } else { If ($AtHome) { Map-myPSDrive } else { Map-myLocal } } } else { # $Psh.count is the number of open PowerShell windows. I know that if it's less than or equal # to 2, then I haven't yet mapped the drives on both limited user and administrative windows. # Therefore, we need to mapdrives here. Or, if I have run this with a -Force command, obviously. if (($Psh.count -le 2) -OR ($Force)) { Remove-myMaps Write-Verbose "SMB is set to $SMB" if ($SMB) { If ($AtHome) { New-mySMBMaps } else { Map-myLocal } } else { If ($AtHome) { Map-myPSDrive } else { Map-myLocal } } } }
Posted in $Profile, net commands, PowerShell, Survival Guide | 4 Comments »