Intentando copiar archivos de una PC XP a otra usando WMI, ya que RPC y UNC no están disponibles

Soy nuevo en VBScript. No puedo encontrar una forma de copiar archivos de un servidor XP a otro usando WMI en una VBS. La forma habitual de copiar archivos (RPC – Llamada a procedimiento remoto, SMB, UNC) no está disponible para varios hosts, pero WMI está disponible para todos los hosts, y necesito copiar los archivos de mi host de administrador a un host de Windows de destino. Pensé que encontraría algún código de muestra pero no encontré información sobre él. No he encontrado nada que me diga que tampoco se puede hacer.

Los archivos fuente son un ejecutable y ‘test1.txt’ en la carpeta ‘F: \ TEMP’ de mi computadora de administrador. Quiero poner los archivos en la carpeta ‘C: \ TEMP’ del host remoto HOST1. Tengo todos los derechos de administrador en ambos hosts. Esto es lo que tengo hasta ahora, solo para un archivo (para mantener las pruebas simples):

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 

Me enteré de que WMI no puede crear archivos en un host remoto y no puede copiar archivos a través de una conexión de red: http://msdn.microsoft.com/en-us/library/windows/desktop/aa389288%28v=vs.85% 29.aspx

Sin embargo, puede ejecutar un proceso cmd. Aquí está el código de Frank White en C sharp, seguido de su ejemplo: https://stackoverflow.com/a/8913231/1569434

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

Necesitarás cuatro cosas para usar los siguientes scriptlets, que se complementan entre sí para usar psexec para ejecutar un script VBScript o por lotes “normal” en el host remoto:

  1. derechos de administrador en el host remoto;
  2. WMI habilitado en el host remoto
  3. un recurso compartido de red (usando RPC, UNC, FTP, etc., pero NO DFS! (“Sistema de archivos distribuido” – vea la nota) al que puede acceder el host remoto;
  4. psexec.exe y su (s) script (s) “normal (es)” en el recurso compartido de la red.

Nota importante: NO use DFS para mapear el recurso compartido de red. Fallará si usa el Sistema de archivos distribuidos para su recurso compartido de red. Un código de error que puede obtener dependiendo de cómo lo intente es “Error del sistema 1312” , no importa qué sistema operativo (por ejemplo, XP, Win 7) utilice.

Cuando RPC no está disponible en un host remoto pero WMI sí lo está, el siguiente método creará un archivo ASCII local en la carpeta c: \ temp del host remoto, que contiene el texto “myTextCommands”, sin las comillas.

 ' 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 

Observe la importante limitación en el script anterior: solo puede crear archivos ASCII, no binarios.

Usemos esa técnica para mapear una letra de unidad:

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

donde “strRemoteLog” está configurado en algo como “c: \ temp \ MyLog.txt”, se solicita “strPassword” (consulte el ejemplo completo del script y la referencia en la parte inferior) y “errProcess” es una subrutina que ejecuta el siguiente proceso utilizando truco “cmd / c” mencionado anteriormente:

 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 

Con una unidad de red asignada, copie su secuencia de comandos al host:

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

SCRIPT1.bat está listo, por lo tanto, inicie psexec en el host remoto, pasando su script una variable strUserID que se obtendría antes y está aquí por ejemplo:

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

Una vez que psexec finaliza, es posible que desee guardar los resultados. Así que cambia el nombre del archivo de registro, lo sube, desasigna la unidad y limpia los archivos residuales:

 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 

Ya terminaste Ha correlacionado correctamente una unidad, ejecuta una secuencia de comandos de rutina contra el host remoto y ha cargado su salida.

Tenga en cuenta que este método también funciona en Windows 7 y Windows 2008 con UAC.

Aquí está la secuencia de comandos integrada de “muestra” completa. Siéntase libre de sugerir correcciones, mejoras, etc.

 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 

En primer lugar, creo que hay un error tipográfico en tu código donde has escrito:

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

Creo que quisiste decir:

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

En segundo lugar, no sé si lo que estás tratando de hacer es posible. Creo que el código que tienes puede copiar un archivo de un directorio en la computadora remota a otro directorio en la computadora remota.

Sin embargo, para una solución, si WMI está disponible de forma remota en todas las computadoras, eso significa que al menos un puerto está abierto. Si ese es el caso, ¿hay otros puertos abiertos? Si es así, tal vez podría configurar un servidor FTP en su host de administrador en el puerto X y luego hacer que los otros hosts envíen el archivo automatizando el cliente de XP FTP predeterminado.

Sé que esta pregunta es antigua, pero me di cuenta de que cuando estaba tratando de encontrar una solución, pensé que dirigiría a las personas a una respuesta que escribí y publiqué aquí:

.NET – Copiar un ejecutable a través de LAN a otra computadora y ejecutarlo

En resumen, es posible hacer eco de la conversión base64 de cualquier archivo (incluido un exe) utilizando WMI y luego decodificarlo con certutil.

Has intentado lo siguiente ?

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

WMI es una base de datos de información. No puedes usarlo para copiar archivos.