PowerShell 远程文件传输 9


背景

在本地给SCOM写一个管理包(MP),写完了需要手动通过远程桌面拷贝至远程测试机器,然后打开SCOM的控制台,将MP导入,重复很多遍以后发现这些工作可以自动化。分为两个步骤:

  1. PowerShell拷贝文件至远程机器 (重点)
  2. 通过Invoke-Command命令导入MP(省略)

在步骤1遇到问题了,怎样将文件通过PowerShell拷贝至远程机器的共享目录呢?我前后尝试了三种方法:

Copy-Item

Copy-Item最直接,缺点是虽然有一个-credential参数,但是这是一个形同摆设的参数,运行后错误信息提示:

The FileSystem provider supports credentials only on the New-PSDrive cmdlet. Perform the operation again without specifying credentials.

如果不用Credential参数,提示用户名和密码不对,坑爹,你也没有给我机会填用户名和密码啊。

Copy-Item : The user name or password is incorrect.

这也不行,那也不行,你想死啊。此处针对Copy-Item我在这里提供两个变通方法:

提前输入密码

打开资源管理器,访问你的共享目录//pstips.net/share/,然后提示你输入密码,输入一次。再回过头来执行PowerShell命令中的Copy-Item,不需要指定用户凭据,可保一天无虞,因为你第二天可能重启电脑。如何自动化呢?请使用cmdkey.exe,

cmdkey /add:targetname /user:username /pass:password

映射网络路径

将远程文件夹和本地的盘符映射,访问起来非常方便。如何自动化呢?请使用com对象WScript.Network

$net = New-Object -com WScript.Network
$drive = "Z:"
$path = "\\pstips.net\logs"
$net.mapnetworkdrive($drive, $path, $true, $username, $password)

Start-BitsTransfer

Start-BitsTransfer的优点是支持同步和异步,进度条显示。所以更多被用来下载文件: 比如HTTP下载,FTP下载。但是经过测试,发现不支持访问共享文件夹,并上传。 但是该命令有个参数-TransferType“,支持“Upload”,那也就是支持“HTTP”协议(非FTP)上传文件了。具体配置如下: 在远程机器上配置IIS后,新建了虚拟目录upload。尝试执行下面命令:

$source = "Test.MP.xml"
$target = 'http://pstips.net/upload/Test.MP.xml'
Start-BitsTransfer  $source $target -Credential (Get-Credential) -TransferType Upload

执行失败,错误信息:

Start-BitsTransfer : HTTP status 405: The method used is not allowed.

显然远程服务器不支持upload。那是因为我缺少了一步:BITS配置

  • 在服务器的添加功能中勾选”Background Intelligent Transfer Service (BITS)”, 和下面的“IIS Server Extension”,启用该功能。
  • 重启IIS管理器,在Other 分类下多了一个“BITS Uploads”配置,打开并配置“允许客户端上传文件”,在Action栏应用更改。

再回过头来执行Start-BitsTransfer,上传文件即可成功。

如果服务器端已经存在一个同名的文件,则会有个非常不友好的提示,我觉得应当算个bug

Access is denied.

Send-File

这是老外写的一个函数。使用场合,当我在使用PowerShell远程管理时,已经创建了一个PSSession,我更期望借助这个Sesion来传文件。如果你的文件是文本文件,文件长度不大,完全可以在Invoke-Command时,将文件内容以字符串参数的形式传递给远程机器。用户不禁要问: 如果是二进制文件怎么办?当然可以使用base64字符串了。 如果文件太大怎么办,当然要对文件按字节进行分割了。 这也是Send-File的原理了。

$session = New-PsSession pstips.net
Send-File c:\temp\test.exe c:\temp\test.exe $session

 

本文链接: https://www.pstips.net/powershell-transform-file-remotely.html
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!

关于 Mooser Lee

我是一个Powershell的爱好者,创建了PowerShell中文博客,热衷于Powershell技术的搜集和分享。本站部分内容来源于互联网,不足之处敬请谅解,并欢迎您批评指正。

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注

9 条评论 “PowerShell 远程文件传输

    • Mooser Lee 文章作者

      @PW
      如果你的Cloud VM开启了http服务,你完全可以按照Start-BitsTransfer中提到的步骤去配置。
      如果你的Cloud VM开启了PowerShell远程管理,你就可以使用Send-File。
      如果你有权限,也可以自己配置开启PowerShell远程管理,按照前一篇文章,”PowerShell远程管理Windows Azure上面的虚拟机“。

      • pw

        Send-File : The term ‘Send-File’ is not recognized as the name of a cmdlet, function, script file, or operable program
        Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
        At line:1 char:1
        + Send-File
        + ~~~~~~~~~
        + CategoryInfo : ObjectNotFound: (Send-File:String) [], CommandNotFoundException
        + FullyQualifiedErrorId : CommandNotFoundException

  • lee

    我现在有一台机器只能够通过cmd进行远程管理,但我又想把这台机器上面一个大文件给传出来,cmd下文件传输太慢几乎无法动弹。
    这种情况下,也可以照您文章的思路,写一个文件传输的ps脚本,通过cmd调用实现文件上传吗?
    这里一是cmd调用powershell的问题能够奏效?二是powershell在命令行模式下能否开启文件传输过程?
    谢谢老师指导