Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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
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 }
share|improve this answer

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

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

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

PS> Get-Item ReadMe.tx?

this should return README.TXT

share|improve this answer

Here's my quick and dirty (no validation) approach:

Function Resolve-PathName { [CmdletBinding()]
    [string] $File,
    [switch] $Cygpath
) Process {
    $cur = $File
    $stack = New-Object System.Collections.Stack

    while ( $cur.length -gt 0) {
        $stack.Push( (split-path $cur -Leaf) )
        $cur = split-path $cur
    $cur = get-item ($stack.pop())
    while ( $stack.Count -gt 0) {
        $cur = $cur | Get-ChildItem -Filter ($stack.Pop())
    if ($Cygpath) {
        cygpath $cur.Fullname
    } else {
share|improve this answer
Why should there be CygWin on a production machine? – Deer Hunter Nov 4 '15 at 8:21

Your Answer


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.