首页/系统/Windows 运维速查/Copy-Item -ToSession 远程传文件

Copy-Item -ToSession 远程传文件

纯 PowerShell 方案:建 PSSession 后用 Copy-Item -ToSession/-FromSession 双向传输,走 WinRM 通道无需 SMB。

Windows 运维速查系统更新于 2026-10-13

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 一定执行。

易错点

  • 目标路径写成本机路径:传到错误位置或直接报错,排查时容易误判为权限问题
  • 用该方式做大文件批量传输:吞吐受限且无断点续传,中断后只能重头来,应换 SMB 或支持续传的工具
  • 忽略目标机前提条件:远程管理未启用或防火墙未放行时,会话根本建立不起来
  • 会话未释放:长时间运行的管理机上会话累积,占用资源且留下认证上下文
  • 传输后不核对:只信命令无报错,未在目标机确认文件大小与时间戳,出现半截文件才发现

数据来源与参考

  • Microsoft Learn:Copy-Item -ToSession

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