none
Logon Script: Copy / Delete files on client PCs

    Question

  • Hello, I'm a newbie to scripting, so please bear with me!

    My scenario:   On every client PC in our domain, I need to delete a certain file, and I need to copy over 2 new files to 2 different directories.  The directories and filenames will be the same on every computer, the only thing that will change is the machine name of the computer.  Our domain consists of Windows Server 2003 servers, XP Pro clients.

    I'm thinking that this would be a fairly straight forward log-on script, using VBScript but I'm having problems getting started with the correct syntax.

    I've tried messing around with the syntax on the following website, but haven't been able to produce any results:
    http://www.wallaceit.co.uk/Logon-scripts/How-to-copy-files-to-client-machines-via-a-logon-script/102/article.aspx

    Thanks in advance for any assistance you can provide me!

    Wednesday, December 9, 2009 2:51 PM

Answers

  • You can use the wshNetwork object to retrieve the NetBIOS name of the computer (and also the pre-Windows 2000 logon name of the user). For example:

    Set objNetwork = CreateObject("Wscript.Network")
    strUserName = objNetwork.UserName
    strComputer = objNetwork.ComputerName
    And you can use the FileSystemObject to check the existence of files, delete files, and copy files. In brief:

    Set objFSO = CreateObject("Scripting.FileSystemObject")
    
    ' File to be deleted.
    strFile = "c:\scripts\Example.txt"
    
    ' Source file.
    strSource = "\\MyServer\MyShare\example1.txt"
    
    ' Target location.
    strTarget = "c:\scripts"
    
    If (objFSO.FileExists(strFile) = True) Then
        obFSO.DeleteFile strFile, True
    End If
    
    ' Copy file.
    objFSO.CopyFile strSource, strTarget, True
    Richard Mueller
    MVP ADSI
    Wednesday, December 9, 2009 5:36 PM
    Moderator

