Test-path with case sensitive

Hi,
I need to find a way to check a CSV file that contains lines of UNC paths and make sure the physical path really exist in the same case.
I couldn’t find an operator (-cmatch) for case sensitive in test-path cmdlet.
Any other idea please?

Maybe something like this. I know there is a way to get just the directory from get- child item. Man I need to get a PC for home

Maybe
If(test-path $csvitem){set-location $csvitem}
$path = $(get-location).Path
if($path -ceq $csvitem){ do something}

The thing is that the actual Windows file system isn’t case-sensitive. It preserves case as typed, but it doesn’t differentiate during comparisons. That’s why Test-Path doesn’t. As Mark points out, your best logic is something like…

$path_to_test = “C:\Some Mixed Case Path”
$exists = $true
if ((Test-Path $path_to_test)) {
$dir = dir $path_to_test
if ($dir.name -cneq $path_to_test) {
$exists = $false
}
} else {
$exists = $false
}

I’m not sure why -match or -cmatch would be right for you, but perhaps there’s something about what you’re doing that you haven’t shared.

Thanks for the answers, I took your advice and created this:

$PathToTest = @("C:\WINdows", "C:\Program Files","D:\backup","D:\CourserA")
$AllNotMatch = ''
$AllMatch = ''
$AllNotExist = ''
foreach ($Path in $PathToTest)
{
    if ((Test-Path $PathToTest))
        {
        $Dir = dir $Path
        if ($Dir.DirectoryName -cne $Path)
            {
            $AllNotMatch += $Path
            Write-Warning "$Path - does not match the physical case"
            }
        else
            {
            $AllMatch += $Path
            Write-host "$Path - matches the physical case" -F Green
            }
        }
    else
        {
        $AllNotExist += $Path
        Write-Warning "$Path - path does not exist"
        }
}

But this code still has issues:

  • For some reason I noticed that 2 paths from the array get to be a different object so for example “D:\backup” is different object than “D:\CourserA” and thus it doesn’t have a property called DirectoryName which I need to use.
  • Another issue is that I noticed that when using dir “D:\CourserA” command with a mix case it still shows the physical folder name in the same mix case although it’s not really so.

Maybe

If(test-path $csvitem){set-location $csvitem}
$path = $(get-location).Path
if($path -ceq $csvitem){ do something}

There are a couple of problems here.

  1. Get-ChildItem (dir) will return a collection of all the files and folders in the “Path” you are supplying, so when you are checking with your if statement “$Dir.DirectoryName -cne $Path”, in the example of “C:\WINdows” you are actually checking

C:\WINdows C:\WINdows C:\WINdows C:\WINdows C:\WINdows -cne C:\WINdows

Obviously that is not what you want. You should used get-item, not get-childitem

  1. When you provide an absolution or relative path, the returned result matches the case you supplied. This is the same for Get-Item, Get-ChildItem, Set-Location, Get-Location, etc.

IE.

PS C:\> (Get-Item "C:\WINdows").Fullname
C:\WINdows
PS C:\> (Get-Item "C:\windows").Fullname
C:\windows
PS C:\> (Get-Item "C:\WINDOWS").Fullname
C:\WINDOWS

This means that no mater what, if you use an absolute or relative path, your case will always match your CSV input.

The only why I have found so far to get PowerShell to return the actual case of the folder is by making PowerShell search and find it with a wildcard

PS C:\> (Get-Item "C:\WINdows*").Fullname
C:\Windows
PS C:\> (Get-Item "C:\windows*").Fullname
C:\Windows
PS C:\> (Get-Item "C:\WINDOWS*").Fullname
C:\Windows

This will be problematic, of course, for cases where the wildcard causes additional matches, such as Program Files on x64 machines.

PS C:\> (Get-Item "C:\pRogrAM FilES*").Fullname
C:\Program Files
C:\Program Files (x86)

You would need to place your wildcard in a location where it would not cause you to get additional results you did not intend.

PS C:\> (Get-Item "C:\pRogrAM* FilES").Fullname
C:\Program Files

It’s not great, but it’s functional

$PathToTest = @("C:\WINdow*s", "C:\Program File*s","D:\backu*p","D:\Courser*A")
$AllNotMatch = ''
$AllMatch = ''
$AllNotExist = ''
foreach ($Path in $PathToTest)
{
    if ((Test-Path $PathToTest))
        {
        $Dir = Get-Item $Path
        $Path = $Path.Replace("*", "")
        if ($Dir.Fullname -cne $Path)
            {
            $AllNotMatch += $Path
            Write-Warning "$Path - does not match the physical case"
            }
        else
            {
            $AllMatch += $Path
            Write-host "$Path - matches the physical case" -F Green
            }
        }
    else
        {
        $AllNotExist += $Path
        Write-Warning "$Path - path does not exist"
        }
}

Thanks Curtis that was very helpful.
I think it wont be an issue to add a * on the begging of all the UNC paths (on the first folder level).
I agree that it’s not that great at all (and hope I won’t run into issues), I was really under the impression that it would be very easy to do with PowerShell.

Unfortunately it’s not PowerShell’s fault here. While NTFS is a case sensitive file system, the Windows operating environment (API, .Net, commandline, etc) is not. PowerShell is built on .Net and it is .Net that reads and returns the path the way it does. Maybe cygwin can provide some options for you. Since it runs a POSIX environment, it should keep your path case. This is of course theory as I have not used it.

Curtis,

The trick to leveraging wildcards with only a single desired match, is to give it a wildcard with only one possible interpretation. The easiest way is to put the last letter in square brackets.

PS C:\> (Get-Item "C:\pRogrAM FilE[S]").Fullname
C:\Program Files

Nice Tim