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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Help with a pretty simple script for the rookie

Status
Not open for further replies.
Mar 12, 2013
5
US
Hi everyone, I am pretty new to scripting and I am trying to practice as much as possible I have a script that is functioning almost correctly there is just one part that I cannot get to work right. Any ideas would be much appreciated. First here is what the script does:
1. Enumerate an active directory group
2. Ping all the members of the group
3. If the member is turned on restart the machine
4. If it is not on write the word DOWN
5. And if it pings, remove the member from the group
So, here is my code.....
On Error Resume Next

Set objGroup = GetObject _
("LDAP://cn=group,ou=domain, dc=OU, dc=net")
objGroup.GetInfo

arrMemberOf = objGroup.GetEx("member")

For Each strMember in arrMemberOf
xcomputer = split(strmember,",")
xname = mid(xcomputer(0),4,len(xcomputer(0))-1)
if Ping( xname ) = True then

Set OpSysSet = GetObject("winmgmts:{impersonationLevel=impersonate,(RemoteShutdown)}//" & xname).ExecQuery("select * from Win32_OperatingSystem where Primary=true")
for each OpSys in OpSysSet
OpSys.Reboot()

If Ping( xname ) = True then
for each xname in arrMemberOf
objGroup.Remove("LDAP://" & xname)
objGroup.SetInfo
next
end if

next

else
strStatus = "DOWN"
end if
wscript.echo strStatus
Next

Function Ping(strComputer)
Dim objShell, boolCode
Set objShell = CreateObject("WScript.Shell")
boolCode = objShell.Run("Ping -n 1 -w 300 " & strComputer, 0, True)
If boolCode = 0 Then
Ping = True
Else
Ping = False
End If
End Function

Ok, everything works the way I want it to except one part. When the computer reboots and is supposed to be removed from the group, the script instead removes every member of the group at one time instead of stepping through each one. Again any advice for the rookie would be greatly appreciated.

Thanks,
Brandon
 
I'm not an expert, but it looks like you're already in the middle of an IF statement from above (before the Set OpSysSet...). Why don't you get rid of the following lines
If Ping( xname ) = True then
for each xname in arrMemberOf

objGroup.Remove("LDAP://" & xname)
objGroup.SetInfo
next
end if
 
Did you try to replace this :
If Ping( xname ) = True then
for each xname in arrMemberOf
objGroup.Remove("LDAP://" & xname)
objGroup.SetInfo
next
end if
with simply this ?
objGroup.Remove "LDAP://" & xname
or perhaps this ?
objGroup.Remove "LDAP://" & strMember

Hope This Helps, PH.
FAQ219-2884
FAQ181-2886
 
Thanks so much for the response guys, actually just two days ago I thought about that and took it out, it is still giving me the same results, but without those statements now it just prints out DOWN for all of the members, what I want it to do is only print DOWN for the members not responding and leave them in the group. Here is what the code looks like without those lines.

On Error Resume Next

Set objGroup = GetObject _
("LDAP://cn=SophoFixIt,ou=CMSD, dc=cmsd, dc=net")
objGroup.GetInfo

arrMemberOf = objGroup.GetEx("member")


For Each strMember in arrMemberOf
xcomputer = split(strmember,",")
xname = mid(xcomputer(0),4,len(xcomputer(0))-1)

if Ping( xname ) = True then

Set OpSysSet = GetObject("winmgmts:{impersonationLevel=impersonate,(RemoteShutdown)}//" & xname).ExecQuery("select * from Win32_OperatingSystem where Primary=true")
for each OpSys in OpSysSet
wscript.echo OpSysSet
OpSys.Reboot()


objGroup.Remove("LDAP://" & xname)
objGroup.SetInfo

next

else
strStatus = "DOWN"
end if
wscript.echo strStatus

Next

Function Ping( xname )
Dim objShell, boolCode
Set objShell = CreateObject("WScript.Shell")
boolCode = objShell.Run("Ping -n 1 -w 300 " & xname, 0, True)
If boolCode = 0 Then
Ping = True
Else
Ping = False
End If
End Function

I appreciate everyones help, I really wan to get this solved. Thanks again.
 
If the current code isn't changing the results, it doesn't sound like it's going through the loop. Put a BREAK in the IF command and see what values you're getting for the Ping(xname).

I'm wondering if your need to change in your Function Ping(xname) subrouting instead of Ping = True & Ping = False to Ping(xname) = True and Ping(xname) = False
 
