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?

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Works great, but why do we need it?
I encourage you to consider @piers7 response below.
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.

5 Comments

Hmm... still get the same error. I know it's not a permissions problem as well since I have admin access on both servers.
I get Microsoft.PowerShell.Core\FileSystem::\\ltlymanb\test1\style.min.css
Sry here is what I've been trying .\compare_js_css.ps1 \\ltlymanb\c$\temp\test1 \\ltlymanb\c$\temp\test2
I've also run this and get the same. .\compare_js_css.ps1 \\ltlymanb\c$\websites\test\website \\c2devweb4\c$\websites\test\website
@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::', '').
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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.