本文目录
背景
在本地给SCOM写一个管理包(MP),写完了需要手动通过远程桌面拷贝至远程测试机器,然后打开SCOM的控制台,将MP导入,重复很多遍以后发现这些工作可以自动化。分为两个步骤:
- PowerShell拷贝文件至远程机器 (重点)
- 通过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
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!
如果是从本地copy文件到cloud上的VM上呢?
@PW
如果你的Cloud VM开启了http服务,你完全可以按照Start-BitsTransfer中提到的步骤去配置。
如果你的Cloud VM开启了PowerShell远程管理,你就可以使用Send-File。
如果你有权限,也可以自己配置开启PowerShell远程管理,按照前一篇文章,”PowerShell远程管理Windows Azure上面的虚拟机“。
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
send-file不是PowerSehll 内置的命令,你应当从文章的链接中去下载,然后导入。
我现在有一台机器只能够通过cmd进行远程管理,但我又想把这台机器上面一个大文件给传出来,cmd下文件传输太慢几乎无法动弹。
这种情况下,也可以照您文章的思路,写一个文件传输的ps脚本,通过cmd调用实现文件上传吗?
这里一是cmd调用powershell的问题能够奏效?二是powershell在命令行模式下能否开启文件传输过程?
谢谢老师指导
只要是win7以上的系统的,自带PowerShell. PowerShell中可以调用cmd,cmd中也可以调用的,所以只要PowerShell中支持,cmd自然可以支持。
cmd中调用PowerShell:
PowerShell中调用cmd:
PowerShell 5.0 的Copy-Item已经支持 -FromSession 和 -ToSession 参数了,传输文件方便多了
Remote File Copy
Copy-Item has new parameters -ToSession/-FromSession It transfer binary via PSRemoting using Base64 encoding. (It is relatively slow)
PowerShell ISE remote file edit feature use similar mechanism.
Example: https://gist.github.com/altrive/0decf052f0d0ebabfdf0
send-file函数怎么下载