42

I am trying to configure my dotnet core project (in Windows) as "case sensitive", so it behaves as in my production server (linux).

I have found this way of doing it:

fsutil.exe file setCaseSensitiveInfo "C:\my folder" enable

The problem is that this function is not recursive:

The case sensitivity flag only affects the specific folder to which you apply it. It isn’t automatically inherited by that folder’s subfolders.

So I am trying to build a powershell script that applies this to all folders and subfolders, recursively.

I have tried googling something similar and just modifying the command line, but I don't seem to find the corrent keywords. This is the closest that I've gotten to this sort of example.

Xavier Peña
  • 7,399
  • 9
  • 57
  • 99
  • 1
    `(gci -Recurse -Directory).FullName | % {fsutil.exe file setCaseSensitiveInfo $_ enable}` (don't have Windows 10 to test it) – Robert Dyjas Jul 30 '18 at 10:20
  • @robdy This is the correct answer. Thanks. It answers with "setCaseSensitiveInfo is an invalid parameter", but this is Window7's fault ... I tested your script with `(gci -Recurse -Directory).FullName | % {echo $_}` and it works like a charm. – Xavier Peña Jul 30 '18 at 11:39
  • 3
    Sadly while the above used to work, Microsoft has now added a "feature" to fsutil where it will no longer allow you to set case sensitivity on a non-empty directory. Now what you'll get is a bunch of this when you try to apply the above to a directory that has subdirectories: Error: The directory is not empty. – eric.green Mar 16 '22 at 19:25

5 Answers5

58

Correct code:

(Get-ChildItem -Recurse -Directory).FullName | ForEach-Object {fsutil.exe file setCaseSensitiveInfo $_ enable}

Explanation:

NOTE: The code in the answer assumes you're in the root of the directory tree and you want to run fsutil.exe against all the folders inside, as it's been pointed out in the comments (thanks @Abhishek Anand!)

Get-ChildItem -Recurse -Directory will give you list of all folders (recursively).

As you want to pass their full path, you can access it by using .FullName[1] (or more self-explanatory | Select-Object -ExpandProperty FullName ).

Then you use ForEach-Object to run fsutil.exe multiple times. Current file's FullName can be accessed using $_ (this represents current object in ForEach-Object)[2].

Hint:

If you want more tracking of what's currently being processed you can add the following to write the path of currently processed file to the console: ; Write-Host $_ (semicolon ; is to separate from fsutil invocation) as it was pointed out in the comments (thanks Fund Monica's Lawsuit !)


[1] .FullName notation works for PowerShell 3.0 and greater, Select-Object -ExpandProperty FullName is preferred if there's a chance that lower version will be used.

[2] $_ is an alias for $PSItem

Robert Dyjas
  • 4,979
  • 3
  • 19
  • 34
  • 4
    first `cd` to the root of the directory tree that needs to become case sensitive. – Abhishek Anand Apr 10 '19 at 13:07
  • 2
    If you'd like more insight into where issues happen, you can add an `echo $_; ` just after the `{`, and it'll print out what it's currently operating on just before it does anything. – Nic Sep 15 '19 at 16:04
  • I get `.FullName was unexpected at this time.` what's wrong? – imbr Jul 28 '21 at 00:31
  • Check the output of `Get-ChildItem`. Might be it's empty for the directory you run it – Robert Dyjas Jul 29 '21 at 05:41
  • 2
    Two things: Use `(Get-ChildItem foldername -Recurse -Directory).Fullname | ForEach-Object {fsutil file setCaseSensitiveInfo "$_" enable}` and replace _foldername_ with the folder you want to use. Second make sure you open an administrator shell, additionally I found that, if a folder already contains something it apparently won't work; I get `The direcotry is not empty` error. – theking2 Oct 21 '21 at 15:31
6
(Get-ChildItem -Recurse -Directory).FullName | ForEach-Object {if (-Not ($_ -like '*node_modules*')) { fsutil.exe file setCaseSensitiveInfo $_ enable } }

I modified @robdy's code to allow excluding node_modules. You can replace the "node_modules" bit in the above with anything to exclude filepaths containing it.

If you're working with npm, you probably want to exclude node_modules. @robdy's answer is great, but was taking minutes at a time iterating over every single node package folder even if I didn't have the package installed; given that this is something one might want to run fairly often since directories might be added all the time, and since you probably aren't modifying anything in node_modules, excluding it seems reasonable.

Daniel Smedema
  • 919
  • 8
  • 15
  • 2
    Note that child directories created under a case-sensitive directory are created case sensitive, so you will never need to run this script again on that directory. – eric.green Mar 10 '20 at 22:57
  • node_modules was the problematic directory I needed this command for. – Citricguy May 06 '20 at 08:41
  • 2
    @eric.green I don't think that's true. [From Microsoft](https://devblogs.microsoft.com/commandline/per-directory-case-sensitivity-and-wsl/): "Note that the per-directory case sensitivity flag is not inherited; directories created in a case sensitive directory are not automatically case sensitive themselves. You must explicitly mark each directory as case sensitive." – Aleksandr Hovhannisyan Jul 04 '20 at 12:44
  • turns out my jenkins build issue was from a library in node_modules and hidden by windows but blew up my jenkins pipeline build on a linux system that was type sensitive so i do not recommend ignoring case in node_modules – JesseBoyd Sep 16 '21 at 19:27
5

With Cygwin and bash shell, you can do this:

$ find $THEDIR -type d -exec fsutil file setCaseSensitiveInfo "{}" enable \;

It appears that Windows handles the '/' characters output by the find command just fine.

jkeatley
  • 91
  • 1
  • 6
4

In my case I had to first enable the Linux subsystem before using the fsutil tool. So my steps were:

Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

then restart, and then @robdy 's solution:

(Get-ChildItem -Recurse -Directory).FullName | ForEach-Object {fsutil.exe file setCaseSensitiveInfo $_ enable}
dreamcrash
  • 47,137
  • 25
  • 94
  • 117
Fede Garcia
  • 677
  • 11
  • 18
  • How do you all run these commands if the directory on which you call fsutil must be empty? – vincenzoml Apr 05 '22 at 13:41
  • @vicenzomi the directory doesn't have to be empty. In fact the command just modifies recursively the children's directory property that controls the case sensitivity configuration for that directory. – Fede Garcia Apr 06 '22 at 07:42
  • 1
    On windows 11 apparently the directory MUST be empty. See https://pastebin.com/cMQrRjXU. To overcome this, I created an empty folder, set the case sensitive flag, and then copied the contents of the other directory therein. New directories do inherit the case sensitive flag. – vincenzoml Apr 07 '22 at 09:38
3

On windows 11, the other answers are not correct, as fsutil requires that the directory is not empty. To overcome this, I created a NEW empty directory, used fsutil file setCaseSensitiveInfo to set the case sensitive flag on the new directory, then MOVED the files from the other directory inside the new one. This works, as the directories are re-created when moved, and new directories inherit the case sensitive flag.

vincenzoml
  • 413
  • 1
  • 3
  • 10
  • is it also worked for subdirectories that are inside a newly created directory with enabled `setCaseSensitiveInfo `? – Amit Joshi Apr 22 '22 at 06:43
  • Yes it works, the flag is inherited if you create a new directory – vincenzoml Apr 26 '22 at 02:31
  • I was using Github, so just deleted all the contents of the folder, enabled the case sensitivity, then discarded all of my changes to the folder and that seems to work. Github and VSCode still didn't recognize that change though. git side now fixed with `git config core.ignorecase false`. – Akaisteph7 Apr 06 '23 at 19:40