12

Assuming I have a mapped drive M:\ to \\SomeServer\SomeShare and in powershell I'm in the folder M:\SomeFolder how do I convert that to a UNC path, i.e. \\SomeServer\SomeShare\SomeFolder.

1
  • should be on stackoverflow?
    – spoon16
    Sep 5, 2009 at 1:49

7 Answers 7

16

I'm fairly new to PowerShell, so the code below may be poor quality. However, it should get the information you want:

$currentDirectory = Get-Location
$currentDrive = Split-Path -qualifier $currentDirectory.Path
# Mapping a non-network drive? Check the DriveType enum documentation https://docs.microsoft.com/en-us/dotnet/api/system.io.drivetype?view=net-6.0
$logicalDisk = Get-CimInstance -ClassName Win32_LogicalDisk -filter "DriveType = 4 AND DeviceID = '$currentDrive'"
$uncPath = $currentDirectory.Path.Replace($currentDrive, $logicalDisk.ProviderName)

$uncPath should contain the UNC path that you are looking for.

2
  • Thanks very much, that works perfectly. I've modified it slightly to work with local paths as well, this should fix my annoying problems with StExBar + runas + powershell to a mapped drive. Aug 26, 2009 at 13:26
  • @firedfly, how would this need to be altered to support local drives (e.g. `C:`)? It would probably need to include the machine's name, but I don't know how one would differentiate between a HDD and CD/DVD drive.
    – Craig
    Sep 22, 2016 at 14:39
4

For any one interested in the RunAs script for StExBar it is:

param([string] $username)

$path = Get-Location
$currentDrive = Split-Path -qualifier $path
$logicalDisk = Get-WmiObject Win32_LogicalDisk -filter "DeviceID = '$currentDrive'"

if ($logicalDisk.DriveType -eq 4)
{
    $path = Join-Path $logicalDisk.ProviderName (Split-Path -NoQualifier $path)
}

$systemroot = [System.Environment]::SystemDirectory

&"$systemroot\runas.exe" /user:$username "$systemroot\windowspowershell\v1.0\powershell.exe -NoExit -Command \`" &{ Set-Location '$path' }\`""

And the command line in StExBar is:

C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -Command "&{ &'%homedrive%%homepath%\RunAs.ps1' 'domain\username' }"

Replace the path with where ever you keep the RunAs.ps1 script, I like to store mine in the root of my home folder.

4

I realize this is an old question, but I wanted to share another way to accomplish this:

$drive = Get-PSDrive -Name (get-location).Drive.Name
$root = if($drive.DisplayRoot -ne $null){$drive.DisplayRoot} else {$drive.Root}
Join-Path -Path $root -ChildPath $drive.CurrentLocation

Get-PSDrive will pull back all the information about a drive (name, used/free space, provider, root and current location) and passing the Name parameter as the current drive letter (using get-location) allows this to work in multiple scenerios (this will also pull back information on local drives on the machine).

In order to make it work on both local and mapped drives the comparison is done to populate $root with the drive letter or network location. the .Root will send back the drive letter, and the .DisplayRoot will pull back the network path (null if it is a local path, which is the reason for the comparison)

Using Join-Path, then you can pull together the path, which will return a drive letter and current location if it's a local path, network path and current location if it's a mapped drive.

4
  • Explain how it works?
    – Adam
    Apr 7, 2017 at 15:29
  • 1
    Added explaination - Thanks for calling that out.
    – Ryan
    Apr 7, 2017 at 16:37
  • 1
    Just as info if you are working with SharePoint. I have mapped a drive to a SharePoint document library using the New-PSDrive cmdlet. In this case I have the drive letter in Name property, the Root property contains the UNC path, and the DisplayRoot property is empty.
    – pholpar
    Mar 11, 2019 at 11:01
  • Just wanted to point out that the call to Get-PSDrive is unnecessary because (Get-Location).Drive gives you the PSDriveInfo object
    – RiverHeart
    Nov 22, 2023 at 20:49
3

I know this is an old question, but in case someone needs the one line version of this:

$unc = (gwmi Win32_LogicalDisk -filter "DeviceID = '$((Get-Location).Drive.Name):'").ProviderName
1
  • Note this only works if you actually are on a drive-mapped network path. If you're on a local path, ProviderName is null; if you're on a non-drive-mapped network path, Drive is null. If you need to distinguish between these 3 cases, a one-liner won't cut it. Aug 30, 2013 at 18:52
0

So combining the best of the answers here into a one-liner; Tests for current path as UNC, maps a drive to current path, changes to new mapped drive, if already a mapped drive, no action is taken.

IF ((Get-Location | %{$_.Drive}) -eq $NUL){$dltr=%{for($j=67;gdr($d=[char]++$j)2>0){}$d}; New-PSDrive –Name $dltr –PSProvider FileSystem –Root ((Get-Location).ProviderPath) –Persist; Set-Location -Path $dltr`: -PassThru}

Not intended to answer the OP, just add useful content. Had a script that I needed mapped drive instead of UNC paths, so I did this to check if a UNC was being used in PS, then map to a drive using that UNC path, then switch to that drive letter.

0

Yet one more way to solve this is to create a PowerShell module with the code below:

#Requires -Modules SmbShare
function Expand-DriveMapping
{
    <#
    .SYNOPSIS
        Expands local drive mappings in a path to the remote UNC path.
    .DESCRIPTION
        If a drive mapping is present in the provided path, the local drive mapping will be expanded using the remote UNC path;
        otherwise, the path will be left unchanged.
    .PARAMETER Path
        The path to perform the local drive mapping expansion on. If no path is specified the current working directory will be used.
    .EXAMPLE
        Expand-DriveMapping 'X:\TheRestOfMyPath'
    .EXAMPLE
        'X:\TheRestOfMyPath1', 'X:\TheRestOfMyPath2' | Expand-DriveMapping
    #>
    [CmdletBinding(SupportsShouldProcess = $false)]
    param
    (
        [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [string] $Path = (Get-Location)
    )

    begin
    {
        $driveMappings = Get-SmbMapping
    }

    process
    {
        $expandedPath = $Path

        if ($null -ne $driveMappings)
        {
            if ([System.IO.Path]::IsPathRooted($Path) -eq $true)
            {
                $pathRoot = [System.IO.Path]::GetPathRoot($Path).TrimEnd('\')

                if ($pathRoot.EndsWith(':') -eq $true)
                {
                    $driveMapping = $driveMappings | ?{ $_.LocalPath -eq $pathRoot }

                    if ($null -ne $driveMapping)
                    {
                        $expandedPath = Join-Path $driveMapping.RemotePath $Path.Remove(0, $pathRoot.Length)
                    }
                }
            }
        }

        $expandedPath
    }
}
-2
$CurrentFolder = "H:\Documents"

$Query = "Select * from Win32_NetworkConnection where LocalName = '" + $CurrentFolder.Substring( 0, 2 ) + "'"
( Get-WmiObject -Query $Query ).RemoteName

$Tst = $CurrentFolder.Substring( 0, 2 )
( Get-WmiObject -Query "Select * from Win32_NetworkConnection where LocalName = '$Tst'" ).RemoteName
1
  • 1
    Coul you elaborate on what this code does? Please see How to Answer and take our tour.
    – Burgi
    Feb 4, 2020 at 9:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .