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

Getting array content outside of function

Status
Not open for further replies.

woter324

Technical User
Jan 26, 2007
179
GB
Hi,

I am writing a script to read a text file with a list of servers to reboot, however I am having problems with the basics of VBScript programming :-(.

I have read the file into a custom function, and split it into an array but I cannot work out how to iterate through the array outside the function. Currently the code returns nothing. No errors either.

I'd be so grateful if anyone would be able to tell me what I am doing wrong. Google isn't much help as most array examples are not inside Functions, and my brain is incapable of working it out on its own.

Here is my code:

Code:
Set fso = CreateObject("Scripting.FileSystemObject")

Function getList()
'Reads serverlist.txt and adds them to an Array
filename = "C:\serverlist.txt"
Set oTextFile = fso.OpenTextFile(filename,1)

Do Until oTextFile.AtEndOfStream
	strLine = oTextFile.ReadLine
	arrList = Split(strLine,",")
	'WScript.Echo "Server name: " & arrList(0)
	'For i = 1 To UBound(arrList)
	'	WScript.Echo vbTab & arrList(i)
	'Next
	For i = 1 To UBound(arrList)
		arrList(i)
	Next
Loop
getList = arrList

End Function

'interate array in function
For i = 1 To UBound(getList)
		wscript.Echo getlist(i)
Next

If I uncomment the 4 lines in the getList() function, I get a list returned.

Many many thanks for any help.

Woter
 
Could you post an example of how the text file you're reading looks like? Reading and getting the information may be much easier than what you're currently trying. Seeing an exact example will be much better for us to be able to give you useful information.

--------------------------------------------------------------------------------
dm4ever
My philosophy: K.I.S.S - Keep It Simple Stupid
 
Hi

Thank you for your response. The text file looks like this:

Code:
server1
server2
server3
server4
server5
etc..

Just one server hostname per line.

Many thanks

Woter
 
Set fso = CreateObject("Scripting.FileSystemObject")
filename = "C:\serverlist.txt"
Set oTextFile = fso_OpenTextFile(filename,1)

Do Until oTextFile.AtEndOfStream
strServerName = oTextFile.ReadLine
' all your code in here that requires the server name
Loop

oTextFile.Close

There really is no need to read the file and add the computer names into an array.

--------------------------------------------------------------------------------
dm4ever
My philosophy: K.I.S.S - Keep It Simple Stupid
 
If you insist for a function:
Code:
Set fso = CreateObject("Scripting.FileSystemObject")

Function getList()
'Reads serverlist.txt and adds them to an Array
filename = "C:\serverlist.txt"
Set oTextFile = fso.OpenTextFile(filename,1)
getList = Split(oTextFile.ReadAll, vbCrLf)
oTextFile.Close
End Function

'interate array in function
arrList = getList
For i = 0 To UBound(arrList)
        WScript.Echo arrList(i)
Next

Hope This Helps, PH.
FAQ219-2884
FAQ181-2886
 
Thank you dm4ever and PH.

As dm4ever suggested, I have built the core logic outside of a function, calling functions, passing 'i' (where i is the list of servers) into the functions.

But now I come to the problem where, in my mind, the creation of the array should be inside a function. The intial phase is to reboot all the servers, then wait 10 minutes before checking their 'uptime' is less that 25 hours - thus assuming that they successfully rebooted. Now if I leave the code as shown bellow, that means I either set the sleep function 'in-line' where each sever waits 10 minutes before rebooting the next, or dupplicate the core logic but including the Uptime function logic only.

I am probably wrong as I am useles at coding, so please suggest any better 'KISS' methods, where I will get the same result.

Here is the core logic code:
Code:
Set fso = CreateObject("Scripting.FileSystemObject")
Set WshShell = CreateObject("WScript.Shell")

filename = "C:\serverlist.txt" 'path and name containing list of servers

If fso.FileExists(filename) Then
	Set oTextFile = fso.OpenTextFile(filename,1)
	'Reads serverlist.txt and adds them to an Array
	Do Until oTextFile.AtEndOfStream
		strLine = oTextFile.ReadLine
		arrList = Split(strLine)
		For Each i In arrList
		reboot i
		WScript.Sleep(5000)
			If Uptime(i) > 25 Then 'This section sends an email if the server did not go down.
				strSubject = "Server " & i & " Reboot failed."
				strBody = "Server " & i & " did not restart. It has been up for " & Uptime(i) & " hours."
				SendMail strSubject,strBody
			End If
		Next
	Loop
Else
	WScript.Echo "Cannot find file containing server list: " & filename & "."
End If

I will now give PH's code a try...

Many thanks. You help and advice is always greatly apreciated.

Woter
 
In the end I copied the core logic - once to perform the reboot, then again to do the check and send mail.

For anyone interested, here is the (almost) completed script. It reboot any server in the list, waits X minutes before checking the uptime, then if the uptime is greater than the variable given it will send an email for the failed server. I've included a 'safety' device using the wshShell.popup function that gives you a 10 sec grace period to cancel if you were to inadvertantly double-click the script during the middle of the day!!

I say 'almost', because the one thing I haven't worked out yet is how to put any errors into one email, rather than an email for one server. Any pointers would be gratefully received, as always :)

Far from perfect but anyway here is the code:
Code:
'==========================================================================
' DATE  : 03/12/2007
'
' COMMENT: this script requires {x}:\...\serverlist.txt to function it should contain
'			a list of server hostnames - one per line. Run cscript.exe in a bat file
'           from a scheduled task.
'
'==========================================================================

' Restarts listed servers

wscript.echo "Restarting teminal servers. Please wait..."
Set fso = CreateObject("Scripting.FileSystemObject")
Set WshShell = CreateObject("WScript.Shell")
waitTimeM = 15 'minute(s)

filename = "C:\serverlist.txt" 'path and name containing list of servers

' -------- Start Reboot -----------------
msgTimeOutS = 10 'seconds
safety = WshShell.Popup("Terminal Servers are about to reboot. Are you sure?" & VbCrLf & _
			            "Reboot will commence in " & msgTimeOutS & " seconds.",msgTimeOutS,"Warning!", 19)
If safety = -1 or safety = 6 Then
	If fso.FileExists(filename) Then
		Set oTextFile = fso.OpenTextFile(filename,1)
		'Reads serverlist.txt and adds them to an Array
		Do Until oTextFile.AtEndOfStream
			strLine = oTextFile.ReadLine
			arrList = Split(strLine)
			For Each i In arrList
				reboot i 'Executes reboot function
			Next
		Loop
		oTextFile.Close
		WScript.Echo "Reboot complete. Waiting " & waitTimeM & " minutes to check results."
	' --------- End Reboot ------------------	
		WScript.Sleep(waitTimeM) * 60000 'time to wait in minutes for reboot then check uptime.
	' -------- Start check & send mail ------	
		Set oTextFile = fso.OpenTextFile(filename,1)
		Do Until oTextFile.AtEndOfStream
			strLine = oTextFile.ReadLine
			arrList = Split(strLine)
			For Each i In arrList
				'This section sends an email if the server did not go down.
				If Uptime(i) > 25 Then ' 25 = 25 hours. Assums a reboot once a day.
					strSubject = "Server " & i & " Reboot failed."
					strBody = "Server " & i & " did not restart. It has been up for " & Uptime(i) & " hours."& VbCrLf & _
		                   "On " & i & ", run command 'net stats srv' and check 'Statistics since...' - indicating uptime."
					SendMail strSubject,strBody
				End If
			Next
		Loop
	Else
		strSubject = "FAILED: Terminal Server Reboot script."
		strBody = "Script could not execute." &VbCrLf & _
		        "REASON: Cannot find file containing server list: " & filename & "."
		SendMail strSubject,strBody
	End If
Else 'User cancelled
	strSubject = "FAILED: Terminal Server Reboot script."
	strBody = "Script could not execute." &VbCrLf & _
		        "REASON: User cancelled the script."
	SendMail strSubject,strBody
End If
WScript.Echo "TS Reboot script complete. Check your email for any errors."
' -------- End check & send mail ------

Function reboot(i) ' reboot function
	Dim strCmd, nRC
	strCmd = "shutdown -r -m \\"& i & " -t 180 -c " & chr(34) & "This computer is being restart. You have 3 mins to save your work and log out!!" &Chr(34)& " -f"
	WScript.echo strCmd
	'WshShell.Run strCmd, 3, True
	'Set WshShell = Nothing
End Function

Function Uptime(i)' Returns uptime of server. 
	Dim strCmd, nRC
	set objWMIDateTime = CreateObject("WbemScripting.SWbemDateTime")
	Set objWMI = GetObject("winmgmts:\\" & i & "\root\cimv2")
	set colOS = objWMI.InstancesOf("Win32_OperatingSystem")
	for each objOS In colOS
	   objWMIDateTime.Value = objOS.LastBootUpTime
	   svrTime = DateDiff("h",objWMIDateTime.GetVarDate,Now())
	Next
	Uptime = svrTime 
	Set WshShell = Nothing
End Function

Function SendMail(strSubject,strBody)'Sends an email if a server has not rebooted.
    strFromAddress = "tsAdmin"
	strToAddress = "youremail@or_distribution_gp"
	strEmailServer = "emailserver"
        
    Set objEmail = CreateObject("CDO.Message")
    objEmail.From = strFromAddress
    objEmail.To = strToAddress
    objEmail.Subject = strSubject
    objEmail.Textbody = strBody
    objEmail.Configuration.Fields.Item ("[URL unfurl="true"]http://schemas.microsoft.com/cdo/configuration/sendusing")[/URL] = 2
    objEmail.Configuration.Fields.Item ("[URL unfurl="true"]http://schemas.microsoft.com/cdo/configuration/smtpserver")[/URL] = strEmailServer
    objEmail.Configuration.Fields.Item ("[URL unfurl="true"]http://schemas.microsoft.com/cdo/configuration/smtpserverport")[/URL] = 25
    objEmail.Configuration.Fields.Update
    objEmail.Send
End Function
Many thanks

Woter
 
But the apparent sophisticated functionality only masks the very troublesome misunderstanding to apparent elementary functionality of array manipulation. Do you understand the essence of PHV's advice?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top