How to Analyze File Locks with Handle: Complete Guide Using ProcMon, PowerShell, and Real-World Cases

Last update: 19/09/2025
Author Isaac
  • Quickly identify processes locking files with Handle and confirm patterns with ProcMon.
  • Automate secure scripts: don't move files in use and manage MOTW with PowerShell.
  • Differentiates between file and SQL Server locks and diagnoses the latter with DMV/XEvents.

Analyze file locks with Handle in Windows

When Windows It gives you the typical message that "The process cannot access the file because it is being used by another process.", the real problem isn't the file, but who has it open. Quickly locating that culprit makes the difference between a stable system and a chain of production failures. This is where Handle, Process Monitor, and some Tricks with PowerShell they shine.

In this guide we put together pieces that are rarely explained together: how to hunt File locks with Handle, how to confirm them with Process Monitor (ProcMon), how to avoid moving files in use from scripts, how to unlock the "Mark of the Web" with PowerShell and, in addition, how to recognize that there are different locks at the file level. SQL Server and diagnose their causes with DMV and Extended Events. We close with tools to debug crashes in apps web using DevTools Crash Analyzer.

What is a file lock in Windows and why does it happen?

A file lock occurs when a process holds a open handle on a file, preventing another process from modifying or deleting it. The typical symptom is an access-denied exception, especially in services that manipulate files rapidly or concurrently.

A real-life example: On a Windows Server 2022 server, a custom service failed with the error "Cannot open file XXX". After instrumenting the machine with ProcMon, it was observed that just before the crash, MsSense.exe (Microsoft Defender for Endpoint) I was accessing the file. Requesting an exclusion from Microsoft resolved the block. The bottom line: sometimes the source is an EDR/antivirus that inspects critical paths.

Other common cases: output folders of tools such as HandBrake, where you want to move newly generated files; if they are touched prematurely, the script fails. For these scenarios, it's a good idea to detect whether the file is still in use and wait for the process to release its handles. The important thing: Do not attempt to act on files while they are open.

Using Sysinternals Handle to view processes that lock files

Quickly locate the process locking a file with Handle (Sysinternals)

Handle is a Sysinternals utility that lists the file handles opened by processesIt's lightweight and straightforward, ideal when the error is intermittent and you need to confirm who's blocking a specific route.

Recommended steps with Handle (line of commands): download the Sysinternals suite (or just Handle), run the console as administrator and use filters based on file or folder names. If the blockage disappears quickly, it's a good idea to run the command in a loop (or schedule it) so you don't miss the critical moment.

Useful commands (orientative syntax): use «handle.exe -a path\to\file» to see who is holding that resource; if you prefer to search by folder, filter partially by name; to identify specific PIDs, cross-reference with the Task Manager. With user options and detail you can fine-tune results, and if you locate the exact process (for example, MsSense.exe), you can decide whether to apply an exclusion or change the workflow.

If the lock is not captured in time, combine Handle with scheduled scripts: runs every X seconds and dumps the output to a log. Sometimes the crash is very brief; recording the moment and the process involved is all you need to escalate the issue to the responsible team or adjust an EDR configuration.

ProcMon, Resource Monitor and EDR Actual Pattern

Process Monitor provides an in-depth view of file system events (creation, read, write) with filters by route and processSet up a filter for the suspicious folder and record until you reproduce the problem; you'll see which binary hits the file, in what order, and with what result.

  What are PowerShell cmdlets and how to master them?

In the mentioned case, ProcMon showed that MsSense.exe was accessing just before the crash. Although there was a GPO exclusion, it did not cover the specific flow. The solution was to request a exclusion at the tenant level in Defender for Endpoint. Lesson: Exclusions must be applied at the correct point and cover the exact path or pattern.

As a quick alternative, Resource Monitor (resmon.exe) allows you to search for open handles by file name. This is useful if the file is still locked; if it disappears quickly, ProcMon or Handle with periodic sampling gives better results. Keep performance in mind: ProcMon can generate large volume; use strict filters and stop capturing after playing back the event.

When services are restarted due to a crash, automate evidence collection: a script that activates Handle/ProcMon Upon system events (e.g. service error detection) it will give you the name of the offending process without manual intervention.

Automate your workflow: Move files without touching them when they're in use

