To state what is perhaps obvious explicitly:
Forcefully terminating other processes with Stop-Process
should generally be a last resort,
especially with the -Force
switch, given that that will terminate other users' processes as well (should others be logged on to the same machine, possibly remotely), without warning - provided you're running in an elevated session (running as administrator), as only then do you have the necessary permissions.
If you're willing to assume this risk, and the assumption is that the only processes preventing your directory subtree from getting removed are those run from executables or DLLs located inside the target subtree, you can try:
while (Test-Path $destinationApplicationFolder) {
try {
Remove-Item -Recurse -Force $destinationApplicationFolder -ErrorAction Stop
}
catch {
Get-Process |
Where-Object { $_.Modules.FileName -like "$destinationApplicationFolder\*" } |
Stop-Process -ErrorAction Stop -WhatIf
}
}
Note: The -WhatIf
common parameter in the command above previews the operation. Remove -WhatIf
once you're sure the operation will do what you want.
Note:
There may also be processes from executables located elsewhere that still block removal, if they have open handles to files and directories in the target directory subtree.
To also identify these, you have two options:
Use openfiles.exe /Query
openfiles.exe
comes with Windows, but requires running openfiles /Local ON
with elevation as a one-time setup action, after which a reboot is required.
Sample call:
openfiles /query /FO csv | findstr.exe /L /c:$(Convert-Path someFile.txt)
Use the download-on-demand handle.exe
SysInternals utility, which, once downloaded, requires no prior setup (add -nobanner
(every time) to hide the copyright message; add -accepteula
(at least once on a given machine) to accept the license).
Remove-Item -Recurse
can generally fail in versions earlier than Windows 10 20H2 even if there are no processes blocking a directory's removal (and if there are no permission issues): Incredibly, the file/folder removal WinAPI functions are inherently asynchronous, which can cause intermittent, unpredictable failures - see this answer.