Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

VBScript to skip pc that is not on network. 1

Status
Not open for further replies.

EUTTECH

MIS
Dec 9, 2010
15
US
I have a script that reads a txt file line by line a list of hostnames. Then it pipes out certain info from that pc to a csv file. When it gets to a hostname that is not on the network or not pinging it takes a while and pipes out the info of the last pc that was pinging. Can someone help me with the code that goes in the script that will ping the pc first and if it is on the network it will continue the script if not it pipes out PC not on network. Here is the code.

Code:
Option Explicit
On Error Resume Next
Dim objFSO, objInFile, objItem, objItem2, objOutFile, strFile, strOutData, strOutFile
Dim strComputer, strModel, strUsername, strMacaddress, strSvcTag, strIPAddress, intRamMB
Dim objWMIService, colItems, colItems2
Dim colComputer, objComputer


strFile = "C:\ComputerInfo\List.txt"
strOutFile = "C:\ComputerInfo\Out.csv"

Set objFSO = CreateObject("Scripting.FileSystemObject")


Set objInFile = objFSO.OpenTextFile(strFile)

Set objOutFile = objFSO.CreateTextFile(strOutFile, True)
Do Until objInFile.AtEndOfStream

    strComputer = objInFile.ReadLine
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") 
    Set colItems = objWMIService.ExecQuery("Select * from Win32_BIOS",,48) 
    For Each objItem in colItems 
    strSvcTag = objItem.SerialNumber 
    Next 

    set colItems2 = objWMIService.ExecQuery("Select * from Win32_ComputerSystem",,48) 
    For Each objItem2 in colItems2 
    strUsername = objItem2.UserName 
    strModel = objItem2.Model 
    Next 

    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery _
    ("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")
    For Each objItem in colItems
    strMacaddress = objItem.Macaddress
    next

    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery _
    ("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")
    For Each objItem in colItems
    stripaddress = objitem.ipaddress(0)
    next

    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\"  & strComputer & "\root\cimv2")
    Set colComputer = objWMIService.ExecQuery ("Select * from Win32_ComputerSystem")
    For Each objComputer in colComputer 
    intRamMB = int((objComputer.TotalPhysicalMemory) /1048576)+1
    next

    strOutData = strComputer &  "|" & strIPAddress &  "|" & strSvcTag &  "|" & strModel &  "|" & strUsername &  "|" & strMacaddress &  "|" & intRamMB & vbCrLf & vbCrLf


objOutFile.Write strOutData

Loop

objOutFile.Close
 
If you are looking to ping a computer and do something based on the response, have a look at this thread: thread222-1611646

Some good stuff in there from strongm.
 
Okay when I implement that coding into the script I have it takes forever to run. Also this kinda of hard to explain but I want it to skip it and write out something line pc not online or pinging something to that sort. The reason I want it to skip it because when I run it and the pc is not pinging, when it gets to that line it writes the data from the last pc that was online. I hope that makes sense. Any other suggestions.

So to sum it up, I want it to check to see if the pc is online first, if it isnt it writes out something like pc not online, and then continues to the next pc on the list.
 
>when I implement that coding into the script I have it takes forever to run

Were you using my code from the thread jges linked or the multiple flawed versions (in the sense that they are slow rather than in the sense that they do not work) that were Execing ping?
 
Well I have about 4000 computers to run this script on. When it gets to a pc that is not on the network, i.e. turned off, renamed or something to that effect it pings it and times out 4 times. So if there is about 20 or 30 computers in a row that do not ping then it takes a long time for the script to run, in that sense. So what I was wanting the script to do is ping it once first, if it pings run the script, if it times out pipe out to the csv file "PC not on" or something to that effect. I am no expert in coding at all I was just trying to get this script to work from an old co worker.

I hope I am making some sort of sense if not I can try to explain better.
 
>So what I was wanting the script to do is ping it once first

And if you use my code that's exactly what happens. I don't think you are reading the responses here properly ...
 
I think you are not understanding the whole picture just part of it. I understand your code will ping the computer but it does not return the pc is not pinging and goes to the next computer. When your code is put in the script it does ping it but when there is a pc not on the network it does skip it but writes out the info on that line as the last entry for the pc that it was pinging.
 
I completely understand your entire problem. Really.

My code is not a complete solution to your problem. It solves the

>When it gets to a hostname that is not on the network or not pinging it takes a while

and

