3

Well I've struggled long enough with this one. I have a project to compare two folders, one on each of two servers. We are comparing files on the source server with those on the target server and will create a list of the files from the source that will need to be refreshed once an update is completed on the target server.

Here's my script (many thanks to http://quickanddirtyscripting.wordpress.com for the original) :

param ([string] $src,[string] $dst)

function get-DirHash()
{
    begin 
    {
        $ErrorActionPreference = "silentlycontinue"
    }
    process 
    {
        dir -Recurse $_ | where { $_.PsIsContainer -eq $false -and ($_.Name -like "*.js" -or $_.Name -like "*.css"} | select Name,FullName,@{Name="SHA1 Hash"; Expression={get-hash $_.FullName -algorithm "sha1" }}
    }
    end 
    {
    }
}  

function get-hash 
{
    param([string] $file = $(throw 'a filename is required'),[string] $algorithm = 'sha256')
    try
    {
        $fileStream = [system.io.file]::openread((resolve-path $file));
        $hasher = [System.Security.Cryptography.HashAlgorithm]::create($algorithm);
        $hash = $hasher.ComputeHash($fileStream);
        $fileStream.Close();
    }
    catch
    {
        write-host $_
    }
    return $hash
}

Compare-Object $($src | get-DirHash) $($dst | get-DirHash) -property @("Name", "SHA1 Hash")

Now for some reason if I run this against local paths say c:\temp\test1 c:\temp\test2 it works fine, but when I run it using UNC paths between two servers I get

Exception calling "OpenRead" with "1" argument(s): "The given path's format is not supported."

Any help with this would be greatly appreciated. The end result should be a list of files, but for some reason it doesn't like the UNC path.

The script name is compare_js_css.ps1 and is called as such:

.\compare_js_css.ps1 c:\temp\test1 c:\temp\test2 <-- This works

.\compare_js_css.ps1 \\\\devserver1\c$\websites\site1\website \\\\devserver2\c$\websites\site1\website <-- Returns the aforementioned exception.

Why?

slava
  • 1,901
  • 6
  • 28
  • 32
Bob Lyman
  • 43
  • 2
  • 5

3 Answers3

7

This gives the path you are after without the Microsoft.PowerShell.Core\FileSystem:::

(Resolve-Path $file).ProviderPath

No need to use a string replace.

Greg Bielleman
  • 161
  • 1
  • 4
1

OpenRead supports UNC paths. Resolve-Path returns you an object. Use (Resolve-Path MyFile.txt).Path.Replace('Microsoft.PowerShell.Core\FileSystem::', '') as the argument for OpenRead. The path returned from Resolve-Path when using UNC paths includes PowerShell's fully qualified schema which contains a header which is unsupported by the OpenRead method so it needs to be omitted.

Andy Arismendi
  • 50,577
  • 16
  • 107
  • 124
  • Hmm... still get the same error. I know it's not a permissions problem as well since I have admin access on both servers. – Bob Lyman May 18 '12 at 17:19
  • I get Microsoft.PowerShell.Core\FileSystem::\\ltlymanb\test1\style.min.css – Bob Lyman May 18 '12 at 18:19
  • Sry here is what I've been trying .\compare_js_css.ps1 \\ltlymanb\c$\temp\test1 \\ltlymanb\c$\temp\test2 – Bob Lyman May 18 '12 at 18:19
  • I've also run this and get the same. .\compare_js_css.ps1 \\ltlymanb\c$\websites\test\website \\c2devweb4\c$\websites\test\website – Bob Lyman May 18 '12 at 18:21
  • @BobLyman `OpenRead` doesn't support the `Microsoft.PowerShell.Core\FileSystem::` part of the path. You could do this: `(Resolve-Path $file).Path.Replace('Microsoft.PowerShell.Core\FileSystem::', '')`. – Andy Arismendi May 18 '12 at 18:47
1

Use the Convert-Path cmdlet, which will provide you with the path in the 'regular' UNC form. This will be required any time you use any shell commands, or need to pass an entire path to a .Net method etc...

See https://technet.microsoft.com/en-us/library/ee156816.aspx

piers7
  • 4,174
  • 34
  • 47