Changing Server Names in a Mapped Path

Good morning,

Sorry to be a bother but I’ve run into a brick wall.

Quest: Create a login script that will search for a specified mapped server share, remove that share and remap to a new server with the same file path…
Problem: If I run these commands on their own, it works exactly as expected. When it’s scripted, all of the sudden my new drive will never actually stick even though my verbose output looks fine. Pulling my hair out in handfuls…

Code:

function Switch-Drive
{
	[CmdletBinding()]
	[OutputType([int])]
	Param
	(
		# Old server name (netbios)
		[Parameter(Mandatory = $true)]
		[String]
		$old,
		
		# New server name (netbios)
		[Parameter(Mandatory = $true)]
		[String]
		$new
	)

	Clear-Host
	
	#Locate first available drive letter
	
	function Get-DriveLetter
	{
		[char[]]"DEFGJKLMNOPQRTUVWXY" |`
		?{ !(Get-PSDrive $_ -ea 'SilentlyContinue') } |`
		select -f 1
	}
	
	$newletter = Get-DriveLetter
	
	Write-Host "Found drive letter: $newletter"
	
	Write-Host "Old drive designated as: $old"
	Write-Host "New drive designated as: $new"
	Start-Sleep -Seconds 1
	
	Write-Host "Searching for old drive"
	
	$search = Get-WmiObject Win32_mappedlogicaldisk
	
	
	If (($search.ProviderName) -like "*$old*")
	{
		$fullpath = $search | Where-Object { $_.ProviderName -like "*$old*" } | Select-Object -ExpandProperty ProviderName
		$fullname = $fullpath.ToString()
		Write-Host "Found $fullname is mapped on $ENV:Computername"
	}
	Else
	{
		Write-Host "Unable to find $old"
		Exit 99
	}
	
	$search | Where-Object { $_.ProviderName -like "*$($old)*" } | ForEach-Object{ 
          $name = ($_.ProviderName)
          $share = $name.TrimStart("\\" + $old)
          Write-Host "Found share path $share"
          $newpath = ("\\" + "$new" + "$share")
          Write-Host "Creating $newpath"
          Get-PSDrive | where {$_.DisplayRoot -eq $fullname} |  Remove-PSDrive -Force -Verbose
          Start-Sleep -Seconds 5 #added during troubleshooting
          New-PSDrive -Name $newletter -PSProvider FileSystem -Root $newpath -Persist -Verbose
        }
	
	

        }



Dyin over here,

Paul :slight_smile:

Personally, I still just use “net use” for mapping drives, rather than New-PSDrive. You could try this:

net use "${newletter}:" $newpath /persistent:yes

Or, you could not even bother searching for an available drive letter yourself, and let net use do it:

net use * $newpath /persistent:yes

Dave,

Thanks for the heads-up. I was sure that I was doing something wrong. What I keep seeing in testing is that the objects listed in Win32_MapLogicalDisk update in real time but the objects gathered by Get-PSdrive…not so much. So, I was able to see the changes when querying WMI but the PSDrive cmdlets were just not performing.

My final product…

function Switch-VWDrive
{
	[CmdletBinding()]
	[OutputType([int])]
	Param
	(
		# Param1 help description
		[Parameter(Mandatory = $true)]
		[String]
		$old,
		
		# Param2 help description
		[Parameter(Mandatory = $true)]
		[String]
		$new
	)
	Write-Host "Old drive designated as: $old"
	Write-Host "New drive designated as: $new"
	Start-Sleep -Seconds 1
	
	Write-Host "Searching for old drive..."
	
	$search = Get-WmiObject Win32_mappedlogicaldisk
	
	
	If (($search.ProviderName) -like "*$old*")
	{
		$fullpath = $search | Where-Object { $_.ProviderName -like "*$old*" } | Select-Object Caption -ExpandProperty ProviderName
		$fullname = $fullpath.ToString()
		$drive = $fullpath.Caption
		Write-Host "Found $fullname is mapped on $ENV:Computername"
	}
	Else
	{
		Write-Host "Unable to find $old"
		Exit 99
	}
	
	$search | Where-Object { $_.ProviderName -like "*$($old)*" } | ForEach-Object{
		$name = ($_.ProviderName)
		$share = $name.TrimStart("\\" + $old)
		Write-Host "Found share path $share"
		$newpath = ("\\" + "$new" + "$share")
		Write-Host "Creating $newpath"
		net use $drive /delete /YES
		Start-Sleep -Seconds 5 #added during troubleshooting
		net use * $newpath /persistent:yes
	}
}