>Can someone help me with the code that goes in the script that will ping the pc first

parts of your problem. And that's the tricky part. The rest is just a simple If block straight after

strComputer = objInFile.ReadLine

I would expect End If to come just before Loop.

(Pseudo version: If isReachable Then do AllMyWMIStuff Else do not).

You have to help yourself a bit here. We're not a free coding shop.
 
Okay, I finally got that. So I did that and it is kinda working now. Here is the code.

Code:
Option Explicit
On Error Resume Next
Dim objFSO, objInFile, objItem, objItem2, objOutFile, strFile, strOutData, strOutFile, strNoData
Dim strComputer, strModel, strUsername, strMacaddress, strSvcTag, strIPAddress, intRamMB
Dim objWMIService, colItems, colItems2
Dim colComputer, objComputer, objPing, objStatus
Dim IsReachable, wmiQuery


strFile = "C:\ComputerInfo\List.txt"
strOutFile = "C:\ComputerInfo\Out.csv"




Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objInFile = objFSO.OpenTextFile(strFile)
Set objOutFile = objFSO.CreateTextFile(strOutFile, True)

Do Until objInFile.AtEndOfStream

    strComputer = objInFile.ReadLine

    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\root\cimv2")
    Set objPing = objWMIService.ExecQuery("Select * From Win32_PingStatus Where Address = '" & strComputer & "' and StatusCode=0")
    For Each objStatus In objPing
    IsReachable = objStatus.StatusCode = 0
    Next

    if IsReachable then
   
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") 
    Set colItems = objWMIService.ExecQuery("Select * from Win32_BIOS",,48) 
    For Each objItem in colItems 
    strSvcTag = objItem.SerialNumber 
    Next 


    set colItems2 = objWMIService.ExecQuery("Select * from Win32_ComputerSystem",,48) 
    For Each objItem2 in colItems2 
    strUsername = objItem2.UserName 
    strModel = objItem2.Model 
    Next 

    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery _
    ("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")
    For Each objItem in colItems
    strMacaddress = objItem.Macaddress
    next

    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery _
    ("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")
    For Each objItem in colItems
    stripaddress = objitem.ipaddress(0)
    next

    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\"  & strComputer & "\root\cimv2")
    Set colComputer = objWMIService.ExecQuery ("Select * from Win32_ComputerSystem")
    For Each objComputer in colComputer 
    intRamMB = int((objComputer.TotalPhysicalMemory) /1048576)+1
    next

    strOutData = strComputer &  "|" & strIPAddress &  "|" & strSvcTag &  "|" & strModel &  "|" & strUsername &  "|" & strMacaddress &  "|" & intRamMB & vbCrLf & vbCrLf


objOutFile.Write strOutData

else

strNoData = "Computer Not Online or Cannot Ping." & vbCrLf

objOutFile.Write strNoData

End If
Loop
objOutFile.Close

When it runs, and it gets to the first pc not on the network it does write out the data pc not pinging, but when it gets to the second one it writes the data from the last pinging pc. Am I missing something else here?
 
i would advise moving the first instance of this line out of your loop

Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\root\cimv2")

this line is setting up a WMI connection to your local machine to use for the Ping of each line in you file, you dont need to keep killing and recreating for each line, this will slow things down. i suggest using something like Set objLOCALWMIService as the variable name, so you dont get confused.

likewise the same applies to the rest of the:

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

you have about 5 instances of this call in your Do Loop, this means you will be attaching to each machine on each line of your file 5 times via WMI, just connect once at the start of the loop, you dont need to keep making the same call over and over

I Hear, I Forget
I See, I Remember
I Do, I Understand

Ronald McDonald
 
Oh, I wasn't going anywhere near optimising the current code any further just yet ...
(for example there are at least two unneccessary WMI ExecQuery calls)

 
>Oh, I wasn't going anywhere near optimising the current code any further just yet ...

Well you wont have to, I turned to Experts Exchange and they were really helpful and very NICE to work with.

I guess it does pay to purchase a subscription.
 
And here dies another learning opportunity.
 
I turned to Experts Exchange and they were really helpful and very NICE to work with

MAKE NO MISTAKE... as is the norm with this site, you were given excellent and accurate help, in a professional, and (yes) NICE manner.

Luckily, it is also the norm that those asking for help are courteous and thankful for the help they receive. You are the exception.
 