zlegar said:
I'm wondering if your need to change in your Function Ping(xname) subrouting instead of Ping = True & Ping = False to Ping(xname) = True and Ping(xname) = False
No, madmardegon had the correct Function syntax. Also, vbscript does not have a "break" command, although I agree about looking at the values. Maybe change the function to this for debugging purposes:

Code:
Function Ping( xname )
	Dim objShell, boolCode
	Set objShell = CreateObject("WScript.Shell")
	boolCode = objShell.Run("Ping -n 1 -w 300 " & xname, 0, True)
	If boolCode = 0 Then
	   Ping = True
	   [highlight #FCE94F]Msgbox "Ping (" & xname & ") was successful."[/highlight]
	Else
	   Ping = False
	   [highlight #FCE94F]Msgbox "Ping (" & xname & ") failed."[/highlight]
	End If

End Function

madmardegon: You also have "On Error Resume Next", which will suppress all runtime errors and may be masking other problems.
 
Thanks a lot guys, going to get right on this, this morning, I will post what happens today sometime.
 
Your ping function isn't doing what you might think it is. When you use the Run property of WshShell, the ErrorLevel returned will always be 0 as long as the program called runs without errors. It is not interpreting whether or not the device replies; it only cares that "ping" executed successfully.

Instead, you'll want to use the Exec command in order to stream the output to a string using the StdOut.ReadLine() parameter. Then you can interrogate the string to determine if a reply was successful.

These links show good examples:


-Carl
"The glass is neither half-full nor half-empty: it's twice as big as it needs to be."

[tab][navy]For this site's posting policies, click [/navy]here.
 
cdogg:
I'm not sure that's correct... The OP's ping function seems to work just fine for me.

On the subject, there is another vbscript ping function in the FAQ below:
faq329-6527
 
Thanks for the responses everyone, so here is what I can tell you so far and then I will post the code again. I took some of the suggestions and what I found is this, if the machines that are pinged in the list start off as being off then the program does not remove them from the list which is what I want, buuutttt, as soon as the program hits one that is on, it removes all members from the group, it doesn't even wait for the all the pings to finish. Now this might be useful info as well, When I run this with wscript it seems to step through each machine, but with cscript it acts in the manor I have been describing. I will be running this first thing in the morning again because I can't shut down machines remotely during the day, don't want to freak out the users lol. Again thanks for all the help everyone.

madmardegon

Set objGroup = GetObject _
("LDAP://cn=SophoFixIt,ou=CMSD, dc=cmsd, dc=net")
objGroup.GetInfo

arrMemberOf = objGroup.GetEx("member")


For Each strMember in arrMemberOf
xcomputer = split(strmember,",")
xname = mid(xcomputer(0),4,len(xcomputer(0))-1)

if Ping( xname ) = True then
strStatus = "UP"

Set OpSysSet = GetObject("winmgmts:{impersonationLevel=impersonate,(RemoteShutdown)}//" & xname).ExecQuery("select * from Win32_OperatingSystem where Primary=true")
For Each OpSys in OpSysSet
OpSys.Reboot()
objGroup.Remove("LDAP://" & xname)
objGroup.SetInfo
Next
else
strStatus = "DOWN"
end if


Next

Function Ping( xname )
Dim objShell, boolCode
Set objShell = CreateObject("WScript.Shell")
boolCode = objShell.Run("Ping -n 1 -w 300 " & xname, 0, True)
If boolCode = 0 Then
Ping = True
Msgbox "Ping (" & xname & ") was successful"
Else
Ping = False
Msgbox "Ping (" & xname & ") failed"
End If
End Function
 
I ran the OP's function as well. If I manually substitute xname with a pingable computer name on my network, the function returns 1. If I subsitute a computer name that doesn't exist (i.e. no reply), the function still returns 1.

In my last post, I said it would always return 0. However, I meant to say it would always return 1, which happens to be the False case in the IF statement.

-Carl
"The glass is neither half-full nor half-empty: it's twice as big as it needs to be."

[tab][navy]For this site's posting policies, click [/navy]here.
 
Carl thank you for your input, but when I am running the script on my computer group it does return different values of up and down for me, and I can ping those same machines and they respond the same way as the scripts response, the part that seems to be goofing up is when it comes to removing them from the group.
 
Yeah, I'm just realizing that now. I believe I'm running into a security issue on my system that seems to be causing the command to return 1 every time. My apologies...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top