Solved

VBScript works in 32bit Windows XP, fails in 64bit Windows 7

Posted on 2011-03-17
15
3,422 Views
Last Modified: 2012-06-27
Hello all,

I'm having a little problem with one of my scripts that I'm going out on a limb and blaming either Windows 7 or the use of a 64bit OS.

Basically the story is I work in a Windows 2003 Server domain with primarily 32bit Windows XP clients. I have a script that runs on user logon that gathers details about the user/computer (username, IP address, etc) and records them in a database on the server.

Now this has all been working fine but recently we introduced 20+ Windows 7 x64 machines to the domain and now (among other things) this script does not seem to work. When I run the script manually from one of these machines there are no errors displayed, it all appears to work. I've used MsgBox to display the variables it collects in the process and it picks up all the correct values, it just doesn't seem to connect to the database or write to the database, something I'm not sure.

I've done a bit of reading regarding scripts that work on 32bit systems but not on 64bit systems (like running the script through SysWOW64) but I haven't had any success with any solutions offered. Would appreciate any suggestions!

The code is as follows:
Const adOpenStatic = 3
Const adLockOptimistic = 3
Const Jet10 = 1
Const Jet11 = 2
Const Jet20 = 3
Const Jet3x = 4
Const Jet4x = 5

Dim adoConnection, adoRecordset

set fs = WScript.CreateObject("Scripting.FileSystemObject")
Set objNetwork = CreateObject("Wscript.Network")

' Variables
dt = Now()
tm = FormatDateTime(dt,vblongtime)
LogDate = Year(dt)*1e4 + Month(dt)*1e2 + Day(dt)
LogMonth = Month(Now)
LogYear = Year(Now)
LogMonthFile = MonthName(LogMonth)
strComputerName = objNetwork.ComputerName
strIP = GetIPAddress(strComputerName)
strUserName = objNetwork.UserName
strLog = "Login"

strDBFile = "\\XXXXX\Logs\Student\" & LogYear & " - " & LogMonthFile & ".mdb"
strTable = LogDate

'// Initial DB setup (is processed only when not already exist)
' Fields going to be created (and can be used)
strFields = "RecordNumber COUNTER ,"  _
          & "UserName TEXT(50) ,"     _
          & "Log TEXT(6) ,"     _
          & "LogTime DATETIME ,"    _
          & "ComputerName TEXT(50) ," _
          & "IPaddress TEXT(50) ,"    _
          & "Notes MEMO"
Call CreateDataTable(strDBFile, Jet4x, strTable, strFields)

'// start Log logon event ---------------------------------------------
If fs.FileExists( strDBFile ) then

  ' Compose the INSERT statement.
  On Error Resume Next
  statement = "INSERT INTO " & strTable _
    & "(UserName,Log,LogTime,ComputerName,IPaddress)"
  statement = statement & " VALUES " _
    & "('" & strUserName & "','" & strLog & "','" & tm & "','" & strComputerName & "','" & strIP & "')"

  ' Initialize the database connection.
  Set adoConnection = CreateObject("ADODB.Connection")

  ' Open the database, use Microsoft Jet OLEDB data provider
  adoConnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strDBFile

  ' Execute the statement.
  adoConnection.Execute statement, , adCmdText
  adoConnection.Close
  On Error GoTo 0
End If

wscript.quit 0


Function GetIPAddress(strComputer)
    Set TmpFolder = FS.GetSpecialFolder(2)
        TmpFile   = TmpFolder & "\" & FS.GetTempName
    With createobject("wscript.shell")
      Onreturn = .run("%comspec% /c ping.exe/a /4 -n 1 -w 1 " _
        & strComputer & ">" & Chr(34) & TmpFile & Chr(34),0 ,True)
    End With
    Set ts = FS.OpenTextFile(TmpFile, 1, True, 0)
    Do Until ts.AtEndOfStream
      strLine = ts.ReadLine
      If CBool(InStr(UCase(strLine),UCase(strComputer))) Then
        GetIPAddress = split(split(strLine,"[")(1),"]")(0)
        Exit Do
      End If
    Loop
    ts.Close
    FS.deletefile TmpFile
    GetIPAddress = GetIPAddress
End Function

Sub CreateDataTable(FileName, Format, sTable, sFields)
  On Error Resume Next
  'Create Access2000 database
  If Not fs.FileExists( FileName ) then
    Set Catalog = CreateObject("ADOX.Catalog")
    Catalog.Create "Provider=Microsoft.Jet.OLEDB.4.0;" & _
      "Jet OLEDB:Engine Type=" & Format & _
     ";Data Source=" & FileName
  End If
  If fs.FileExists( FileName ) then
    'create table
    Set adoConnection = CreateObject("ADODB.Connection")
    'check if table already exist (will not raise error)
    Set adoRecordSet = CreateObject("ADODB.Recordset")
    adoRecordset.Open "SELECT * FROM " & sTable , _
      adoConnection, adOpenStatic, adLockOptimistic
    If not err.number = 0 then
      Err.clear
      If adoRecordset.RecordCount = 0 Then
        adoConnection.Open _
          "Provider= Microsoft.Jet.OLEDB.4.0; " & _
          "Data Source=" & FileName
        adoConnection.Execute "CREATE TABLE " & _
        sTable & "(" & sFields & ")"
      End If
    End If
    adoRecordset.close
    adoConnection.Close
  End If
End Sub

Open in new window


Thanks all,

Terry
0
Comment
Question by:teztickles
  • 7
  • 2
  • 2
  • +2
15 Comments
 
LVL 3

Expert Comment

by:pasolo
ID: 35161221
As you know there is no 64-bit provider for Jet or ACE.
All you need is force the script to run as 32-bit, i.e, you need to start the 32-bit scripting host cscript.exe which is in the syswow64 folder  
0
 