All replies

  • You can use the wshNetwork object to retrieve the NetBIOS name of the computer (and also the pre-Windows 2000 logon name of the user). For example:

    Set objNetwork = CreateObject("Wscript.Network")
    strUserName = objNetwork.UserName
    strComputer = objNetwork.ComputerName
    And you can use the FileSystemObject to check the existence of files, delete files, and copy files. In brief:

    Set objFSO = CreateObject("Scripting.FileSystemObject")
    
    ' File to be deleted.
    strFile = "c:\scripts\Example.txt"
    
    ' Source file.
    strSource = "\\MyServer\MyShare\example1.txt"
    
    ' Target location.
    strTarget = "c:\scripts"
    
    If (objFSO.FileExists(strFile) = True) Then
        obFSO.DeleteFile strFile, True
    End If
    
    ' Copy file.
    objFSO.CopyFile strSource, strTarget, True
    Richard Mueller
    MVP ADSI
    Wednesday, December 9, 2009 5:36 PM
    Moderator
  • Hi,

    Be aware that logon scripts execute as the user, so if the script tries to copy files where the user doesn't have permission, it will fail.

    Bill
    Wednesday, December 9, 2009 6:02 PM
    Moderator
  • Richard:

    Thank you very much for your help.  This is exactly the kind of nudge in the right diretion I needed.  I sincerely appreciate it!

    Wednesday, December 9, 2009 9:54 PM
  • Bill:

    Ah, thanks for the heads up.  I suppose I'll need to run a startup script then, as opposed to a logon script.  The files are computer specific, and not user specific, so that would make more sense anyway.  Would that bypass the user's lack of permissions?  Or would I need to somehow run the script as an administrator?

    Wednesday, December 9, 2009 9:56 PM
  • Logon scripts run with the permissions of the user. Startup scripts have System privileges on the local computer (equivalent to Administrator), but the permissions of the Computer object elsewhere in the network. For startup scripts that access files or folders I grant the needed permissions to the group "Domain Computers". By default, all AD computer objects are members of this group. You could also grant permissions to the specific computer object, but that's more work and harder to manage.

    I agree with your thinking. Things that should be done per user should be done in a logon script. Things done per computer belong in a startup script. The only other factor is that Startup scripts run when the computer authenticates to the domain at startup. In some situations, computers can remain on and authenticated for days. If the task should be done daily, make sure computers restart each day.

    If it is a one time task, and you want to know when it completes, another option would be a script you run yourself. You could design it update all computers remotely in bulk. Because you are copying files to the local computer, such a script would need to use WMI to connect to the computers. That's more complicated, but can be done. Reply if you need this. Or, I have an example VBScript program to deploy and run an executable (like a script) on all computers in a domain group linked here:

    http://www.rlmueller.net/Deploy.htm

    You would create a script, similar to the one you have, to delete the one file and copy a few others. This script is designed to be run on the local computer by a member of the local Administrators group. The program I linked would deploy this to all computers in a domain group. Assuming you are a member of "Domain Admins" (so you are a member of the local Administrators group on all computers joined to the domain), the program you specify would run remotely on each computer with your permissions. The program writes a log, so you can tell which computers could not be contacted.

    Richard Mueller


    MVP ADSI
    Wednesday, December 9, 2009 11:49 PM
    Moderator
  • Wow, that sounds like it would work perfectly in my situation.  Because with a start-up script, I don't know which computers the script has applied to, and which still need the files.  And I'm having problems with my wireless clients not connecting before group-policy tries to apply, so they don't get my "computer configuration" policies.

    So, let me just recap and make sure I've got it.  First I need to get the "file delete / copy" script working the way I want, then I need to use your "deploy" VBScript and apply it to the "Domain Computers" group (since I want it to apply to all computers in the domain), and since I'm a member of the "Domain Admins" group, it would execute on the local computer as a member of the local Administrators group, and give me a log of which computers it was not able to connect with.

    Thanks again for all of your help!
    Thursday, December 10, 2009 1:55 PM
  • Using the absolutely simplest form of the "copy" script...  I'm able to copy a file from a network share down to the c:\ drive.  Here is my script for that:

    Set objFSO = CreateObject("Scripting.FileSystemObject")
    
    ' Source file.
    strSource = "\\server_name\Testing.txt"
    
    ' Target location.
    strTarget = "C:\"
    
    ' Copy file.
    objFSO.CopyFile strSource, strTarget, True

    And this script works without any problems.

    Now when I try and use the "Deploy" script to try and copy the same file to the remote computer's C:\ drive, I get the following error:

    =====
    12/10/2009 10:14:47 AM Deployment started
    -- Deployment executable C:\Scripts\Testing.vbs
    -- Command to execute Testing.vbs
    -- Deploy to computers in group TestGroup
    -- Connected to local computer xxx-xxx-xxxxxxx
    12/10/2009 10:14:49 AM deploy to computer yyy-yyy-yyyyyyy
    -- Computer found
    -- ### Failed to connect with WMI, Error Number: 462, Description: The remote server machine does not exist or is unavailable
    12/10/2009 10:15:34 AM Deployment finished
    -- Successfully deployed to 0 computers
    -- Failed to deploy to 1 computers
    =====

    I didn't really examine the code in the "deploy" script, but do I need to modify it to work in my domain environment?

    Thursday, December 10, 2009 3:26 PM
  • The message means the Deploy.vbs program was able to ping the computer (yyy-yyy-yyyyyy), but then failed to connect with WMI. Possible causes include:

    A firewall is blocking.
    DCOM is disabled on the remote computer.
    WMI is not installed (the client is older than Windows 2000, like NT or Windows 98).
    WMI on the remote computer is corrupt.
    You are logged on with an account that is not a member of the local Administrators group on the remote computer.

    If you are a member of "Domain Admins", you should be fine, as this group should be a member of the local Administrators group. I've used the following command to allow remote administration in Windows firewall:

    netsh firewall set service remoteadmin enable

    More on connecting through Windows firewall here:

    http://msdn.microsoft.com/en-us/library/aa389286(VS.85).aspx

    I've also found the following restrictions connecting to remote computers with WMI, although these situations seem less likely today in an AD environment (assuming your computer is W2k SP2 or above):

    1. You cannot connect to computer running XP Home.
    2. An NT computer cannot connect to OS later than W2k.
    3. A W2k3 computer cannot connect to Win9x.
    4. To connect to W2k Server SP4 you must set impersonation level to Impersonate.
    5. W2k computers must have SP2 to connect to XP or above.
    6. W2k3 can only connect to Win9x and NT if credentials supplied.
    7. To connect to XP or W2k3 you must set authentication level to Pkt.

    The script handles # 4 and 7, as impersonationLevel and authenticationLevel are set.

    In the worst case, where WMI is corrupt on the remote computer, the following links describe how to troubleshoot WMI:

    http://www.microsoft.com/technet/scriptcenter/topics/help/wmi.mspx

    http://support.microsoft.com/kb/875605

    http://www.microsoft.com/technet/scriptcenter/resources/wmifaq.mspx

    You can rebuild the WMI repository, if you have XP SP2, with the command:

    rundll32 wbemupgd, UpgradeRepository

    The following commands reinstall WMI in the registry:

    winmgmt /clearadap
    winmgmt /kill
    winmgmt /unregserver
    winmgmt /regserver
    winmgmt /resyncperf

    Finally, if you get this working but the log indicates a few computers could not be contacted, I would suggest creating a group (it sounds like you already have for testing, which is a good idea), and make these few computers members for another try. Hopefully, something above explains what you experience and can be easily fixed.

    Richard Mueller


    MVP ADSI
    Thursday, December 10, 2009 5:36 PM
    Moderator
  • Thank you again for your time Richard!  I am a member of the Domain Admins group, so there shouldn't be a problem with permissions.  And all of our client PCs are XP Pro SP2 or SP3, and our servers are W2k3, so there shouldn't be any problems there either.

    After running the "netsh firewall set service remoteadmin enable" command on the remote computer, I no longer get the "Failed to connect with WMI" error message, so it must've been a firewill issue.

    Now when I run the "Deploy" script, it successfully copies the "Testing.vbs" script file over to the C:\ drive of the remote computer...  but then I get another failure error message.  (Pasted below.)  But after the "Deploy" script copies over the "Testing.vbs" file, if I double click "Testing.vbs" on the remote computer, it executes without any problems or errors.  So for some reason, after the "Testing.vbs" file is copied over to the remote computer, the "Deploy" script errors-out while trying to execute it.

    =====
    12/10/2009 4:03:38 PM Deployment started
    -- Deployment executable C:\Scripts\Testing.vbs
    -- Command to execute Testing.vbs
    -- Deploy to computers in group TestGroup
    -- Connected to local computer UCP-HOL-3RN8BG1
    12/10/2009 4:03:39 PM deploy to computer UCP-HOL-HBH2W6
    -- Computer found
    -- Connected with WMI
    -- Drive mapped
    -- Executable file copied
    -- ### Failed to start program, Error: 8
    -- Drive mapping removed
    12/10/2009 4:03:44 PM Deployment finished
    -- Successfully deployed to 0 computers
    -- Failed to deploy to 1 computers
    =====
    





    Thursday, December 10, 2009 9:20 PM
  • Ah. It's been awhile since I've used the program to run a VBScript remotely. I normally deploy either batch files or *.exe files. My guess is that the Process object does not consider a *.vbs file as an executable.

    I'll need to test to be sure, but one fix would be to launch the VBScript from a batch file. The VBScript itself would be saved in a shared location that can be referenced from each computer with a UNC path. The batch file could be similar to below:

    @echo off
    c:\Windows\System32\cscript.exe \\MyServer\MyShare\Testing.vbs
    

    You would save Testing.vbs in the shared location. Then when you run Deploy.vbs, when prompted for the program to run, specify the batch file (with *.bat extension). There would be no parameters. The batch file specifies to use the cscript host program to run the VBScript.

    Another fix would be to revise the Deploy.vbs program specifically to handle deployment of VBScript programs. For example, replace this line:

        intReturnCode = objProcess.Create("c:\\" & m_strCommand)

    with this:

        intReturnCode = objProcess.Create("c:\\Windows\\System32\\cscript.exe c:\\" & m_strCommand)

    In both cases, my fear is that there will be no path so that cscript.exe will not be found unless we specify the full path to the executable, as I've done above. But if the path is different on different computers, depending on the OS and how it was installed, you may need to use environment variables like %systemroot%.

    If I find more, I'll post again.

    Richard Mueller


    MVP ADSI
    • Proposed as answer by CraigLieb Sunday, January 10, 2010 8:07 PM
    Friday, December 11, 2009 12:15 AM
    Moderator