Suppose you have an output folder of HandBrake and a script that, every minute, moves the files to their final destination. You don't want to touch files that are still being written. There are several safe strategies:

  • Check with Handle If there is a process with the file open; if there are active handles, the move is postponed. You can parse the output of "handle.exe" and act accordingly.
  • Try to open the file with a Filestream in exclusive mode (no sharing); if it fails, it is in use and you should try again later.
  • Check that the size stops growing for a reasonable interval; useful for transcoding streams.
  • Detect that the producing process (HandBrake) no longer has active threads on that route, combining WMI and handler queries.

Practical tips: add a exponential backoff during retries to avoid disk congestion; it marks files "in transit" (for example, by renaming them with a temporary extension) to avoid race conditions with other services; and it logs each decision (which files were skipped because they were in use) for later diagnostics.

If you need extra robustness, use a FileSystemWatcher that triggers checks upon completion of changes, but remember that “Changed” can be triggered multiple times; the stable size/released handle criterion is still key to getting the timing right.

Unlock files and manage MOTW with PowerShell

Unlock Mark of the Web with PowerShell

When downloads Internet files, Windows may mark the file with Mark of the Web (MOTW). It's not a process crash, but it can prevent processes from running or opening normally. PowerShell fixes this with a single cmdlet.

For a specific file: Run PowerShell as administrator and use Unblock-File -Path «C:\path\file». It's immediate and useful when you trust the source. For folders with many files, apply Get-ChildItem «C:\path» | Unblock-File and, if you need to, filter by extension with -Filter.

Security recommendation: Unlock only what you have certainty of originFirst, run it through an antivirus program. In corporate environments, it's a good idea to automate unblocking in trusted repositories and maintain audit logs.

SQL Server Deadlocks: Concepts, Diagnosis, and Resolution

Database locks are not the same as file locks, but they often produce similar symptoms: you expect them to paralyze the workIn SQL Server, locking is part of the engine for ensuring consistency under concurrency. The problem arises when it persists.

In SQL Server, each connection is a session identified by session_id (SPID). The same application can open multiple sessions, and one can block another. The duration of the block depends on the query, the transaction, and the isolation levelSELECT statements lock just enough for reading unless you're in a transaction; DML operations (INSERT/UPDATE/DELETE) hold locks for the duration of the query (and potentially the transaction).

When there is a serious impact, it is usually due to: 1) a session that retains resources for a long time and eventually releases them (degrades performance for the duration), or 2) a session that never releases (it's left open in a transaction or trapped by application logic). In the first case, the snapshot changes quickly; in the second, the state is more stable and easier to isolate.

  Phantom RAM usage due to closed apps in Windows 11: Complete guide

Recommended working method

The system is clear: 1) identify the root blocker, 2) locates the query/transaction causing it, 3) understands the reason (plan/waits/open transaction), and 4) redesigns query and transaction. To capture evidence: DMVs (Dynamic Management Views/Functions) and Extended Events (XEvents) are your allies.

Essential DMVs for diagnosis

  • sys.dm_exec_sessions y sys.dm_exec_requests: relate them to see who blocks whom by column blocking_session_id. Observe the status (running, executable, suspended, waiting), There waiting, and the last type of waiting.
  • sys.dm_exec_input_buffer: shows you the last instruction sent by a session (for example, SELECT * FROM sys.dm_exec_input_buffer(66,0) for session_id 66).
  • sys.dm_os_waiting_tasks: explains what wait_type is an active request.
  • sys.dm_tran_locks: Lists the held locks; combine with waiting_tasks to see only what is currently waiting.
  • sys.dm_tran_active_transactions y sys.dm_tran_session_transactions: contextualize open transactions (start, status, duration), useful for hunting orphan transactions.

In addition to ad-hoc queries, SSMS incorporates reports: on the server, Reports > Standard Reports > Activity: All blocking transactions, as well as the Activity monitor with the "Blocked By" column. For extended scans, capture periodic DMV results (PSSDiag/DiagManager are referenced in support).

Interpreting waiting and resource

The spine wait_type indicates what the request is waiting for; wait_time helps you see if it progresses or jumps to another wait; and wait_resource tells you the specific resource (table, page, row, key). For example, TAB: dbid:object_id:index_id for table-level locks or RID for a specific row. Cross hobt_id with sys.partitions helps you locate an index or table.

When open_transaction_count is greater than zero in the session or request, there are transactions in play and therefore locks that may persist beyond a specific statement. Also check reads, cpu_time, memory_usage in the session to distinguish whether a long query is alive or whether the SPID is waiting for client commands.

Extended Events and Blocking

