# Solved: Something not quite right in computer shutdown VB script.



## StumpedTechy (Jul 7, 2004)

Okay here is what I have so far - I did take some of this from another users code here - http://hacks.oreilly.com/pub/h/1104 - BUT I had to modify alot of it to fit our needs and make things automatic.

Now mind you running this with this exact setup it runs and displays the shutdown prompt box as it should.

When it doesn't work is if I take ANY other computername and subsitute it for strComputer = "." I.E. strComputer = "Remoteuserscomputername"


```
strComputer = "."

function Ping(byval strComputer)
dim objFSO, objShell, objTempFile, objTS
dim sCommand, sReadLine
dim bReturn

set objShell = WScript.CreateObject("Wscript.Shell")
set objFSO = CreateObject("Scripting.FileSystemObject")

bReturn = false

sCommand = "cmd /c ping.exe -n 3 -w 1000 " & strComputer & " > C:\ComputerShutdown\temp.txt"

objShell.run sCommand, 0, true

set objTempFile = objFSO.GetFile("C:\ComputerShutdown\temp.txt")
set objTS = objTempFile.OpenAsTextStream(1)

do while objTs.AtEndOfStream <> true
sReadLine = objTs.ReadLine
if instr(lcase(sReadLine), "reply from") > 0 then
bReturn = true
exit do
end if
loop

objTS.close
objTempFile.delete
set objTS = nothing
set objTempFile = nothing
set objShell = nothing
set objFSO = nothing

Ping = bReturn
end function

bPingtest = ping(strcomputer)

If bPingtest = False Then
set objWSHShell = WScript.CreateObject("WScript.Shell")
objWSHShell.Run "shutdown.exe /s /f /m \\" & strComputer & " /t 15"
end if
```
What I want is to have a script that will 1) ping a machine and 2) determine if its active on the network then 3)if it is have it run shutdown.exe /s /f /m \\" & strComputer & " /t 15.

As a side note I want it to get the entire script to work from a text file that has a list of machine names that will sometimes be 10's sometimes may be 100's of computers machine variable from a text file we will have in place.


----------



## cristobal03 (Aug 5, 2005)

In what way does it fail if you use a different computer name? What line breaks?

chris.


----------



## StumpedTechy (Jul 7, 2004)

None that is the strange part about it.

When I run it on the local PC with the . I get the file created and removed, I get a quick flash of the command window and the shutdown prompt. When I change the . to a computername I do get the file made and removed on the PC I ran the VBS from, I don't get the flash of the cmd window (on either PC) and I don't get the shutdown (on either PC). But I don't get a VBS error code.

?


----------



## cristobal03 (Aug 5, 2005)

Is it possible to make the cmd window persistent and toss in a couple breaks/pauses there? Or perhaps log the output? I'm sure you're of the same opinion that the problem must be with the command-line portion, which doesn't do much in the way of error trapping/handling.

I don't know much about Windows networking. How is shutdown.exe resolving the address when you use the computer name? In other words, can you get the command to work manually if you debug.print both shell strings and copy them into cmd.exe?

Don't mind me, I'm sure you've tried all this stuff. I'm only suggesting it because I don't see anything wrong with the script.

chris.


----------



## StumpedTechy (Jul 7, 2004)

Actually I figured it out -

Made a ton of changes when I read about 10 more sites -


```
'Opens up text file for reading
Const FOR_READING = 1
g_strHostFile = "C:\Computershutdown\computers.txt"
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(g_strHostFile) Then
  Set objTextStream = objFSO.OpenTextFile(g_strHostFile, FOR_READING)
Else
  WScript.Echo "Input file " & g_strHostFile & " not found."
  WScript.Quit
End If
'Loops the string for all lines in the text.
Do Until objTextStream.AtEndOfStream
  g_strComputer = objTextStream.ReadLine
  blnPing = PingHost
  If blnPing = True Then
'runs the shutdown if the ping is true
set objWSHShell = WScript.CreateObject("WScript.Shell")
objWSHShell.Run "shutdown.exe /s /f /m \\" & g_strComputer & " /t 15"
else
'gives me a prompt if the ping isn't true
WScript.Echo "ERROR: " & g_strComputer & " did not respond to ping."
End if
loop
objTextStream.Close

'ping function scripting (allows the ping to be performed).
Function PingHost

Set objShell = CreateObject("WScript.Shell")
Set objExec = objShell.Exec("ping -n 3 -w 1000 " & g_strComputer)
strPingResults = LCase(objExec.StdOut.ReadAll)
If InStr(strPingResults, "reply from") Then
  PingHost = True
Else
  PingHost = False
End If

End Function
```
I think there may be something flawed in how I was addressing the ping portion. and this new code has fixed that. Thats really my only thought. Thanks for trying to help but I have a finished piece of work now.


