尝试使用WMI将文件从一台XP PC复制到另一台,因为RPC和UNC不可用
我是VBScript的新手。 我无法find一种方法来从VBS中使用WMI将文件从一台XP主机复制到另一台主机。 复制文件(RPC – 远程过程调用,SMB,UNC)的常用方法对于几台主机不可用,但是WMI可用于所有主机,并且需要将文件从pipe理主机复制到目标Windows主机。 我以为我会find一些示例代码,但我没有发现任何信息。 还没有发现任何告诉我不能做的事情。
源文件是我的pipe理员电脑的“F:\ TEMP”文件夹中的可执行文件和“test1.txt”。 我想将文件放在远程主机HOST1的“C:\ TEMP”文件夹中。 我在两台主机上都有完整的pipe理员权限。 这是我迄今为止,只是为了一个文件(保持简单的testing):
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
我了解到WMI无法在远程主机上创build文件,也无法通过networking连接复制文件: 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或批处理脚本:
- 远程主机上的pipe理员权限;
- 在远程主机上启用WMI
- 远程主机可以访问的networking共享(使用RPC,UNC,FTP等,但不包括 DFS!(“分布式文件系统” – 请参阅注释);以及
- psexec.exe和networking共享上的“正常”脚本。
重要说明:请勿使用DFS映射networking共享! 如果您使用分布式文件系统进行networking共享, 则会失败。 一个错误代码可能取决于你如何尝试是“系统错误1312” ,不pipe你使用哪个操作系统(例如XP,Win 7)。
当RPC在远程主机上不可用,但WMI是,则以下方法将在远程主机的c:\ temp文件夹中创build一个本地ASCII文件,其中包含文本“myTextCommands”,不带引号。
' 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
注意上面脚本中的重要限制:它只能创buildASCII文件 – 不是二进制文件。
让我们用这种技术来映射一个盘符:
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
映射networking驱动器后,将脚本复制到主机:
strCommand="cmd /c xcopy Z:\scripts\SCRIPT1.bat c:\temp\ >>" & strRemoteLog Call errProcess
SCRIPT1.bat已经准备就绪,所以在远程主机上启动psexec,在脚本中传递一个variablesstrUserID,这个variables可以在之前获得,例如:
strCommand="cmd /c Z:\psexec \\%COMPUTERNAME% /accepteula -s -n 120 " _ & cmd /cc:\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。
这是完整的“示例”集成脚本。 随意build议修复,改进等
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 /cc:\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
首先,我认为您的代码中存在一个拼写错误:
errResults = objFolder.Copy("f:\temp\test1.txt")
我认为你的意思是:
errResults = objFiles.Copy("f:\temp\test1.txt")
其次,我不知道你想做什么是可能的。 我认为你得到的代码可能会将远程计算机上的目录中的文件复制到远程计算机上的另一个目录中。
对于一个解决scheme,如果WMI在所有计算机上远程可用,则意味着至less有一个端口是打开的。 如果是这样,有没有其他的端口是开放的? 如果是这样,也许你可以在你的pipe理主机的端口X上build立一个FTP服务器,然后让其他主机通过自动化默认XP FTP客户端来发送文件。
我知道这个问题是古老的,但碰到的是当我试图find一个解决scheme,所以计算将引导人们回答我写了并张贴在这里:
.NET – 将可执行文件复制到另一台计算机并执行
简而言之,可以使用WMI对任何文件(包括exe文件)进行base64转换,然后使用certutil进行解码。
你有没有尝试过以下?
set fso = CreateObject("Scripting.FileSystemObject") fso.CopyFile "f:\temp\test1.txt", "\\HOST1\C$\temp\test1.txt", true
WMI是一个信息数据库。 你不能用它来复制文件。