Delete complete folder using a PowerShell script - powershell

I am using the following expression to delete a folder from PowerShell. I need to delete a complete folder (including all the files and sub folders).
Remove-Item -Recurse -Force $DesFolder
But this gives me the exception "The directory is not empty"
I am not getting this exception every time when I run the program; it happens randomly. What would be the reason for this and how do I fix this? Because I was failing to reproduce this.

We cannot delete an non-empty directory using commands like rmdir or Remove-Item, this is to avoid accidental deletion of important system files by users during programming.
Therefore before trying to delete the directory, empty it. Clear the contents and then delete it. :)

Remove-Item -Recurse always deletes the directory and all its contents recursively. But it may still fail if directory is modified (i.e. new files are created) by some third-party activity in middle of remove process.
Also, if some of the files cannot be deleted (e.g. due to permission restrictions) Remove-Item will also fail.
So, I'd recommend you to check what exactly is laying inside the directory after exception.

Related

In PowerShell, how to tell if a directory "delete" op will succeed?

I'm writing a PowerShell script that will, if possible, delete an occasional extraneous directory if a subtask (over which I have no control, apart from invoking it) fails to properly delete it.
The catch is that the directory (which has a lot of files and recursive hierarchy) may or may not be in use by another (large, 3rd party) program. Normally, I'm doing this in Windows Explorer: I hit the "delete" key, I get a "in use" dialog, shrug and move on, no harm done. (It's a big process and it usually cleans up after itself.)
What I don't want to do is call Remove-Item -Recursive and have it purge half a directory and then discover that some random file is in use. Nor am I even sure it's a file-in-use issue; maybe it's because the directory (or a subdirectory) is some process's current directory or, for some reason, the directory (or subdirectory) itself is open (I'm just making stuff up at this point), or some entirely different and mysterious cause.
I'm hoping to duplicate the current manual process.
Can anyone point me in the right direction? Basicaly, I'm looking for Remove-Directory-If-You-Can-But-Don't-Do-Anything-At-All-If-You-Can't.
(Edit)
Note that I don't want to remove anything in the directory if the directory is still "in use", in some sense. That will corrupt the large process using the directory. If the large process has finished and moved on, I can delete the directory.
(Edit)
This? https://github.com/pldmgg/misc-powershell/blob/master/MyFunctions/PowerShellCore_Compatible/Get-FileLockProcess.ps1
Called recursively? (Not sure if it'll work for subdirs, but I can experiment.)
Could try moving the items away somewhere safe first, and restore items that were successfully moved if anything goes wrong.
If you move things to a folder in the path for temp files, you don't have to delete them - the system will delete them sometime after your process releases the handle on the new folder.
Simple case:
$tempRoot = Split-Path (New-TemporaryFile).FullName
$tempDir = New-Item "$tempRoot\$(New-Guid)" -Type Directory
Move-Item "$HOME\Downloads\SomeFolder\" $tempDir
If anything is holding a file handle in the folder being moved, it will fail and the move won't occur.
Deleting several files and folders:
$tempRoot = Split-Path (New-TemporaryFile).FullName
$tempDir = New-Item "$tempRoot\$(New-Guid)" -Type Directory
try {
Move-Item "$HOME\Downloads\*" $tempDir.FullName -ErrorAction Stop
Remove-Variable tempDir
} catch {
Move-Item "$($tempDir.FullName)\*" "$HOME\Downloads"
}
Move-Item will move whole folders as given above, so no need for recursion.
The move operation should be quick, assuming the files/folders you're moving are on the same drive as the temp folder. The files themselves don't have to be physically moved on disk. The OS just modifies an entry in a table. Moving an entire folder only requires one update (not one for each file within it).
If the above doesn't satisfy your needs, maybe check out this article: How to Manage Open File Handles with PowerShell.

What is the use of -recurse in powershell?

Sorry it's probably a dumb question: what is the difference between
Remove-Item -recurse -Force -Verbose and Remove-Item -Force -Verbose
it seems if we use -recurse for a folder and subfolders powershell delete file one by one inside the folder. and if we remove the -recurse powershell simply delete the main folder without checking inside the folder. technically isn't script will run faster without -recurse?
tl;dr
Pass both -Recurse and -Force to Remove-Item in order to (more) predictably delete (remove) a given folder, which - barring any permission and timing problems - deletes the folder and any contents it may have.
Caveat: This instantly deletes any contents inside the target folder, and, given that deleted items are not placed in the operating system's recycle bin, can only be recovered, potentially, with specialty software.
it seems if we use -recurse for a folder and subfolders powershell delete file one by one inside the folder.
More accurately, it deletes the target folder's subtree, i.e. it recursively deletes all files and subfolders located in the target folder, including their files and subfolders, recursively, before deleting the target folder itself. In effect, it deletes the target folder and all of its contents, if any, but note the caveats:
re "protected" items, which additionally require -Force, discussed below.
re intermittent failures due to the file-system APIs being asynchronous in older Windows versions, discussed in the bottom section.
In fact, deleting all the contents of a folder before deleting the folder itself is the only way to delete a nonempty folder, technically: the file-system APIs do not offer deletion of a nonempty folder as a single operation.
Because inadvertently deleting an entire subfolder tree can have disastrous consequences, as a safety mechanism PowerShell requires you to signal the intent to delete a nonempty folder explicitly - by passing -Recurse.
If you neglect to pass -Recurse and the target folder is nonempty, you get an interactive confirmation prompt - irrespective of whether -Force is specified or not. Choose [A] Yes to All (type a) to delete the folder and all its contents - but see the situational additional need for -Force below.
That said, you do also need -Force in order to (more) predictably remove a nonempty target folder, because -Force makes PowerShell also delete "protected" files and folders, which are hidden files and folders and files that have the ReadOnly and/or System attributes set (on Windows).
If you neglect to pass -Force when you use -Recurse or interactively choose [A] Yes to All in response to the confirmation prompt, the presence of at least one protected item will prevent removal of the target folder as a whole, though unprotected items inside the subtree will get deleted right away.
Each protected item will cause a non-terminating error to be emitted, concluded by a non-terminating error that the target folder cannot be removed, because it isn't empty (yet). Perhaps confusingly, in Windows PowerShell the per-protected-item error messages only talks about "[in]sufficient access rights", even though the real problem in this case isn't one of permissions; the error message has been amended in _PowerShell (Core) 7+ to explicitly mention hidden, system, and readonly items.
if we remove the -recurse powershell simply delete the main folder without checking inside the folder.
No: It follows from the above that you cannot delete a given nonempty folder unless you delete its contents first.
If you attempt that without -Recurse, you'll invariably get the confirmation prompt (or, in non-interactive scenarios, the call will fail outright).
technically isn't script will run faster without -recurse?
It also follows from the above that only an empty folder can be removed without -Recurse without triggering the confirmation prompt.
If you do also specify -Recurse when targeting an empty folder, hypothetically unnecessary work of testing whether child items exist could be performed. In practice, Remove-Item's implementation always performs this test, whether or not you pass -Recurse.
Even with both -Recurse and -Force specified, overall removal may fail:
... due to insufficient file-system permission held by the current user relative to the target folder and its contents.
... intermittently, due to running on Windows versions older than Windows 10 20H2 (I don't know that Windows Server version that corresponds to), because file-system item deletion there was inherently asynchronous(!), resulting in intermittent failure to fully delete a given target folder, namely if deletion of an item inside the folder hadn't completed yet by the time deletion of the folder itself was attempted: see this answer for details and a workaround.
when you use Remove-Item on a dir tree that holds files ... and do NOT use -Recurse, you will get the standard confirmation prompt. so using that parameter makes it run without the delay from the "do you really want to do this?" prompt.
this is one of the reasons that some folks prefer to pipe the output of Get-ChildItem -Recurse to Remove-Item.

PowerShell access denied for deleting file/folder

I have a script in PowerShell where I collect old log files, create a zip archive from each file, then delete the original file. Same script is doing folder compression and files compression separately.
While running my script, the files are getting compressed successfully, but when trying to delete the source file I get an access denied error. If I try and delete the file manually in Windows explorer, it gets deleted with no issues.
Most of the files are getting deleted successfully but just for some I get that error.
To delete I use the following command:
get-childitem -Path "mypath" | Remove-item
Tried using -Force and it's still the same.
How can I get around that "access denied" error?

Deleting an Empty Directory - Blocked by "It is being used by another process"

I've successfully moved the contents out of a directory into another directory and now I'm attempting to clean up the folder. Upon attempting to delete the folder via Powershell I'm receiving an error "The process cannot access the file because it is being used by another process" even though the folder is now empty. I have the following syntax:
Remove-Item -Recurse -Force pathtodirhere
How can I get around this?

Copy-Item script creating files on google drive that I cannot delete

I am trying to create a new folder on google drive and append the date and hour to the end of it to create a rolling 1 hour backup with old versions still accessible. I am not knowledgeable enough about PowerShell in order to automatically delete folders over 7 days old so I have to do it manually. The problem seems to be when PowerShell creates the new folders and copies the files, I no longer have access to delete them. I have checked permissions and added Everyone, Administrators, and the current user (the only user and admin) and it still will not allow me to delete the folders that PowerShell creates. I can delete files I manually put into Google drive. Here is my code:
$yest = (Get-Date).AddDays(-1).ToString(‘hhMMddyy’)
mkdir "C:\Users\admin\Google Drive\SpaceEngineersDedicated.$yest" -Force
Copy-Item C:\Users\admin\AppData\Roaming\SpaceEngineersDedicated -Destination "C:\Users\admin\Google Drive\SpaceEngineersDedicated.$yest" -Recurse -Force
If someone could help me with code that will just delete folders over 7 days, I would appreciate it but worst case scenario I'm fine with occasionally cleaning them up manually.