Copy-Item -ToSession 是什么
PowerShell 远程传输文件的原生方式:先建立 PSSession,再用 Copy-Item 的 -ToSession 或 -FromSession 双向传输。它最大的价值是「通道已就绪」——很多安全加固环境只放行远程管理的端口,SMB 的文件共享端口被禁,此时命令行传输走的就是同一条已开通道,不需要额外开放端口。代价是吞吐明显低于 SMB,大文件与批量传输要有心理预期。
基本信息
| 适用平台 | Windows PowerShell 5.1 与 PowerShell 7(Windows 目标);PowerShell 7 也可对 Linux 目标使用 |
|---|---|
| 基本语法 | Copy-Item -Path 本地路径 -Destination 远程路径 -ToSession $session |
| 反向传输 | Copy-Item -Path 远程路径 -Destination 本地路径 -FromSession $session |
| 会话建立 | New-PSSession -ComputerName 主机,可带 -Credential 与 -UseSSL |
| 前提条件 | 目标机启用远程管理、网络与认证链路可用(工作组场景见另一条相关条目) |
| 权限要求 | 需要对源与目标路径的读写权限,UAC 与文件系统权限照常生效 |
典型使用场景
- 受限网络传输:只放行远程管理端口、SMB 被禁的环境中投放安装包
- 远程取日志:把远端日志文件拉回本地集中分析
- 脚本化部署:配合会话一次性完成投放、执行、回收结果
- 临时修复:手动上传补丁文件、配置文件到目标机
- 无共享环境:没有可写共享目录时完成文件交换
常用示例
常用示例
$s = New-PSSession -ComputerName srv01 # 建立会话
Copy-Item C:\pkg\agent.msi -Destination C:\temp\ -ToSession $s # 上传文件到远程
Copy-Item C:\pkg\ -Destination C:\temp\pkg -ToSession $s -Recurse # 上传整个目录
Copy-Item C:\logs\app.log -Destination C:\collect\ -FromSession $s # 从远程取回文件
Invoke-Command -Session $s -ScriptBlock { Get-ChildItem C:\temp } # 在会话中核对结果
Remove-PSSession $s # 用完释放会话
# 多台目标:为每台建会话后逐个传输
# $hosts = 'srv01','srv02'
# $sessions = New-PSSession -ComputerName $hosts
# foreach ($x in $sessions) { Copy-Item C:\pkg\agent.msi -Destination C:\temp\ -ToSession $x }传输方式对照
| 方式 | 通道 | 适用场景 |
|---|---|---|
| Copy-Item -ToSession | 远程管理通道 | 端口受限环境、脚本内顺带传文件 |
| robocopy over SMB | 文件共享端口 | 大批量、大文件、需要镜像与重试 |
| BITS 传输 | HTTP/SMB 均可 | 大文件后台传输,可断点续传 |
| 共享映射复制 | 文件共享 | 交互式操作与常规拷贝 |
目标路径要按「远程机器视角」书写:写 C:\temp\ 表示目标机的 C 盘临时目录,不是本机路径。写成本机路径会得到「路径不存在」或传到意外位置。
大文件经远程管理通道传输速度受协议与序列化开销限制,明显慢于 SMB,且中途中断没有断点续传。量级较大的传输优先考虑文件共享方式,或用支持续传的传输工具。
批量与核对
批量与核对
# 建立多台会话并逐个投放,随后统一核对
$hosts = 'srv01','srv02','srv03'
$sessions = New-PSSession -ComputerName $hosts -ErrorAction Continue
foreach ($x in $sessions) {
Copy-Item C:\pkg\agent.msi -Destination C:\temp\ -ToSession $x -Force -ErrorAction Continue
}
Invoke-Command -Session $sessions -ScriptBlock {
Get-Item C:\temp\agent.msi | Select-Object @{n='Host';e={$env:COMPUTERNAME}}, Length, LastWriteTime
}
Get-PSSession | Remove-PSSession # 收尾释放全部会话会话用完要显式释放:遗留会话会占用目标资源并保持认证上下文,管理主机上越积越多;脚本里建议用 try/finally 保证 Remove-PSSession 一定执行。