Moving and Deleting Really Locked Files in PowerShell

Once in awhile, you need to do brain surgery on files locked by the system. This is a common problem run into by patches and hotfixes, so Windows has a special mechanism that lets it move files before any process has the chance to get its grubby little hands on it. This can only be done during a reboot, leading to the dire warning given to you by many installers.

The Win32 API that enables this is MoveFileEx. Calling this API with the MOVEFILE_DELAY_UNTIL_REBOOT flag tells Windows to move (or delete) your file at the next boot.

Here’s how to do it from PowerShell:

 

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024

function Move-LockedFile
{
    param($path, $destination)

    $path = (Resolve-Path $path).Path
    $destination = $executionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($destination)

    $MOVEFILE_DELAY_UNTIL_REBOOT = 0x00000004

    $memberDefinition = @’
    [DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
    public static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName,
       int dwFlags);
‘@

    $type = Add-Type -Name MoveFileUtils -MemberDefinition $memberDefinition -PassThru
    $type::MoveFileEx($path, $destination, $MOVEFILE_DELAY_UNTIL_REBOOT)
}

[C:\Windows\system32\config\txr]
PS:181 > dir -force | % { Move-LockedFile $_.Name (Join-Path c:\temp\txr ($_.Name + ".Bak")) }

[C:\Users\leeholm]
PS:182 > dir -Filter "NTUser.DAT{*" -force | % { Move-LockedFile $_.Name (Join-Path c:\temp\txr ($_.Name + ".Bak")) }

3 Responses to “Moving and Deleting Really Locked Files in PowerShell”

  1. Joel "Jaykul" Bennett writes:

    Awesome! I love it. This is the kid of script that we really needed Add-Type for :) … can we have it on PoshCode?

    One point to mention: to DELETE a locked file, you have to put $null in for the destination.

  2. Lee Holmes writes:

    Definitiely — feel free to put it up on PoshCode.

    Lee

  3. Freeman writes:

    Awesome script, thanks :)

    When i put $null in the destination the file would not be delete.
    The RegKey “PendingFileRenameOperations” is not created.

    Any idea?

    Thanks
    Freeman

Leave a Reply