Search code examples
windowspowershellpowershell-2.0powershell-3.0powershell-remoting

service is stopped but still not able to run copy-item


I have verified that the service is in stopped status.

I have also verified that no process is being used by the file E:\folder\file.exe using below cmdlets which is returning blank output.

$lockedFile='E:\folder\file.exe'
Get-Process | foreach{$processVar = $_;$_.Modules | foreach{if($_.FileName -eq $lockedFile){$processVar.Name + " PID:" + $processVar.id}}}

However, I am still not able to run the below cmdlet:

copy-item e:\newfolder\file.exe e:\folder

The above cmdlet is generating below error:

The process cannot access the file 'E:\folder\file.exe' because it is being used by another process.
+ CategoryInfo          : NotSpecified: (:) [Copy-Item], IOException
+ FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.CopyItemCommand

Solution

  • You are trying to copy a file from a folder to the exact same folder, and that's just not going to work. Define a different folder as the destination.

    As for closing file locks, I don't think Get-Process is what you really need to close handles on a locked file. For that I have always resorted to SysInternal's Handle.exe. I even wrote a short script to handle closing processes that have a file locked to keep on hand:

    Function Close-LockedFile{
    Param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)][Object[]]$InputFile
    )
    Begin{
        $HandleApp = 'C:\localbin\Handle.exe'
        If(!(Test-Path $HandleApp)){Write-Host "Handle.exe not found at $HandleApp`nPlease download it from www.sysinternals.com and save it in the afore mentioned location.";break}
    }
    Process{
        $HandleOut = Invoke-Expression ($HandleApp+' '+$InputFile.Fullname)
        $Locks = $HandleOut |?{$_ -match "(.+?)\s+pid: (\d+?)\s+type: File\s+(\w+?): (.+)\s*$"}|%{
            [PSCustomObject]@{
                'AppName' = $Matches[1]
                'PID' = $Matches[2]
                'FileHandle' = $Matches[3]
                'FilePath' = $Matches[4]
            }
        }
        ForEach($Lock in $Locks){
            Invoke-Expression ($HandleApp + " -p " + $Lock.PID + " -c " + $Lock.FileHandle + " -y") | Out-Null
        }
        $InputFile
    }
    }
    

    You can pipe file objects to that to close any locks on a whole list of files if needed. Such as:

    Get-ChildItem e:\newfolder | Close-LockedFile | Copy-Item -Dest e:\newdest
    

    That would close any locks on any files in the e:\newfolder folder, and then copy them to the e:\newdest folder.