Photo Gallery Member List Search Calendars FAQ Ticket List Log Out


Require assistance with script

 
Logged in as: Guest
arrSession:exec spGetSession 2,2,25982
 Active Users: There are 0 members and 0 guests.
 Users viewing this topic: none
 

 

 
  
  Printable Version
All Forums >> [Scripting] >> WSH & Client Side VBScript >> Require assistance with script
  Do you like VisualBasicScript.com? Link to us and help spread the word about our forum. Thanks!
Page: [1]
Login
Message << Older Topic   Newer Topic >>
 Require assistance with script - 9/15/2005 3:52:06 AM   
  Bretai2k

 

Posts: 3
Score: 0
Joined: 9/15/2005
Status: offline
I have recently gotten into scripting and WMI, and by looking at example codes I was able to piece together a script that will call machine names from a text file, dump it into an array, collect hardware inventory data about each machine, and dump them into text files on my computer.  The issue I am running into now is that any time the script comes across a machine that is not pinging on the network (either unknown host or no reply) the script dies.

Could someone help me come up with a solution where the if the script cannot connect to the machine it will skip that machine and continue onto the next?

I have looked everywhere and cannot find much about this specific issue.  I have copied the script below and changed some of the system specific values.  It was Frankensteined and tweaked from many different sources, so most of this code is not entirely my own.  All help would be appreciated.

TIA

