• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1485
  • Last Modified:

vbscript to merge REG into remote registry problem

I am trying to add a REG file to all the machines in an OU via vbscript.  This script will check a folder every 10 seconds to see if a new REG file has been created there.  If it has, it will then go through the OU and merge the new REG file in to the remote machine registry.

The problem I'm having is that the script will only merge the REG file into the registry of the local machine the script is being run on and not to any other machine.  Can someone take a look at this code to see what the problem is?

From what I can tell, the objService.Create ('regedit.exe /s " & strnFileName) is running on the local machine, but not on any other machine even though the script drills through the OU correctly.

Here is the code:

'This script checks a directory for new files
'then uses regedit.exe to merge a new registy
'file into the registries of computers in
'a given OU in AD

Const ADS_SCOPE_SUBTREE = 2
On Error Resume Next


'This portion is set to run on the host computer where a new file will be created

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

'Checks on a certain interval of time for a creation event.

Set colMonitoredEvents = objWMIService.ExecNotificationQuery _
    ("SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE " _
        & "Targetinstance ISA 'CIM_DirectoryContainsFile' and " _
            & "TargetInstance.GroupComponent= " _
                & "'Win32_Directory.Name=""c:\\\\scripts""'")

'Loop to control what happens after an event is triggered

Do
    Set objLatestEvent = colMonitoredEvents.NextEvent
    strNewFile = objLatestEvent.TargetInstance.PartComponent
    arrNewFile = Split(strNewFile, "=")
    strFileName = arrNewFile(1)
    strFileName = Replace(strFileName, "\\", "\")
    strFileName = Replace(strFileName, Chr(34), "")
    strFilename = Replace(strFilename, "c:", "\\gpotest")

'Connects to AD LDAP

    Set objConnection = CreateObject("ADODB.Connection")
    Set objCommand =   CreateObject("ADODB.Command")
    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "Active Directory Provider"

    Set objCommand.ActiveConnection = objConnection
    objCommand.CommandText = _
    "Select Name From 'LDAP://OU=BLAH,DC=BLAH,DC=COM' Where objectClass='computer'"  
    objCommand.Properties("Page Size") = 1000
    objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
    Set objRecordSet = objCommand.Execute
    objRecordSet.MoveFirst

'This loop drills through AD OU to make sure every object is hit

    Do Until objRecordSet.EOF
       strComputer = objRecordSet.Fields("Name").Value
       Set objShell = CreateObject("Wscript.Shell")
       Set objService = GetObject("winmgmts:{impersonationLevel=impersonate}!//" & strComputer & "\root\cimv2:Win32_Process")
       WScript.Echo strComputer & strFileName
       objService.Create("regedit.exe /s " & strFileName)
       objRecordSet.MoveNext
    Loop
Loop
------

Thanks for your help!

-Doug
0
idiot3qu3
Asked:
idiot3qu3
  • 4
  • 3
2 Solutions
 
RobSampsonCommented:
Hi, I just had a quick look at this, and it looks like you might be better off using StdRegProv, instead of the process.

Something like this could get you started:
'===========
Const HKEY_LOCAL_MACHINE = &H80000002
strRegBranch = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"

strComputer = "."

Set objRegistry = GetObject("winmgmts:"   & _
      "{impersonationLevel=Impersonate}!\\" & _
      strComputer & "\root\default:StdRegProv")

'Returns a non-zero return value if the key does not exist
If objRegistry.EnumKey(HKEY_LOCAL_MACHINE, strRegBranch, arrValueNames) = 0 Then
   For intValueCount = LBound(arrValueNames) To UBound(arrValueNames)
      MsgBox arrValueNames(intValueCount)
   Next
End If
'=============

I can help you further tomorrow.....I'll spend more time looking at it.

Regards,

Rob.
0
 
idiot3qu3Author Commented:
Would this method mean that I would have to include the keys I want to add in the script?
0
 
VorenusCommented:
Hi,

I suggest you use Sysinternals' psexec which is a command-line tool which allows you to launch processes very easily onto remote computers.

Very powerful and invaluable once you tasted it once... will be useful to you far beyond this script I think.

http://www.microsoft.com/technet/sysinternals/utilities/psexec.mspx

It will allow you to keep your regfiles and not include them to your script as commands and only change few lines to your existing code.

The switches are fully documented on the link I gave you, but here is an example :
psexec \\computer_or_ip -c -d -u DOMAIN\UserName -p Password cscript c:\test.vbs

Hope this helps,

Vorenus.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
RobSampsonCommented:
Oh right, i see.  OK, forget my first post, Vorenus is right.
I've had more time to look at it, and I now understand what you're doing.

Yes, PSExec would be the way to go here.  I'm assuming that the C:\Scripts folder on the server GPOTEST is shared out AS Scripts, otherwise you wouldn't be able to access it via \\gpotest\scripts.

The top of your script is correct, and you'll just need to change this part:
    Do Until objRecordSet.EOF
       strComputer = objRecordSet.Fields("Name").Value
       Set objShell = CreateObject("Wscript.Shell")
       Set objService = GetObject("winmgmts:{impersonationLevel=impersonate}!//" & strComputer & "\root\cimv2:Win32_Process")
       WScript.Echo strComputer & strFileName
       objService.Create("regedit.exe /s " & strFileName)
       objRecordSet.MoveNext
    Loop

to this:
    Do Until objRecordSet.EOF
       strComputer = objRecordSet.Fields("Name").Value
       Set objShell = CreateObject("Wscript.Shell")
       strCommand = "cmd /c C:\Scripts\PSExec -accepteula -e \\" & strComputer & " cmd /c regedit /s " & strFileName)
       objShell.Run strCommand, 0, True
       objRecordSet.MoveNext
    Loop

And have PSExec.exe in the C:\Scripts folder.

Also, if you want to see what PSExec is doing on the server, change the cmd /c to cmd /k and change the objShell.Run strCommand, 0, True to objShell.Run strCommand, 1, True
It is the zero in that Run command that hides the PSExec command prompt.
Do not use the zero with cmd /k though, otherwise you will have hidden command prompts that never close until you terminate cmd.exe.

Regards,

Rob.
0
 
idiot3qu3Author Commented:
Thanks guys!  This looks like the best way to do it.  I had used PStools before, but the thought never crossed my mind to use it this way.

Remind me to bonk my head on my keyboard the next time I forget :-)

-Doug
0
 
idiot3qu3Author Commented:
Something's a little funky with the strCommand line...
I keep getting an "Expected end of Statement" when I try to run it.  When I parse it, it looks like it has all the correct amount of quotes...?

-Doug
0
 
idiot3qu3Author Commented:
NM...I found it.  There was a loose parenthesis at the end.

Thanks again!

-Doug
0
 
RobSampsonCommented:
Great, no problem.  Thanks for the grade,

Rob.
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now