开发者

Vbscript - Creating a script that mirrors several sets of folders

Ok, this is my problem. I'm doing a logonscript that basically copies Microsoft Word templates from a serverpath on to a local path of each computer. This is done using a check for group membership.

If MemberOf(ObjGroupDict, "g_group1") Then
    oShell.Run "%comspec% /c %LOGONSERVER%\SYSVOL\mydomain.com\scripts\ROBOCOPY \\server\Templates\Group1\OFFICE2003\ " & TemplateFolder & "\" & " * /E /XO", 0, True
End If

Previously I used the /MIR switch of robocopy, which is exellent. But, if a user is member of more than one group, the /MIR switch removes the content from the first group, since it's mirroring the content from the second group. Meaning, I can't have both contents.

This is "solved" by not using the /MIR switch and just let the content get copied anyway. BUT the whole idea of having the templates on a server is so that I can control the content the users receive through the script. So if I delete a file or folder from the server path, this doesn't replicate on the local computer. Since I don't use the /MIR switch anymore. Comprende?

So, what do I do? I did a small script that basically checks the folders and files and then removes them accordingly, but this actually ended up being the same functionality as the /MIR switch anyway. How do I solve this problem?

Edit: I've found that what I actually need is a routine that scans my local template folder for files and folders and checks if the same structure exists in any of the source template folders.

The server template folders are set up like this:

\\fileserver\templates\group1\
\\fileserver\templates\group2\
\\fileserver\templates\group3\
\\fileserver\templates\group4\
\\fileserver\templates\group5\
\\fileserver\templates\group6\

And the script that does the copying is structures like this (pseudo):

If User is MemberOf (group1) Then
   RoboCopy.exe \\fileserver\templates\group1\ c:\templates\workgroup *.* /E /XO
End if

If User is MemberOf (group2) Then
   RoboCopy.exe \\fileserver\templates\group2\ c:\templates\workgroup *.* /E /XO
End if

If User is MemberOf (group3) Then
   RoboCopy.exe \\fileserver\templates\group3\ c:\templates\workgroup *.* /E /XO
End if

Etc etc With the /E switch, I make sure it copies subfolders as well. And the /XO switch only copies files and folders that are newer than those in my local path. But it doesn't consider if the local path contains files or folders that doesn't exist on the server template path.

So after the copying is done, I would lik开发者_JAVA百科e to check if any of the files or folders on my c:\templates\workgroup actually exists in either of the sources. And if they don't, delete them from my local path. Something that could be combined in these memberchecks perhaps?


Using a lookup table

I'd suggest an approach that puts all templates into one common file server directory and use a lookup table to assign templates to groups.

The benefit would be that your templates would be guaranteed to be in sync; i.e. you don't have to worry that a template for group A, B, and C is really the same in all group specific folders on your file server.

Another bonus is a maintainable configuration table which allows you to assign templates to groups without the need to make changes to your logon script.

The lookup table config file would look something like

group1;\templateA.dot;\templateA.dot
group2;\B\templateB.dot;\B\templateB.dot
group3;\B\C\templateC.dot;\templateC.dot

with column 1 listing your AD group names; column 2 the source path and column 3 the target path. This would also allow for flattening your template folder on the client side.

In any case you can avoid having to maintain multiple copies of all your templates on your file server and adding more groups or templates doesn't require to touch your logon script but just the config file.

In your logon script you can iterate over all lines and copy the ones with matching groups

Logon script code

open lookup table config file

For Each line In lookup table
    If MemberOf(ObjGroupDict, groupname_column_value) Then
        execute Robocopy templatename_column_value local_target
    End If
Next


Removing old files on the client

Here's a script that removes files in the template directory the user's machine not present in one of the file groups copied. For clarity, the code is at the end of this answer. Here's how to use the script in your current solution that doesn't use /MIR.

In the code for each group copied, add one additional method call to 'ListFiles' - this tracks the files copied from the server:

If User is MemberOf (group3) Then
   RoboCopy.exe \\fileserver\templates\group3\ c:\templates\workgroup *.* /E /XO
   ListFiles("\\fileserver\templates\group3\", userTemplates)
End if

Do this for each group copied. (It is ok if the same template appears in more than one group.)

After all groups have been copied, you add this code block:

   ListFiles "c:\templates\workgroup", toDelete
   removeAllFrom toDelete, userTemplates

This lists all files in the user's local templates folder to toDelete. All the files just copied are then removed from that set, leaving just the files that were not copied from the server. We can then print the files to delete, and then actually delete them.

   echoDictionary "deleting old user templates", toDelete
   ' deleteFiles c:\templates\workgroup", toDelete

The call to deleteFiles commented out - probably wise to do a trial run first! The first argument to deleteFiles is the user's template directory - it should not have a trailing slash.

With these changes in place, any files in the templates folder on the users machine that were not copied from the server will be deleted, providing effectively multi-directory synchronization.

Now comes the script. The first block can be pasted to the top of your file, and the remainder at the bottom, to help avoid clutter.

// script to remove files not present on one of the group folders on the fileserver

Set fs = CreateObject("Scripting.FileSystemObject")
Set userTemplates = CreateObject("Scripting.Dictionary")
userTemplates.CompareMode = 1
Set toDelete = CreateObject("Scripting.Dictionary")
toDelete.CompareMode = 1

-- under here are just procedures so they can go at 
-- the bottom of your script if desired

Sub deleteFiles(basedir, dictionary)
   for each key in dictionary.Keys
      fs.DeleteFile(basedir+"\"+key)             
   next
End Sub

Sub echoDictionary(msg, dictionary)
    for each key in dictionary.Keys
       Wscript.Echo msg & ": " & key
    next
End Sub


Sub removeAllFrom(target, toRemove)
   for each key in toRemove.Keys
      if target.Exists(key) then
         target.remove key
      end if
   next
End Sub

Sub ListFiles(folderName, dictionary)
    Set folder = fs.GetFolder(folderName)
    ListSubFolders folder, "", dictionary
End Sub

Sub ListSubFolders(folder, prefix, dictionary)
    Set files = folder.Files
    For Each file in files
         qualifiedName = prefix & file.Name
         dictionary.add qualifiedName, file
    Next

    For Each Subfolder in Folder.SubFolders
        qualifiedName = prefix+Subfolder.Name & "\"
        ListSubFolders Subfolder, qualifiedName, dictionary
        dictionary.add qualifiedName, Subfolder 
    Next
End Sub
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