背景
在本地给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
×用微信扫描并分享