1

I have a script in which Some of the files get deleted...

VERBOSE: Performing the operation "Remove Directory" on target \name1\subitem

VERBOSE: Performing the operation "Remove Directory" on target \name1\subitem1

VERBOSE: Performing the operation "Remove Directory" on target \name1\subitem2

but others throw this error following the other verbose messages:

Cannot remove item d:\temp\name1.db\metadata.sqlitedb: The process cannot access the file 'metadata.sqlitedb' because it is being used by another process.

Directory d:\temp\name1.db cannot be removed because it is not empty.

How can i automatically kill the process used (whichever it is) and attempt to remove the item again as part of my script above?

i tried handle suggestion from this thread PowerShell script to check an application that's locking a file?, but i think our servers dont allow external tools as i either dont get any output or getting access denied...so im looking for some other option that doesnt require external tool

Essentially looking for something like this as part of my script:

$Directory = "d:\temp"
Invoke-Command -Computer $Server -ScriptBlock { 
    param ($dir, $name)

#Write-Output "dir='$dir', name='$name'"

$f = Get-ChildItem -Path $dir | Where {$_.Name -Match $name} | Select -ExpandProperty FullName
if ($f) {
    $f | Foreach {
                try
            {
                Remove-Item $_ -confirm:$false -recurse -Verbose #-WhatIf
            }
            catch
            {
                if ($_.Exception.Message -like '*it is being used by another process*')
                { write-host "that process is " $pid + $pname
                    try{
                        KILL PROCESS
                        Remove-Item $_ -confirm:$false -recurse -Verbose #-WhatIf
                    }
                    catch
                    {
                        $error[0]
                    }

                }
                else
                {
                    Write-Host "$($error[0])`r`n" -foregroundcolor magenta -backgroundcolor black
                }
            }
    }
}
else {
    Write-Verbose "No file found"
}
} -ArgumentList $Directory, $DB -verbose
Cataster
  • 3,081
  • 5
  • 32
  • 79
  • If there was a built in way to do it, why would anyone be recommending handle.exe? – TessellatingHeckler Apr 05 '19 at 17:03
  • @TessellatingHeckler damn :/ what if i just want to kill the associated process...do i do it like this? Stop-Process -path $_ -Name "metadata.sqlitedb" -Force – Cataster Apr 05 '19 at 17:08
  • From my research, essentially, the only "real" way to get the PID of a file in use is to use a tool like [Handle](https://learn.microsoft.com/en-us/sysinternals/downloads/handle). There is no "easy" way, script-wize to do it, unless you are willing to delve into the belly of Windows NT NTDLL.DLL API's and uglyness to get a "pure" script solution. Unfortunately you can't use `Stop-Process` with the `-Path` like that, you have to stop the sqlite process. e.g 'Stop-Process sqlite'. – HAL9256 Apr 05 '19 at 17:52
  • Is it always a sqlite database that you are having the issue? i.e. are you having this issue: [How do I unlock a SQLite database](https://stackoverflow.com/questions/151026/how-do-i-unlock-a-sqlite-database) – HAL9256 Apr 05 '19 at 17:53
  • @HAL9256 is that the same as 'metadata.sqlitedb? – Cataster Apr 05 '19 at 18:25
  • @HAL9256 so i guess i would have to stop the process remotely with another nested invoke-command like this right? Invoke-Command -Computer $Server -ScriptBlock { Stop-Process -Name "sqlitedb" -Force } -Verbose – Cataster Apr 05 '19 at 18:30
  • 1
    @Cataster Correct. – HAL9256 Apr 05 '19 at 18:43

0 Answers0