PDA

View Full Version : Windows : Script/Program to update files on networked PCs


Joe 90
06-09-2011, 17:30
The scenario -
9 PCs on a LAN, 1 Instructor system and 8 Clients, all with static IPs.
Files within a directory on the instructor system could be updated at any time and I'd like to launch a script, or a program which would connect to the client PCs, lookup that set directory and copy across the files to ensure they're up to date. This would also require to kill an .exe to ensure that things worked correctly. Then if possible, restart that app.

If it was possible to exclude specific files that'd also be good because the clients all have specific configs within the directory at the moment to identify themselves.


Does anybody have any suggestions for this?

I've managed to find a site today with loads of VBS files to do a whole load of similar stuff. My problem being I don't know VB. (although I can read through it and figure stuff out if I have to)

I'm sure this can be done pretty easily, I just don't know the best methods.

volospian
06-09-2011, 22:05
if I get 5 mins tomorrow I'll knock something up in VBS.

Joe 90
07-09-2011, 07:29
thank you. if it helps, I found this yesterday:



'Updates existing files in a tree from another tree. The two trees do NOT
'have to have the same structure.

Option Explicit

Main

Sub Main
Dim fs, strSourceStartFolder, strDestStartFolder
If WScript.Arguments.Count = 0 Then
If MsgBox("Updates existing files in a ""destination"" tree (folders and subfolders) with more recent files found in a ""source"" tree. The two trees don't have to share the same structure! Proceed?", vbYesNo, "Proceed") = vbNo Then Exit Sub
End If
Set fs = CreateObject("Scripting.FileSystemObject")
'Get the source folder
If WScript.Arguments.Named.Exists("source") Then
strSourceStartFolder = WScript.Arguments.Named.Item("source")
Else
strSourceStartFolder = BrowseForFolder("SOURCE FOLDER (Or use the /source argument like " & vbCrLf & WScript.ScriptName & " /source:""C:\updateSource"")")
End If
If strSourceStartFolder = "" Then Exit Sub
If Not fs.FolderExists(strSourceStartFolder) Then Exit Sub
'Get the destination folder
If WScript.Arguments.Named.Exists("dest") Then
strDestStartFolder = WScript.Arguments.Named.Item("dest")
Else
strDestStartFolder = BrowseForFolder("DESTINATION FOLDER (Or use the /dest argument like " & vbCrLf & WScript.ScriptName & " /dest:""C:\updateDestination"")")
End If
If strDestStartFolder = "" Then Exit Sub
If Not fs.FolderExists(strDestStartFolder) Then Exit Sub
'Update the destination tree with files from the source tree
UpdateTree strDestStartFolder, strSourceStartFolder
End Sub


Sub UpdateTree(strDestStartFolder, strSourceStartFolder)
Dim fs, fil, fils, fol, fols, ofol, strSourceFile
Set fs = CreateObject("Scripting.FileSystemObject")
Set ofol = fs.GetFolder(strDestStartFolder)
'Check each file in the destination folder
On Error Resume Next
Err.Clear
Set fils = ofol.Files
If Err.Number <> 0 Then Exit Sub
For Each fil In fils
strSourceFile = FindFile(fil.Name, strSourceStartFolder)
If strSourceFile <> "" Then
If fil.DateLastModified < fs.GetFile(strSourceFile).DateLastModified Then
'Use the newer source file to overwrite the old destination file.
fs.CopyFile strSourceFile, fil.Path, True
Status strSourceFile & vbCrLf & " >>> " & fil.Path
End If
End If
Next
'Check for any sub folders and recursively process them
Set fols = ofol.SubFolders
For each fol in fols
If Lcase(fol.Name) <> "recycled" Then
UpdateTree fol.Path, strSourceStartFolder
End If
Next
End Sub


Function FindFile(strFileName, strStartPath)
Dim fs, fil, fils, fol, fols, ofol, strFound
Set fs = CreateObject("Scripting.FileSystemObject")
Set ofol = fs.GetFolder(strStartPath)
'Check each file in the folder
'On Error Resume Next
Err.Clear
Set fils = ofol.Files
If Err.Number = 0 Then
For Each fil In fils
If Lcase(fil.Name) = Lcase(strFileName) Then
'Return the path to the file
FindFile = fil.Path
Exit Function
End If
Next
End If
'Check for any sub folders and recursively process them
Set fols = ofol.SubFolders
For each fol in fols
If Lcase(fol.Name) <> "recycled" Then
strFound = FindFile(strFileName, fol.Path)
If strFound <> "" Then
FindFile = strFound
Exit Function
End If
End If
Next
'Return an empty result if the file isn't found
FindFile = ""
End Function

Sub Status(strMessage)
If Lcase(Right(Wscript.FullName, 12)) = "\cscript.exe" Then
Wscript.Echo strMessage
End If
End Sub

Function BrowseForFolder(strPrompt)
'Uses the "Shell.Application" (only present in Win98 and newer)
'to bring up a file/folder selection window. Falls back to an
'ugly input box under Win95.
Const ssfDRIVES = 17 'My Computer
Const SFVVO_SHOWALLOBJECTS = 1
Const SFVVO_SHOWEXTENSIONS = 2
Dim sh, fol, fs, lngView, strPath
Set sh = CreateObject("Shell.Application")
If Instr(TypeName(sh), "Shell") = 0 Then
BrowseForFolder = InputBox(strPrompt, "Select Folder", CreateObject("Scripting.FileSystemObject").GetParentFolderName(WScript.ScriptFullName))
Exit Function
End If
Set fs = CreateObject("Scripting.FileSystemObject")
lngView = SFVVO_SHOWALLOBJECTS Or SFVVO_SHOWEXTENSIONS
strPath = ""
Set fol = sh.BrowseForFolder(&0, strPrompt, lngView, ssfDRIVES)
Err.Clear
On Error Resume Next
strPath = fol.ParentFolder.ParseName(fol.Title).Path
'An error occurs if the user selects a drive instead of a folder
If Err.Number <> 0 Then
BrowseForFolder = Left(Right(fol.Title, 3), 2) & "\"
Else
BrowseForFolder = strPath
End If
End Function


