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/