Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have a file README.TXT. If I issue the following command:

PS> Get-Item ReadMe.txt

...then it returns "ReadMe.txt". I want to find out the actual name of the file on disk, including case. How do I get it to return "README.TXT"?

I ask because I'm trying to track down a problem with case-insensitive filenames on Windows versus case-sensitive files on a Unix box, and I want to get the actual case used on the Windows box.

More detail: I have a list of files (stored in a .CSPROJ file) which are in a different case from those stored on disk. I want to be sure that they match. For example: if the .CSPROJ file says "ReadMe.txt", but the file on disk is "README.TXT", sometimes editing the file in Visual Studio rewrites the file as "ReadMe.txt", which then confuses Perforce, because it's case-sensitive, and the filename no longer has the case it was expecting. I want to write a script that spots the mismatched filenames, so that I can do something about them before it causes a problem.

share|improve this question
add comment

4 Answers

up vote 3 down vote accepted

Here's what I came up with:

function Get-ActualFileName($file) {
    $parent = Split-Path $file
    $leaf = Split-Path -Leaf $file

    $result = Get-ChildItem $parent | where { $_ -like $leaf }
    $result.Name
}
share|improve this answer
add comment

The bulk of the file system work in PowerShell is done by some .NET classes in the System.IO namespace. If you know the path (like in your example, you've navigated to the file system location where your subject file is located), then you could use something like

(get-item $pwd).GetFiles('readme.txt')

Since the base .NET classes are case sensitive, the resulting output of your file names will be case sensitive as well.

For reference, the in the example, you are calling the GetFiles method of the System.IO.DirectoryInfo object that represents the current working directory ($pwd). You can change that to point to the directory containing the file you need to confirm the casing on.

The Name, BaseName, and FullName properties should all reflect the proper casing.

More info on the GetFiles method.

share|improve this answer
    
No, those return the path however you typed it. E.g.: cd C:\WINDOWS\SYSTEM32; (get-item $pwd).GetFiles(".\w32time.dll").FullName # Prints "C:\WINDOWS\SYSTEM32\.\w32time.dll" which is not only cased wrong, but also has a \.\ in it because that's how I typed it.... –  Jaykul Sep 28 '13 at 4:21
add comment

The fastest way I can think of is to replace all the slashes with *\ and then call Get-Item, and to make sure you get no dupes, pick the one that's case-insensitively equal to the one you specified.

$Path = Get-Item "$($Path.TrimEnd('\/') -replace "(?<!:)(\\|/)", '*$1')*" |
           Where { $_.FullName -ieq $Path } | Convert-Path
share|improve this answer
add comment

Rather than specifying the exact name, just use a wildcard:

PS> Get-Item ReadMe.tx?

this should return README.TXT

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.