and this is the samples site I found... http://www.ericphelps.com/scripting/samples/

volospian
07-09-2011, 08:33
lol, that's handy.

A couple of questions...

Are the client PC's always the same ones, or do you always need to locate them somehow?

Are the destination folders always the same, or do you always need to be able to select them?

What's the executable you need to kill/restart

What are the files you want to avoid (or do you want to select them ad hoc?)

Would it be easier to use Synctoy? :D

Joe 90
07-09-2011, 09:51
The PCs will always be the same, so I'd assume it's easiest to find them by their IP...
10.50.3.81
through to
10.50.3.88

With the Instructor PC on .80

The path will always be the same, not too sure on that yet, but I can change sort that.

Not too sure what the config file is, but lets call it config.ini

I think the app is Unity which sits in C:\Program Files (x86)\Unity\Editor\Unity.exe

I just need a place to start, I'm good at reading code & making it do what I want, but no good and just writing it as I've never done this before.

Thanks.

And synctoy - interesting, never heard of that. But we're building some software, so something like this might let me build it in to some other ideas at a later date.

* just had a quick test of SyncToy - looks great and really simple, but looks like we'd have to setup a sync pair for every client PC, what we want is a simple single process to do all the clients at once. (although now I've just seen 'run all')

Stan_Lite
07-09-2011, 11:06
What about Dropbox? I use it to sync files between the work laptop on the rig, my own laptop and my PC at home. It updates regularly and the files are also stored online so I can access them from anywhere I have an internet connection.

Incidentally, the work folder on the work laptop isn't in the Dropbox folder so wouldn't normally sync automatically but I use synctoy to sync the 'official' work folder with the 'unofficial' work folder in the Dropbox directory.
I set up a scheduled task in Windows to run synctoy several times a day to keep the folder up to date when I'm not on the rig. That may help you - setting up a scheduled task to run synctoy as regularly as you need it.

volospian
07-09-2011, 11:15
There's some command line switches for synctoy, so you could potentially run it from one batch command.

Usage: SyncToyCmd [-args]
All arguments are optional.
-R Run all folder pairs that are marked as Active for Run All.
-R<name> Run the named folder pair only.
-? Display this help.

Examples:
SyncToyCmd -RMyFolderPair
SyncToyCmd -R


You could always use something like PSKill and PSExec for PSTools (http://technet.microsoft.com/en-us/sysinternals/bb896649) to stop/start the executable either side of the sync.

You could also put in a command that copies the ini file to a staging area prior to sync and then copies it back after.

Stick all the command lines in a batch file, add it to the sceduler if needed, or a desktop shortcut, and Robert is your Mothers Brother.

It's not as elegant as a nice vbs script, but it's probably easier to set up and maintain...

Joe 90
07-09-2011, 11:33
Dropbox wouldn't work as we're developing for a closed network.

I hadn't thought about the command line args - that should work nicely in a batch file as long as it waits for the sync to complete before moving on to relaunch.

thanks.

just unzipped PsTools & Sophos decided to inform me of my hacking tools! Looks like I'll have to play around with Sophos

volospian
07-09-2011, 11:43
just unzipped PsTools & Sophos decided to inform me of my hacking tools!

lol, that's nice of it!

If it doesn't work as a batch process, we could perhaps use VBS to run those tools. It may have greater granularity in controlling the processes. That way, at least you'd only have a simple vbs script that runs obvious steps to modify if you need to, rather than a few pages of vbs to scroll through, trying to work out what bit does what when you need to mod it...

Joe 90
07-09-2011, 15:46
How do you pass switches with an exe call?

I was reading that to execute from a folder with a space in the name you pass the string as a quote, but it's obviously not the case for what I'm trying.

I've got the following which should work after I can pass parameters in VBS-


Sub RunApplication(ByVal sFile)
Dim shell

Set WShell = CreateObject("WScript.Shell")
WShell.Run Chr(34) & sFile & Chr(34), 1, true
Set shell = Nothing
End Sub


'Executing apps.

RunApplication """C:\PsTools\pskill.exe calc"""
RunApplication """C:\Program Files\SyncToy 2.1\SyncToyCmd.exe -R"""
RunApplication "C:\Windows\system32\calc.exe"

The only thing I've wondered beyond that is that when using WShell.Run with it waiting for a return. Do you know if you can get SyncToy to run without the user having to close any prompts or 'finished' type boxes. That's not a major issue, but if it can be avoided I'd prefer to.

volospian
08-09-2011, 08:41
I don't have synctoy on my machine here to try the options, but have you tried changing the 1 in the shell.run command to a 0?

There's also an optional "WaitOnReturn" option that tells the method whther it needs to wait for the program to finish before continuing that may be useful.

These are the arguments for the shell.run method... one option may work better than others...

http://msdn.microsoft.com/en-us/library/d5fk67ky(v=vs.85).aspx

Joe 90
08-09-2011, 16:22
Got the copy process sorted.

Now just need to figure out why PsExec doesn't seem to launch the app straight away, just seems to wait for something.