Link to home
Start Free TrialLog in
Avatar of ADTADatacenter
ADTADatacenter

asked on

Script to Copy file to client macine

I needed a script to copy a file to client machines
I will double click the script file
It should take the machine names from an input file
Script should open a status window or a blank command prompt window so that I know it is still running
Script should give a message once it has completed
Script should log success and failures with the computer names mentioned
Success and failures; in a separate file if possible
Many thanks to you all for helping me in the past
Avatar of arnold
arnold
Flag of United States of America image

Where do you want this file placed??

Why not use a simple startup script

@echo off
FILENAME="file.ext"
if not exist "c:\location\%FILENAME%" (
copy \\shareserver\sharename\%FILENAME% c:\location\
echo "on %date% %Time% ran on %COMPUTERNAME% and copied the file %filename%" >> \\shareserver\sharename\report_file_copy.log
)


if you want to have an option to copy the file on another occasion, you could add a check to a share that deals with overwriting the file or deleting the file prior to getting to the test.
Avatar of ADTADatacenter
ADTADatacenter

ASKER

Dear arnold,
I needed a script to run manually
As machines are not regularly restarted
And as the file should be copied to a system location user group policy will get an access denied error
The file will copy of attached to a computer group policy
But as machines are not regularly restarted \I will have to wait until restart of many machines

What about a script that
- you can run on your own machine.  It takes a list of computer names held on your own machine in a text file.  Then runs a batch file on each target machine using PSEXEC.

Try out the attached.  Save them all into a folder and rename them

Remote_run.vbs
batchfile.bat
computers.txt

Download psexec.exe from Microsoft Systernals Suite.
http://technet.microsoft.com/en-us/sysinternals/bb897553

Copy PSEXEC.EXE into the same folder

Populate the computers.txt file with your target computer names.

Double click on REMOTE_RUN.vbs to start it all happening and watch it happen before your eyes..

cheers
MarkieS batchfile.txt computers.txt REMOTE-RUN.txt
Dont forget to edit arnolds code so that it matches your environment.  
I have copied it into batchfile.txt so you should save it as batchfile.bat

cheers
MarkieS
You do not really need to copy the batch file to the individual systems

strCMD= chr(34) & "\\shareserver\sharename\batchfile.bat" & chr(34)

Another option is instead of calling the remote script, simply do a copy of the file to the remote and then check the status of the copy attempt.
Dear Arnold and MarkieS,
I was under flu / viral fever so could not try your advised solutions
I have used psexec extensively in the past but do not have good experience since client OS Windows 7 32 but and 64 bit came over
Anyway I will try the above and revert back
Dear MarkieS;
I duoble clicked the file
Nothing happens
I ran it in commad prompt; nothing happens
I am using a Windows 7 64 bit machine

Please advise

To be more clear
I have the fiels

REMOTE_RUN.vbs
computers.txt
batchfile.bat
psexec.exe
pdh.dll
Pstools.chm

All the above in the same folder
I have edited the batch file
I tested by running the batch file separately
It runs fine enough
It is probably to do with rights on the remote machines.  Do all your machines have the same local admin account password?  Or can you run it as an account that has local admi rights?

If all your machines have the same local admin password, you could simply try running your command prompt as a local Administrator and then launch remote_run.vbs from the command prompt.

You can avoid relying on the remote machine by remotely running the remote bat file.

psexec \s %client% "\\shareserver\sharename\batchfile.bat"
The problem might be that AUC blocking the running of the batchfile.
can you using psexec /s \\testsystem cmd
connect and get a prompt ?
Dear MarkieS,
Yes, i am logged-in to my machine with a user having admin rights on target machines
I am testing this on my test machines
The script does not show any window also
I think there is something wrong with the vbs script
Below is the contents of the script please check and advice if I am doing anything wrong


vbs script
File name "REMOTE-RUN.vbs"

'--------------------------------------------------------
'Remote_Run.vbs
'
'for each computer in computers.txt, the vbs copies
'batchfile.bat to:
'C:\temp
'on the remote machine, and executes it with psexec.exe
'(psexec.exe provided by sysinternals.com)
'--------------------------------------------------------
Const OverwriteExisting = True
'on error resume next
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set txtStream = objFSO.OpenTextFile(GetPath & "computers.txt")
      Do While Not (txtStream.atEndOfStream)
            strComputer = txtStream.ReadLine
            if objFSO.FolderExists("\\" & strComputer & "C$\temp") then
                  if objFSO.FileExists("\\" & strComputer & "\C$\temp\batchfile.bat") then
                        strCMD = Chr(34) & "C:\temp\batchfile.bat" & Chr(34)
                        errReturn = psexec(strComputer,strCMD)
                  else
                        strSource =  GetPAth & "batchfile.bat"
                        objFSO.CopyFile strSource , "\\" & strComputer & "\C$\temp\",OverwriteExisting
                        wscript.Sleep 3000
                        strCMD = Chr(34) & "C:\temp\batchfile.bat" & Chr(34)
                        errReturn = psexec(strComputer,strCMD)
                  end if
            end if
      Loop
