STUFF YOU CAN USE!! Finger Saving Good – No Touch Administration
Remote Desktop has changed the way we interact with our servers. However if you have a farm of 50+ servers…heck even 10 servers, having to Remote into each server can not only be time consuming but cause your fingerprints to wear off. Utilizing tools such as WMI (Windows Management Instrumentation), For Loop and PSEXEC you can administer a large number of servers remotely with minimum joint pain. The Examples below go from beginning WMI usage to more advanced techniques. These scripts are meant to be a base to start from and help you build a powerful toolset.
Index of scripts below:
Example 1: A basic WMI Script to warm up with.
Example 2: Collect Connection and Processor Information from 2 separate server lists and email the results.
Example 3: Need an inventory from a large amount of servers and write the results to a file? Personal Favorite!
Example 4: Have an unnecessary service which you need to stop and disable across your environment?
Example 5: Ever wanted to send an email without configuring Outlook Express to test an SMTP server?
Example 6: Need to know who is a member of a group across your environment?
Example 7: Use a For Loop in the command line to execute a command across multiple servers.
Example 8: PSEXEC – Every Engineers necessity.
To get a full description and the many functions available for WMI, check out https://windowssdk.msdn.microsoft.com/en-us/library/ms758280.aspx.
Example 1: Understanding WMI Basics. Save file as WMIBasics.vbs.
' ------------------------------------------------------------------------------
' August 11th, 2006
' A basic WMI Script to capture performance information
' Output to Screen
'
' Created by Brian Carney
' bcarney@microsoft.com
' Systems Engineer
' Microsoft.Com Operations Team
'
' Copy Contents and paste into a file called WMIBasics.vbs
' Run from a Command Prompt to see output and error information.
' Text encapsulated with <> indicates information required from you.
' ------------------------------------------------------------------------------
' Set Variable to call Server List
Dim oFSO
Set oFSO = CreateObject("Scripting.FileSystemObject")
Dim oFile
Set oFile = oFSO.OpenTextFile("<Your Server List.txt>")
'Set Variable to pass to Function GetEnvA_Info.
Dim sServer
'Loop through server list until each server has been processed.
Do while oFile.AtEndOfStream =false
sServer = oFile.ReadLine
'Call Function GetEnvA and pass server name.
GetEnvA_Info sServer
Loop
'Close file when completed.
oFile.Close
Function GetEnvA_Info(strServer)
'If the script encounters an error, continue. Remark out to see error information.
On Error Resume Next
'These next 2 lines are the power of WMI. You can replace these with a seemingly endless amount of WMI Calls:
'To see all WMI Calls, goto https://windowssdk.msdn.microsoft.com/en-us/library/ms758280.aspx
'Call WMI Object Win32_PerfFormattedData_Tcpip_TCPV4 to determine current user count.
Set objWMIService = GetObject("winmgmts:\\" & strServer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_PerfFormattedData_Tcpip_TCPV4",,48)
'Loop through each WMI Object
For Each objItem in colItems
'Set WMI Variable to Current Connections
CountConnections = objItem.ConnectionsEstablished
Next
'Display Information to Computer Screen
wscript.echo strServer & ": " & CountConnections
End Function
Example 2: Collecting Server Information and email the results. Save to file: EnvironmentStatsEmail.vbs.
' ------------------------------------------------------------------------------
' August 10th, 2006
' Script will Collect Information from 2 Environments: EnvironmentA, EnvironmentB.
' It will collect this information and email the results to a specified email recipient.
'
' Created by Brian Carney
' bcarney@microsoft.com
' Systems Engineer
' Microsoft.Com Operations Team
'
' Copy Contents and paste into a file called EnvironmentStatsEmail.vbs
' Run from a Command Prompt to see output and error information.
' Text encapsulated with <> indicates information required from you.
' ------------------------------------------------------------------------------
' Set Variables to 0 to ensure absolute zero starting point.
' EnvironmentA Variables
EnvA_ServerCount = 0
EnvA_Proc = 0
EnvA_CountConnections = 0
EnvA_CountTotal = 0
EnvA_ProcTotal = 0
EnvA_ProcAverage = 0
' EnvironmentB Variables
EnvB_ServerCount = 0
EnvB_Proc = 0
EnvB_CountConnections = 0
EnvB_CountTotal = 0
EnvB_ProcTotal = 0
EnvB_ProcAverage = 0
' Begin Process EnvironmentA Server List
' Set Variable to call Server List
Dim oFile
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFile = oFSO.OpenTextFile("<YourServerList-EnvA.txt>")
'Set Variable to pass to Function GetEnvA_Info.
Dim sServer
'Loop through server list until each server has been processed.
Do while oFile.AtEndOfStream = false
sServer = oFile.ReadLine
'Call Function EnvironmentB and pass server name.
GetEnvA_Info sServer
Loop
'Close file when completed.
oFile.Close
Function GetEnvA_Info(strServerName)
‘If the script encounters an error, continue. Remark out to see error information.
On Error Resume Next
'Call WMI Object Win32_PerfFormattedData_Tcpip_TCPV4 to determine current user count.
Set objWMIService = GetObject("winmgmts:\\" & strServerName & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_PerfFormattedData_Tcpip_TCPV4",,48)
'Loop through each WMI Object
For Each objItem in colItems
EnvA_CountConnections = objItem.ConnectionsEstablished
Next
'Sum up Connections Total and keep a running tally
EnvA_CountTotal = EnvA_CountTotal + EnvA_CountConnections
'Increment each pass of the function to determine how many servers are analyzed.
EnvA_ServerCount = EnvA_ServerCount + 1
'Call WMI Function Win32_Processor to determine processor utilization.
Set objWMIService = GetObject("winmgmts:\\" & strServerName & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor",,48)
'Loop through each WMI Object
For Each objItem in colItems
'Set Variable to Current processor utilization
EnvA_Proc = objItem.LoadPercentage
Next
'Add processor utilization to running talley
EnvA_ProcTotal = EnvA_ProcTotal + EnvA_Proc
End Function
'Determine Average Processor statistic
EnvA_ProcAverage = Round(EnvA_ProcTotal / EnvA_ServerCount ,2)
' Begin Process EnvironmentB Server List
' Set Variable to call Server List
Dim oFSO
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFile = oFSO.OpenTextFile("<YourServerList-EnvB.txt>")
'Loop through server list until each server has been processed.
Do while oFile.AtEndOfStream =false
sServer = oFile.ReadLine
'Call Function EnvironmentB and pass server name.
GetEnvB_Info sServer
Loop
'Close file when completed.
oFile.Close
Function GetEnvB_Info(strServerName)
‘If the script encounters an error, continue. Remark out to see error information.
On Error Resume Next
'Call WMI Object Win32_PerfFormattedData_Tcpip_TCPV4 to determine current user count.
Set objWMIService = GetObject("winmgmts:\\" & strServerName & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_PerfFormattedData_Tcpip_TCPV4",,48)
'Loop through each WMI Object
For Each objItem in colItems
EnvB_CountConnections = objItem.ConnectionsEstablished
Next
'Sum up Connections Total and keep a running tally
EnvB_CountTotal = EnvB_CountTotal + EnvB_CountConnections
'Increment each pass of the function to determine how many servers are analyzed.
EnvB_ServerCount = EnvB_ServerCount + 1
Set objWMIService = GetObject("winmgmts:\\" & strServerName & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor",,48)
'Loop through each WMI Object
For Each objItem in colItems
'Set Variable to Current processor utilization
EnvB_Proc = objItem.LoadPercentage
Next
'Add processor utilization to running talley
EnvB_ProcTotal = EnvB_ProcTotal + EnvB_Proc
End Function
'Determine Average Processor statistic
EnvB_ProcAverage = Round(EnvB_ProcTotal / EnvB_ServerCount,2)
'Send Email with All Statistics gathered above
set msg = WScript.CreateObject("CDO.Message")
msg.From = "<FromEmailAddress>"
msg.To = "<ToEmailAddress>"
msg.Subject = "Performance Counters from Environment A and B."
msg.TextBody = "Script Completion Time: " & Date() & " at " & Time() _
& vbCrLf & vbCrLf & "Number of EnvA_ Servers Analyzed: " & EnvA_ServerCount _
& vbCrLf & "Total EnvA_ Connections: " & EnvA_CountTotal _
& vbCrLf & "Average EnvA_ Proc: " & EnvA_ProcAverage _
& vbCrLf & vbCrLf & "Number of EnvB_ Servers Analyzed: " & EnvB_ServerCount _
& vbCrLf & "Total EnvB_ Connections: " & EnvB_CountTotal _
& vbCrLf & "Average EnvB_ Proc: " & EnvB_ProcAverage
msg.Configuration.Fields("https://schemas.microsoft.com/cdo/configuration/smtpserver") =
"<InsertYourSMTPAddress>"
msg.Configuration.Fields("https://schemas.microsoft.com/cdo/configuration/sendusing") = 2
msg.Configuration.Fields.Update
msg.Send
Example 3: Inventory: Having an accurate Inventory Script can be a time saver. Save to file: Inventory.vbs
' ------------------------------------------------------------------------------
' August 11th, 2006
' A Script to collect Inventory Information and write it to a file
'
' Created by Brian Carney
' bcarney@microsoft.com
' Systems Engineer
' Microsoft.Com Operations Team
'
' Copy Contents and paste into a file called Inventory.vbs
' Run from a Command Prompt to see output and error information.
' Text encapsulated with <> indicates information required from you.
' ------------------------------------------------------------------------------
LogFile = "<OutputFile.txt>" 'You may need to create this file in advance.
Const ForWriting = 2
Const HARD_DISK = 3
'Set Variable to write inventory data to a file.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(LogFile, ForWriting)
' Set Variable to call Server List
Dim oFSO
Set oFSO = CreateObject("Scripting.FileSystemObject")
Dim oFile
' Replace <YourServerList.txt> with your list of servers.
Set oFile = oFSO.OpenTextFile("<YourServerList.txt>")
Dim sServer
'Loop through server list until each server has been processed.
Do while oFile.AtEndOfStream = false
'Call Function GetInfo and pass server name.
sServer = oFile.ReadLine
GetInfo sServer
Loop
'Close file when completed.
oFile.Close
Function GetInfo(strComputer)
‘If the script encounters an error, continue. Remark out to see error information.
On Error Resume Next
'Call WMI Object Win32_ComputerSystem to determine server information.
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_ComputerSystem")
'Loop through each WMI Object and collect specific information.
For Each objItem In colItems
WScript.Echo "Server Name: " & objItem.Name
objFile.WriteLine "Server Name: " & objItem.Name
WScript.Echo "Manufacturer: " & objItem.Manufacturer
objFile.WriteLine "Manufacturer: " & objItem.Manufacturer
WScript.Echo "Model: " & objItem.Model
objFile.WriteLine "Model: " & objItem.Model
WScript.Echo "Number Of Processors (Includes MultiThread): " & objItem.NumberOfProcessors
objFile.WriteLine "Number Of Processors (Includes MultiThread): " & objItem.NumberOfProcessors
'Call WMI Object Win32_Processor to determine processor information.
Set colProcessors = objWMIService.ExecQuery("Select MaxClockSpeed from Win32_Processor")
ClockSpeed = 0
TotalClockSpeed = 0
ProcCount = 0
'Begin gathering information and storing in a variable. Used at end of script to sum up processor information.
For Each objProcessor in colProcessors
ClockSpeed = objProcessor.MaxClockSpeed
TotalClockSpeed = ClockSpeed + TotalClockSpeed
ProcCount = ProcCount + 1
Next
REM Wscript.echo "Proc Count: " & ProcCount
WScript.Echo "Maximum Clock Speed: " & ((TotalClockSpeed / ProcCount)/1000) & " - GHZ"
objFile.WriteLine "Maximum Clock Speed: " & ((TotalClockSpeed / ProcCount)/1000) & " - GHZ"
'Call WMI Object Win32_SystemEnclosure to determine Serial Number.
Set colSMBIOS = objWMIService.ExecQuery("Select * from Win32_SystemEnclosure")
'Loop Through each item in object.
For Each objSMBIOS in colSMBIOS
Wscript.Echo "Serial Number: " & objSMBIOS.SerialNumber
objFile.WriteLine "Serial Number: " & objSMBIOS.SerialNumber
Next
'Call WMI Object Win32_Processor to determine Processor load.
Set ProcItems = objWMIService.ExecQuery("Select LoadPercentage from Win32_Processor",,48)
'Loop Through each item in object.
For Each ProcItem in ProcItems
Proc = ProcItem.LoadPercentage
Next
'Write out to screen processor information as the script runs.
Wscript.echo "Proc Usage: (1 Proc Sample Only) " & Proc & "%"
objFile.WriteLine "Proc Usage: (1 Proc Sample Only) " & Proc & "%"
'Call WMI Object Win32_PhysicalMemory to determine memory utilization.
Set MemItems = objWMIService.ExecQuery("Select Capacity from Win32_PhysicalMemory")
Mem = 0
TotalMem = 0
'Loop Through each item in object.
For Each MemItem in MemItems
Mem = MemItem.Capacity
TotalMem = Mem + TotalMem
Next
Wscript.Echo "Mem Total: " & (TotalMem / 1000000000) & " - GB"
objFile.WriteLine "Mem Total: " & (TotalMem / 1000000000) & " - GB"
'Call WMI Object Win32_LogicalDisk to determine hard disk utilization.
Set colDisks = objWMIService.ExecQuery("Select * from Win32_LogicalDisk Where DriveType = " & HARD_DISK & "")
'Loop Through each item in object.
For Each objDisk in colDisks
Wscript.Echo "DeviceID: "& vbTab & objDisk.DeviceID & "Free Space: " & (objDisk.FreeSpace / 1000000000) & " - GB"
objFile.WriteLine "DeviceID: "& vbTab & objDisk.DeviceID & "Free Space: " & (objDisk.FreeSpace / 1000000000) & " - GB"
Next
'Call WMI Object IIsWebServerSetting to determine IIS Information.
Set IISWMIService = GetObject ("winmgmts:{authenticationLevel=pktPrivacy}\\" & strComputer & "\root\microsoftiisv2")
Set IISLogItems = IISWMIService.ExecQuery("Select * from IIsWebServerSetting")
'Loop Through each item in object.
For Each IISLogItem in IISLogItems
Wscript.Echo "Log File Directory: " & IISLogItem.LogFileDirectory
objFile.WriteLine "Log File Directory: " & IISLogItem.LogFileDirectory
Next
'Call WMI Object Win32_NetworkAdapterConfiguration to determine IP Information.
Set IPConfigSet = objWMIService.ExecQuery("Select * from Win32_NetworkAdapterConfiguration Where IPEnabled=TRUE")
'Loop Through each item in object.
For Each IPConfig in IPConfigSet
If Not IsNull(IPConfig.IPAddress) Then
For i=LBound(IPConfig.IPAddress) to UBound(IPConfig.IPAddress)
WScript.Echo "IP Address: " & IPConfig.IPAddress(i)
objFile.WriteLine "IP Address: " & IPConfig.IPAddress(i)
Next
End If
Next
'Call WMI Object Win32_OperatingSystem to determine Service Pack Information.
Set colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
'Loop Through each item in object.
For Each objOperatingSystem in colOperatingSystems
Wscript.Echo "Service Pack: " & objOperatingSystem.ServicePackMajorVersion & "." & objOperatingSystem.ServicePackMinorVersion
objFile.WriteLine "Service Pack: " & objOperatingSystem.ServicePackMajorVersion & "." & objOperatingSystem.ServicePackMinorVersion
Next
'Call WMI Object Win32_PerfFormattedData_Tcpip_TCPV4 to determine Current Connection Information.
Set ConnItems = objWMIService.ExecQuery("Select * from Win32_PerfFormattedData_Tcpip_TCPV4",,48)
'Loop Through each item in object.
For Each ConnItem in ConnItems
wscript.echo "Connections: " & ConnItem.ConnectionsEstablished
objFile.WriteLine "Connections: " & ConnItem.ConnectionsEstablished
Next
'Call Registry Value to determine HTTPERR Folder Location.
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
Const HKEY_LOCAL_MACHINE = &H80000002
strKeyPath = "SYSTEM\CurrentControlSet\Services\HTTP\Parameters\"
strValueName = "ErrorLoggingDir"
oReg.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
Wscript.Echo "HTTPERR Directory: " & strValue
objFile.WriteLine "HTTPERR Folder: " & strValue
'Call WMI Object Win32_OperatingSystem to determine Current Connection Information.
Set colOSItems = objWMIService.ExecQuery("SELECT * FROM Win32_OperatingSystem")
'Loop Through each item in object.
For Each objOSItem In colOSItems
WScript.Echo "Windows Directory: " & objOSItem.WindowsDirectory
objFile.WriteLine "OS Directory: " & objOSItem.WindowsDirectory
WScript.Echo "System Directory: " & objOSItem.SystemDirectory
objFile.WriteLine "System Directory: " & objOSItem.SystemDirectory
Next
WScript.Echo "----------------------------"
objFile.WriteLine "----------------------------"
Next
'End of the GetInfo Function
End Function
Example 4: Stop/Suspend Unnecessary Service. Save to file: StopSuspendService.vbs
' ------------------------------------------------------------------------------
' August 11th, 2006
' A Script to Stop and Suspend an Unneaded Service
'
' Created by Brian Carney
' bcarney@microsoft.com
' Systems Engineer
' Microsoft.Com Operations Team
'
' Copy Contents and paste into a file called StopSuspendService.vbs
' Run from a Command Prompt to see output and error information.
' Text encapsulated with <> indicates information required from you.
' ------------------------------------------------------------------------------
' Set Variable to call Server List
Dim oFSO
Set oFSO = CreateObject("Scripting.FileSystemObject")
Dim oFile
' Replace <YourServerList.txt> with your list of servers.
Set oFile = oFSO.OpenTextFile("<YourServerList.txt>")
Dim sServer
'Loop through server list until each server has been processed.
Do while oFile.AtEndOfStream =false
'Call Function GetInfo and pass server name.
sServer = oFile.ReadLine
GetInfo sServer
Loop
'Close file when completed.
oFile.Close
Function GetInfo(Computer)
‘If the script encounters an error, continue. Remark out to see error information.
On Error Resume Next
'Call WMI Object Win32_Service.Name to stop selected service.
strComputer = Computer
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colServiceList = objWMIService.ExecQuery("Associators of " _
& "{Win32_Service.Name='NetDDE'} Where " _
& "AssocClass=Win32_DependentService " & "Role=Antecedent" )
'Loop through each WMI Object.
For Each objService in colServiceList
objService.StopService()
Next
'Sleep to allow for service to stop.
Wscript.Sleep 10000
'Call WMI Object Win32_Service. Replace <ServiceName> with service you would like to stop/disable.
Set colServiceList = objWMIService.ExecQuery _
("Select * from Win32_Service where Name='<ServiceName>'")
For Each objService in colServiceList
errReturn = objService.StopService()
Next
'Disable Service.
For Each objService in colServiceList
errReturnCode = objService.Change( , , , , "Disabled")
Next
Wscript.echo Computer & " - Complete"
'End of the GetInfo Function
End Function
Example 5: Send Email without an Email Client: (Very useful to call or attach at the end of script so you know when the script is done.) Save to file: SendEmail.vbs
' ------------------------------------------------------------------------------
' August 11th, 2006
' Send an email without an email client.
'
' Created by Brian Carney
' bcarney@microsoft.com
' Systems Engineer
' Microsoft.Com Operations Team
'
' Copy Contents and paste into a file called SendEmail.vbs
' Run from a Command Prompt to see output and error information.
' Text encapsulated with <> indicates information required from you.
' ------------------------------------------------------------------------------
set msg = WScript.CreateObject("CDO.Message")
msg.From = "<FromEmailAddress>"
msg.To = "<ToEmailAddress>"
msg.Subject = "TestEmail "
msg.TextBody = "Hi, This is a Test Email"
msg.Configuration.Fields("https://schemas.microsoft.com/cdo/configuration/smtpserver") = "<IP Address of SMTP Server>"
msg.Configuration.Fields("https://schemas.microsoft.com/cdo/configuration/sendusing") = 2
msg.Configuration.Fields.Update
msg.Send
Example 6: Display Group Membership. Save to file: DisplayGroupMembership.vbs
' Begin Script
'------------------------------------------------------------------------------
' August 11th, 2006
' Send an email without an email client.
'
' Created by Brian Carney
' bcarney@microsoft.com
' Systems Engineer
' Microsoft.Com Operations Team
'
' Copy Contents and paste into a file called DisplayGroupMembership.vbs
' Run from a Command Prompt to see output and error information.
' Text encapsulated with <> indicates information required from you.
' ------------------------------------------------------------------------------
' Set Variable to call Server List
Set objNetwork = CreateObject("WScript.Network")
Dim oFSO
Set oFSO = CreateObject("Scripting.FileSystemObject")
Dim oFile
' Replace <YourServerList.txt> with your list of servers.
Set oFile = oFSO.OpenTextFile("<YourServerList>")
Dim sServer
'Replace Administrators with any group.
strGroup = "Administrators" ' Or Any other Group
'Loop through server list until each server has been processed.
Do while oFile.AtEndOfStream =false
'Call Function GetInfo and pass server name.
sServer = oFile.ReadLine
GetInfo sServer
Loop
'Close file when completed.
oFile.Close
Function GetInfo(Computer)
‘If the script encounters an error, continue. Remark out to see error information.
On Error Resume Next
strComputer = Computer
'Call to gather group members.
Set objGroup = GetObject("WinNT://" & strComputer & "/" & strGroup & ",group")
WScript.Echo " Group members:"
WScript.Echo "Computer: " & strComputer
'Loop through each Object.
For Each objMember In objGroup.Members
WScript.Echo " " & objMember.Name
Next
'End of the GetInfo Function
End Function
Example 7: Using a For Loop:
For /F %i in ( <YourServerList.txt> ) Do xcopy d:\test.txt \\%i\d$\test.txt
You can replace xcopy with any command you normally would use on a single server.
Log Parser:
For /F %i in ( <YourServerList.txt> ) Do logparser –q:on “Select Count(*) from \\%i\e$\wwwlog\W3SVC1\ex*.log where sc-status = ‘404’
Find Current Connections:
For /F %i in ( <YourServerList.txt> ) do psexec \\%i netstat -an | find "ESTABLISHED" | FIND /c ":80"
Example 8: PSEXEC:
https://www.sysinternals.com/ psexec.exe provides a powerful tool to remotely run applications.
Run a Command Prompt remotely:
psexec -u <Domain\User> -p <password> \\ <ServerName> cmd
When you are done, type Exit.
Additional Scripting Resources:
Microsoft Scripting Center: https://www.microsoft.com/technet/scriptcenter/scripts/default.mspx?mfr=true
WMI Resource: https://windowssdk.msdn.microsoft.com/en-us/library/ms758323.aspx
Sysinternals: https://www.sysinternals.com/
Comments
- Anonymous
January 01, 2003
PingBack from http://kevindevin.com/?p=2354 - Anonymous
January 01, 2003
PingBack from http://www.iis-digest.com/?p=246