Remove-Item -Force on NULL Filewatcher 文件删除了我服务器上的 1000 个文件,这是 Powershell 错误吗?或者只是我的错误代码?
Remove-Item -Force on NULL Filewatcher file removed 1000 files on my server, is this a Powershell bug? Or just my bad code?
因此,我正在使用类似于此的 FileSystemWatcher 开发一个脚本:https://powershell.one/tricks/filesystem/filesystemwatcher
我只使用 Created 事件。
然后我 运行 在“已创建”的文件上使用以下代码。
当我 运行 将这段代码放在一个已被另一段代码删除的文件上时,我遇到了一个非常意外的错误。所以基本上,“Remove-WrongFileType”函数收到了一个 NULL 文件,什么都没有。然后它就开始删除我服务器上的大量不同文件。
我 运行 我的脚本来自 C:\ 并且我显然将它赋予了高权限。但是,我发现当 $Path 为 Null 时,脚本只是查找要删除的文件,这确实让人感到震惊运行。我已经设法在我的代码中解决了这个问题,方法是首先检查文件的路径是否导致某些东西,但是我想了解是什么导致脚本崩溃,以及为什么 Get-ChildItem 在 $Path 时找到文件是一个 NULL 文件。我想知道这是否可能是 Powershell 中的某种错误? (很可能不是..但我想知道..)
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
}
}
}
所以我查看了将 NULL 传递给 Get-childitem 时会发生什么。这显然是一个已知问题。 Get-ChildItem -Path $null does not throw an error #8708
评论描述了相同的问题:
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 :).
所以,是的,不要将 null 传递给 get-childitem 并尝试强制删除具有高权限的输出。
因此,我正在使用类似于此的 FileSystemWatcher 开发一个脚本:https://powershell.one/tricks/filesystem/filesystemwatcher
我只使用 Created 事件。
然后我 运行 在“已创建”的文件上使用以下代码。
当我 运行 将这段代码放在一个已被另一段代码删除的文件上时,我遇到了一个非常意外的错误。所以基本上,“Remove-WrongFileType”函数收到了一个 NULL 文件,什么都没有。然后它就开始删除我服务器上的大量不同文件。
我 运行 我的脚本来自 C:\ 并且我显然将它赋予了高权限。但是,我发现当 $Path 为 Null 时,脚本只是查找要删除的文件,这确实让人感到震惊运行。我已经设法在我的代码中解决了这个问题,方法是首先检查文件的路径是否导致某些东西,但是我想了解是什么导致脚本崩溃,以及为什么 Get-ChildItem 在 $Path 时找到文件是一个 NULL 文件。我想知道这是否可能是 Powershell 中的某种错误? (很可能不是..但我想知道..)
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
}
}
}
所以我查看了将 NULL 传递给 Get-childitem 时会发生什么。这显然是一个已知问题。 Get-ChildItem -Path $null does not throw an error #8708
评论描述了相同的问题:
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 :).
所以,是的,不要将 null 传递给 get-childitem 并尝试强制删除具有高权限的输出。