"I have a script that runs against only one computer. How can I make it run against a list of computers in a text file?"This article will provide you with an understanding of what you need to do to get this done, and also throw in some helpful features to make things a bit "neater".
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("SELECT FreeSpace FROM Win32_LogicalDisk WHERE DeviceID = 'C:'")
For Each objItem In colItems
dblFreeSpace = Round(objItem.FreeSpace / 1024 / 1024, 3)
Next
WScript.Echo dblFreeSpace & " MB Free"
Computer1
Computer2
Computer3
strInputFile = "computers.txt"
strOutputFile = "CDriveSpace.csv"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Const intForReading = 1
Const WMITimeOutInSeconds = 10
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20
Set objInputFile = objFSO.OpenTextFile(strInputFile, intForReading, False)
Set objOutputFile = objFSO.CreateTextFile(strOutputFile, True)
objOutputFile.WriteLine """Computer"",""C Drive Free Space (MB)"""
While Not objInputFile.AtEndOfStream
strComputer = objInputFile.ReadLine
If Ping(strComputer) = True Then
strReturn = TestWMIConnection(strComputer, WMITimeOutInSeconds)
If strReturn = "success" Then
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
' The wbemFlagReturnImmediately flag is the default ExecQuery behavior and is semi-synchronous. The important optimization is the addition of the wbemFlagForwardOnly flag.
' Combining wbemFlagReturnImmediately with wbemFlagForwardOnly results in a forward-only enumerator. A forward-only enumerator performs much faster than the default enumerator,
' because WMI doesn't maintain references to objects in the SWbemObjectSet.
' Source: http://msdn.microsoft.com/en-us/library/ms974547.aspx
Set colItems = objWMIService.ExecQuery("SELECT FreeSpace FROM Win32_LogicalDisk WHERE DeviceID = 'C:'", "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
dblFreeSpace = Round(objItem.FreeSpace / 1024 / 1024, 3)
Next
objOutputFile.WriteLine """" & strComputer & """,""" & dblFreeSpace & """"
ElseIf strReturn = "failed" Then
objOutputFile.WriteLine """" & strComputer & """,""WMI ERROR"""
Else
objOutputFile.WriteLine """" & strComputer & """,""WMI TIME OUT"""
End If
Else
objOutputFile.WriteLine """" & strComputer & """,""OFFLINE"""
End If
Wend
objInputFile.Close
objOutputFile.Close
WScript.Echo "Script complete. Please see " & strOutputFile
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
Function TestWMIConnection(strComputer, intTimeOutInSeconds)
' Function written by Rob Sampson - 12 Jan 2011
' Experts-Exchange volunteer: http://www.experts-exchange.com/M_3820065.html
' Return strings from this function are in lower case, and consist of:
' "success": WMI Connection successful
' "failed": WMI Connection failed
' "time out": WMI Connection attempt timed out
Set objFSO = CreateObject("Scripting.FileSystemObject")
strTempScript = Replace(WScript.ScriptFullName, WScript.ScriptName, "") & "TempWMITestToBeDeleted.vbs"
Set objTempFile = objFSO.CreateTextFile(strTempScript, True)
objTempFile.WriteLine "On Error Resume Next"
objTempFile.WriteLine "Set objWMIService = GetObject(""winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2"")"
objTempFile.WriteLine "If Err.Number = 0 Then"
objTempFile.WriteLine vbTab & "WScript.StdOut.Write ""success"""
objTempFile.WriteLine "Else"
objTempFile.WriteLine vbTab & "WScript.StdOut.Write ""failed"""
objTempFile.WriteLine "End If"
objTempFile.Close
Set objShell = CreateObject("WScript.Shell")
Set objExec = objShell.Exec("wscript " & objFSO.GetFile(strTempScript).ShortPath)
intSeconds = 0
While objExec.Status = 0 And intSeconds <= intTimeOutInSeconds
WScript.Sleep 1000
intSeconds = intSeconds + 1
Wend
If objExec.Status = 1 Then
strReturn = objExec.StdOut.ReadAll
Else
On Error Resume Next
objExec.Terminate
Err.Clear
On Error GoTo 0
strReturn = "time out"
End If
objFSO.DeleteFile strTempScript, True
TestWMIConnection = LCase(strReturn)
End Function
strInputFile = "computers.txt"
strOutputFile = "CDriveSpace.csv"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Then we have some Constants we need to create for use in the script.
Const intForReading = 1
Const WMITimeOutInSeconds = 10
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20
objOutputFile.WriteLine """Computer"",""C Drive Free Space (MB)"""
That looks odd, doesn’t it? Well, as we know, with the CSV format, the comma is the default delimiter, and when you have a comma as part of the actual data in a field, this field is treated as two fields, with the comma not being displayed as part of the data. To get around this, you can enclose each field in quotes to be able to keep the comma as part of the data, and not split the field. This is what I have done here. By providing the extra quotes, we avoid the possibility that the data will be split up if the system is configured to present numbers in #,### format. In VBScript, if you want to place a literal quote inside a string, you need to double it, hence the doubling up of the quotes around the field names.
While Not objInputFile.AtEndOfStream
strComputer = objInputFile.ReadLine
...
Wend
If Ping(strComputer) = True Then
strReturn = TestWMIConnection(strComputer, WMITimeOutInSeconds)
If strReturn = "success" Then
objOutputFile.WriteLine """" & strComputer & """,""" & dblFreeSpace & """"
objInputFile.Close
objOutputFile.Close
WScript.Echo "Script complete. Please see " & strOutputFile
Function Ping(strComputer)
...
End Function
And
Function TestWMIConnection(strComputer, intTimeOutInSeconds)
...
End Function
If Ping(strComputer) = True Then
strReturn = TestWMIConnection(strComputer, WMITimeOutInSeconds)
Ping -n 1 -w 300 computername
Set objShell = CreateObject("WScript.Shell")
boolCode = objShell.Run("Ping -n 1 -w 300 " & strComputer, 0, True)
Const wbemConnectFlagUseMaxWait = 128
Set objSWBemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objWMIService = objSWBemLocator.ConnectServer(strComputer, "root\cimv2", Null, Null, , ,wbemConnectFlagUseMaxWait)
Set colItems = objWMIService.ExecQuery("SELECT FreeSpace FROM Win32_LogicalDisk WHERE DeviceID = 'C:'")
On Error Resume Next
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\<computername>\root\cimv2")
If Err.Number = 0 Then
WScript.StdOut.Write "success"
Else
WScript.StdOut.Write "failed"
End If
strReturn = objExec.StdOut.ReadAll
objOutputFile.WriteLine """" & strComputer & """,""WMI ERROR"""
And
objOutputFile.WriteLine """" & strComputer & """,""WMI TIME OUT"""
And
objOutputFile.WriteLine """" & strComputer & """,""OFFLINE"""
Function Ping(strComputer)
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colPings = objWMIService.ExecQuery ("Select StatusCode From Win32_PingStatus Where Address = '" & strComputer & "'")
For Each objStatus in colPings
If IsNull(objStatus.StatusCode) or objStatus.StatusCode <> 0 Then
Ping = False
Else
Ping = True
End If
Next
End Function
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (14)
Author
Commented:Open in new window
I have edited my post ID: 73062 so that it uses
Open in new window
instead of
Open in new window
and also
Open in new window
instead of
Open in new window
For this to work, I have also added
strLocalAdmin = "localadmin"
strLocalPassword = "password"
at the top of the code.
Regards,
Rob.
Author
Commented:Commented:
Thanks a lot for the code. Its working fine.
But its shows the output along with the OFFLINE message.
What could be the reason? Please tell me if i have to comment any line in this code.
I have attached the output.
Thanks!
Krish.
Wmi-output.jpg
Author
Commented:Rob.
Commented:
Thanks for your help.
Thanks!
Krish.
View More