Command/Environment/GetLockingProcess.ps1
Import-Module CmxModule -Force -DisableNameChecking function GetLockingProcessList { <# .SYNOPSIS Gets the process list which locks the given file. #> [cmdletbinding()] Param ( [Parameter(Position = 0, Mandatory = $true, HelpMessage = "Path to the file to check.")] [ValidateNotNullorEmpty()] [string]$Path, [Parameter(Position = 1, Mandatory = $true, HelpMessage = "Path to the sysinternals [handle.exe].")] [ValidateNotNullorEmpty()] [string]$HandleExe ) [regex]$expression = "^(?<Name>.+)\s+" + "pid:\s+(?<PID>\d+)\s+" + "type:\s+(?<Type>\w+)\s+" + "(?<User>.+)\s+" + "\w+:\s+" + "(?<Path>.*)$" # https://docs.microsoft.com/en-us/sysinternals/downloads/handle $lines = & "$HandleExe" -u -a -nobanner "$Path" $lines = $lines | Where-Object { $_.ToString().Length -gt 0 } $lines | Foreach-Object { $matchList = $expression.Matches($_) if($matchList.Count) { $match = $matchList[0] $groups = $match.groups [PsCustomObject]@{ Text = $match.ToString() Name = $groups["Name"].Value.Trim() ProcessId = $groups["PID"].Value.Trim() Type = $groups["Type"].Value.Trim() User = $groups["User"].Value.Trim() Path = $groups["Path"].Value.Trim() } } } } SetWindowTitle $MyInvocation.MyCommand.Name Write-Output "Gets the process which locks a file via sysinternals handle tool." $filePath = Read-Host "Enter the file path" if(-not $filePath) { $filePath = $BinariesFolder + "\Release\x64" } Write-Output "Path: $filePath" $handleExe = $CmxRootFolder + "\Internals\Handle\handle.exe" if(-not(Test-Path $handleExe)) { Write-Output "The path to the handle tool [$handleExe] does not exist." Read-Host "The script has finished. Press any key to exit" exit 1 } Write-Output "Get locking process list . . ." [array]$processList = GetLockingProcessList -Path $filePath -HandleExe $handleExe Write-Output "Get locking process list has finished" if($processList.Count) { Write-Output "Found locking processes" $uniquePids = $processList | Foreach-Object { $_.ProcessId } | Get-Unique -AsString [array]$processes = Get-Process -PID $uniquePids -ErrorAction Ignore $processes | Format-Table ProcessName, Id $answer = Read-Host "Do you like to stop the processes (Y|N)" if($answer -eq "Y") { Stop-Process -InputObject $processes -Force $processes = Get-Process -PID $uniquePids -ErrorAction Ignore $stillRunningProcesses = $processes | Where-Object { $_.HasExited -eq $false } $count = $stillRunningProcesses.Count if($count -gt 0) { Write-Output "Not all instances were stopped." } else { Write-Output "Instances were successfully stopped." } } } Read-Host "The script has finished. Press any key to exit" exit 0 |