Search code examples
powershellfilesystemwatcherfile-watcher

Remove-Item -Force on NULL Filewatcher file removed 1000 files on my server, is this a Powershell bug? Or just my bad code?


So, I am developing a script using FileSystemWatcher similar to this one: https://powershell.one/tricks/filesystem/filesystemwatcher

I only use the Created event.

I then run the following code on the files that are "Created."

I met a really unexpected error when I ran this code on a file that was already removed by another piece of code. So basically, the "Remove-WrongFileType" function received a file that was NULL, just nothing. And then it just started deleting tons of different files on my server.

I run my script from C:\ and I obviously gave it to high rights. However, I find it really strange that when the $Path is Null, the script just finds files to remove. I've managed to fix this in my code, by checking first if the path to the file leads to something, however I want to learn what caused the script to crash this hard, and why the Get-ChildItem finds files when the $Path is a NULL file. I wonder if this could be some kind of bug in Powershell? (Most likely not.. but I wonder..)

Function Remove-WrongFileType {
    Param (
    [string]$Path
    )

$Files = Get-ChildItem -Path $Path -Force -Recurse

foreach($file in $Files) {
    if(-not (Assert-LegalFileType -File $file.FullName){
        Remove-Item -Path $file.Fullname -Force
        Add-ToLog -logString “File $file was removed because of illegal filetype”
        }
    }
}

Function Assert-LegalFileType {
    Param (
    [string]$File
    )

    if(Test-Path -Path $File -PathType Container){
        return $true
    }

    $fileToCheck = Get-Item -Path $File
    $ExtensionOfFile = $fileToCheck.Extension

    foreach($type in $AllowedFiles){
        if($ExtensionOfFile -match $type) {
            return $true
        }
    }
}




Solution

  • So I looked up what happens when you pass NULL to Get-childitem. And it is a known issue apparently. Get-ChildItem -Path $null does not throw an error #8708

    A comment describe the same issue:

    One of the side effects of this bug/feature could be to accidentally delete your system when you are using the output of this command piped to say a $_.Delete(). That is exactly what happened when I refactored my code to delete previous test runs; so From : Get-ChildItem -Path C:\SourceCodeTLM\testRunResults-Include * -File -Recurse | foreach { $.Delete() } To: $testRunResults= "C:\SourceCodeTLM\testRunResults" Get-ChildItem -Path $testRunResults-Include * -File -Recurse | foreach { $.Delete() } and forgot to initialize the variable while doing a debug. In the worst case, I expected an error but instead, the cmd ran and started deleting my current dir content (Which by default was PS C:\windows\system32>). Before I could understand what happened and pressed ctrl+c; enough files were deleted to corrupt my system. I had to restore and all of my stuff on my machine was lost. I learned this lesson the hard way but maybe others don't have to :). May be giving an error (when null) or keeping this parameter (mandatory) would be better from a risk standpoint :).

    So yeah, don’t pass null to get-childitem and try to force delete the output with high privileges.