{"id":98,"date":"2026-07-09T09:00:00","date_gmt":"2026-07-09T09:00:00","guid":{"rendered":"https:\/\/backendside.com\/blog\/2026\/07\/09\/map-processes-open-connections-windows-server\/"},"modified":"2026-07-09T09:00:00","modified_gmt":"2026-07-09T09:00:00","slug":"map-processes-open-connections-windows-server","status":"publish","type":"post","link":"https:\/\/backendside.com\/blog\/2026\/07\/09\/map-processes-open-connections-windows-server\/","title":{"rendered":"Which Process Owns That Port? Mapping Connections to Processes on a Windows Server"},"content":{"rendered":"<p class=\"lead\">You run a quick scan and there it is: something is listening on port 8443, or an outbound connection keeps reaching a remote address you do not recognise. The port is easy to see. The hard question is always the same one &mdash; <em>which process opened it?<\/em> On Windows, every socket is owned by a process, and every process has a PID. Mapping a connection back to that PID, and then to a real executable on disk, is the core skill behind server monitoring, incident response and network debugging. This guide walks through every reliable way to do it.<\/p>\n<h2>The one number that ties it all together: the PID<\/h2>\n<p>A TCP or UDP endpoint on Windows is never anonymous. The kernel records the <strong>owning process ID (PID)<\/strong> for every connection and every listening socket. So the job is really two lookups:<\/p>\n<ol>\n<li><strong>Port &rarr; PID<\/strong> &mdash; find which process ID owns the port or connection.<\/li>\n<li><strong>PID &rarr; process<\/strong> &mdash; turn that number into a name and, ideally, a full path on disk so you know exactly what is running.<\/li>\n<\/ol>\n<p>Do both and the mystery is solved. Let us do it manually first, so you understand what is happening, and then with a tool that collapses both steps into one live view.<\/p>\n<h2>Step 1 &mdash; Map the port to a PID with <code>netstat<\/code><\/h2>\n<p>The classic tool is <code>netstat<\/code>. The flags that matter are <code>-a<\/code> (all connections and listening ports), <code>-n<\/code> (numeric &mdash; do not resolve names, which is much faster), and crucially <code>-o<\/code> (show the owning PID). Open an <strong>Administrator<\/strong> command prompt or PowerShell and run:<\/p>\n<pre style=\"background:#1e1d1b;color:#eceae6;padding:1rem 1.15rem;border-radius:8px;overflow-x:auto;font-size:.85rem;line-height:1.5;\"><code>netstat -ano<\/code><\/pre>\n<p>Every row ends with a PID in the last column. A typical listening line looks like this:<\/p>\n<pre style=\"background:#1e1d1b;color:#eceae6;padding:1rem 1.15rem;border-radius:8px;overflow-x:auto;font-size:.85rem;line-height:1.5;\"><code>  Proto  Local Address        Foreign Address      State        PID\n  TCP    0.0.0.0:8443         0.0.0.0:0            LISTENING    5240\n  TCP    10.0.0.12:52210      93.184.216.34:443    ESTABLISHED  7864<\/code><\/pre>\n<p>Now narrow it to the port you care about. On Windows, <code>findstr<\/code> is the filter of choice:<\/p>\n<pre style=\"background:#1e1d1b;color:#eceae6;padding:1rem 1.15rem;border-radius:8px;overflow-x:auto;font-size:.85rem;line-height:1.5;\"><code>netstat -ano | findstr :8443\nnetstat -ano | findstr LISTENING\nnetstat -ano | findstr ESTABLISHED<\/code><\/pre>\n<p>The first line shows only rows touching port 8443; the others let you see just the listeners, or just the live established sessions. In the example above, port 8443 is owned by <strong>PID 5240<\/strong>. That is half the puzzle.<\/p>\n<h2>Step 2 &mdash; Turn the PID into a process name with <code>tasklist<\/code><\/h2>\n<p>A bare number is not much use, so map it to a process. <code>tasklist<\/code> with a PID filter does exactly that:<\/p>\n<pre style=\"background:#1e1d1b;color:#eceae6;padding:1rem 1.15rem;border-radius:8px;overflow-x:auto;font-size:.85rem;line-height:1.5;\"><code>tasklist \/FI \"PID eq 5240\"<\/code><\/pre>\n<pre style=\"background:#1e1d1b;color:#eceae6;padding:1rem 1.15rem;border-radius:8px;overflow-x:auto;font-size:.85rem;line-height:1.5;\"><code>Image Name          PID  Session Name    Session#   Mem Usage\n=================== ==== =============== ========== ============\njava.exe           5240  Services              0     412,880 K<\/code><\/pre>\n<p>If the PID turns out to be a <code>svchost.exe<\/code> &mdash; the shared host for Windows services &mdash; the name alone will not tell you which service is responsible. Add <code>\/svc<\/code> to expand it:<\/p>\n<pre style=\"background:#1e1d1b;color:#eceae6;padding:1rem 1.15rem;border-radius:8px;overflow-x:auto;font-size:.85rem;line-height:1.5;\"><code>tasklist \/svc \/FI \"PID eq 5240\"<\/code><\/pre>\n<p>That lists every service hosted inside the PID, so you can tell whether it is the DNS Client, the Web Deploy agent, or something you did not expect.<\/p>\n<h2>The one-shot shortcut: <code>netstat -anob<\/code><\/h2>\n<p>You can skip the two-step dance and ask <code>netstat<\/code> to print the owning executable directly with the <code>-b<\/code> flag:<\/p>\n<pre style=\"background:#1e1d1b;color:#eceae6;padding:1rem 1.15rem;border-radius:8px;overflow-x:auto;font-size:.85rem;line-height:1.5;\"><code>netstat -anob<\/code><\/pre>\n<p>This shows the process name (and sometimes the component that requested the connection) under each row. It is handy, but it comes with two real costs: it <strong>requires Administrator rights<\/strong>, and it is noticeably <strong>slow<\/strong> &mdash; enumerating the executable for every socket can take many seconds on a busy server, and the output is verbose and awkward to scan. It is a good spot-check, not something you want to run in a tight loop.<\/p>\n<h2>The PowerShell way &mdash; and why it is nicer<\/h2>\n<p>On any modern Windows Server, PowerShell gives you the same mapping as structured objects you can filter and sort. <code>Get-NetTCPConnection<\/code> already includes the <code>OwningProcess<\/code> (the PID), so you can go straight from a port to the process in a single pipeline:<\/p>\n<pre style=\"background:#1e1d1b;color:#eceae6;padding:1rem 1.15rem;border-radius:8px;overflow-x:auto;font-size:.85rem;line-height:1.5;\"><code># Which process is listening on port 8443?\nGet-Process -Id (Get-NetTCPConnection -LocalPort 8443 -State Listen).OwningProcess<\/code><\/pre>\n<p>That prints the process name, and because it is a real process object you also get the path via <code>.Path<\/code>. To see the connection and its owner side by side, join the two yourself:<\/p>\n<pre style=\"background:#1e1d1b;color:#eceae6;padding:1rem 1.15rem;border-radius:8px;overflow-x:auto;font-size:.85rem;line-height:1.5;\"><code>Get-NetTCPConnection -State Listen |\n  Select-Object LocalAddress, LocalPort, State, OwningProcess,\n    @{Name='Process'; Expression={ (Get-Process -Id $_.OwningProcess).Name }},\n    @{Name='Path';    Expression={ (Get-Process -Id $_.OwningProcess).Path }} |\n  Sort-Object LocalPort | Format-Table -AutoSize<\/code><\/pre>\n<p>UDP listeners work the same way through <code>Get-NetUDPEndpoint<\/code>. This is far more pleasant than parsing <code>netstat<\/code> text, and it is scriptable &mdash; but you are still hand-writing calculated properties every time, and each snapshot is frozen the instant it runs.<\/p>\n<h2>Where the manual approach starts to hurt<\/h2>\n<p>These commands all work, and every Windows admin should know them. But on a live server the friction adds up:<\/p>\n<ul>\n<li><strong>It is a static snapshot.<\/strong> <code>netstat<\/code> and <code>Get-NetTCPConnection<\/code> capture one instant. A connection that flickers open for half a second between two runs is simply invisible.<\/li>\n<li><strong>Port &rarr; PID &rarr; name &rarr; path is three joins.<\/strong> You are constantly copying a PID from one command into the filter of the next, and the fast options rarely give you the full executable path &mdash; the single most useful field for deciding whether something is legitimate.<\/li>\n<li><strong><code>-b<\/code> is slow and needs admin.<\/strong> The one command that shows the executable is the one you least want to run repeatedly.<\/li>\n<li><strong>Acting on a finding is a separate job.<\/strong> Once you have identified a rogue connection, blocking it means switching to <code>netsh advfirewall<\/code> or the Firewall MMC and re-typing the IP, port and protocol by hand.<\/li>\n<\/ul>\n<p>For a one-off &#8220;who has port 8443?&#8221; the command line is perfect. For actually watching a server &mdash; catching short-lived connections, seeing the full path at a glance, and blocking something the moment you spot it &mdash; you want a live view.<\/p>\n<div style=\"border:1px solid #c5d3f8;background:linear-gradient(135deg,#eef2fd 0%,#ffffff 72%);border-radius:14px;padding:1.5rem 1.65rem;margin:2rem 0;\">\n<div style=\"font-size:.7rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#2d5be3;margin-bottom:.55rem;\">&#128295; BackendSide Tool<\/div>\n<h4 style=\"margin:0 0 .45rem;font-size:1.15rem;color:#1a1916;font-weight:700;\">Process &amp; Port Analyzer &mdash; See the Owning Process for Every Connection<\/h4>\n<p style=\"margin:0 0 1.05rem;color:#3d3c38;font-size:.92rem;line-height:1.65;\"><strong>Process &amp; Port Analyzer<\/strong> is a free Windows utility that lists every active TCP\/UDP connection and listening port alongside its <strong>PID, process name and full executable path<\/strong> &mdash; live, refreshing in real time, with no manual PID-to-name lookup. Right-click any suspicious connection to block it with a one-click firewall rule. Native Windows APIs only, no Npcap or third-party drivers.<\/p>\n<p>  <a href=\"https:\/\/backendside.com\/processandportanalyzer.php\" style=\"display:inline-flex;align-items:center;gap:.4rem;background:#2d5be3;color:#ffffff;font-weight:600;font-size:.85rem;padding:.6rem 1.2rem;border-radius:6px;text-decoration:none;\">Explore Process &amp; Port Analyzer &rarr;<\/a>\n<\/div>\n<h2>The faster way: a live process-to-port map<\/h2>\n<p><strong>Process &amp; Port Analyzer<\/strong> does both lookups for you, continuously. Instead of running three commands and joining their output in your head, you open one window and read the answer straight off the row.<\/p>\n<h3>Every connection already carries its owner<\/h3>\n<p>The <strong>Active TCP\/UDP Connections<\/strong> view lists each connection with its protocol, local IP and port, remote IP and port, connection state (ESTABLISHED, TIME_WAIT, and so on), <em>and<\/em> the owning PID, process name and full executable path &mdash; all on the same line, refreshing in real time. There is no second lookup: the port and the process that opened it are already together.<\/p>\n<h3>Listening ports, sorted and named<\/h3>\n<p>The <strong>Listening Ports<\/strong> view shows every TCP and UDP socket in a listening state with its owning PID, process name and full file path, so &#8220;what is accepting inbound connections on this box?&#8221; is answered the moment the window opens. Click the port column to sort &mdash; numeric columns sort as integers, not text, so port 80 does not end up next to port 8000.<\/p>\n<h3>From &#8220;what is this?&#8221; to &#8220;block it&#8221; in one right-click<\/h3>\n<p>When a connection looks wrong, you do not need to leave the app. Right-click it and choose <em>Block this connection<\/em>: the built-in Windows Firewall rule creator opens pre-filled with that connection&#8217;s IP, port and protocol, and a block rule is in place in seconds. The same manual investigation that took three commands and a trip to the firewall console becomes point, read, right-click.<\/p>\n<h3>Drill into a process<\/h3>\n<p>Suspicious PID? The <strong>Running Processes<\/strong> view lists every process with its PID, name and full path, and a double-click opens a module view showing every DLL and file that process has loaded &mdash; useful when a legitimate-looking host process is doing something it should not.<\/p>\n<h2>Manual commands vs. Process &amp; Port Analyzer<\/h2>\n<table style=\"width:100%;border-collapse:collapse;margin:1rem 0;font-size:.9rem;\">\n<thead>\n<tr style=\"background:#f2f1ef;\">\n<th style=\"text-align:left;padding:.6rem .8rem;border:1px solid #e4e2de;\">Task<\/th>\n<th style=\"text-align:left;padding:.6rem .8rem;border:1px solid #e4e2de;\">Manual (netstat \/ PowerShell)<\/th>\n<th style=\"text-align:left;padding:.6rem .8rem;border:1px solid #e4e2de;\">Process &amp; Port Analyzer<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">Port &rarr; PID<\/td>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\"><code>netstat -ano | findstr :PORT<\/code><\/td>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">&#9989; Shown on every row<\/td>\n<\/tr>\n<tr>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">PID &rarr; process name<\/td>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">Second command: <code>tasklist \/FI<\/code><\/td>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">&#9989; Same row, no lookup<\/td>\n<\/tr>\n<tr>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">Full executable path<\/td>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">&#9888;&#65039; <code>-b<\/code> (slow, admin) or PowerShell <code>.Path<\/code><\/td>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">&#9989; Always shown<\/td>\n<\/tr>\n<tr>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">Live \/ continuous view<\/td>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">&#10060; Static snapshot per run<\/td>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">&#9989; Real-time refresh<\/td>\n<\/tr>\n<tr>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">Catch short-lived connections<\/td>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">&#10060; Easy to miss between runs<\/td>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">&#9989; Appear as they happen<\/td>\n<\/tr>\n<tr>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">Block a bad connection<\/td>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\"><code>netsh advfirewall<\/code> \/ MMC, re-typed by hand<\/td>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">&#9989; Right-click &rarr; pre-filled block rule<\/td>\n<\/tr>\n<tr>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">Cost<\/td>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">Built in<\/td>\n<td style=\"padding:.6rem .8rem;border:1px solid #e4e2de;\">Free on the Microsoft Store<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>A practical workflow<\/h2>\n<ol>\n<li><strong>Spot the port.<\/strong> Something is listening on 8443, or an outbound session keeps reappearing.<\/li>\n<li><strong>Find the owner.<\/strong> Quick check from the shell: <code>netstat -ano | findstr :8443<\/code>, then <code>tasklist \/FI \"PID eq &lt;pid&gt;\"<\/code>. Or open Process &amp; Port Analyzer and read the PID, name and path off the row directly.<\/li>\n<li><strong>Judge it.<\/strong> Is the full executable path where you would expect it &mdash; a service in <code>C:Program Files...<\/code>, or something loading out of a temp directory? The path is what tells you.<\/li>\n<li><strong>Act.<\/strong> If it is legitimate, you are done. If it is not, right-click the connection and block it, then investigate the process and its loaded modules.<\/li>\n<\/ol>\n<h2>Key takeaways<\/h2>\n<ul>\n<li>Every Windows connection and listening port is owned by a <strong>PID<\/strong> &mdash; mapping a port to a process is really two lookups: <strong>port &rarr; PID<\/strong> and <strong>PID &rarr; process<\/strong>.<\/li>\n<li><code>netstat -ano<\/code> gives you the PID; <code>netstat -ano | findstr :PORT<\/code> narrows it to a port; <code>tasklist \/FI \"PID eq N\"<\/code> (add <code>\/svc<\/code> for <code>svchost<\/code>) names it.<\/li>\n<li><code>netstat -anob<\/code> shows the executable in one shot but needs admin and is slow; PowerShell&#8217;s <code>Get-NetTCPConnection<\/code> + <code>Get-Process<\/code> is cleaner and scriptable.<\/li>\n<li>The manual commands are perfect for a one-off, but they are static snapshots that miss short-lived connections and rarely show the full path in one step.<\/li>\n<li><strong>Process &amp; Port Analyzer<\/strong> shows the PID, process name and full path on every connection and listening port in a live view &mdash; and lets you block a suspicious connection with a single right-click. It is free on the Microsoft Store.<\/li>\n<\/ul>\n<p>Learn the commands &mdash; they are the foundation, and they are always there when you SSH into a box with nothing installed. But for the everyday job of watching what your Windows server is really talking to, a live process-to-port map turns a three-command investigation into a glance.<\/p>\n<div style=\"border:1px solid #c5d3f8;background:linear-gradient(135deg,#eef2fd 0%,#ffffff 72%);border-radius:14px;padding:1.5rem 1.65rem;margin:2rem 0;\">\n<div style=\"font-size:.7rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#2d5be3;margin-bottom:.55rem;\">&#128295; BackendSide Tool<\/div>\n<h4 style=\"margin:0 0 .45rem;font-size:1.15rem;color:#1a1916;font-weight:700;\">Process &amp; Port Analyzer &mdash; See the Owning Process for Every Connection<\/h4>\n<p style=\"margin:0 0 1.05rem;color:#3d3c38;font-size:.92rem;line-height:1.65;\"><strong>Process &amp; Port Analyzer<\/strong> is a free Windows utility that lists every active TCP\/UDP connection and listening port alongside its <strong>PID, process name and full executable path<\/strong> &mdash; live, refreshing in real time, with no manual PID-to-name lookup. Right-click any suspicious connection to block it with a one-click firewall rule. Native Windows APIs only, no Npcap or third-party drivers.<\/p>\n<p>  <a href=\"https:\/\/backendside.com\/processandportanalyzer.php\" style=\"display:inline-flex;align-items:center;gap:.4rem;background:#2d5be3;color:#ffffff;font-weight:600;font-size:.85rem;padding:.6rem 1.2rem;border-radius:6px;text-decoration:none;\">Explore Process &amp; Port Analyzer &rarr;<\/a>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>An open port with no obvious owner is every admin&#8217;s least favourite mystery. Here is how to map any TCP\/UDP connection or listening port back to the exact process that created it on Windows \u2014 first the manual way with netstat, tasklist and PowerShell, then a faster live view with Process &#038; Port Analyzer.<\/p>\n","protected":false},"author":1,"featured_media":99,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,2],"tags":[],"class_list":["post-98","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-networking","category-windows"],"_links":{"self":[{"href":"https:\/\/backendside.com\/blog\/wp-json\/wp\/v2\/posts\/98","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/backendside.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/backendside.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/backendside.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/backendside.com\/blog\/wp-json\/wp\/v2\/comments?post=98"}],"version-history":[{"count":0,"href":"https:\/\/backendside.com\/blog\/wp-json\/wp\/v2\/posts\/98\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/backendside.com\/blog\/wp-json\/wp\/v2\/media\/99"}],"wp:attachment":[{"href":"https:\/\/backendside.com\/blog\/wp-json\/wp\/v2\/media?parent=98"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/backendside.com\/blog\/wp-json\/wp\/v2\/categories?post=98"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/backendside.com\/blog\/wp-json\/wp\/v2\/tags?post=98"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}