To see the exact sequence of commands, create an XEvents session in SSMS. You're interested in events from the error/warning category, such as blocked_process_report, "attention" and "error_reported". Adjusts the process blocked threshold with sp_configure (in seconds) to have reports issued when a wait exceeds the threshold.

Typical blocking scenarios in SQL Server

  • Normal query taking a long time and holding locks: optimize the plan, uses Query Store to detect suboptimal plans and, if necessary, offloads that OLTP workload to a reporting environment or read-only replication.
  • SPID suspended with unconfirmed transaction After a timeout or cancellation: the batch ends, but the transaction remains open; check error control and use SET XACT_ABORT ON to self-revert upon errors.
  • Client who does not consume all rows from a SELECT statement: Locks are held until the result set is read to the end; adjust your application to flush the cursor or paginate properly.
  • Client/Server Distributed Deadlock: SQL Server cannot resolve it if the blockage is at the application layer (see examples A and B below).
  • Session in state ROLL BACK: after canceling/deleting outside of the user's transaction or deadlock victim; you must wait for it to complete (with ADR in SQL 2019, the impact is reduced).
  • Orphaned connection: the client dies and leaves open transactions; improves exception handling, considers XACT_ABORT and, if applicable, KILL of the SPID.

Distributed deadlocks at the application layer

Example A (a single thread on the client with two connections): The thread processes results from dbproc1 while SPID1 is blocked on a resource on SPID2; dbproc2 waits for the only thread that is busy, and the loop exits. SQL Server can't resolve this because it owns only one of the resources.

  How do I set up Google Translate to work with my microphone? Improving its performance

Example B (one thread per connection): dbproc2 (SELECT) produces rows and passes them to dbproc1, which attempts an INSERT/UPDATE/DELETE, but that SPID is blocked by the first. Again, a deadlock develops between the application layer and the database. Solution: reasonable waiting times, disciplined consumption of results and coordination between threads.

When blocking is security: MOTW, warnings and best practices

In addition to blocking by process, Windows may stop the opening of downloaded files with the warning security by origin. Identify it from the file's Properties ("Unlock" box) or with PowerShell. Remember: not everything you download needs to be unlocked; if you have any questions, scan with antivirus before.

For large batches, automate with PowerShell and log what is unlocked and when. If your pipeline downloads artifacts from trusted sources, integrate the Unblock-File in the post-download stage and applies compensating controls (signatures, hashes, etc.).

Diagnosing crashes and failures in web applications with DevTools Crash Analyzer

In the web world, "blocking" is often a front-end crash. Microsoft Edge includes the "Crash Analyzer" tool in DevTools to deminify and understand production stack traces. Key: annotate the trace with «Source Modules» (Script URLs and byte-by-byte SHA-256 hash of content.)

How to prepare your app: install the library @microsoft/edge-devtools-crash-analyzer-support and invokes installErrorStackModuleAnnotations(Error) to attach the "Source modules" section to the exceptions. This way, DevTools will retrieve the source maps adequate.

Make source maps accessible to DevTools. Ideally, publish them to the server of Symbols from Azure Artifacts for on-demand retrieval. If you use the //# sourceMappingURL= comment, DevTools may cache them for future sessions. Note that localhost is not cached, so the flow works best with real production traces.

To open the tool: start DevTools, use the menu Quick View or Command Menu (Ctrl/Cmd+Shift+P), search for "Crash Analyzer" and paste the trace with "Source Modules". You'll see original file names and functions, upload the source code to the Sources tab and copy the full deminified stack if you need to.

Good practices to reduce recurring crashes

  • On servers with EDR/Defender, it applies precise exclusions to work routes and validate their effectiveness on the correct map (GPO vs. EDR tenant). Be sure to monitor before and after with ProcMon to confirm.
  • In file orchestration scripts, don't force competition: detect active handles or stable size, use backoff and mark files in transit. Avoid operating during peak hours if volume is high.
  • In SQL Server, shorten Transactions, lower the insulation level when appropriate, consume all customer rows, handle cancellations/errors, and trigger XACT_ABORT where needed. Query Store and XEvents should be part of everyday operations.
  • In web applications, it instruments the capture of traces with source modules and publish source maps safely. This will shorten the diagnostic window.

With a combined approach—Handle to hunt down processes with open files, ProcMon to trace the system, PowerShell to automate and unlock MOTW, and SQL Server and DevTools for database and front-end locks—it is possible Isolate causes, reduce downtime, and prevent recurrences in Windows and mixed environments.