ssh-handler 1.0.6__tar.gz → 1.0.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. {ssh_handler-1.0.6/ssh_handler.egg-info → ssh_handler-1.0.7}/PKG-INFO +9 -5
  2. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/README.md +8 -4
  3. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/pyproject.toml +2 -2
  4. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/ssh_handler/__init__.py +1 -1
  5. ssh_handler-1.0.7/ssh_handler/openssh/OpenSSH-ARM64.zip +0 -0
  6. ssh_handler-1.0.7/ssh_handler/openssh/OpenSSH-Win32.zip +0 -0
  7. ssh_handler-1.0.7/ssh_handler/openssh/OpenSSH-Win64.zip +0 -0
  8. ssh_handler-1.0.7/ssh_handler/setup_openssh_server.ps1 +170 -0
  9. {ssh_handler-1.0.6 → ssh_handler-1.0.7/ssh_handler.egg-info}/PKG-INFO +9 -5
  10. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/ssh_handler.egg-info/SOURCES.txt +3 -0
  11. ssh_handler-1.0.6/ssh_handler/setup_openssh_server.ps1 +0 -150
  12. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/LICENSE +0 -0
  13. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/setup.cfg +0 -0
  14. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/ssh_handler/__main__.py +0 -0
  15. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/ssh_handler/cli.py +0 -0
  16. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/ssh_handler/config.py +0 -0
  17. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/ssh_handler/core.py +0 -0
  18. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/ssh_handler/credentials.py +0 -0
  19. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/ssh_handler/exceptions.py +0 -0
  20. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/ssh_handler/ftp.py +0 -0
  21. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/ssh_handler/pool.py +0 -0
  22. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/ssh_handler/pyqt_worker.py +0 -0
  23. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/ssh_handler/results.py +0 -0
  24. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/ssh_handler/winrm_bootstrap.py +0 -0
  25. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/ssh_handler.egg-info/dependency_links.txt +0 -0
  26. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/ssh_handler.egg-info/entry_points.txt +0 -0
  27. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/ssh_handler.egg-info/requires.txt +0 -0
  28. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/ssh_handler.egg-info/top_level.txt +0 -0
  29. {ssh_handler-1.0.6 → ssh_handler-1.0.7}/tests/test_offline.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ssh-handler
3
- Version: 1.0.6
3
+ Version: 1.0.7
4
4
  Summary: Extensive SSH/SFTP/SCP/FTP handler built on Paramiko, for test automation, CLIs and PyQt5 tools.
5
5
  Author: ssh-handler contributors
6
6
  License-Expression: MIT
@@ -226,14 +226,18 @@ administrator** on the target. If SSH already works, this code path never runs.
226
226
 
227
227
  ### Set up OpenSSH Server on a machine (bundled installer)
228
228
 
229
- Installing the package also gives you a one-command setup for the *local* Windows
230
- machine it ships inside the wheel, self-elevates to Administrator, installs &
231
- starts OpenSSH Server, and opens the firewall:
229
+ Installing the package also gives you a one-command, **fully offline** setup for
230
+ the local Windows machine. The OpenSSH ZIPs (ARM64 / Win64 / Win32) ship *inside*
231
+ the wheel, so the installer needs **no internet and no Windows Update** — it picks
232
+ the ZIP matching the CPU architecture, self-elevates to Administrator, installs &
233
+ starts OpenSSH Server, and opens the firewall. (This avoids the
234
+ `Add-WindowsCapability` hang common on locked-down corporate networks.)
232
235
 
233
236
  ```powershell
234
237
  pip install ssh-handler
235
- ssh-handler-setup # install + start sshd + firewall (self-elevates)
238
+ ssh-handler-setup # offline install + start sshd + firewall (self-elevates)
236
239
  ssh-handler-setup --install-pip # also (re)install the package as admin
240
+ ssh-handler-setup --force # reinstall even if sshd already exists
237
241
  # equivalent: python -m ssh_handler setup-server
238
242
  ```
239
243
 
@@ -195,14 +195,18 @@ administrator** on the target. If SSH already works, this code path never runs.
195
195
 