'On Error Resume Next directive is specified so that users
'are not bothered by potential operational errors with the script.
'On Error Resume Next
'Using both of these flags of the WbemFlagEnum enumeration
'makes a semisynchronous WMI call. See "Making a Semisynchronous Call"
'in the WMI SDK for more information.
Const wbemFlagReturnImmediately = 16
Const wbemFlagForwardOnly = 32
'WbemCimtypeEnum Enumerations used in the script
Const wbemCimtypeUint32 = 19
Const wbemCimtypeSint64 = 20
Const wbemCimtypeUint64 = 21
'Formatting and number conversion constants
Const HR = "----"
Const KB = 1024
Const MB = 1048576
Const GB = 1073741824
'Change this to the UNC path where inventory files should be created
'Anyone running this script must have read and  write access to the
'path.
strInvFilePath = "location"
'Gathering the machine name data from the text file and
'place it into an array.
On Error Resume Next
'Open the file system object
Set oFSO = CreateObject("Scripting.FileSystemObject")
set WSHShell = wscript.createObject("wscript.shell")
'Open the data file
Set oTextStream = oFSO.OpenTextFile("text.txt")
'Make an array from the data file
RemotePC = Split(oTextStream.ReadAll, vbNewLine)
'Close the data file
oTextStream.Close
For Each strComputer In RemotePC
Set objWMIService = GetObject("winmgmts:" _
  & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

'Determine the OS because not all classes listed here are supported
'on all versions of the Windows operating systems
strProperties = "CreationClassName,Version,CSName,Caption"
Set objOS = objWMIService.ExecQuery _
("SELECT " & strProperties & " FROM Win32_OperatingSystem",_
  ,wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each Setting in objOS
strCreationClass = Setting.CreationClassName
intVersion = Setting.Version
strCSName = Setting.CSName
strCaption = Setting.Caption
Next
'Check for a file named after the computer. If it doesn't
'exist, then create a file that contains the computer's
'hardware inventory.
Set objFSO = CreateObject("Scripting.FileSystemObject")
strFileName = "HrdWrInv_" & strCSName & ".txt"
strFullName = objFSO.BuildPath(strInvFilePath, strFileName)
If (objFSO.FileExists(strFullName)) Then WScript.Quit
Set objFile = objFSO.CreateTextFile(strFullName)
'Write the Operating System name and version but nothing more.
'The goal is to collect hardware inventory, not software inventory
'and configuration information.
objFile.WriteLine("OSInformation:")
objFile.WriteLine("CreationClassName: " & strCreationClass)
objFile.WriteLine("ComputerName: " & strCSName)
objFile.WriteLine("Caption: " & strCaption)
objFile.WriteLine("Version: " & intVersion)
'The name property is automatically returned (because it's a key value), so
'it's not absolutely necessary to specify it in strProperties
strProperties = _
"CreationClassName,Manufacturer,Model,Name,NumberofProcessors," & _
"SystemType,TotalPhysicalMemory"
QueryInstances "Win32_ComputerSystem",strProperties,"None"
'Page file information.
strProperties = _
"Name,MaximumSize"
QueryInstances "Win32_PageFileSetting",strProperties,"None"
'Physical memory information.
'Note, total memory is aggregated and listed with win32_computersystem so there's
'no need to query the memory classes, such as  Win32_PhysicalMemoryArray or
'Win32_PhysicalMemory. However, if you need to find out how much memory
'a computer will hold, it's useful to query Win32_PhysicalMemoryArray as
'shown
strProperties = _
"MaxCapacity,CreationClassName"
QueryInstances "Win32_PhysicalMemoryArray",strProperties,"None"
'SCSI Disk controller information
strProperties = _
"Name,Manufacturer,Description,CreationClassName"
QueryInstances "Win32_SCSIController",strProperties,"None"
'IDE Disk controller information
strProperties = _
"Name,Manufacturer,Description,CreationClassName"
QueryInstances "Win32_IDEController",strProperties,"None"
'Phyiscal Media information
'Note, this class is only in XP (ver5) and the Windows
'Server 2003 family (ver5).
'Win98SE reports a version number of 4 (4.10.2222)
If Mid(intVersion,1,3) >= 5.1 Then
strProperties = _
  "SerialNumber,CreationClassName"
QueryInstances "Win32_PhysicalMedia",strProperties,"None"
End If
'Logical Disk information
strProperties = _
"DriveType,Description,DeviceID,CreationClassName"
QueryInstances "Win32_LogicalDisk",strProperties,_
"DriveType!=3 AND DriveType !=4"
'Disk drive information
strProperties = _
"Caption,Description,DeviceID,InterfaceType," & _
"Manufacturer,MediaType,Model,Partitions,Size,CreationClassName"
QueryInstances "Win32_DiskDrive",strProperties,"None"
'Processor information
strProperties = _
"Manufacturer,MaxClockSpeed,ExtClock,ProcessorType," & _
"Revision,Version,CreationClassName"
QueryInstances "Win32_Processor",strProperties,"None"
'NIC information
strProperties = _
"Manufacturer,MACAddress,ProductName,AdapterType,CreationClassName"
QueryInstances "Win32_NetworkAdapter",strProperties,_
"AdapterType='Ethernet 802.3' AND ProductName !='Packet Scheduler Miniport'"
'Monitor information
strProperties = _
"Description,MonitorType,CreationClassName"
QueryInstances "Win32_DesktopMonitor",strProperties,"None"
'Video adapter information
strProperties = _
"Name,MaxRefreshRate,AdapterRAM,CreationClassName"
QueryInstances "Win32_VideoController",strProperties,"None" 
'Motherboard information
strProperties = _
"Description,Manufacturer,Product,CreationClassName"
QueryInstances "Win32_BaseBoard",strProperties,"None"
'BIOS information
strProperties = _
"Manufacturer, Name,SoftwareElementID,SMBIOSBIOSVersion," & _
"SMBIOSMajorVersion,SMBIOSMinorVersion,Version"
QueryInstances "Win32_BIOS",strProperties,"None"
objFile.Close
Next
MsgBox "Processing Done"
'*****Subroutines and Functions*********
Sub QueryInstances(objClass,Properties,Conditions)
If Conditions = "None" Then
  strSelect = "Select " & Properties & " From " & objClass
Else
  strSelect = "Select " & Properties & " From " & objClass & _
    " Where " & Conditions
End If
Set objClassName = _
  objWMIService.ExecQuery _
    (strSelect,,wbemFlagReturnImmediately + wbemFlagForwardOnly)
intCounter = 0
'  Can use the following to determine the # of items in the sWbemObjectSet but
'  it's processor intensive and it means that you can't use a semi-synchronous
'  call because the count property doesn't work with wbemFlagForwardOnly.
'  WScript.Echo "# of items in collection: " & objClassName.Count
For Each objComponent in objClassName
  If intCounter = 0 Then
    objFile.WriteLine(HR)
    objFile.WriteLine(Mid(objClass,7) & ":")
  End If
  For Each objProperty in objComponent.Properties_
    'Start by verifying that there's a value in the property.
    'If not, it isn't necessary to perform the evaluation in this loop.
    If ISNull(objProperty.Value) Then
      objFile.WriteLine(objProperty.Name & ": Not available")
    Else
      If objProperty.CIMType <> wbemCimtypeUint32 And _
        objProperty.CIMType <> wbemCimtypeUint64 And _
        objProperty.CIMType <> wbemCimtypeSint64 Then
          objFile.WriteLine(objProperty.Name & ": " & _
            objProperty.Value & " " & _
            GetUnits(objClass,objProperty.Name))
      Else
        strUnits = GetUnits(objClass,objProperty.Name)
        intValue = _
          SizeFormat(objProperty.Name,objProperty.Value,strUnits)
        objFile.WriteLine(objProperty.Name & ": " & intValue)
      End If
    End If
    intCounter = intCounter + 1
  Next
  If intCounter > 1 Then objFile.WriteLine(HR)
Next
objFile.WriteLine(HR)
objFile.WriteLine()
End Sub
Function GetUnits(ClassName,ClassProperty)
Set objSchemaClass = objWMIService.Get(ClassName)
For Each objClassProperty in objSchemaClass.Properties_
  If objClassProperty.Name = ClassProperty Then
    For Each objQualifier in objClassProperty.Qualifiers_
      If LCase(objQualifier.Name) = "units" Then
        GetUnits = LCase(objQualifier.Value)
      End If
    Next
  End If
Next
End Function
Function SizeFormat(PropertyName,RawValue,Units)
Select Case LCase(Units)
  Case "bytes"
    If int(RawValue/GB) >= 1 Then
      SizeFormat = Round((RawValue/GB),1) & " gigabyte(s)"
    ElseIf int(RawValue/MB) >= 1 Then
      SizeFormat = int(RawValue/MB) & " megabyte(s)"
    Else
      SizeFormat = RawValue & " byte(s)"
    End If
  Case "kilobytes"
    If int(RawValue/MB) >= 1 Then
      SizeFormat = Round((RawValue/MB),1) & " gigabyte(s)"
    ElseIf int(RawValue/KB) >= 1 Then
      SizeFormat = int(RawValue/1024) & " megabyte(s)"
    Else
      SizeFormat = RawValue & " kilobyte(s)"
    End If
  Case Else
    SizeFormat = RawValue & " " & Units
End Select
End Function
 
 
Post #: 1
 
 RE: Require assistance with script - 9/15/2005 4:11:19 AM   
  ebgreen


Posts: 5069
Score: 31
Joined: 7/12/2005
Status: online
This is a common problem. There is the common solution and what is in my opinion the right solution. :)

