0


I want to get all files recursively from my drive and I'm using the enumeratefiles from system.io.directory as follows:

[System.IO.Directory]::EnumerateFiles("J:\","*","AllDirectories")|out-file -Encoding ascii $outputfile
foreach($line in select-string -Path $outputfile) {
  # Some of the $line is the name of a hidden or system file
}

That works fine, however many lines contain hidden or system files.
I've used ennumeratefiles as the j: drive is very large and this function works fast and much better than the equivalent powershell cmdlets.

How can I test for these file types?

There is something on how to exlude these file types from enumeratefiles for c++ but nor for powershell and I don't know how to change the code for powershell:
c++ file hidden or system

phillip-from-oz
  • 352
  • 1
  • 5
  • 16

2 Answers2

2

Using System.IO.FileInfo and a little -boring enum magic will get you want you want.

Below is an example that will print the full path of any item that contains the attributes Hidden or System.

$hidden_or_system = [System.IO.FileAttributes]::Hidden -bor [System.IO.FileAttributes]::System

[System.IO.Directory]::EnumerateFiles("J:\","*","AllDirectories") | ForEach-Object {
    if ([System.IO.FileInfo]::new($_).Attributes -band $hidden_or_system) {
        "A hidden or system item: $_"
    }
}

Be warned that if you run into a file or folder that you do not have permissions to access a terminating error will be thrown stopping execution, you can work around this by reverting to the built-in cmdlets as they will throw non-terminating errors and continue.

$hidden_or_system = [System.IO.FileAttributes]::Hidden -bor [System.IO.FileAttributes]::System

Get-ChildItem -Path 'J:' -Recurse -Force | ForEach-Object {
    if ($_.Attributes -band $hidden_or_system) {
        "A hidden or system item: $($_.FullName)"
    }
}
Persistent13
  • 1,522
  • 11
  • 20
0

Thanks for the suggestion.

It seems when you get the file attributes for a "hidden" file sometimes powershell throws an non-terminating error.

I fixed the issue using the suggestion:

[System.IO.Directory]::EnumerateFiles("J:\","*","AllDirectories")|out-file -Encoding ascii $outputfile
foreach($line in select-string -Path $outputfile) {
  # Some of the $line is the name of a hidden or system file
  if ((Get-ItemProperty $line -ErrorAction SilentlyContinue).attributes -band [io.fileattributes]::Hidden) {continue}
  if (-not $?) {continue}
  # Is the file a system file?
  if ((Get-ItemProperty $line -ErrorAction SilentlyContinue).attributes -band [io.fileattributes]::System) {continue}
  if (-not $?) {continue}
  #
  # Do the work here...
  #
}
phillip-from-oz
  • 352
  • 1
  • 5
  • 16