196
196
  ### Set up OpenSSH Server on a machine (bundled installer)
197
197
 
198
- Installing the package also gives you a one-command setup for the *local* Windows
199
- machine it ships inside the wheel, self-elevates to Administrator, installs &
200
- starts OpenSSH Server, and opens the firewall:
198
+ Installing the package also gives you a one-command, **fully offline** setup for
199
+ the local Windows machine. The OpenSSH ZIPs (ARM64 / Win64 / Win32) ship *inside*
200
+ the wheel, so the installer needs **no internet and no Windows Update** — it picks
201
+ the ZIP matching the CPU architecture, self-elevates to Administrator, installs &
202
+ starts OpenSSH Server, and opens the firewall. (This avoids the
203
+ `Add-WindowsCapability` hang common on locked-down corporate networks.)
201
204
 
202
205
  ```powershell
203
206
  pip install ssh-handler
204
- ssh-handler-setup # install + start sshd + firewall (self-elevates)
207
+ ssh-handler-setup # offline install + start sshd + firewall (self-elevates)
205
208
  ssh-handler-setup --install-pip # also (re)install the package as admin
209
+ ssh-handler-setup --force # reinstall even if sshd already exists
206
210
  # equivalent: python -m ssh_handler setup-server
207
211
  ```
208
212
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ssh-handler"
7
- version = "1.0.6"
7
+ version = "1.0.7"
8
8
  description = "Extensive SSH/SFTP/SCP/FTP handler built on Paramiko, for test automation, CLIs and PyQt5 tools."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -38,4 +38,4 @@ ssh-handler-setup = "ssh_handler.cli:setup_server_main"
38
38
  packages = ["ssh_handler"]
39
39
 
40
40
  [tool.setuptools.package-data]
41
- ssh_handler = ["*.ps1"]
41
+ ssh_handler = ["*.ps1", "openssh/*.zip"]
@@ -22,7 +22,7 @@ dependencies (PyQt5 / scp) don't break the core package.
22
22
 
23
23
  from __future__ import annotations
24
24
 
25
- __version__ = "1.0.6"
25
+ __version__ = "1.0.7"
26
26
 
27
27
  from .config import SSHConfig, FTPConfig
28
28
  from .core import SSHHandler, ShellSession