----------



## Squashman (Apr 4, 2003)

Here is another way to do it as well.


```
option explicit 

dim arrComputers() 
dim objFSO 
dim objTextFile 
dim intUpperBound 
dim strComputer 
dim blnPingTest 
dim objWMIService 
dim colOpSys 
dim objOpSys 

const ForReading = 1 

set objFSO = CreateObject("Scripting.FileSystemObject") 
set objTextFile = objFSO.OpenTextFile ("computers.txt", ForReading) 

intUpperBound = 0 

while not objTextFile.AtEndOfStream 
   ReDim Preserve arrComputers(intUpperBound) 
   arrComputers(UBound(arrComputers)) = objTextFile.ReadLine 
   intUpperBound = intUpperBound + 1 
wend 

objTextFile.Close 

set objTextFile = nothing 
set objFSO = nothing 


for each strComputer in arrComputers 
    
   blnPingtest = ping(strComputer) 
   if blnPingtest = True then 
      set objWMIService=GetObject("winmgmts:{(Debug,RemoteShutdown)}\\" & strComputer & "\root\cimv2") 
      set colOpSys = objWMIService.ExecQuery( "SELECT * FROM Win32_OperatingSystem WHERE Primary = true") 
      for each objOpSys in colOpSys 
         objOpSys.Win32Shutdown(12) 
      next 
      set colOpSys = nothing 
      set objWMIService = nothing 
   end if 
next 

function Ping(byval strName) 
      
     dim objFileSystemObject 
     dim objWSH 
     dim objTempFile 
     dim objTextStream 
     dim strCommand 
     dim strReadLine 
     dim blnReturn 
      
     set objWSH = WScript.CreateObject("Wscript.Shell") 
     set objFileSystemObject = CreateObject("Scripting.FileSystemObject") 
      
     blnReturn = false 
      
     strCommand = "cmd /c ping.exe -n 3 -w 1000 " & strName & " > tmp.txt" 
      
     objWSH.run strCommand, 0, true 
      
     set objTempFile = objFileSystemObject.GetFile("tmp.txt") 
     set objTextStream = objTempFile.OpenAsTextStream(1) 
      
     do while objTextStream.AtEndOfStream <> true 
          strReadLine = objTextStream.ReadLine 
          if instr(lcase(strReadLine), "reply from") > 0 then 
               blnReturn = true 
               exit do 
          end if 
     loop 
      
     objTextStream.close 
     objTempFile.delete 
     set objTextStream = nothing 
     set objTempFile = nothing 
     set objWSH = nothing 
     set objFileSystemObject = nothing 
      
     Ping = blnReturn 
end function
```


----------



## StumpedTechy (Jul 7, 2004)

Yeah it looks good but I am kind of worried about going into a objOpSys.Win32Shutdown(12) rather than using the shell to run the exe. Using WMI I am very illiterate with, even more so than VBS which I have just pieced together from a ton of other code writters. Do you know if the WMI also allows for you to customize shutdown times and even change the message prompt? Just wondering how far I can take the WMI approach?


----------



## Squashman (Apr 4, 2003)

Hey Stumpy, I posted your problem on another forum and they may have come up with a better solution for you. They used a combination of the above script but also used it with PsShutdown. It pings the computers on the network that are in the computers.txt file and then makes an output file of whether or not the computer shutdown. Read the whole thread, the new script is on the last page.

http://www.littleblackdog.com/viewtopic.php?t=38176


----------



## StumpedTechy (Jul 7, 2004)

Tks. I'll look at it I think this is definitely doable though.


----------