wscript.sleep 5000
'//////////////////////////////////////////////////////////////////////////////////////////////////////////
Function GetPath
DIM Path
 Path = WScript.ScriptFullName  ' Script name
 GetPath = LEFT(Path, INSTRREV(Path, "\"))
End Function

Function psexec(strComputer,strCMD)

Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run "psexec \\" & strComputer & " " & strCMD


End Function


Batch file contents
Batch filename "batchfile.bat"

REM  This batch file will be executed by the target machine

@echo off
set FILENAME="NameOfFileToBeBeCopiedWithExtension"

if not exist "c:\Windows\%FILENAME%" (
copy \\servername\sharename\sub-foldername\%FILENAME% c:\Windows\
echo "on %date% %Time% ran on %COMPUTERNAME% and copied the file %filename%" >> \\servername\sharename\sub-foldername\report_file_copy.log
)


computers file contents
Filename "computers.txt"
d1-itd-w7test1
10.10.1.87
10.10.1.57
computername2
computername3


I have given NetBIOS name of machine as well as IP as well as dummy computer names in the computres.txt file to check what errors and success reports I get


Dear arnold,
You mean I shuld run the psexec command directly from my management machine?
I trided to rn but got teh below error

D:\JunkMail\CopyFile>psexec \s \\10.10.1.57 "\\servername\sharename\sub-foldername\batchfile.bat"

PsExec v1.31 - execute processes remotely
Copyright (C) 2001-2002 Mark Russinovich
www.sysinternals.com


PsExec could not start \s on 10.10.1.57:
The system cannot find the file specified.


Dear MarkieS,
Can we have in the vbs file something like the "pause" command in a batch file; so that we will know what is actually happening when we run the vbs script
Will the below help?

crt.Screen.WaitForKey()

The vbs script that MarkieS provided uses the existance of the batch file C:\temp\batchfile.bat locally.

Change this entry in the code to point to the batchfile example I posted that is in a shared location to which your user can access i.e. \\domain\netlogon\batchfile.bat (make sure to copy the batchfile.bat to the shared location.

regarding the psexec your entry has a typo to designate system you would use /s nor \s
i.e.
psexec /s \\10.10.1.57 "\\servername\sharename\sub-foldername\batchfile.bat"
not
psexec \s \\10.10.1.57 "\\servername\sharename\sub-foldername\batchfile.bat"

with the "\\servername\sharename\sub-foldername\" replaced with your actual server and sharename where the file can be found.
Dear arnold,
Many thanks for your reply

I change the path in the vbs file as below

Old path
if objFSO.FileExists("\\" & strComputer & "\C$\temp\batchfile.bat") then

New path
if objFSO.FileExists("\\" & strComputer & "\\\backupsrv\ScriptShare\ADTA-ScreenSaver\batchfile.bat"

I also tried the below

if objFSO.FileExists("\\" & strComputer & "\\backupsrv\ScriptShare\ADTA-ScreenSaver\batchfile.bat"

But even then nothing happens when I double click or even when I run it in a command prompt window


Secondly, yes you are right the command runs when I use /s
I get the below output
Batchfile.bat exited on 10.10.1.57 with error code 0.

Actually I wanted a better output
Like success and failure
Picking up computer names from the input file
As many machine are involved

Thanks again for your time and effort on this
The batch file records data in the logfile.
oops, the vbs script is supposed to copy the file to c:\temp
from where you are running the script.
i.e. batchfile.bat has to be in the directory from which you are running the vbs script markies provided.

The changes you are making consist of three statements.
Check the existence of the directory
check the existence of the file else copy

The problem is if you do not have c:\temp the script ends.
Using the script from the batchfile script from the shared location:


'--------------------------------------------------------
'Remote_Run.vbs
'
'for each computer in computers.txt, the vbs copies
'batchfile.bat to:
'C:\temp
'on the remote machine, and executes it with psexec.exe
'(psexec.exe provided by sysinternals.com)
'--------------------------------------------------------
Const OverwriteExisting = True
'on error resume next
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set txtStream = objFSO.OpenTextFile(GetPath & "computers.txt")
      Do While Not (txtStream.atEndOfStream)
            strComputer = txtStream.ReadLine
                  if objFSO.FileExists("\\server\sharename\batchfile.bat") then
                        strCMD = Chr(34) & "\\server\sharename\batchfile.bat" & Chr(34)
                        errReturn = psexec(strComputer,strCMD)
                  else
                      wscript.interactive=true
                      wscript.popUp("Error batchfile is missing")
                      exit do  
                end if
      Loop
wscript.sleep 5000
'//////////////////////////////////////////////////////////////////////////////////////////////////////////
Function GetPath
DIM Path
 Path = WScript.ScriptFullName  ' Script name
 GetPath = LEFT(Path, INSTRREV(Path, "\"))
End Function

Function psexec(strComputer,strCMD)

Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run "psexec \\" & strComputer & " " & strCMD


End Function

Open in new window

Dear arnold,
C:\TEMP is present on all machines

I copied your new script to a file
Saved it as .vbs
Kept the batch file in the shared location
Script runs
But it opens a command prompt window for every computer name mentioned

Also no output appears in the log file
Before when I has run the batch file separately it was outputting data in the log file
But now no

I think restart my management machine and check everything afresh!

Hi Guys,

Sorry - the original remote_run.VBS script was missing a backslash!
I have amended and re-attached.
Try it again as originally planned.

I guess my Time-zone is different to yours!

cheers
MarkieS
REMOTE-RUN-1-.txt
check whether markies script copied the batch file to \\computername\c$\temp\?

There are many scripts available.
You can use markies script and instead of using psexec to execute a batchfile, you can use the portion in the else to whether the batch file exists
i.e. objFSO.CopyFile strSource , "\\" & strComputer & "location where you want the file copied",OverwriteExisting
http://www.visualbasicscript.com/Script-To-Copy-Files-From-One-Location-To-Another-m39787.aspx

You could use the example for function definitions to create one that verifies the existance of the file after the process run and/or use comparing techniques to make sure the file on the other end is what you need it to be.

It all depends on what those file/s do that they have to be immediately copied versus waiting for the restart of the system.

You could also use schtasks to schedule a task that will copy data from a shared location to a specified location.
Once scheduled, you would only need to update the contents of the shared location and the task will do the rest.
You could schedule the task to run every so often
http://technet.microsoft.com/en-us/library/cc725744%28WS.10%29.aspx
Dear MarkieS,
Well this one at least runs
It opens a command prompt window
Copies the file but only to Windows XP machines
Does copy for windows 7 32 bit and Windows 7 64 bit
I guess it may be an issue with starting the psexec service on these machines
Also it does not post anything in the output file
No errors logged

Hmmm, I still a file copy script which will
Copy file to the windows folder
Log success and errors in an output file
Pick computer names from an input file
Dear Arnold,
I am quite weak at scripting
If you draft a small script according to the steps you outlined in your last solution
You guidance is not enough for me to make the script on my own
I tried but it gets quite confusing for me

strCMD = Chr(34) & schtasks /create /S system /s strComputer /sc minute /mo 20 /tn "copy files process mechanism" /tr "xcopy  '\\shareserver\sharename\sharedirectory\' 'c:\localfolder\' /Y /R /Z /E "
objShell.Run "strCMD"

The scheduled task will run with System privileges on computers identified by /s

One runs excopy one runs the batchfile.
You could add a check that negates the if exists file when you want to overwrite.
'--------------------------------------------------------
'Remote_Run.vbs
'
'for each computer in computers.txt, the vbs copies
'batchfile.bat to:
'C:\temp
'on the remote machine, and executes it with psexec.exe
'(psexec.exe provided by sysinternals.com)
'--------------------------------------------------------
Const OverwriteExisting = True
'on error resume next
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set txtStream = objFSO.OpenTextFile(GetPath & "computers.txt")
      Do While Not (txtStream.atEndOfStream)
            strComputer = txtStream.ReadLine
            strCMD = Chr(34) & "schtasks /create /S system /s strComputer /sc minute /mo 20 /tn 'copy files process mechanism every 20 minutes' /tr \\shareserver\sharename\batchfile.bat "
            objShell.Run "strCMD"
     objShell=undef
      Loop
wscript.sleep 5000

Open in new window

The one with xcopy
'--------------------------------------------------------
'Remote_Run.vbs
'
'for each computer in computers.txt, the vbs copies
'batchfile.bat to:
'C:\temp
'on the remote machine, and executes it with psexec.exe
'(psexec.exe provided by sysinternals.com)
'--------------------------------------------------------
Const OverwriteExisting = True
'on error resume next
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set txtStream = objFSO.OpenTextFile(GetPath & "computers.txt")
      Do While Not (txtStream.atEndOfStream)
            strComputer = txtStream.ReadLine
            strCMD = Chr(34) & "schtasks /create /S system /s strComputer /sc minute /mo 20 /tn 'copy files process mechanism every 20 minutes' /tr xcopy  '\\shareserver\sharename\sharedirectory\' 'c:\localfolder\' /Y /R /Z /E "
            objShell.Run "strCMD"
     objShell=undef
      Loop
wscript.sleep 5000

Open in new window

Hi ADTA,

I have tested this successfully my end launched from an XP 32bit machine and running on target machines of Windows 7 64bit.  I think you may have problems with the accounts not having the authority to run.

Sorry but I have to head of now.  Will be back on tomorrow.
kind regards
MarkieS
Dear Arnold,
Both the script you have pasted seem to be the same
Are you sure there is a difference in the two?
The second one you have mentioned is with "xcopy"; are you sure
Dear Arnold,
Sorry; just saw the difference in the two scripts
So you are not using psexec at all right?
What does the line "chtasks /create /S system /s strComputer /sc minute /mo 20 /tn 'copy files process mechanism every 20 minutes'" mean
Will it keep running a scheduled task every 2o minutes?

Sorry I do not understand scripting commends that well
Getting old
Many thanks for your help
We are almost there
Yes, the first was a modification of the original that Markies provided, the problem is that I did not look past the adjusting what it will execute and left the section that if the file does not exist, it will copy it.

The second script just goes through the loop of computers and then runs schtasks /s computername to remotely setup a schedule on which a command will run.
one would use xcopy to copy the data which means everytime it runs it will effectively copy the files.
The other will use the batchfile which you can then manage in terms of checking whether files have changed and only copy newer ones. etc.
Yes schtasks is the scheduler using the /s option means that you can remotely schedule a task on a system /s computer_name
/S system means that the scheduled task will run with System privileges. You could use /U username /P password if you prefer to have the task ran using a specific user credential.  Note that should the password for username change, the scheduled task will fail unless the password is updated.

IT means exactly what it says the "/sc minute /mo 20" means the the scheduler will run this task every 20 minutes. (/TR 'command')
/tn task name


Please see the link detailing the schtasks options they provide examples and explanations.
Dear Arnold
I just ran the copy script
It gave the error for line 17 character 13
Could you please check?

I edited the script to include the source and destination location of the file I need to be copied
I populated the computesr.txt file with computer names
I think s al what is required from side
Let me know if I need to do any pother changes
Dear Arnold,
Also why should we schedule a task every 20 minutes on the client machines?
I just to need copy a file once
Maybe this task may have to be repeated every two - four months
But for this it would not be right to keep a scheduled task running every 20 minutes on client machines
What do you think?
Dear Arnold,
The erro says
object required : 'objShell'
oops, remove line 18
objShell=undef.
not sure which you decided to use.
Also take out the quotes on line 17 surrounding the variable strCMD.
'--------------------------------------------------------
'Remote_Run.vbs
'
'for each computer in computers.txt, the vbs copies
'batchfile.bat to:
'C:\temp
'on the remote machine, and executes it with psexec.exe
'(psexec.exe provided by sysinternals.com)
'--------------------------------------------------------
Const OverwriteExisting = True
'on error resume next
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set txtStream = objFSO.OpenTextFile(GetPath & "computers.txt")
      Do While Not (txtStream.atEndOfStream)
            strComputer = txtStream.ReadLine
            strCMD = Chr(34) & "schtasks /create /S system /s strComputer /sc minute /mo 20 /tn 'copy files process mechanism every 20 minutes' /tr \\shareserver\sharename\batchfile.bat "
            objShell.Run strCMD
      Loop

Open in new window

The frequency of the script schedule was only an example.
The link I posted to MS detailing the scheduled task covers it.
You can use this script and instead of schedule issue a direct copy.

http://www.visualbasicscript.com/Copy-Files-Using-VbScript-m43169.aspx

The difficulty is that you want to know the results which is how the batch file was introduced i.e. it will do the work and write info into a log file.

What is the nature of the file you want to copy?
Must the file exist on each remote system?
'--------------------------------------------------------
'Remote_Run.vbs
'
'for each computer in computers.txt, the vbs copies
'batchfile.bat to:
'C:\temp
'on the remote machine, and executes it with psexec.exe
'(psexec.exe provided by sysinternals.com)
'--------------------------------------------------------
Const OverwriteExisting = True
'on error resume next
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set txtStream = objFSO.OpenTextFile(GetPath & "computers.txt")
      Do While Not (txtStream.atEndOfStream)
            strComputer = txtStream.ReadLine
            strCMD = Chr(34) & "schtasks /create /S system /s strComputer /sc minute /mo 20 /tn 'copy files process mechanism every 20 minutes' /tr \\shareserver\sharename\batchfile.bat "
            Set objShell = WScript.CreateObject("WScript.Shell")
            objShell.Run strCMD
            objShell=undef
      Loop

Open in new window

Dear Arnold,
I need to copy a file to the windows folder of every machine
So admin privileges will be required
I will double click / run the command while looged-in to a management system with a user having admin rights on all client machines
The file may be present on old client systems (maybe older version of the file)
The file will not be present if the system is new on the network
In any case; I think we can use the "overwrite" command while copying
Only if i get the errors in a log file I will know if the script is doing what it is supposed to do
And then I will manually copy the file to machines which failed
Dear Arnold
The last script throws an error
Line 18 char 13
The system cannot find the file specified
Did you adjust the script to actually reference the location and the file that will be executed as the scheduled task?
?

The easiest thing is to setup a GPO with a startup script this way when a new system is joined into the domain and rebooted, the file will be copied.

What is the file that you are copying? IS this a hosts file?
Yes I just edited the line "strCMD = Chr(34) & "schtasks /create /S system /s strComputer /sc minute /mo 20 /tn 'copy files process mechanism every 20 minutes' /tr \\Servername\Sharename\FileName "
Correct?

Forget this. Since this is a one time thing and you will be running as admin

@echo OFF

FOR /F  %%A IN ('more computers.txt') DO (echo copying filename to \\%%A\c$\path/to/file
xcopy filename \\%%A\c$path\to\directory\ /Y /R /F 
echo "Errorlevel =%ERRORLEVEL% if not 0, there was an error"
)

Open in new window

with schtasks you can create a task on each system that does not run unless triggered.
you can then use the above example and run the tasks remotely
schstasks /RUN /s %%A /TN 'Copy files process'
Dear Arnold,
The script is very good
Small and sweet
There is a small issue with the error logging
Can we have the logging output to another file?

Also I tested with a non-existent computer name in the computers.txt file
It gives the below error

Copying filename to \\computername2\c$\Windows
Invalid drive specification
0 File(s) copied
"Error level =0 if not 0, there was an error"

As you see the error level is zero
While as you say "if not 0, there was an error"

Can we do something about the above two issues?
Files copied is the result of the xcopy, the %ERORRLEVEL% should have reported a 4.on the next line.
i.e. 0 File(s) copied
ErrorLevel = 4


You can log the information anywhere you need.  The example outputs the data to stfdout

you can use >> somefile
batchscript.bat >> somefile

It all depends on what you want to add
you could use if exists "\\%%A\C$\" to check whether the computer\directory exists before attempting the copy.

etc.


Dear Arnold,
Yes the output works fine
But when I test it with a non-existent computer name which it should not be able to connect to; even then it is giving the same error level which is "0"
Please see below; the machine name is given as "computername3"; which is a non-existent machine
Can we do something so that it will give a proper error?
This way I will never know which machines it was successful and which machines it was not successful
..........................

copying filename to \\computername3\c$\Windows
0 File(s) copied
"Errorlevel =0 if not 0, there was an error"
....................................
can you post the complete command you are using?
I tested
xcopy file \\nonexistant\c$\
and the error code was 4
adjust
if exist "\\%%A\c$" (
xcopy filename \\%%A\c$
echo %errorlevel%
) else (echo "\\%%A\c$ does not exist")
Dear Arnold
There seems to be something wrong with the brackets
The script does not run at all
Below is the whole script I am executing

.........................
@echo on
FOR /F  %%A IN ('more computers.txt') DO (echo copying filename to \\%%A\c$\Windows
if exist "\\%%A\c$\Windows" (
xcopy \\Sharename\Filename \\%%A\c$\Windows
echo %errorlevel%
) else (echo "\\%%A\c$ does not exist")

..............................

The computers.txt file is n the same folder
ASKER CERTIFIED SOLUTION
Avatar of arnold
arnold
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Dear Arnold,
Excellent;
The script runs and throws output in the output file
In the end it just gives the below (in the command prompt windows from where I am running the script)

.......
Sharing violation
............

Any idea?
But the script is fine enough
Certainly job of a Genius
Dera Arnold
The "Sharing Violation" was because the file I was copying was stil in use in a windows process
You scritp is ok
Awesome guys!  Nice to see it's sorted...

All the best
MarkieS