{"id":43,"date":"2026-10-22T22:57:23","date_gmt":"2026-10-22T20:57:23","guid":{"rendered":"https:\/\/wp-opsec.eagleeye-intelligence.com\/?page_id=43"},"modified":"2026-10-25T06:50:07","modified_gmt":"2026-10-25T05:50:07","slug":"windows-installation","status":"publish","type":"page","link":"https:\/\/wp-opsec.eagleeye-intelligence.com\/?page_id=43","title":{"rendered":"Windows Installation"},"content":{"rendered":"\n<style>\n.thessley-downloads{--td-ink:#f2f6fc;--td-muted:#cad5e3;--td-blue:#1976b5;--td-line:#40516a;color:var(--td-ink);font-family:inherit;background:#0c1422;padding:clamp(1rem,3vw,2rem);border-radius:18px;color-scheme:dark}\n.thessley-downloads *{box-sizing:border-box}\n.thessley-downloads .td-hero{padding:clamp(1.8rem,5vw,3.2rem);border-radius:22px;background:linear-gradient(128deg,#102b4d,#176b9e);color:#fff}\n.thessley-downloads .td-hero .td-kicker{margin:.1rem 0 .55rem;color:#b8e4f7;font-weight:800;letter-spacing:.12em;text-transform:uppercase}\n.thessley-downloads .td-hero p{max-width:65ch;color:#e4f0f7;line-height:1.65}\n.thessley-downloads section{margin:2.8rem 0}\n.thessley-downloads h2{font-size:clamp(1.55rem,3vw,2rem);color:#f5f8fc}\n.thessley-downloads h3{margin-top:1.8rem;color:#eef4fc}\n.thessley-downloads p,.thessley-downloads li{line-height:1.7;color:var(--td-muted)}\n.thessley-downloads a:not(.td-download){color:#9edaff;text-decoration:underline;text-underline-offset:.15em}\n.thessley-downloads a:not(.td-download):hover{color:#d1efff}\n.thessley-downloads .td-card{margin:1rem 0;padding:1.25rem 1.4rem;border:1px solid var(--td-line);border-radius:16px;background:#172235}\n.thessley-downloads .td-card h3{margin:.1rem 0 .4rem}\n.thessley-downloads .td-card p{margin:.45rem 0}\n.thessley-downloads .td-download{display:inline-block;margin:.45rem .7rem .25rem 0;padding:.7rem 1rem;border-radius:999px;background:#145a8d;color:#fff!important;font-weight:750;text-decoration:none}\n.thessley-downloads .td-download:hover{background:#0f456d}\n.thessley-downloads .td-warn{padding:1rem 1.2rem;border-left:4px solid #e3ad45;border-radius:0 10px 10px 0;background:#332a1b;color:#ffe6b2}\n.thessley-downloads pre{position:relative;overflow:auto;padding:3.1rem 1rem 1rem;border-radius:10px;background:#17243a;color:#f0f5f9;font-size:.9rem;line-height:1.55}\n.thessley-downloads pre code{display:block;min-width:max-content;white-space:pre;overflow-wrap:normal}\n.thessley-downloads .td-copy{position:absolute;top:.55rem;right:.6rem;display:inline-flex;align-items:center;gap:.4rem;padding:.4rem .6rem;border:1px solid #9ab2cc;border-radius:7px;background:#314966;color:#fff;font:inherit;font-size:.78rem;cursor:pointer}\n.thessley-downloads .td-copy:hover,.thessley-downloads .td-copy:focus-visible{background:#42658a;outline:2px solid #b4e6ff;outline-offset:2px}\n.thessley-downloads .td-copy svg{width:1rem;height:1rem;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}\n.thessley-downloads .td-copy-label{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n.thessley-downloads :not(pre)>code{padding:.1em .3em;border-radius:4px;background:#25354b;color:#f4f7fb}\n\n.thessley-downloads .td-hero h1{margin:.2rem 0 .7rem;color:#fff;font-size:clamp(2rem,5vw,3rem)}\n.thessley-downloads details{margin:1rem 0;padding:0 1rem 1rem;border:1px solid var(--td-line);border-radius:12px;background:#121e30}\n.thessley-downloads summary{padding:1rem 0;color:#f5f8fc;font-size:1.1rem;font-weight:750;cursor:pointer}\n.thessley-downloads details[open]>summary{border-bottom:1px solid var(--td-line)}\n<\/style>\n<main class=\"thessley-downloads alignwide\">\n  <section class=\"td-hero\">\n    <p class=\"td-kicker\">Thessley computer installation<\/p>\n    <h1>Windows 11 \u2014 install on this PC<\/h1>\n    <p>Use these steps at the Windows computer you are setting up. The install is local; it does not require sending an SSH key to another computer.<\/p>\n    <p><a href=\"?page_id=16\">All downloads<\/a> \u00b7 <a href=\"?page_id=42\">Ubuntu \/ Linux installation<\/a><\/p>\n  <\/section>\n\n  <section id=\"local-install\">\n    <h2>1. Install and verify Windows OpenSSH on this PC<\/h2>\n    <p>Open <strong>PowerShell as Administrator on this Windows PC<\/strong>, then run this block. Keep the window open while Windows installs the optional feature; it may take several minutes.<\/p>\n    <pre><code>$ErrorActionPreference = 'Stop'\n$cap = Get-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0\nif ($cap.State -ne 'Installed') {\n    Write-Host 'Installing OpenSSH Server. Keep this PowerShell window open.'\n    Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 | Out-Null\n}\n$cap = Get-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0\nif ($cap.State -ne 'Installed') { throw \"OpenSSH Server is not installed (state: $($cap.State)).\" }\n$service = Get-Service -Name sshd -ErrorAction SilentlyContinue\n$sshd = Join-Path $env:WINDIR 'System32\\OpenSSH\\sshd.exe'\nif (-not $service -or -not (Test-Path $sshd)) { throw 'OpenSSH is reported installed but sshd is missing. Stop and see the FAQ.' }\nSet-Service -Name sshd -StartupType Automatic\nStart-Service sshd\nGet-Service sshd\n$rule = Get-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -ErrorAction SilentlyContinue\nif ($rule) {\n    Set-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -Enabled True -RemoteAddress LocalSubnet\n} else {\n    New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 -RemoteAddress LocalSubnet\n}<\/code><button type=\"button\" class=\"td-copy\" aria-label=\"Copy command\">Copy command<\/button><\/pre>\n    <p>Success means the final command reports <code>Status: Running<\/code> and <code>StartType: Automatic<\/code>. This step installs OpenSSH only; the Thessley installer separately configures phone and web access.<\/p>\n  <\/section>\n\n  <details id=\"localhost-test\">\n    <summary>Optional: test SSH locally on this PC (no key transfer)<\/summary>\n    <p>This optional check creates a separate test key on this PC, adds its public half to this PC\u2019s Windows SSH administrator key file, and connects only to <code>localhost<\/code>. The private key stays in this Windows user\u2019s profile. Skip this if you do not need a localhost SSH test; it is not required to install Thessley.<\/p>\n    <p>Run in the same <strong>Administrator PowerShell on this PC<\/strong>:<\/p>\n    <pre><code>$ErrorActionPreference = 'Stop'\n$sshKeygen = Join-Path $env:WINDIR 'System32\\OpenSSH\\ssh-keygen.exe'\n$ssh = Join-Path $env:WINDIR 'System32\\OpenSSH\\ssh.exe'\nif (-not (Test-Path $sshKeygen) -or -not (Test-Path $ssh)) { throw 'OpenSSH client tools are missing.' }\n$sshDir = Join-Path $HOME '.ssh'\nNew-Item -ItemType Directory -Path $sshDir -Force | Out-Null\n$privateKey = Join-Path $sshDir 'thessley-localhost'\nif (-not (Test-Path -LiteralPath $privateKey)) {\n    &amp; $sshKeygen -t ed25519 -a 64 -f $privateKey -C 'thessley-localhost'\n    if ($LASTEXITCODE -ne 0) { throw 'Local test key generation failed.' }\n}\n$publicKey = (Get-Content -Raw -LiteralPath \"${privateKey}.pub\").Trim()\n$authorizedKeys = Join-Path $env:ProgramData 'ssh\\administrators_authorized_keys'\n$sshConfigDir = Join-Path $env:ProgramData 'ssh'\nNew-Item -ItemType Directory -Path $sshConfigDir -Force | Out-Null\nif (-not (Test-Path -LiteralPath $authorizedKeys)) { New-Item -ItemType File -Path $authorizedKeys -Force | Out-Null }\nif ($publicKey -notin @(Get-Content -LiteralPath $authorizedKeys)) { Add-Content -LiteralPath $authorizedKeys -Value $publicKey -Encoding ascii }\nicacls.exe $authorizedKeys \/inheritance:r \/grant '*S-1-5-32-544:F' \/grant '*S-1-5-18:F'\nif ($LASTEXITCODE -ne 0) { throw 'Could not set the local SSH key file permissions.' }\n&amp; $ssh -i $privateKey \"$env:USERNAME@localhost\" exit\nif ($LASTEXITCODE -ne 0) { throw 'The local SSH key login failed.' }\nWrite-Host 'Local SSH key login succeeded; the remote session exited cleanly.'<\/code><button type=\"button\" class=\"td-copy\" aria-label=\"Copy command\">Copy command<\/button><\/pre>\n    <p>Accept the host fingerprint for <code>localhost<\/code>. The test logs in, runs <code>exit<\/code> remotely, and returns to PowerShell automatically. The test key is not used by any remote computer.<\/p>\n  <\/details>\n\n  <section id=\"install-thessley\">\n    <h2>2. Install Thessley on this PC<\/h2>\n    <p>Still in Administrator PowerShell on the Windows PC, run the guided installer:<\/p>\n    <pre><code>irm https:\/\/wp-opsec.eagleeye-intelligence.com\/wp-content\/uploads\/thessley-windows-downloads\/install.ps1 | iex<\/code><button type=\"button\" class=\"td-copy\" aria-label=\"Copy command\">Copy command<\/button><\/pre>\n    <p>Follow its prompts for the phone approval listener, optional web admin, firewall source networks, and SSH account policy. If your administrator account needs its first phone, the installer prints a one-time enrollment link and code. Open that link on the phone; no SSH key is involved in phone enrollment.<\/p>\n    <p><strong>Automatic SSH recovery:<\/strong> before enabling SSH QR access, the installer saves the original SSH configuration and verifies a 30-minute recovery timer. The optional Windows QR sign-in tile creates its own timer when installed. Both appear under <strong>Admin \u2192 Setup rollback<\/strong>, labelled by the login method they protect.<\/p>\n    <p>Keep the current SSH session open and test a new SSH login. If you installed the Windows sign-in tile, test that too while keeping PIN\/password recovery available. Once every enabled login method works, choose <strong>Keep setup and stop rollback<\/strong> in Admin and approve on your phone. The page verifies cancellation. If you leave SSH recovery active, expiry restores the original SSH configuration; your enrolled phones are retained.<\/p>\n    <p>After those tests succeed, this administrator PowerShell command is an alternative way to keep the setup:<\/p>\n    <pre><code>powershell.exe -NoProfile -ExecutionPolicy Bypass -File \"$env:ProgramData\\ThessleyPamWin\\confirm-setup.ps1\"<\/code><button type=\"button\" class=\"td-copy\" aria-label=\"Copy command\">Copy command<\/button><\/pre>\n    <p>The installer enables verified automatic updates for Sundays at 03:00 local time. Admin \u2192 Settings can turn the schedule off. Updates verify the package hash and use the installer\u2019s rollback path; SSH policy and firewall rules are preserved.<\/p>\n    <p>There is no installer clock check. Signed phone-approval requests have a freshness check, so keep the Windows and phone clocks synchronized; their time-zone settings may differ.<\/p>\n  <\/section>\n\n  <section id=\"after-install\">\n    <h2>3. Finish setup and test<\/h2>\n    <p>Open the local Admin page shown by the installer, enroll the phone, then manage QR approval for Windows SSH accounts under <strong>Admin \u2192 Users<\/strong>. Test a new SSH login while keeping the local console available. The optional localhost test above is separate from remote SSH clients.<\/p>\n    <p>For issues installing the Windows optional feature, see the <a href=\"https:\/\/learn.microsoft.com\/en-us\/windows-server\/administration\/openssh\/openssh_install_firstuse?pivots=windows-11\">Microsoft OpenSSH Server guide<\/a>. Do not remove or reinstall OpenSSH while an installation command is still running.<\/p>\n  <\/section>\n\n  <section id=\"other-platforms\">\n    <h2>Other operating systems and downloads<\/h2>\n    <div class=\"td-card\"><h3>Ubuntu \/ Linux<\/h3><p>Install Thessley PAM on an Ubuntu or Linux computer.<\/p><a class=\"td-download\" href=\"?page_id=42\">Open Linux installation<\/a><\/div>\n    <div class=\"td-card\"><h3>All Thessley downloads<\/h3><p>Windows helper apps, Android app, Linux packages, and checksums.<\/p><a class=\"td-download\" href=\"?page_id=16\">Browse downloads<\/a><\/div>\n  <\/section>\n<\/main>\n<script>\n(() => {\n  document.querySelectorAll('.thessley-downloads .td-copy').forEach((button) => {\n    button.addEventListener('click', async () => {\n      const code = button.closest('pre').querySelector('code');\n      const text = code.innerText.replace(\/\\n$\/, '');\n      try {\n        if (navigator.clipboard && window.isSecureContext) {\n          await navigator.clipboard.writeText(text);\n        } else {\n          const range = document.createRange();\n          range.selectNodeContents(code);\n          const selection = window.getSelection();\n          selection.removeAllRanges();\n          selection.addRange(range);\n          if (!document.execCommand('copy')) throw new Error('Copy failed');\n          selection.removeAllRanges();\n        }\n        button.textContent = 'Copied';\n        window.setTimeout(() => { button.textContent = 'Copy command'; }, 1600);\n      } catch (_) {\n        button.textContent = 'Select and copy';\n      }\n    });\n  });\n})();\n<\/script>\n\n","protected":false},"excerpt":{"rendered":"<p>Guided one-line installer and alternative setup instructions.<\/p>\n","protected":false},"author":0,"featured_media":0,"parent":16,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-43","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/wp-opsec.eagleeye-intelligence.com\/index.php?rest_route=\/wp\/v2\/pages\/43","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wp-opsec.eagleeye-intelligence.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/wp-opsec.eagleeye-intelligence.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"replies":[{"embeddable":true,"href":"https:\/\/wp-opsec.eagleeye-intelligence.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=43"}],"version-history":[{"count":31,"href":"https:\/\/wp-opsec.eagleeye-intelligence.com\/index.php?rest_route=\/wp\/v2\/pages\/43\/revisions"}],"predecessor-version":[{"id":104,"href":"https:\/\/wp-opsec.eagleeye-intelligence.com\/index.php?rest_route=\/wp\/v2\/pages\/43\/revisions\/104"}],"up":[{"embeddable":true,"href":"https:\/\/wp-opsec.eagleeye-intelligence.com\/index.php?rest_route=\/wp\/v2\/pages\/16"}],"wp:attachment":[{"href":"https:\/\/wp-opsec.eagleeye-intelligence.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=43"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}