dsh-winrm 0.3.1 → 0.4.1
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.
- package/README.en.md +132 -0
- package/README.md +20 -7
- package/docs/screenshots/winrm-panel.png +0 -0
- package/lib/client.js +597 -73
- package/lib/index.js +898 -26
- package/lib/types/client/locales.d.ts +44 -0
- package/lib/types/client/tool/card-model.d.ts +71 -0
- package/lib/types/client/tool/cards.d.ts +9 -0
- package/lib/types/diff.d.ts +62 -0
- package/lib/types/engine/client.d.ts +30 -4
- package/lib/types/engine.d.ts +51 -1
- package/lib/types/index.d.ts +4 -3
- package/lib/types/powershell.d.ts +64 -0
- package/lib/types/protocol.d.ts +54 -0
- package/lib/types/tools.d.ts +7 -1
- package/package.json +8 -4
- package/scripts/verify-live.mts +116 -0
- package/src/client/index.ts +17 -0
- package/src/client/locales.ts +44 -0
- package/src/client/tool/card-model.ts +151 -0
- package/src/client/tool/cards.module.css +128 -0
- package/src/client/tool/cards.tsx +335 -0
- package/src/diff.ts +128 -0
- package/src/engine/client.ts +66 -16
- package/src/engine.ts +222 -5
- package/src/index.ts +10 -3
- package/src/powershell.ts +253 -0
- package/src/protocol.ts +59 -0
- package/src/smb.ts +4 -1
- package/src/tools.ts +303 -4
- package/README.zh.md +0 -126
package/README.en.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# dsh-winrm — remote Windows administration for DSH (WinRM / PowerShell Remoting)
|
|
2
|
+
|
|
3
|
+
[中文](README.md) | English
|
|
4
|
+
|
|
5
|
+
A DSH plugin modeled on [dsh-ssh](https://github.com/zhu1090093659/dsh-web-ui/tree/main/packages/dsh-ssh): it administers Windows servers over the native **WinRM / PowerShell Remoting** protocol, so **the target machine needs no OpenSSH**.
|
|
6
|
+
|
|
7
|
+
> **Provenance**: this project is a fork of [andyfan1094/dsh-winrm](https://github.com/andyfan1094/dsh-winrm) (Apache-2.0) that replaces the backend's Python + pywinrm implementation with a native Node.js client ([winrm-client](https://github.com/shide1989/winrm-client)), so **Python is no longer required locally**. The GUI, the agent tools and the feature scope follow the upstream design.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
| Surface | What it does |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| "Windows" sidebar entry | A main panel with five tabs: **Hosts** / **Console** / **Services** / **Processes** / **Transfer** |
|
|
14
|
+
| Agent tools | `winrm_list` `winrm_exec` `winrm_service` `winrm_process` `winrm_read` `winrm_write` `winrm_edit` `winrm_upload` `winrm_download` `winrm_cluster` |
|
|
15
|
+
| PowerShell console | A WebSocket command session (each command runs through the native Node WinRM client and streams its output back) |
|
|
16
|
+
| Service management | List / start / stop / restart / change start type (automatic, manual, disabled) |
|
|
17
|
+
| Process management | List (CPU, memory, path) / kill by PID |
|
|
18
|
+
| Remote text files | Read (paged by line, encoding aware, numbered envelope) / write (whole-file overwrite, optional UTF-8 / UTF-8 BOM / UTF-16LE) / edit (exact string replacement that keeps the original encoding; a non-unique match is refused by default) |
|
|
19
|
+
| Transcript cards | `winrm_read` / `winrm_write` / `winrm_edit` render as a **file content card and diff cards** in the transcript (reusing the harness's own `ReadBlock` / `DiffBlock` primitives) instead of the raw model-facing envelope |
|
|
20
|
+
| File transfer | Streamed over WinRM (upload through one shell and one stream, download through parallel byte ranges, **no SMB dependency**, any path works); uploads create parent directories |
|
|
21
|
+
| Cluster | Run one command across many hosts concurrently (filtered by aliases / environment / tags) |
|
|
22
|
+
|
|
23
|
+
## Authentication and transport
|
|
24
|
+
|
|
25
|
+
- Uses a native Node.js WinRM client ([winrm-client](https://github.com/shide1989/winrm-client)) and picks the authentication automatically per transport: Basic first over HTTPS, NTLM first over HTTP, each falling back to the other (HTTP Basic is for trusted intranets only — use HTTPS on the public internet)
|
|
26
|
+
- Local accounts are written as `Administrator`; domain accounts as `DOMAIN\user` or `user@domain`
|
|
27
|
+
- No Python locally — WinRM runs on a pure Node dependency (winrm-client) installed with the plugin
|
|
28
|
+
- Transport: HTTP (5985) or HTTPS (5986); HTTPS offers an "accept self-signed certificate" checkbox
|
|
29
|
+
- Chinese output is never mangled: every command goes through a **UTF-8 base64 envelope** (`Out-String -Stream` wrapping plus three labelled envelope lines), which sidesteps the WinRM transport code page
|
|
30
|
+
- PowerShell's CLIXML host records are stripped from `stderr` automatically; real process-level stderr (for example `[Console]::Error`) is preserved verbatim
|
|
31
|
+
- **Scripts travel over WinRS stdin, not the command line**: WinRS hands the command line to `cmd.exe`, which caps it at roughly 8191 characters, while `-EncodedCommand` inflates a script by 2.67x — long scripts used to fail outright with `The command line is too long.`. The command line is now a **constant** and the script is chunked to stdin behind a UTF-8 byte-length prefix; a 200 KB script is verified working
|
|
32
|
+
|
|
33
|
+
## Preparing the target machine (one time)
|
|
34
|
+
|
|
35
|
+
On the Windows machine you want to manage, run this **as administrator**:
|
|
36
|
+
|
|
37
|
+
```powershell
|
|
38
|
+
powershell -ExecutionPolicy Bypass -File .\scripts\enable-winrm.ps1
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The script enables the WinRM service and the 5985 listener, allows Basic/Negotiate authentication, permits unencrypted HTTP (intranet), raises the WinRS memory limit to 512 MB, opens the firewall and prints the machine's IP address.
|
|
42
|
+
|
|
43
|
+
> ⚠️ **Security**: HTTP + Basic is cleartext and belongs on trusted intranets only. On the public internet, configure HTTPS with a self-signed certificate and tick "accept self-signed certificate" in the plugin. Passwords are stored in cleartext in `~/.dsh/dsh-winrm.json` locally (mode 0600, readable only by the current user) and are never echoed back by the plugin UI.
|
|
44
|
+
|
|
45
|
+
## Screenshot
|
|
46
|
+
|
|
47
|
+

|
|
48
|
+
|
|
49
|
+
## Install
|
|
50
|
+
|
|
51
|
+
> Requires DeepSeek Harness **0.1.7-alpha.2 or newer** (including `0.1.7-rc.1`, `0.2.0-rc.*` and `0.2.x`). The plugin declares `peerDependencies` as `^0.1.7-alpha.2 || ^0.2.0-rc.1`, which DSH checks at startup: every 0.1.7 and 0.2.x version loads, and `0.3.0` onward is refused (use `dsh plugin allow-version` to admit a specific version if you accept the risk).
|
|
52
|
+
|
|
53
|
+
Download the latest `dsh-winrm-*.tgz` from [Releases](https://github.com/MoRanYue/dsh-winrm/releases) and add it to your profile:
|
|
54
|
+
|
|
55
|
+
```powershell
|
|
56
|
+
dsh plugin --profile web add D:\downloads\dsh-winrm-0.3.1.tgz
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
You can also install straight from npm:
|
|
60
|
+
|
|
61
|
+
```powershell
|
|
62
|
+
dsh plugin --profile web add dsh-winrm
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
For local development, link the checkout instead:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
dsh plugin --profile web add link:D:\projects\dsh-winrm
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Restart dsh web** after installing (quit and start `dsh web` again) so the plugin takes effect. A "Windows" entry appears in the sidebar, and `winrm_list` and friends become available in the conversation.
|
|
72
|
+
|
|
73
|
+
### Building from source
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
cd D:\projects\dsh-winrm
|
|
77
|
+
pnpm install
|
|
78
|
+
npm run build # tsc declarations + tsdown host/client bundles + postbuild wrapping
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Usage examples (agent tools)
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
winrm_list # list configured hosts
|
|
85
|
+
winrm_exec alias=web1 command="Get-Service | Select -First 5 | Format-Table"
|
|
86
|
+
winrm_service alias=web1 name=W3SVC action=restart
|
|
87
|
+
winrm_process alias=web1 action=list
|
|
88
|
+
winrm_process alias=web1 id=1234 action=kill
|
|
89
|
+
winrm_read alias=web1 remotePath=C:\logs\app.log offset=1 limit=200
|
|
90
|
+
winrm_write alias=web1 remotePath=C:\temp\run.ps1 content="$env:TEMP" encoding=utf8bom
|
|
91
|
+
winrm_edit alias=web1 remotePath=C:\temp\app.config oldString="port=8080" newString="port=9090"
|
|
92
|
+
winrm_upload alias=web1 localPath=D:\a.zip remotePath=C:\temp\a.zip
|
|
93
|
+
winrm_download alias=web1 remotePath=C:\logs\app.log localPath=D:\app.log
|
|
94
|
+
winrm_cluster command="Get-Date" tags=prod
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Architecture
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
src/
|
|
101
|
+
index.ts Cordis plugin entry (webServer/tools/systemPrompt mounts + settings panel + announcement)
|
|
102
|
+
engine.ts WinRmEngine facade: exec / services / processes / readFile / writeFile / editFile / ls / upload / download / console / cluster / test
|
|
103
|
+
store.ts ~/.dsh/dsh-winrm.json host store (atomic write, 0600)
|
|
104
|
+
protocol.ts Host <-> browser wire types
|
|
105
|
+
diff.ts Bounded hunk derivation for the transcript cards (no diff package)
|
|
106
|
+
powershell.ts PS fragment builders + stdin envelope (outer/child wrapping / services / processes / directory / streamed send-receive scripts)
|
|
107
|
+
routes.ts /api/dsh-winrm route family + console WebSocket (loopback fence)
|
|
108
|
+
tools.ts The 10 winrm_* agent tools
|
|
109
|
+
engine/client.ts winrm-client transport: in-process authentication (NTLM/Basic), UTF-8 envelope, streamed upload/download + chunked fallback
|
|
110
|
+
engine/wsman.ts Hand-written WSMan Send/Receive envelopes (raw bytes over stdin, no double base64; 512000 envelope cap)
|
|
111
|
+
engine/console.ts Streaming PowerShell console session
|
|
112
|
+
client/ Browser half: sidebar entry + main panel (5 tabs)
|
|
113
|
+
client/tool/ Transcript cards: three tool.call.toolview frames rendered with DSH's own ReadBlock / DiffBlock
|
|
114
|
+
scripts/
|
|
115
|
+
enable-winrm.ps1 One-shot WinRM enablement on the target machine
|
|
116
|
+
postbuild.mjs __ModuleLoader__ wrapping for the client artifact
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Transport relies on the native Node.js [winrm-client](https://github.com/shide1989/winrm-client) (NTLM/Basic, in-process authentication); the password is used only inside the host process and never appears on any child process command line.
|
|
120
|
+
|
|
121
|
+
## Known limitations
|
|
122
|
+
|
|
123
|
+
- The console is a command session: it does not preserve PowerShell variables or the current directory, and every command runs independently
|
|
124
|
+
- Uploads go over **one stdin stream**: a single shell, a single command, one `Send` per 256 KB, with per-chunk gzip for compressible content (a 1.7 MB JSON fixture travels as 91 KB on the wire). The old 48 KB chunked path is kept as a fallback, used only when the streaming channel is unavailable
|
|
125
|
+
- Downloads go over **parallel byte ranges**: up to four workers by default, each with its own shell reading an absolute byte range of the same file, compressed on the remote side and written locally at the matching offset (measured: 2 MiB in about 10-12 s, 16 MiB in about 21-23 s, 16 MiB of compressible content in about 6 s; the old 48 KB chunked path needed 129 s for 2 MiB and remains as a fallback). A single server `Receive` returns at most 128 KB regardless of the envelope size, so downloads are round-trip bound rather than bandwidth bound
|
|
126
|
+
- `channel=auto` (the default) probes port 445 first: `net use` has no short timeout of its own and takes about 60 s to fail when SMB is unavailable, and that wait used to happen before every upload. It is now decided within 3 s and the transfer goes straight over WinRM. An explicit `channel=smb` on a host whose 445 is closed fails immediately and names `winrm` as the way out
|
|
127
|
+
- A streaming transfer is bounded by **whether bytes are still moving**, not by a fixed deadline for the whole transfer: it keeps going as long as data arrives, and only a range that delivers nothing for 180 s is treated as stalled. A 700 MiB file therefore completes normally at the ~0.73 MiB/s this link measures even though it takes about sixteen minutes; the absolute cap exists only so a wedged transfer cannot stay alive forever, and it scales with the payload
|
|
128
|
+
- A failed download leaves no residue: bytes already written are discarded and the target file is removed. If the failure happens before any byte arrives (missing path, target is a directory, host unreachable), an existing local file is left untouched — the target file is only created on the first write
|
|
129
|
+
- When an attempt is abandoned mid-transfer (for example a failed auth candidate retried from the start), the sender process on the target can outlive it and keep the file open until its shell is reclaimed; a transfer that finishes normally exits on its own. If a remote file refuses to delete, end the corresponding `powershell.exe` sender on the target first
|
|
130
|
+
- A single command times out after 60 s by default; pass `timeoutMs` to change it
|
|
131
|
+
- The target machine must already have WinRM enabled (see above); cleartext HTTP Basic must not be used on the public internet
|
|
132
|
+
- Closing and reopening the panel returns to the Hosts tab: the panel occupies the `main` slot, so it unmounts when you switch back to the conversation and the active tab is not preserved across toggles
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# dsh-winrm — Windows 远程管理插件(WinRM / PowerShell Remoting)
|
|
2
2
|
|
|
3
|
-
[
|
|
3
|
+
中文 | [English](README.en.md)
|
|
4
4
|
|
|
5
5
|
仿照 [dsh-ssh](https://github.com/zhu1090093659/dsh-web-ui/tree/main/packages/dsh-ssh) 开发的 DSH 插件:用 Windows 原生的 **WinRM / PowerShell Remoting** 协议远程管理 Windows 服务器,**目标机不需要装 OpenSSH**。
|
|
6
6
|
|
|
@@ -11,10 +11,12 @@
|
|
|
11
11
|
| 面 | 说明 |
|
|
12
12
|
| --- | --- |
|
|
13
13
|
| GUI 侧边栏「Windows」入口 | 居中面板:**主机** / **控制台** / **服务** / **进程** / **传输** 五个页签 |
|
|
14
|
-
| Agent 工具 | `winrm_list` `winrm_exec` `winrm_service` `winrm_process` `winrm_upload` `winrm_download` `winrm_cluster` |
|
|
14
|
+
| Agent 工具 | `winrm_list` `winrm_exec` `winrm_service` `winrm_process` `winrm_read` `winrm_write` `winrm_edit` `winrm_upload` `winrm_download` `winrm_cluster` |
|
|
15
15
|
| PowerShell 控制台 | WebSocket 命令会话(每条命令通过原生 Node WinRM 客户端执行,输出实时返回) |
|
|
16
16
|
| 服务管理 | 列出 / 启动 / 停止 / 重启 / 改启动类型(自动/手动/禁用) |
|
|
17
17
|
| 进程管理 | 列出(CPU/内存/路径)/ 按 PID 结束 |
|
|
18
|
+
| 远程文本文件 | 读(按行分页、编码感知、行号信封)/ 写(整文件覆盖,可选 UTF-8 / UTF-8 BOM / UTF-16LE)/ 编辑(精确串替换,保持原编码,非唯一匹配默认拒绝) |
|
|
19
|
+
| 转录卡片 | `winrm_read` / `winrm_write` / `winrm_edit` 在会话里渲染为**文件内容卡片与 diff 卡片**(直接复用 harness 自带的 `ReadBlock` / `DiffBlock` 原语),不再是模型可见的原始信封文本 |
|
|
18
20
|
| 文件传输 | WinRM 流式传输(上传单 shell 单流 / 下载并行区间,**不依赖 SMB**,任意路径可传);上传自动建目录 |
|
|
19
21
|
| 集群 | 一条命令并发跑多台主机(按 aliases / environment / tags 过滤) |
|
|
20
22
|
|
|
@@ -40,6 +42,10 @@ powershell -ExecutionPolicy Bypass -File .\scripts\enable-winrm.ps1
|
|
|
40
42
|
|
|
41
43
|
> ⚠️ **安全**:HTTP + Basic 是明文,仅限受信内网;公网请配置 HTTPS + 自签名证书,并在插件里勾选「接受自签名证书」。密码明文存于本机 `~/.dsh/dsh-winrm.json`(0600 权限,仅当前用户可读),插件界面永不回显。
|
|
42
44
|
|
|
45
|
+
## 截图
|
|
46
|
+
|
|
47
|
+

|
|
48
|
+
|
|
43
49
|
## 安装
|
|
44
50
|
|
|
45
51
|
> 需要 DeepSeek Harness **0.1.7-alpha.2 及以后**(含 `0.1.7-rc.1`、`0.2.0-rc.*`、`0.2.x`)。插件的 `peerDependencies` 声明为 `^0.1.7-alpha.2 || ^0.2.0-rc.1`,DSH 启动时会据此校验:0.1.7 与 0.2.x 各版本可加载,`0.3.0` 起会被拒绝(确需冒险可用 `dsh plugin allow-version` 逐版本放行)。
|
|
@@ -47,7 +53,7 @@ powershell -ExecutionPolicy Bypass -File .\scripts\enable-winrm.ps1
|
|
|
47
53
|
从 [Releases](https://github.com/MoRanYue/dsh-winrm/releases) 下载最新的 `dsh-winrm-*.tgz`,加入 profile:
|
|
48
54
|
|
|
49
55
|
```powershell
|
|
50
|
-
dsh plugin --profile web add D:\downloads\dsh-winrm-0.3.
|
|
56
|
+
dsh plugin --profile web add D:\downloads\dsh-winrm-0.3.1.tgz
|
|
51
57
|
```
|
|
52
58
|
|
|
53
59
|
也可以直接从 npm 安装:
|
|
@@ -80,6 +86,9 @@ winrm_exec alias=web1 command="Get-Service | Select -First 5 | Format-Table"
|
|
|
80
86
|
winrm_service alias=web1 name=W3SVC action=restart
|
|
81
87
|
winrm_process alias=web1 action=list
|
|
82
88
|
winrm_process alias=web1 id=1234 action=kill
|
|
89
|
+
winrm_read alias=web1 remotePath=C:\logs\app.log offset=1 limit=200
|
|
90
|
+
winrm_write alias=web1 remotePath=C:\temp\run.ps1 content="$env:TEMP" encoding=utf8bom
|
|
91
|
+
winrm_edit alias=web1 remotePath=C:\temp\app.config oldString="port=8080" newString="port=9090"
|
|
83
92
|
winrm_upload alias=web1 localPath=D:\a.zip remotePath=C:\temp\a.zip
|
|
84
93
|
winrm_download alias=web1 remotePath=C:\logs\app.log localPath=D:\app.log
|
|
85
94
|
winrm_cluster command="Get-Date" tags=prod
|
|
@@ -90,16 +99,18 @@ winrm_cluster command="Get-Date" tags=prod
|
|
|
90
99
|
```
|
|
91
100
|
src/
|
|
92
101
|
index.ts Cordis 插件入口(webServer/tools/systemPrompt 挂载 + 设置面板 + 公告)
|
|
93
|
-
engine.ts WinRmEngine 门面:exec / services / processes / ls / upload / download / console / cluster / test
|
|
102
|
+
engine.ts WinRmEngine 门面:exec / services / processes / readFile / writeFile / editFile / ls / upload / download / console / cluster / test
|
|
94
103
|
store.ts ~/.dsh/dsh-winrm.json 主机存储(原子写,0600)
|
|
95
104
|
protocol.ts 宿主↔浏览器 wire 类型
|
|
105
|
+
diff.ts 转录卡片用的有界 hunk 推导(不依赖 diff 包)
|
|
96
106
|
powershell.ts PS 片段构造器 + stdin 信封(outer/child 包装 / 服务 / 进程 / 目录 / 流式收发脚本)
|
|
97
107
|
routes.ts /api/dsh-winrm 路由族 + 控制台 WebSocket(loopback 围栏)
|
|
98
|
-
tools.ts
|
|
108
|
+
tools.ts 10 个 winrm_* agent 工具
|
|
99
109
|
engine/client.ts winrm-client 传输层:进程内认证(NTLM/Basic)、UTF-8 信封、流式上传/下载 + 分块回退
|
|
100
110
|
engine/wsman.ts 手写 WSMan Send/Receive 信封(原始字节走 stdin,不做二次 base64;512000 信封上限)
|
|
101
111
|
engine/console.ts 流式 PowerShell 控制台会话
|
|
102
112
|
client/ 浏览器半:侧边栏入口 + 居中面板(5 页签)
|
|
113
|
+
client/tool/ 转录卡片:tool.call.toolview 三个帧 + DSH 原生 ReadBlock / DiffBlock 渲染
|
|
103
114
|
scripts/
|
|
104
115
|
enable-winrm.ps1 目标机一键启用 WinRM
|
|
105
116
|
postbuild.mjs 客户端产物 __ModuleLoader__ 包装
|
|
@@ -112,8 +123,10 @@ scripts/
|
|
|
112
123
|
- 控制台是命令会话,不保持 PowerShell 变量和当前目录状态;每条命令独立执行
|
|
113
124
|
- 上传走**单条 stdin 流**:一个 shell、一个命令,每 256KB 一个 `Send`,可压缩内容自动按块 gzip(实测 1.7MB JSON 线上仅 91KB)。旧的 48KB 分块路径保留为回退,仅在流式通道不可用时启用
|
|
114
125
|
- 下载走**并行区间流**:默认最多 4 个 worker,各自一个 shell 读同一文件的绝对字节区间,远端 gzip 后回传,本地按 offset 落位(实测 2MiB 约 10-12 秒,16MiB 约 21-23 秒,可压缩的 16MiB 约 6 秒;旧的 48KB 分块路径 2MiB 需 129 秒,保留为回退)。服务端单次 `Receive` 最多回 128KB,与信封大小无关,所以下载是往返次数受限而非带宽受限
|
|
115
|
-
- `channel=auto`(默认)先探测目标机 445 端口:`net use` 自身没有短超时,SMB 不可用时要等约 60 秒才失败,此前这段等待发生在每次上传之前。现在 3 秒内判定并直接走 WinRM
|
|
116
|
-
-
|
|
126
|
+
- `channel=auto`(默认)先探测目标机 445 端口:`net use` 自身没有短超时,SMB 不可用时要等约 60 秒才失败,此前这段等待发生在每次上传之前。现在 3 秒内判定并直接走 WinRM;显式 `channel=smb` 且 445 未开放时立即报错,并提示改用 `winrm`
|
|
127
|
+
- 流式传输以**字节是否还在流动**判定超时,而不是给整次传输一个固定时限:只要还有数据到达就继续,某条区间连续 180 秒没有任何字节才判失败。因此大文件(实测 700MiB)在该链路的约 0.73MiB/s 速率下会跑十几分钟并正常完成;绝对上限只是防止传输卡死后永久占用,按载荷大小放大
|
|
128
|
+
- 下载失败不留残留文件:已写入的数据会被丢弃、目标文件被删除;若失败发生在任何字节到达之前(路径不存在、目标是目录、主机不可达),已存在的本地文件保持原样不动(目标文件在首次写入时才创建)
|
|
129
|
+
- 一次传输被中途放弃时(例如某次认证尝试失败后从头重试),目标机上的发送进程可能残留并继续占用该文件,直到其 shell 被回收;正常结束的传输会自行退出。遇到远端文件删不掉时,先结束目标机上对应的 `powershell.exe` 发送进程再删
|
|
117
130
|
- 单命令默认 60s 超时,可传 `timeoutMs`
|
|
118
131
|
- 目标机需已启用 WinRM(见上);HTTP 明文 Basic 不应用于公网
|
|
119
132
|
- 面板关闭再打开会回到「主机」页签:面板是 `main` 插槽的占用者,切回对话时卸载,页签状态不跨开关保留
|
|
Binary file
|