Author Comment

by:teztickles
ID: 35161423
Hi pasolo,

I actually tried that but I still had the same result - no errors, just no writing to the database.
0
 

Author Comment

by:teztickles
ID: 35161472
Ok I take that back!

I just tried it again and I got a successful result!

I guess now the question would be how do I get this script to run from cscript if it's running from a Windows 7 machine?
0
Simplifying Server Workload Migrations

This use case outlines the migration challenges that organizations face and how the Acronis AnyData Engine supports physical-to-physical (P2P), physical-to-virtual (P2V), virtual to physical (V2P), and cross-virtual (V2V) migration scenarios to address these challenges.

 

Author Comment

by:teztickles
ID: 35161535
Sorry I should have explained how this all works a little better. This script runs from user logon group policy rule so that when a user logs on to any computer in the domain the script runs. As there is now this mix of Windows XP x86 and Windows 7 x64 machines is there anyway to distinguish which operating system a user has logged onto and run the script accordingly?
0
 
LVL 11

Expert Comment

by:yelbaglf
ID: 35161541
This has to do with UAC.  Have a look at this article for ways around this.
http://blogs.technet.com/b/elevationpowertoys/
0
 
LVL 65

Accepted Solution

by:
RobSampson earned 500 total points
ID: 35162359
This snippet can tell you the OS Version, so just add a objWshShell.Run line there to run whatever you need to run for each OS.

Regards,

Rob.
Set objWshShell = WScript.CreateObject("WScript.Shell")
strOSVersion = objWshShell.RegRead("HKLM\Software\Microsoft\Windows NT\CurrentVersion\CurrentVersion")
If strOSVersion = "5.1" Then
    'Insert Windows XP Statements
ElseIf strOSVersion = "6.0" Then
    'Insert Windows Vista Statements
ElseIf strOSVersion = "6.1" Then
    'Insert Windows 7 Statements
End If

Open in new window

0
 

Author Comment

by:teztickles
ID: 35162444
Thanks for that Rob, I actually have just managed to make something very similar so when the script runs it knows which OS it's in and from there I can call the original script(s). Of course yours is much more streamlined though!

I have it now so it's working from XP, it calls the script and runs it from objWshShell.Run. To run it from the cscript in Windows 7 however would I would imagine I woudl just use the objWshShell.Run and then  put the path of the cscript.exe in the SysWOW64 folderfollowed by the path of the script to run it in (i.e. %windir%\SysWOW64\cscript.exe \\server\share\script.vbs). Would this be correct?

I'm actually at home now so can't test out my theory.

Thanks again,

Terry
0
 
LVL 65

Expert Comment

by:RobSampson
ID: 35162463
Yes, that looks correct.  I can't test it either, but I believe that's where the 32 bit CScript.exe is.

Rob.
0
 
LVL 3

Expert Comment

by:pasolo
ID: 35163164
Use a second script to launch the correct version, like this:

Set objWshShell = WScript.CreateObject("WScript.Shell")
if objWshShell.ExpandEnvironmentStrings("%PROCESSOR_ARCHITECTURE%") = "AMD64" Then
      objWshShell.run("%windir%\SysWOW64\cscript.exe \\server\share\script.vbs")
Else
      objWshShell.run("%windir%\System32\cscript.exe \\server\share\script.vbs")
End If
0
 
LVL 51

Expert Comment

by:Netman66
ID: 35166088
UAC.

Try turning it off.

This was mentioned already!

No zupe for me!!!  LOL


0
 

Author Comment

by:teztickles
ID: 35177009
Hi all,

Now that I'm back at work I've had a chance to quickly try turning off UAC (with restart) and that has had no effect on the script, it still runs without error but does not do what it's supposed to do.

I'll try out the scripting side of things now and post back when I'm done.

Thanks,

Terry
0
 
LVL 11

Expert Comment

by:yelbaglf
ID: 35379614
When you used SysWoW64, did you run it like the below?  If not, give that a try.

C:\Windows\SysWoW64\cscript.exe C:\ScriptDirectory\Script.vbs


Here's an article about Jet on 64-bit systems.
http://www.connectionstrings.com/Articles/Show/using-jet-in-64-bit-environments

The reason this is how it has to be done is referenced here.
http://support.microsoft.com/kb/957570
0
 

Author Closing Comment

by:teztickles
ID: 35406030
Thanks Rob!
0
 

Author Comment

by:teztickles
ID: 35406040
Sorry for the very late reply. I've actually changed jobs now so I never got a chance to fully implement that script. I'd tried it out and it did work, I think there were a couple of little hiccups I wanted to fix but just never got round to doing that what with training my replacement.

Points awarded to RobSampson as his script had the desired effect that I was after, just a shame it was never fine tuned enough to implement.

Thanks all for your suggestions!
0

Featured Post

Back Up Your Microsoft Windows Server®

Back up all your Microsoft Windows Server – on-premises, in remote locations, in private and hybrid clouds. Your entire Windows Server will be backed up in one easy step with patented, block-level disk imaging. We achieve RTOs (recovery time objectives) as low as 15 seconds.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When you start your Windows 10 PC and got an "Operating system not found" error or just saw  "Auto repair for startup" or a blinking cursor with black screen. A loop for Auto repair will start but fix nothing.  You will be panic as there are no back…
While working, an annoying popup showing below will come and we cannot cancel or close it form the screen. The error message will come again and again.
This Micro Tutorial will give you a basic overview of Windows DVD Burner through its features and interface. This will be demonstrated using Windows 7 operating system.
This Micro Tutorial will give you a introduction in two parts how to utilize Windows Live Movie Maker to its maximum editing capability. This will be demonstrated using Windows Live Movie Maker on Windows 7 operating system.

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question