Subscaper
Subscaper

Reputation: 252

Use Remove-Item in PowerShell

I know there are a lot of similar questions, but i still didn't found an answer.

I try to Remove a Folder with some Scripts inside.

Folder is in : C:\Public\Folder

Inside the Folder are 7 Scripts.

The Script CopyFiles.ps1, copies 4 of them to a different Location.

After the Copy, it Removes the Folder itself with all the other Files.

Script looks like this :

[string] $Path = "";
[string] $Destination = "";

# Copy the Folder
[string] $Destination = "C:\ProgramData\Path\To\Folder";
[string] $Path = "C:\Public\Folder";

Copy-Item -Path $Path -Destination $Destination

#Copy Files
[string[]] $Files = ("CreateUser.ps1", "RemoveFiles.ps1", "RemoveUser.ps1", "UpdateUser.ps1");

foreach($file in $Files)
{
    $Script = $Path + "\" + $file
    write-host $Script
    Copy-Item -Path $Script -Destination $Destination
}


[string] $Path = "C:\Public";

Remove-Item -Path $Path -Include *UserManager* -Recurse -Force

So far this Script worked like a charm. But today not. Im getting following Error Message :

Remove-Item : Cannot remove the item at 'C:\Public' because it is in use. At C:\Public\Folder\CopyFiles.ps1:24 char:1

Which also make totally sense, since its in use, it cannot get deletetd. But why did it work till now?

Upvotes: 0

Views: 794

Answers (1)

codewario
codewario

Reputation: 21418

You need to Set-Location (cd) outside of the folder you are trying to delete. A shell will have an open handle on a folder if that folder is its present working directory.

You don't necessarily need to Set-Location from the script (though you could), just don't invoke the script with C:\Public\Folder set as the working directory.

In the case you are not in that folder, you will have to determine what process is locking the folder. I have never done this programmatically, but the tool I generally use for this is LockHunter. If you have Chocolatey, you can easily install it with:

choco install lockhunter

Additional Reading

I have not attempted this yet, but curiosity finally got the best of me on this topic and I found a Hey, Scripting Guy! article about using P/Invoke to call the necessary Win32 API functions which can tell you which process is locking a file. You may find this useful to read. From the article, it looks like the key Win32 API functions in scope are:

  • NtQuerySystemInformation: Amongst other things, can query the handles open on the system.

  • NtQueryObject: Queries additional information about a handle.

  • OpenProcess: Allows us to get more information about the process that owns the handle.

  • DuplicateHandle: Creates a copy of a handle in the current process (for example, ISE) so we can perform additional operations on it.

  • QueryDosDevice: Converts a logical drive (such as drive C) into the DOS device identifier.

Upvotes: 3

Related Questions