2012-08-01 58 views
4

我是VBScript的新手。我无法找到在VBS中使用WMI将文件从一台XP主机复制到另一台的方法。复制文件(RPC - 远程过程调用,SMB,UNC)的常用方式不可用于多台主机,但WMI可用于所有主机,并且需要将文件从管理主机复制到目标Windows主机。我想我会找到一些示例代码,但我没有发现任何信息。还没有发现任何告诉我它不能完成的事情。尝试使用WMI将文件从一台XP PC复制到另一台,因为RPC和UNC不可用

源文件是我的管理员电脑的'F:\ TEMP'文件夹中的可执行文件和'test1.txt'。我想将文件放在远程主机HOST1的'C:\ TEMP'文件夹中。我拥有两台主机的完整管理权限。这里是我到目前为止,只为一个文件(为了保持测试简单):

strComputer = "HOST1" 
Set objWMIService = GetObject("winmgmts:" _ 
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") 
Set colFiles = objWMIService.ExecQuery(_ 
    "Select * from Win32_Directory where Name = 'c:\\temp'") 
For Each objFiles in colFiles 
    errResults = objFolder.Copy("f:\temp\test1.txt") 
    Wscript.Echo errResults 
Next 
+0

http://msdn.microsoft.com/en-us/library/windows/desktop/aa394594(v=vs.85).aspx – 2012-08-02 00:09:13

+0

thx Boo,但该链接不告诉任何方法将文件复制到另一个使用WMI的主机 – Lizz 2012-08-02 04:25:48

+0

声明'objFolder'在哪里?这可能是一个错误的var名称?此外,我不熟悉VB脚本,但它看起来像你在循环中复制一个和相同的文件,这很奇怪。 (我不拖车,只要确保其他错误不会导致问题) – 2012-08-02 13:54:27

回答

6

我了解到,WMI不能在远程主机上创建的文件,它不能在网络连接复制文件: http://msdn.microsoft.com/en-us/library/windows/desktop/aa389288%28v=vs.85%29.aspx

但是,它可以运行CMD进程。这里是弗兰克·怀特的代码在C调,其次是他的榜样: https://stackoverflow.com/a/8913231/1569434

InputParameters("CommandLine") = "cmd /c echo myFTPCommands > c:\ftpscript.txt" 

您将需要四样东西使用下面所有的小脚本,它建立在相互使用PSEXEC运行“正常”的VBScript或批处理脚本在远程主机上:

  1. 远程主机上的管理权限;远程主机
  2. 网络共享上启用
  3. WMI(使用RPC,UNC,FTP等,但不DFS(“分布式文件系统” - 见注),你的远程主机可以访问;!和
  4. psexec.exe和网络共享你的 “正常” 的脚本(S)

重要提示:使用DFS映射网络共享!它失败,如果您使用分布式文件系统为您的网络共享。无论您使用哪种操作系统(例如XP,Win 7),您可能会得到的错误代码取决于您的尝试方法"System error 1312"

如果RPC在远程主机上不可用,但WMI是,则以下方法将在远程主机的c:\ temp文件夹(包含文本“myTextCommands”,不带引号)上创建本地ASCII文件。

' https://stackoverflow.com/questions/8884728/wmi-remote-process-to-copy-file 
strCommand = "cmd /c echo myTextCommands > c:\temp\testscript.txt" 
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" _ 
    & strComputer & "\root\cimv2") 
Set objProcess = objWMIService.Get("Win32_Process") 
errReturn = objProcess.Create(strCommand, null, null, intProcessID) 
' See following link for error codes returned by errReturn 
' http://msdn.microsoft.com/en-us/library/windows/desktop/aa389388(v=vs.85).aspx 

注意上面脚本中的重要限制:它只能创建ASCII文件 - 不是二进制文件。

让我们使用该技术来映射一个驱动器号:

strCommand = "cmd /c net use z: " & MyShare & " /user:%USERDOMAIN%\%USERNAME% " _ 
    & strPassword & ">" & strRemoteLog 
Set objProcess = objWMIService.Get("Win32_Process") 
Call errProcess 

其中 “strRemoteLog” 设置为类似 “C:\ TEMP \ MyLog.txt”, “strPassword” 提示(见完整的脚本例如,在底部参考),以及“errProcess”是上面提到运行使用“CMD/C”特技以下过程的子程序:

Sub errProcess 
errReturn = objProcess.Create(strCommand, null, null, intProcessID) 
If errReturn = 0 Then 
    Wscript.Echo "Process was started with a process ID: " & intProcessID 
    WScript.Sleep 5000 
Else 
    Wscript.Echo "Process could not be started due to error: " & errReturn 
End If 
End Sub 

随着映射,脚本复制到主机的网络驱动器:

strCommand="cmd /c xcopy Z:\scripts\SCRIPT1.bat c:\temp\ >>" & strRemoteLog 
Call errProcess 

SCRIPT1.bat准备好,所以在远程主机上启动PSEXEC反对,通过你的脚本,将较早获得,在这里例如可变strUserID:

strCommand="cmd /c Z:\psexec \\%COMPUTERNAME% /accepteula -s -n 120 " _ 
    & cmd /c c:\temp\SCRIPT1.bat " & strUserID & ">>" & strRemoteLog 
Call errProcess 

一旦PSEXEC完成后,你可能想要保存结果。因此,您重命名日志文件,上传它,取消映射驱动器,并清理残留文件:

strCommand="cmd /c REN " & strRemoteLog & " SCRIPT1-%COMPUTERNAME%.txt" 
Call errProcess 
strCommand="cmd /c MOVE /Y c:\temp\SCRIPT1*.txt Z:\scripts\LOGS\" 
Call errProcess 
strCommand="cmd /c net use * /del /Y" 
Call errProcess 
strCommand="cmd /c del c:\temp\SCRIPT1*.bat /q" 
Call errProcess 

您完成了。您已成功映射驱动器,针对远程主机运行例程脚本并上传其输出。

注意此方法也适用于带有UAC的Windows 7和Windows 2008。

下面是完整的“示例”集成脚本。随时提出修正,改良等

On Error Resume Next 

MyShare="\\SHARE1" 
strRemoteLog="c:\temp\MapZ.txt" 

' Set remote hostname 
strComputer="HOST2" 
'strComputer = InputBox("Enter Computer name", _ 
'"Find PC", strComputer) 

' Set remote userid 
strUserID="USERID1" 
'strComputer = InputBox("Enter userid", _ 
'"Find User", strComputer) 

' Enumerate cimv2 on remote host strComputer 
Set objWMIService = GetObject("winmgmts:" & _ 
"{impersonationLevel=Impersonate}!//" & strComputer & "\root\cimv2") 

' Verify remote host exists on domain 
If(IsEmpty(objWMIService) = True) Then 
    WScript.Echo("OBJECT_NOT_INITIALIZED :: " & strComputer) 
    WScript.Quit(OBJECT_NOT_INITIALIZED) 
End If 

' Prompt for masked password 
strPassword=GetPass 

' Build and run command to execute on strComputer 
strCommand = "cmd /c net use z: " & MyShare & " /user:%USERDOMAIN%\%USERNAME% " & strPassword & ">" & strRemoteLog 
Set objProcess = objWMIService.Get("Win32_Process") 
Call errProcess 

' Copy script(s) from MyShare to HOST2 since psexec cannot run scripts on shared drives 
strCommand="cmd /c xcopy Z:\scripts\cleanpclocal.bat c:\temp\ /V /C /I /Q /H /R /Y>>" & strRemoteLog 
Call errProcess 

' Change directory to c:\temp 
'strCommand="cmd /c cd c:\temp>" & strRemoteLog 
'Call errProcess 

' Start PSEXEC against script 
strCommand="cmd /c Z:\psexec \\%COMPUTERNAME% /accepteula -s -n 120 cmd /c c:\temp\cleanpclocal.bat " & strUserID & ">>" & strRemoteLog 
Call errProcess 

' Rename logfile to include hostname, upload to share, unmap networked drive, and delete script 
strCommand="cmd /c REN " & strRemoteLog & " cleanpc-%COMPUTERNAME%.txt" 
Call errProcess 
strCommand="cmd /c MOVE /Y c:\temp\clean*.txt Z:\scripts\LOGS\" 
Call errProcess 
strCommand="cmd /c net use * /del /Y" 
Call errProcess 
strCommand="cmd /c del c:\temp\clean*.bat /q" 
Call errProcess 

WScript.Quit 





' *********** 
' APPENDIX 
' Subroutines, functions 
' *********** 

' **SUBROUTINES** 
'strCommand="cmd /c dir z:\scripts\>" & strRemoteLog ' Works to get dir of z:\scripts\ 

' Function to handle errReturn 
Sub errProcess 
WScript.Echo "strCommand=" & strCommand 
errReturn = objProcess.Create(strCommand, null, null, intProcessID) 

If errReturn = 0 Then 
    Wscript.Echo "Process was started with a process ID: " & intProcessID 
    WScript.Sleep 5000 
Else 
    Wscript.Echo "Process could not be started due to error: " & errReturn 
End If 
WScript.Echo 

' Error return codes for Create method of the Win32_Process Class 
' http://msdn.microsoft.com/en-us/library/windows/desktop/aa389388(v=vs.85).aspx 
' 0=Successful Completion 
' 2=Access Denied 
' 3=Insufficient Privilege 
' 8=Unknown failure 
' 9=Path Not Found 
' 21=Invalid Parameter 

End Sub 



' **FUNCTIONS** 

' Subroutine to get masked password 
Function GetPass 
' Mask Passwords Using Internet Explorer 
' Ensure you follow the technet.com instructions and create file password.htm 
' http://blogs.technet.com/b/heyscriptingguy/archive/2005/02/04/how-can-i-mask-passwords-using-an-inputbox.aspx 

Set objExplorer = WScript.CreateObject _ 
    ("InternetExplorer.Application", "IE_") 

objExplorer.Navigate "file:///C:\SCRIPTS\password.htm" 
objExplorer.ToolBar = 0 
objExplorer.StatusBar = 0 
objExplorer.Width = 400 
objExplorer.Height = 350 
objExplorer.Left = 300 
objExplorer.Top = 200 
objExplorer.Visible = 1    

Do While (objExplorer.Document.Body.All.OKClicked.Value = "") 
    Wscript.Sleep 250     
Loop 

strPassword = objExplorer.Document.Body.All.UserPassword.Value 
strButton = objExplorer.Document.Body.All.OKClicked.Value 
objExplorer.Quit 
Wscript.Sleep 250 

If strButton = "Cancelled" Then 
    Wscript.Quit 
'Else 
' Wscript.Echo strPassword 
End If 

' Return the password 
GetPass = strPassword 

End Function 
+1

令人敬畏的写作! – 2012-08-28 12:22:34

+0

你是灵感,弗兰克,所以*谢谢*! :) – Lizz 2012-08-28 17:07:25