And out of interest I've looked at the solution on Experts Exchange (those of you without accounts may not be able to see the answers or comments until Google get around to indexing and cacheing this page, which they have not so far). Can't see that they are more helpful or nicer. In fact they seem to have provided you with far less than we have here, namely:

a) the quick ping, resolving speed issue

and

b) the correct pseudocode (If isReachable Then do AllMyWMIStuff Else do not) to resolve the logging issue (albeit without writing all the lines of code for you)

In fact, all experts exchange have done is pointed out that you got isReachable wrong and provided a fix so that the pseudocode runs as intended. A tiny bit of patience (an hour and a half between "Am I missing something else here" and trying to put us in our place does not really count as patience) and I would have pointed out the same problem and explained how the transition from a function to inline code had stopped it working as intended (and provided a much shorter, much simpler variation). But I guess that would have been educational ...

If anyone is still interested I have a pretty clean, fast version of the solution that implements most of the improvements/changes to the original code that we have discussed (it does not include, however, the explanation for why isReachable stopped working when moved inline...)
 
I'm interested, not that I have an immediate use for it; but I'm sure I'd learn something.
 
Ok ...
Code:
[blue]Option Explicit
[green]'On Error Resume Next ' I wouldn't do this unless you know exactly why your using it ...[/green]
Dim objFSO, objInFile, objOutFile, strFile, strOutData, strOutFile, strNoData
Dim strComputer, strModel, strUsername, strMacaddress, strSvcTag, strIPAddress, intRamMB
Dim objLocalWMIService, objWMIService, colItems, objItem
Dim objPing, objStatus
Dim IsReachable

strFile = "C:\ComputerInfo\List.txt"
strOutFile = "C:\ComputerInfo\Out.csv"

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objInFile = objFSO.OpenTextFile(strFile)
Set objOutFile = objFSO.CreateTextFile(strOutFile, True)

[green]' Move out of loop as an optimisation[/green]
Set objLocalWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\root\cimv2")

Do Until objInFile.AtEndOfStream

    strComputer = objInFile.ReadLine

    [green]' The following two lines allow a quick check of whether a PC is available[/green]
    Set objPing = objLocalWMIService.ExecQuery("Select * From Win32_PingStatus Where Address = '" & strComputer & "' and StatusCode=0")
    IsReachable = objPing.Count > 0
    
    [green]'The following was a little over-engineered for the original isReachable function (because it needed to be a clear illustration of a technique), and can be happily replaced with the single line above
    'For Each objStatus In objPing
    '    IsReachable = objStatus.StatusCode = 0 ' I overengineered this in the original function
    'Next
    
    ' The following addresses the second part of the OPs problem
    ' (Pseudo version: If isReachable Then do AllMyWMIStuff Else do not).[/green]
    If IsReachable Then
        Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") [green]' Optimised: just need to do this the once for each pinged PC[/green]
        
        Set colItems = objWMIService.ExecQuery("Select * from Win32_BIOS", , 48)
        For Each objItem In colItems
            strSvcTag = objItem.SerialNumber
        Next
    
        Set colItems = objWMIService.ExecQuery("Select * from Win32_ComputerSystem", , 48)
        For Each objItem In colItems
            strUsername = objItem.UserName
            strModel = objItem.Model
            intRamMB = Int((objItem.TotalPhysicalMemory) / 1048576) + 1
        Next
        
        Set colItems = objWMIService.ExecQuery("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")
        For Each objItem In colItems
            strMacaddress = objItem.Macaddress
            strIPAddress = objItem.ipaddress(0)
        Next
      
        strOutData = strComputer & "|" & strIPAddress & "|" & strSvcTag & "|" & strModel & "|" & strUsername & "|" & strMacaddress & "|" & intRamMB & vbCrLf & vbCrLf
        objOutFile.Write strOutData
    
    Else
        strNoData = strComputer & ": Computer Not Online or Cannot Ping." & vbCrLf
        objOutFile.Write strNoData

    End If
Loop

objOutFile.Close[/blue]
 
you definitely deserve a star strongm.

EUTTECH, dont look a gift horse in the mouth.

i really wish this site had little button you can push to place OP / Users on some sort of 'ignore' list ;-)

merry christmas everyone, i am off on a weeks holiday skiing :) back in the office after crimbo, got a project i have to write in powershell, even though i have the code in vbscript, i am not looking forward to it!

I Hear, I Forget
I See, I Remember
I Do, I Understand

Ronald McDonald
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top