pf-Smb.ps1

function Get-UNC_FileName {
    param (
        [Parameter(ValueFromPipeline=$true)]
        $filename
    )
    process {
        function Get-DefaultSmbShare {
            Get-PSDrive -PSProvider FileSystem | Select-Object Name, Root | 
                ForEach-Object { [PSCustomObject]@{'Path'=$_.Root; 'Name'="$($_.Name)$"} }
        }
    
        if (-not $SharesCache ) {
            try {
                Import-Module SmbShare
                $global:SharesCache = Get-SmbShare | Where-Object { -not [string]::IsNullOrWhiteSpace($_.Path) } | 
                    Select-Object -Property Path, Name
            }
            catch {
                $global:SharesCache = Get-DefaultSmbShare
            }
        }
        $share = $SharesCache | Get-LongestPrefix $filename 'Path'
    
        $uncfilename = $filename | Update-Prefix $share.Path ( $share.Name + '\' )
        $uncfilename = '\\' + $env:COMPUTERNAME + '\' + $uncfilename  
        # $result = "file://$filename"
        return $uncfilename
    }
}
function Get-UNC_FileName:::Test {
    Get-UNC_FileName -filename C:\Users | assert -eq "\\$env:computername\C$\Users"
    'C:\Users' | Get-UNC_FileName | assert -eq "\\$env:computername\C$\Users"
}

function Get-SmbShareMap {
    param (
        [Parameter(ValueFromPipeline=$true)]
        $computerName,
        $CachePath,
        [Switch]$IncludeShortName
    )
    process {
        if ( -not $computerName ) { return }

        $hostDSNName = [System.Net.Dns]::GetHostByName($computerName).HostName
        $hostName = $hostDSNName.Split('.')[0]

        try {
            $cim = New-CimSession -ComputerName $hostDSNName
            try {
                $shares = Get-SmbShare -CimSession $cim | Where-Object Path
            }
            finally {
                $cim | Remove-CimSession
            }
        }
        catch {
            # Try first to obtain shares, and if fails try to get it from the cache
        }

        if ($CachePath -and -not $shares) {
            $CacheFile = "$CachePath\$computerName.FolderShares.Cache.json"
            if ( test-path $CacheFile ) {
                $json = Get-Content -Raw -Path $CacheFile
                $result = ConvertFrom-Json $json
                return $result
            }
        }

        $shares = $shares | Sort-Object Path -Descending | Where-Object ScopeName -eq '*'

        $result = $shares | ForEach-Object { 
            $local = $_.Path | Update-Suffix '\'
            if ($IncludeShortName) {
                [PSCustomObject]@{ 
                    Local = $local
                    Remote = "\\$hostName\" + $_.Name } 
            }
            [PSCustomObject]@{ 
                Local = $local
                Remote = "\\$hostDSNName\" + $_.Name } 
        }

        if ($CacheFile) {
            $json = ConvertTo-Json -InputObject $result
            Set-Content -Path $CacheFile -Value $json
        }

        return $result
    }
}
function Get-SmbShareMap:::Example {
    'VmHostServer3' | Get-SmbShareMap
    'VmHostServer2' | Get-SmbShareMap -IncludeShortName
    'localhost' | Get-SmbShareMap
}

function SmbShareRemotePath {
    begin {
        $shareList = $env:COMPUTERNAME | Get-SmbShareMap -IncludeShortName
    }
    process {
        $path = Get-Path $_
        if ( -not $path ) { return }
        if ( $path.StartsWith('\\' ) ) {
            return $path
        }
        foreach ( $share in $shareList ) {
            $prefixPath = $share.Local
            $sharePath = $prefixPath + '\'
            if ( $path.StartsWith( $sharePath, [System.StringComparison]::InvariantCultureIgnoreCase ) -or ( $path -eq $prefixPath ) ) {
                $path | Update-Prefix -prefix $prefixPath -replace $share.Remote
            }
        }
    }
}
function SmbShareRemotePath:::Example {
     $path = 'C:\Windows\System32'
     $path | SmbShareRemotePath
}

function SmbShareLocalPath {
    Param (
        [Parameter(ValueFromPipeLine=$true)]
        $path,
        $computername = $env:COMPUTERNAME
    )
    begin {
        $shareList = $computername | Get-SmbShareMap -IncludeShortName
    }
    process {
        $path = Get-Path $Path
        if ( -not $path ) { return }
        if ( -not $path.StartsWith('\\' ) ) {
            return $path
        }
        foreach ( $share in $shareList ) {
            $prefixPath = $share.Remote
            $sharePath = $prefixPath + '\'
            if ( $path.StartsWith( $sharePath, [System.StringComparison]::InvariantCultureIgnoreCase ) -or ( $path -eq $prefixPath ) ) {
                $path | Update-Prefix -prefix $prefixPath -replace $share.Local
            }
        }
    }
}
function SmbShareLocalPath:::Example {
     $path = '\\VmHostServer2\Nuget\abc'
     $path | SmbShareLocalPath
}