1

首先,我觉得有一个在你的代码中的错字,你已经写了:

errResults = objFolder.Copy("f:\temp\test1.txt") 

我认为你的意思是:

errResults = objFiles.Copy("f:\temp\test1.txt") 

其次,我不知道你想做什么是可能的。我认为你得到的代码可能会将远程计算机上目录中的文件复制到远程计算机上的另一个目录中。

对于解决方案,如果WMI在所有计算机上远程可用,则意味着至少有一个端口处于打开状态。如果是这样的话,有没有其他的端口是开放的?如果是这样,也许你可以在你的管理主机的端口X上建立一个FTP服务器,然后让其他主机通过自动化默认的XP FTP客户端来发送文件。

+0

谢谢,ho1!你的错字更正是正确的。另外,我相信你是正确的WMI没有能力(还没有?)复制文件而不使用一些外部技术,如FTP,RPC等。我要将我的脚本更新为1)映射到网络共享并将文件复制到该共享文件夹; 2)使用WMI连接到远程PC;和3)映射到网络共享并将文件拉下。准备好后我会更新这个问题。我只希望微软明确定义WMI ... – Lizz 2012-08-03 09:58:01

-1

您是否尝试过以下方法?

set fso = CreateObject("Scripting.FileSystemObject") 
fso.CopyFile "f:\temp\test1.txt", "\\HOST1\C$\temp\test1.txt", true 
+0

不可以,因为那些代码可以复制到启用了RPC的主机上,而我们没有。谢谢,寿。 – Lizz 2012-08-21 03:47:39

-3

WMI是一个信息数据库。你不能用它来复制文件。

+1

@Vishal D - 呃......你真的可能想在做出这样的评论之前获得更多的知识。 – 2012-08-28 12:22:02

相关问题