@@ -0,0 +1,170 @@
1
+ <#
2
+ .SYNOPSIS
3
+ One-shot OpenSSH Server setup for a Windows machine, fully OFFLINE.
4
+ Installs from the OpenSSH ZIP bundled with the ssh-handler package
5
+ (chosen by CPU architecture), starts sshd, opens the firewall, and
6
+ optionally pip-installs the package. Self-elevates to Administrator.
7
+
8
+ .DESCRIPTION
9
+ No Windows Update / Features-on-Demand and no internet required - this
10
+ avoids the Add-WindowsCapability hang on locked-down corporate networks.
11
+ The matching ZIP (ARM64 / Win64 / Win32) ships inside the package under
12
+ .\openssh\ next to this script.
13
+
14
+ .PARAMETER InstallPip
15
+ Also run `pip install -U "ssh-handler[winrm]"` (needs Python+pip on PATH).
16
+
17
+ .PARAMETER Port
18
+ SSH port to open in the firewall (default 22).
19
+
20
+ .PARAMETER ZipPath
21
+ Use a specific OpenSSH ZIP instead of the bundled one (override).
22
+
23
+ .PARAMETER Force
24
+ Reinstall even if sshd already exists.
25
+
26
+ .EXAMPLE
27
+ powershell -ExecutionPolicy Bypass -File .\setup_openssh_server.ps1
28
+ .EXAMPLE
29
+ ssh-handler-setup --install-pip
30
+ #>
31
+
32
+ param(
33
+ [switch]$InstallPip,
34
+ [int]$Port = 22,
35
+ [string]$ZipPath,
36
+ [switch]$Force
37
+ )
38
+
39
+ $ErrorActionPreference = 'Stop'
40
+ $ProgressPreference = 'SilentlyContinue'
41
+
42
+ # --- 1. Self-elevate to Administrator -------------------------------------- #
43
+ $isAdmin = ([Security.Principal.WindowsPrincipal]`
44
+ [Security.Principal.WindowsIdentity]::GetCurrent()`
45
+ ).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
46
+
47
+ if (-not $isAdmin) {
48
+ Write-Host "Elevating to Administrator..." -ForegroundColor Yellow
49
+ $argList = "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" -Port $Port"
50
+ if ($InstallPip) { $argList += " -InstallPip" }
51
+ if ($Force) { $argList += " -Force" }
52
+ if ($ZipPath) { $argList += " -ZipPath `"$ZipPath`"" }
53
+ Start-Process powershell -Verb RunAs -ArgumentList $argList
54
+ exit
55
+ }
56
+
57
+ Write-Host "=== OpenSSH Server setup (Administrator, offline) ===" -ForegroundColor Cyan
58
+
59
+ function Test-SshdPresent {
60
+ return [bool](Get-Service -Name sshd -ErrorAction SilentlyContinue)
61
+ }
62
+
63
+ # --- 2. Pick the right bundled ZIP by CPU architecture --------------------- #
64
+ function Get-OSArch {
65
+ try {
66
+ $a = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString()
67
+ if ($a) { return $a }
68
+ } catch {}
69
+ $p = $env:PROCESSOR_ARCHITEW6432
70
+ if (-not $p) { $p = $env:PROCESSOR_ARCHITECTURE }
71
+ switch ($p) {
72
+ 'AMD64' { 'X64' } 'ARM64' { 'Arm64' } 'x86' { 'X86' } default { $p }
73
+ }
74
+ }
75
+
76
+ function Resolve-BundledZip {
77
+ $arch = Get-OSArch
78
+ switch -Regex ($arch) {
79
+ 'Arm64' { $name = 'OpenSSH-ARM64.zip' }
80
+ 'X64' { $name = 'OpenSSH-Win64.zip' }
81
+ 'X86' { $name = 'OpenSSH-Win32.zip' }
82
+ default { throw "Unsupported architecture: $arch" }
83
+ }
84
+ Write-Host (" Detected architecture: {0} -> {1}" -f $arch, $name)
85
+ return (Join-Path $PSScriptRoot ("openssh\" + $name))
86
+ }
87
+
88
+ # --- 3. Install OpenSSH Server from the ZIP -------------------------------- #
89
+ if ((Test-SshdPresent) -and -not $Force) {
90
+ Write-Host "OpenSSH Server already present (use -Force to reinstall)." -ForegroundColor Green
91
+ }
92
+ else {
93
+ $zip = if ($ZipPath) { $ZipPath } else { Resolve-BundledZip }
94
+ if (-not (Test-Path $zip)) {
95
+ throw "OpenSSH ZIP not found: $zip"
96
+ }
97
+ Write-Host "Installing OpenSSH Server from: $zip"
98
+
99
+ $dest = Join-Path $env:ProgramFiles 'OpenSSH'
100
+ $tmp = Join-Path $env:TEMP ("openssh_" + [guid]::NewGuid().ToString('N'))
101
+ try {
102
+ Expand-Archive -Path $zip -DestinationPath $tmp -Force
103
+ # the archive nests a single OpenSSH-XXX folder
104
+ $srcDir = Get-ChildItem $tmp -Directory | Select-Object -First 1
105
+ if (-not $srcDir) { $srcDir = Get-Item $tmp }
106
+
107
+ if (-not (Test-Path $dest)) {
108
+ New-Item -ItemType Directory -Path $dest | Out-Null
109
+ }
110
+ Copy-Item (Join-Path $srcDir.FullName '*') $dest -Recurse -Force
111
+ Write-Host " Files copied to $dest"
112
+
113
+ $installer = Join-Path $dest 'install-sshd.ps1'
114
+ if (-not (Test-Path $installer)) { throw "install-sshd.ps1 missing in $dest" }
115
+ & powershell -NoProfile -ExecutionPolicy Bypass -File $installer | Out-Null
116
+ Write-Host " OpenSSH Server installed." -ForegroundColor Green
117
+ }
118
+ finally {
119
+ if (Test-Path $tmp) { Remove-Item $tmp -Recurse -Force -ErrorAction SilentlyContinue }
120
+ }
121
+
122
+ # add the install dir to the machine PATH so ssh/sshd are callable
123
+ $machinePath = [Environment]::GetEnvironmentVariable('Path', 'Machine')
124
+ if ($machinePath -notlike "*$dest*") {
125
+ [Environment]::SetEnvironmentVariable('Path', "$machinePath;$dest", 'Machine')
126
+ }
127
+ }
128
+
129
+ # --- 4. Service + firewall -------------------------------------------------- #
130
+ Write-Host "Configuring sshd service and firewall..."
131
+ Set-Service -Name sshd -StartupType Automatic
132
+ Start-Service sshd
133
+
134
+ $ruleName = "OpenSSH-Server-In-TCP"
135
+ if (-not (Get-NetFirewallRule -Name $ruleName -ErrorAction SilentlyContinue)) {
136
+ New-NetFirewallRule -Name $ruleName -DisplayName 'OpenSSH Server (sshd)' `
137
+ -Enabled True -Direction Inbound -Protocol TCP -Action Allow `
138
+ -LocalPort $Port | Out-Null
139
+ Write-Host " Firewall rule added for TCP $Port." -ForegroundColor Green
140
+ }
141
+ else {
142
+ Write-Host " Firewall rule already present." -ForegroundColor Green
143
+ }
144
+
145
+ # --- 5. Optional: pip install the package ---------------------------------- #
146
+ if ($InstallPip) {
147
+ Write-Host "Installing ssh-handler (pip)..."
148
+ try {
149
+ python -m pip install --upgrade pip | Out-Null
150
+ python -m pip install -U "ssh-handler[winrm]"
151
+ Write-Host " ssh-handler installed." -ForegroundColor Green
152
+ }
153
+ catch {
154
+ Write-Warning "pip install failed: $($_.Exception.Message)"
155
+ }
156
+ }
157
+
158
+ # --- 6. Verify -------------------------------------------------------------- #
159
+ Write-Host "`n=== Verification ===" -ForegroundColor Cyan
160
+ $svc = Get-Service sshd
161
+ Write-Host ("sshd status : {0}" -f $svc.Status)
162
+ $test = Test-NetConnection localhost -Port $Port -WarningAction SilentlyContinue
163
+ Write-Host ("port {0} open : {1}" -f $Port, $test.TcpTestSucceeded)
164
+
165
+ if ($svc.Status -eq 'Running' -and $test.TcpTestSucceeded) {
166
+ Write-Host "`nDone. This machine now accepts SSH on port $Port." -ForegroundColor Green
167
+ }
168
+ else {
169
+ Write-Warning "Setup finished but sshd is not listening yet - check the messages above."
170
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ssh-handler
3
- Version: 1.0.6
3
+ Version: 1.0.7
4
4
  Summary: Extensive SSH/SFTP/SCP/FTP handler built on Paramiko, for test automation, CLIs and PyQt5 tools.
5
5
  Author: ssh-handler contributors
6
6
  License-Expression: MIT
@@ -226,14 +226,18 @@ administrator** on the target. If SSH already works, this code path never runs.
226
226
 
227
227
  ### Set up OpenSSH Server on a machine (bundled installer)
228
228
 
229
- Installing the package also gives you a one-command setup for the *local* Windows
230
- machine it ships inside the wheel, self-elevates to Administrator, installs &
231
- starts OpenSSH Server, and opens the firewall:
229
+ Installing the package also gives you a one-command, **fully offline** setup for
230
+ the local Windows machine. The OpenSSH ZIPs (ARM64 / Win64 / Win32) ship *inside*
231
+ the wheel, so the installer needs **no internet and no Windows Update** — it picks
232
+ the ZIP matching the CPU architecture, self-elevates to Administrator, installs &
233
+ starts OpenSSH Server, and opens the firewall. (This avoids the
234
+ `Add-WindowsCapability` hang common on locked-down corporate networks.)
232
235
 
233
236
  ```powershell
234
237
  pip install ssh-handler
235
- ssh-handler-setup # install + start sshd + firewall (self-elevates)
238
+ ssh-handler-setup # offline install + start sshd + firewall (self-elevates)
236
239
  ssh-handler-setup --install-pip # also (re)install the package as admin
240
+ ssh-handler-setup --force # reinstall even if sshd already exists
237
241
  # equivalent: python -m ssh_handler setup-server
238
242
  ```
239
243
 
@@ -20,4 +20,7 @@ ssh_handler.egg-info/dependency_links.txt
20
20
  ssh_handler.egg-info/entry_points.txt
21
21
  ssh_handler.egg-info/requires.txt
22
22
  ssh_handler.egg-info/top_level.txt
23
+ ssh_handler/openssh/OpenSSH-ARM64.zip
24
+ ssh_handler/openssh/OpenSSH-Win32.zip
25
+ ssh_handler/openssh/OpenSSH-Win64.zip
23
26
  tests/test_offline.py
@@ -1,150 +0,0 @@
1
- <#
2
- .SYNOPSIS
3
- One-shot setup for an SSH target / RDP jump machine:
4
- installs & starts OpenSSH Server, opens the firewall, and (optionally)
5
- pip-installs the ssh-handler package. Self-elevates to Administrator.
6
-
7
- .DESCRIPTION
8
- Run this once on a Windows machine that you want to reach over SSH (e.g. the
9
- RDP box you tunnel through). It:
10
- 1. Re-launches itself elevated if not already running as Administrator.
11
- 2. Installs OpenSSH Server (Windows capability -> winget fallback).
12
- 3. Starts sshd, sets it to start automatically, opens TCP 22.
13
- 4. Optionally runs `pip install -U "ssh-handler[winrm]"`.
14
- 5. Verifies sshd is running and listening.
15
-
16
- .PARAMETER InstallPip
17
- Also install/upgrade the ssh-handler Python package (needs Python+pip on PATH).
18
-
19
- .PARAMETER Port
20
- SSH port to open in the firewall (default 22).
21
-
22
- .EXAMPLE
23
- powershell -ExecutionPolicy Bypass -File .\setup_openssh_server.ps1
24
-
25
- .EXAMPLE
26
- powershell -ExecutionPolicy Bypass -File .\setup_openssh_server.ps1 -InstallPip
27
- #>
28
-
29
- param(
30
- [switch]$InstallPip,
31
- [int]$Port = 22
32
- )
33
-
34
- $ErrorActionPreference = 'Stop'
35
- $ProgressPreference = 'SilentlyContinue'
36
-
37
- # --- 1. Self-elevate to Administrator -------------------------------------- #
38
- $isAdmin = ([Security.Principal.WindowsPrincipal]`
39
- [Security.Principal.WindowsIdentity]::GetCurrent()`
40
- ).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
41
-
42
- if (-not $isAdmin) {
43
- Write-Host "Elevating to Administrator..." -ForegroundColor Yellow
44
- $argList = "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`""
45
- if ($InstallPip) { $argList += " -InstallPip" }
46
- $argList += " -Port $Port"
47
- Start-Process powershell -Verb RunAs -ArgumentList $argList
48
- exit
49
- }
50
-
51
- Write-Host "=== OpenSSH Server setup (running as Administrator) ===" -ForegroundColor Cyan
52
-
53
- # --- 2. Install OpenSSH Server --------------------------------------------- #
54
- function Test-SshdPresent {
55
- return [bool](Get-Service -Name sshd -ErrorAction SilentlyContinue)
56
- }
57
-
58
- if (Test-SshdPresent) {
59
- Write-Host "OpenSSH Server already present." -ForegroundColor Green
60
- }
61
- else {
62
- Write-Host "Installing OpenSSH Server..."
63
- $installed = $false
64
-
65
- # 2a. Windows capability (Features-on-Demand). May be slow on corporate nets.
66
- try {
67
- $cap = Get-WindowsCapability -Online -Name 'OpenSSH.Server*' |
68
- Select-Object -First 1
69
- if ($cap -and $cap.State -ne 'Installed') {
70
- Write-Host " Trying Add-WindowsCapability (can take a few minutes)..."
71
- Add-WindowsCapability -Online -Name $cap.Name | Out-Null
72
- }
73
- if (Test-SshdPresent) { $installed = $true }
74
- }
75
- catch {
76
- Write-Host " Windows capability install failed: $($_.Exception.Message)" `
77
- -ForegroundColor DarkYellow
78
- }
79
-
80
- # 2b. winget fallback
81
- if (-not $installed) {
82
- try {
83
- Write-Host " Trying winget (Microsoft.OpenSSH.Beta)..."
84
- winget install --id Microsoft.OpenSSH.Beta -e --silent `
85
- --accept-source-agreements --accept-package-agreements | Out-Null
86
- if (Test-SshdPresent) { $installed = $true }
87
- }
88
- catch {
89
- Write-Host " winget not available or failed." -ForegroundColor DarkYellow
90
- }
91
- }
92
-
93
- if (-not $installed -and -not (Test-SshdPresent)) {
94
- Write-Warning @"
95
- Could not auto-install OpenSSH Server (Windows Update / winget likely blocked).
96
- Manual fallback:
97
- 1. On a machine with internet, download OpenSSH-Win64.zip from
98
- https://github.com/PowerShell/Win32-OpenSSH/releases/latest
99
- 2. Copy it here, extract to 'C:\Program Files\OpenSSH'
100
- 3. Run: powershell -ExecutionPolicy Bypass -File 'C:\Program Files\OpenSSH\install-sshd.ps1'
101
- Then re-run this script to finish service + firewall setup.
102
- "@
103
- exit 1
104
- }
105
- Write-Host "OpenSSH Server installed." -ForegroundColor Green
106
- }
107
-
108
- # --- 3. Service + firewall -------------------------------------------------- #
109
- Write-Host "Configuring sshd service and firewall..."
110
- Set-Service -Name sshd -StartupType Automatic
111
- Start-Service sshd
112
-
113
- $ruleName = "OpenSSH-Server-In-TCP"
114
- if (-not (Get-NetFirewallRule -Name $ruleName -ErrorAction SilentlyContinue)) {
115
- New-NetFirewallRule -Name $ruleName -DisplayName 'OpenSSH Server (sshd)' `
116
- -Enabled True -Direction Inbound -Protocol TCP -Action Allow `
117
- -LocalPort $Port | Out-Null
118
- Write-Host " Firewall rule added for TCP $Port." -ForegroundColor Green
119
- }
120
- else {
121
- Write-Host " Firewall rule already present." -ForegroundColor Green
122
- }
123
-
124
- # --- 4. Optional: pip install the package ---------------------------------- #
125
- if ($InstallPip) {
126
- Write-Host "Installing ssh-handler (pip)..."
127
- try {
128
- python -m pip install --upgrade pip | Out-Null
129
- python -m pip install -U "ssh-handler[winrm]"
130
- Write-Host " ssh-handler installed." -ForegroundColor Green
131
- }
132
- catch {
133
- Write-Warning "pip install failed: $($_.Exception.Message)"
134
- Write-Host " Ensure Python and pip are on PATH, then run: pip install -U ssh-handler"
135
- }
136
- }
137
-
138
- # --- 5. Verify -------------------------------------------------------------- #
139
- Write-Host "`n=== Verification ===" -ForegroundColor Cyan
140
- $svc = Get-Service sshd
141
- Write-Host ("sshd status : {0}" -f $svc.Status)
142
- $test = Test-NetConnection localhost -Port $Port -WarningAction SilentlyContinue
143
- Write-Host ("port {0} open : {1}" -f $Port, $test.TcpTestSucceeded)
144
-
145
- if ($svc.Status -eq 'Running' -and $test.TcpTestSucceeded) {
146
- Write-Host "`nDone. This machine now accepts SSH on port $Port." -ForegroundColor Green
147
- }
148
- else {
149
- Write-Warning "Setup finished but sshd is not listening yet - check the messages above."
150
- }
File without changes
File without changes