The common solution is to put the line 'On Error Resume Next' at the top of your script. THis essentially tells the script to ignore errors and keep on going.

The right solution is to identify the specific line that is the problem. In you case I would sya that it is probably:
Set objWMIService = GetObject("winmgmts:" _
  & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Immediately before the problem line, put the line 'On Error Resume Next'. This is the only place that you should have that line (unless you have other calls that will be expected to fail). Immediately after the problem line, put some code like this:
If Err.Number <> 0 Then
    bValidComputer = False
    'If you want to, you can log the computers that were not available here.
Else
    bValidComputer = True
End If
On Error Goto 0

Then you will need to wrap all the code that you only want to do for valid computers in an If - Then block like this:

If bValidComputer Then
    'Do your stuff here
    .
    .
    .
    .
End If

(in reply to Bretai2k)
 
 
Post #: 2
 
 RE: Require assistance with script - 9/15/2005 5:56:47 AM   
  Bretai2k

 

Posts: 3
Score: 0
Joined: 9/15/2005
Status: offline
ebgreen,

Thanks for the quick response!  I am trying your suggestion but I guess I am having a hard time figuring out where the last End If statement should really go in this script.

It seems to work if I have pinging machines in the list, but I get a Object Not in Collection error on the line containing For Each Setting in objOS.
 
I am a completely new to this and am trying to learn how most of this works.  I find I have the best luck by reverse engineering completed scripts to see what works and what doesn't but I am lost right now figuring out how to get this to work.
 
Any more ideas for me?
 
Thanks again!

(in reply to ebgreen)
 
 
Post #: 3
 
 RE: Require assistance with script - 9/15/2005 6:13:16 AM   
  ebgreen


Posts: 5069
Score: 31
Joined: 7/12/2005
Status: online
Here is what I would suggest doing (changes in red):

'Using both of these flags of the WbemFlagEnum enumeration
'makes a semisynchronous WMI call. See "Making a Semisynchronous Call"
'in the WMI SDK for more information.
Const wbemFlagReturnImmediately = 16
Const wbemFlagForwardOnly = 32
'WbemCimtypeEnum Enumerations used in the script
Const wbemCimtypeUint32 = 19
Const wbemCimtypeSint64 = 20
Const wbemCimtypeUint64 = 21
'Formatting and number conversion constants
Const HR = "----"
Const KB = 1024
Const MB = 1048576
Const GB = 1073741824
'Change this to the UNC path where inventory files should be created
'Anyone running this script must have read and  write access to the
'path.
strInvFilePath = "location"
'Gathering the machine name data from the text file and
'place it into an array.
On Error Resume Next<--- REMOVE THIS
'Open the file system object
Set oFSO = CreateObject("Scripting.FileSystemObject")
set WSHShell = wscript.createObject("wscript.shell")
'Open the data file
Set oTextStream = oFSO.OpenTextFile("text.txt")
'Make an array from the data file
RemotePC = Split(oTextStream.ReadAll, vbNewLine)
'Close the data file
oTextStream.Close
For Each strComputer In RemotePC
    On Error Resume Next
    Set objWMIService = GetObject("winmgmts:" _
      & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    'Determine the OS because not all classes listed here are supported
    'on all versions of the Windows operating systems
    If Err.Number <> 0 Then
        bValidComputer = False
        'If you want to log the machines that were not inventoried, do it here
    Else
        bValidComputer = True
    End If
    On Error Goto 0
    If bValidComputer Then

        strProperties = "CreationClassName,Version,CSName,Caption"
        Set objOS = objWMIService.ExecQuery _
        ("SELECT " & strProperties & " FROM Win32_OperatingSystem",_
          ,wbemFlagReturnImmediately + wbemFlagForwardOnly)
        For Each Setting in objOS
            strCreationClass = Setting.CreationClassName
            intVersion = Setting.Version
            strCSName = Setting.CSName
            strCaption = Setting.Caption
        Next
        'Check for a file named after the computer. If it doesn't
        'exist, then create a file that contains the computer's
        'hardware inventory.
        Set objFSO = CreateObject("Scripting.FileSystemObject")
        strFileName = "HrdWrInv_" & strCSName & ".txt"
        strFullName = objFSO.BuildPath(strInvFilePath, strFileName)
        If (objFSO.FileExists(strFullName)) Then WScript.Quit
        Set objFile = objFSO.CreateTextFile(strFullName)
        'Write the Operating System name and version but nothing more.
        'The goal is to collect hardware inventory, not software inventory
        'and configuration information.
        objFile.WriteLine("OSInformation:")
        objFile.WriteLine("CreationClassName: " & strCreationClass)
        objFile.WriteLine("ComputerName: " & strCSName)
        objFile.WriteLine("Caption: " & strCaption)
        objFile.WriteLine("Version: " & intVersion)
        'The name property is automatically returned (because it's a key value), so
        'it's not absolutely necessary to specify it in strProperties
        strProperties = _
        "CreationClassName,Manufacturer,Model,Name,NumberofProcessors," & _
        "SystemType,TotalPhysicalMemory"
        QueryInstances "Win32_ComputerSystem",strProperties,"None"
        'Page file information.
        strProperties = _
        "Name,MaximumSize"
        QueryInstances "Win32_PageFileSetting",strProperties,"None"
        'Physical memory information.
        'Note, total memory is aggregated and listed with win32_computersystem so there's
        'no need to query the memory classes, such as  Win32_PhysicalMemoryArray Or
        'Win32_PhysicalMemory. However, if you need to find out how much memory
        'a computer will hold, it's useful to query Win32_PhysicalMemoryArray as
        'shown
        strProperties = _
        "MaxCapacity,CreationClassName"
        QueryInstances "Win32_PhysicalMemoryArray",strProperties,"None"
        'SCSI Disk controller information
        strProperties = _
        "Name,Manufacturer,Description,CreationClassName"
        QueryInstances "Win32_SCSIController",strProperties,"None"
        'IDE Disk controller information
        strProperties = _
        "Name,Manufacturer,Description,CreationClassName"
        QueryInstances "Win32_IDEController",strProperties,"None"
        'Phyiscal Media information
        'Note, this class is only in XP (ver5) and the Windows
        'Server 2003 family (ver5).
        'Win98SE reports a version number of 4 (4.10.2222)
        If Mid(intVersion,1,3) >= 5.1 Then
            strProperties = _
              "SerialNumber,CreationClassName"
            QueryInstances "Win32_PhysicalMedia",strProperties,"None"
        End If
        'Logical Disk information
        strProperties = _
        "DriveType,Description,DeviceID,CreationClassName"
        QueryInstances "Win32_LogicalDisk",strProperties,_
        "DriveType!=3 AND DriveType !=4"
        'Disk drive information
        strProperties = _
        "Caption,Description,DeviceID,InterfaceType," & _
        "Manufacturer,MediaType,Model,Partitions,Size,CreationClassName"
        QueryInstances "Win32_DiskDrive",strProperties,"None"
        'Processor information
        strProperties = _
        "Manufacturer,MaxClockSpeed,ExtClock,ProcessorType," & _
        "Revision,Version,CreationClassName"
        QueryInstances "Win32_Processor",strProperties,"None"
        'NIC information
        strProperties = _
        "Manufacturer,MACAddress,ProductName,AdapterType,CreationClassName"
        QueryInstances "Win32_NetworkAdapter",strProperties,_
        "AdapterType='Ethernet 802.3' AND ProductName !='Packet Scheduler Miniport'"
        'Monitor information
        strProperties = _
        "Description,MonitorType,CreationClassName"
        QueryInstances "Win32_DesktopMonitor",strProperties,"None"
        'Video adapter information
        strProperties = _
        "Name,MaxRefreshRate,AdapterRAM,CreationClassName"
        QueryInstances "Win32_VideoController",strProperties,"None"
        'Motherboard information
        strProperties = _
        "Description,Manufacturer,Product,CreationClassName"
        QueryInstances "Win32_BaseBoard",strProperties,"None"
        'BIOS information
        strProperties = _
        "Manufacturer, Name,SoftwareElementID,SMBIOSBIOSVersion," & _
        "SMBIOSMajorVersion,SMBIOSMinorVersion,Version"
        QueryInstances "Win32_BIOS",strProperties,"None"
        objFile.Close
    End If
Next
MsgBox "Processing Done"
'*****Subroutines and Functions*********
Sub QueryInstances(objClass,Properties,Conditions)
If Conditions = "None" Then
  strSelect = "Select " & Properties & " From " & objClass
Else
  strSelect = "Select " & Properties & " From " & objClass & _
    " Where " & Conditions
End If
Set objClassName = _
  objWMIService.ExecQuery _
    (strSelect,,wbemFlagReturnImmediately + wbemFlagForwardOnly)
intCounter = 0
'  Can use the following to determine the # of items in the sWbemObjectSet but
'  it's processor intensive and it means that you can't use a semi-synchronous
'  call because the count property doesn't work with wbemFlagForwardOnly.
'  WScript.Echo "# of items in collection: " & objClassName.Count
For Each objComponent in objClassName
  If intCounter = 0 Then
    objFile.WriteLine(HR)
    objFile.WriteLine(Mid(objClass,7) & ":")
  End If
  For Each objProperty in objComponent.Properties_
    'Start by verifying that there's a value in the property.
    'If not, it isn't necessary to perform the evaluation in this loop.
    If ISNull(objProperty.Value) Then
      objFile.WriteLine(objProperty.Name & ": Not available")
    Else
      If objProperty.CIMType <> wbemCimtypeUint32 And _
        objProperty.CIMType <> wbemCimtypeUint64 And _
        objProperty.CIMType <> wbemCimtypeSint64 Then
          objFile.WriteLine(objProperty.Name & ": " & _
            objProperty.Value & " " & _
            GetUnits(objClass,objProperty.Name))
      Else
        strUnits = GetUnits(objClass,objProperty.Name)
        intValue = _
          SizeFormat(objProperty.Name,objProperty.Value,strUnits)
        objFile.WriteLine(objProperty.Name & ": " & intValue)
      End If
    End If
    intCounter = intCounter + 1
  Next
  If intCounter > 1 Then objFile.WriteLine(HR)
Next
objFile.WriteLine(HR)
objFile.WriteLine()
End Sub
Function GetUnits(ClassName,ClassProperty)
Set objSchemaClass = objWMIService.Get(ClassName)
For Each objClassProperty in objSchemaClass.Properties_
  If objClassProperty.Name = ClassProperty Then
    For Each objQualifier in objClassProperty.Qualifiers_
      If LCase(objQualifier.Name) = "units" Then
        GetUnits = LCase(objQualifier.Value)
      End If
    Next
  End If
Next
End Function
Function SizeFormat(PropertyName,RawValue,Units)
Select Case LCase(Units)
  Case "bytes"
    If int(RawValue/GB) >= 1 Then
      SizeFormat = Round((RawValue/GB),1) & " gigabyte(s)"
    ElseIf int(RawValue/MB) >= 1 Then
      SizeFormat = int(RawValue/MB) & " megabyte(s)"
    Else
      SizeFormat = RawValue & " byte(s)"
    End If
  Case "kilobytes"
    If int(RawValue/MB) >= 1 Then
      SizeFormat = Round((RawValue/MB),1) & " gigabyte(s)"
    ElseIf int(RawValue/KB) >= 1 Then
      SizeFormat = int(RawValue/1024) & " megabyte(s)"
    Else
      SizeFormat = RawValue & " kilobyte(s)"
    End If
  Case Else
    SizeFormat = RawValue & " " & Units
End Select
End Function


I did not test this, but it should work barring silly things like typos. Speaking of which, once you get this working, you should consider investing the time in learning about 'Option Explicit' and using it.

(in reply to Bretai2k)
 
 
Post #: 4
 
 RE: Require assistance with script - 9/15/2005 6:44:48 AM   
  Bretai2k

 

Posts: 3
Score: 0
Joined: 9/15/2005
Status: offline
That worked!  Thank you so much.

I actually had to go through all of this so we could have a good idea of who may need upgraded systems at my office.  We are now looking into ways to deploy this into logon scripts, and having it dump the data out to a SQL database that will be push to a PHP page.  Fortunately I have a bit more experience with SQL and PHP. 

Thanks again for all of your help!

P.S. I will look into Option Explicit as well.

(in reply to ebgreen)
 
 
Post #: 5
 
 
 
  

If you found our site useful please link to us <a href="http://www.visualbasicscript.com">VisualBasicScript.com</a>.
All Forums >> [Scripting] >> WSH & Client Side VBScript >> Require assistance with script Page: [1]
Jump to:





New Messages No New Messages
Hot Topic w/ New Messages Hot Topic w/o New Messages
Locked w/ New Messages Locked w/o New Messages
 Post New Thread
 Reply to Message
 Post New Poll
 Submit Vote
 Delete My Own Post
 Delete My Own Thread
 Rate Posts