我正在尝试编写一个PowerShell
脚本,用于检查特定文件夹中的任何文件是否都被任何进程锁定;如果为true,则仅删除该文件夹。
一种方法是通过迭代地以RW模式打开它们来检查每个文件上的锁定 - 查看是否发生异常。但那太麻烦了。
有没有办法检查文件夹的相同内容?我尝试将Remove-Item
与-WhatIf
标志一起使用,但它没有用,因为该命令不返回任何值 - 也没有检测到锁定的文件。如果我尝试在没有标志的情况下运行Remove-Item
来查找异常,那么它只删除空闲文件,而我想要一个All或None条件。
答案 0 :(得分:2)
只要您不打算发布解决方案,就可以使用handle.exe。它显示正在使用的所有文件/文件夹以及谁正在使用它。
$path = "C:\Users\frode\Desktop\Test folder"
(.\handle64.exe /accepteula $path /nobanner) -match 'File'
explorer.exe pid: 1888 type: File F3C: C:\Users\frode\Desktop\Test folder
explorer.exe pid: 1888 type: File 2E54: C:\Users\frode\Desktop\Test folder
notepad.exe pid: 2788 type: File 38: C:\Users\frode\Desktop\Test folder
WINWORD.EXE pid: 2780 type: File 40: C:\Users\frode\Desktop\Test folder
WINWORD.EXE pid: 2780 type: File 6FC: C:\Users\frode\Desktop\Test folder\New Microsoft Word-dokument.docx
如果您只想要一个是/否答案,您可以使用if-test和-match
查看是否返回任何结果。
if((.\handle64.exe /accepteula $path /nobanner) -match 'File') { "IN USE, ABORT MISSION!" }
通常即使explorer.exe
正在浏览文件夹,您也可以删除文件夹,因此您通常可以从结果中排除该过程:
if((.\handle64.exe /accepteula $path /nobanner) -match 'File' -notmatch 'explorer.exe') { "IN USE, ABORT MISSION!" }
答案 1 :(得分:2)
如果您不想安装句柄,您可以查看给定目录或子目录中正在运行的进程。
$lockedFolder="C:\Windows\System32"
Get-Process | % {
$processVar = $_
$_.Modules | %{
if($_.FileName -like "$lockedFolder*"){
$processVar.Name + " PID:" + $processVar.id + " FullName: " + $_.FileName
}
}
}
答案 2 :(得分:0)
这不是一个完整的解决方案,而是一个可以构建的起点。
我有一个名为" demo.txt"的txt文件。在:" E:\ Work \ Powershell \ scripts \ demo"。我正在使用Notepad.exe打开它。在这种情况下,我将无法删除文件夹" demo",直到我关闭记事本。
如果记事本正在使用该文件,则必须查询" Win32_process" 类才能理解。
Get-WmiObject win32_process | where {$_.name -eq 'notepad.exe'}
在上述cmdlet的输出中," CommandLine" 属性将显示该进程当前正在使用的文件。
您可能需要对此进行迭代才能找到问题的完整解决方案。
某些流程,例如 - " chrome.exe"将在" CommandLine"下面有一个巨大的列表。由于chrome或iExplorer不会阻止您在打开文件时删除该文件夹,因此您可以忽略这些进程。
注意:" FileName"在"(Get-Process)。模块",只为您提供了可以找到的路径" notepad.exe" (即E:\ Work \ Powershell \ scripts \ demo)
答案 3 :(得分:0)
或者您也可以尝试在$ path上重命名项目,如果失败,它就会被锁定。尝试一下{抓住{在那里},您可能会看到下面的内容。漂亮又简单
#check for locking handle
Function Check-LockedItem {
param([string]$path)
$name = Split-Path "$path" -leaf
$pathorg = Split-Path "$path" -Parent
try {Rename-Item -Path "$path" -NewName "$name--" -ErrorAction Stop}
catch {write-host "A process is locking $path. Please close the process and try again"}
Finally {Rename-Item -path "$pathorg\$name--" -NewName $name -ErrorAction SilentlyContinue}
}
用法
Check-LockedItem -Path "C:\Mypathtotest"