• No results found

Desktop Checker

In document Oreilly Windows Server Hacks pdf (Page 98-123)

Got a Hack?

Hack 14 Desktop Checker

Here's a useful script to quickly display the configuration of a remote system for troubleshooting or inventory purposes.

This handy script will attempt to gather various Windows NT/2000/XP/2003 operating-system attributes and display them in a coherent way to assist in troubleshooting. I highly suggest modifying the customization variables located within the script. To edit this text file, just open it with Notepad (leave Word Wrap turned off). Even if you have no experience with VBScript, you should find the changes quite easy to make. Please read the comments for different sections to make the tool viable for your organization.

This tool was intended to use only standard API calls and nothing from third-party COM objects. This keeps the tool lightweight and portable as only a text file. I suggest putting the tool into a local directory by itself so that the HTML pages it creates don't get out of hand. If a machine does not have WMI 1.5, then a lot of info might be missing. You will get similar results if you don't have administrator rights on the remote box. This script will not work on any Windows 9x operating systems.

The Code

You can download this script as DesktopChecker.vbs from the O'Reilly web site at http://www.oreilly.com/catalog/winsvrhks/:

'************************************************************** '* * '* Desktop Checker - This script will ATTEMPT to gather * '* various OS attributes and diplay them in a coherent * '* way to assist in troubleshooting. I highly suggest * '* modifying the customization variables located 2 sections * '* below. Please read the comments for different sections * '* to make the tool viable for your organization. This *

'* tool was intended to use only standard API calls and * '* nothing from 3rd party COM objects. This keeps the * '* tool lightwieght and portable as only a text file. * '* I suggest putting the tool into a directory by itself * '* so that the HTML pages it creates don't get out of hand. * '* If a machine does not have WMI 1.5 then lots of info may * '* be missing. * '* * '* Dennis Abbott * '* [email protected] * '* * '************************************************************** On Error Resume Next

Dim WshShell,WshFso,WshNet,WshSysEnv,IE,wmi,ADSIobj,OutPutFile,DumpFile Dim PathToScript,ComSpec,Cnt,CompName,Company,Title,LogoLink,SelectService s, _ Domain,Progress,Instance,CurLine

Set WshShell = CreateObject("Wscript.Shell")

Set WshFso = CreateObject("Scripting.FileSystemObject") Set WshNet = CreateObject("Wscript.Network")

Set WshSysEnv = WshShell.Environment("SYSTEM") PathToScript =

Left(WScript.ScriptFullName,(Len(WScript.ScriptFullName) - _ (Len(WScript.ScriptName) + 1)))

ComSpec = WshSysEnv("COMSPEC") Cnt = 0

' grab contents of clipboard

' This allows you to work a LIST of boxes by cut-n-paste Set IE = CreateObject("InternetExplorer.Application") IE.Navigate("about:<script language=" & Chr(34)

& "vbscr" & "ipt" & Chr(34) & ">function go( ):document.all.it2.select"

& "( ):document.execCommand " &

Chr(34) & "Paste" & Chr(34) & ":en" & "d function</script><body onload=go( )>

<input type=t" & "ext value=" & Chr(34) & "start" & Chr(34) & " id=it2></body>")

While IE.ReadyState <> 4:Wend

CompName = IE.document.all.it2.value IE.quit( )

Set IE = Nothing

' SET CUSTOMIZATION VARIABLES Company = "myITforum"

Title = Company & " - Helpdesk Diagnostic Tool"

LogoLink = "http://www.myitforum.com/img/logo_final.gif"

' The next line alows you to query a variety of NT services of your choosing

' Make sure you enter the service NAME not the DISPLAY NAME, they can be

different names

SelectServices = Array("WinMgmt","Norton Antivirus Server","DefWatch","clisvc","Dhcp")

Domain = "amd" 'Your NT domain Progress = True

'causes pop-up boxes when set to True it is silent when set to False

CompName = InputBox("Enter the name of the remote computer",Title,CompName)

If CompName = "" Then MsgBox "No machine name was entered...goodbye" : _ Wscript.Quit(0)

Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!//" & _ CompName)

Set ADSIobj = GetObject("WinNT://" & CompName & ",Computer")

Call PrepHTML(CompName) 'create an HTML file

If Progress Then

WshShell.Popup "Getting OS information",2,Title, vbokonly + _ vbsystemmodal

End If

Call GetOS(CompName) If Progress Then

WshShell.Popup "Getting NT administrators",2,Title, vbokonly + _ vbsystemmodal

End If

Call GetAdmins(CompName) If Progress Then

WshShell.Popup "Checking Vital Services",2,Title, vbokonly + _ vbsystemmodal

End If

Call Services(CompName,SelectServices) If Progress Then

vbsystemmodal End If

Call AdminShares(CompName) If Progress Then

WshShell.Popup "Getting date/time stamp",2,Title, vbokonly + _ vbsystemmodal

End If

Call GetTime(CompName) If Progress Then

WshShell.Popup "Getting NetBIOS information",2,Title, vbokonly + _

vbsystemmodal End If

Call GetNBTstat(CompName) If Progress Then

WshShell.Popup "Pinging computer",2,Title, vbokonly + vbsystemmodal

End If

Call Ping(CompName) If Progress Then

WshShell.Popup "Getting Registry Quota",2,Title, vbokonly + _ vbsystemmodal

End If

Call GetRegQuota(CompName) If Progress Then

WshShell.Popup "Getting Hardware information",2,Title, vbokonly + _

vbsystemmodal End If

Call GetHW(CompName) If Progress Then

WshShell.Popup "Getting Network Card information",2,Title, vbokonly + _

vbsystemmodal End If

Call GetNIC(CompName) If Progress Then

WshShell.Popup "Getting Software information",2,Title, vbokonly + _

vbsystemmodal End If

Call GetSW(CompName) If Progress Then

WshShell.Popup "Getting Critical NT Events",2,Title, vbokonly + _ vbsystemmodal

End If

Call GetEvents(CompName) Call ExitScript

Function PrepHTML(CompName)

Set OutPutFile = WshFso.CreateTextFile(PathToScript & "\" & CompName _

& ".html")

OutPutFile.WriteLine "<body>"

OutPutFile.WriteLine "<h1><center>" & Title & "</center></h1>" OutPutFile.WriteLine "<p><IMG SRC=" & Chr(34) & LogoLink & Chr(34) _

OutPutFile.WriteLine "</p><p>" & "Account running this script is " _

& WshNet.UserDomain & "\" & WshNet.UserName & " @ " _

& Now & " from workstation " & WshNet.ComputerName & "</p>" OutPutFile.WriteLine "<p>Information on remote machine <b>\\" _ & UCase(CompName) & "</b></p>"

OutPutFile.WriteLine "<p><font color=red>To see information as it " _

loads hit the REFRESH button on your web browser.</font></p>" OutPutFile.WriteLine "<hr>"

WshShell.Run PathToScript & "\" & CompName & ".html" End Function

Function GetOS(CompName)

OutPutFile.WriteLine "<h3>1 - Operating System</h3>" OutPutFile.WriteLine "Operating System Version = " _

& ADSIobj.OperatingSystem & " " & ADSIobj.OperatingSystemVersion & "<br>"

For Each Instance in wmi.ExecQuery("Select * From Win32_OperatingSystem")

OutPutFile.WriteLine "Operating System Caption = " _ & Instance.Caption & "<br>"

OutPutFile.WriteLine "Operating System Service Pack = " _ & Instance.CSDVersion & "<br>"

OutPutFile.WriteLine "Operating System LastBootUpTime = " _ & StrDateTime(Instance.LastBootUpTime) & "<br>"

OutPutFile.WriteLine "Operating System Directory = " _ & Instance.WindowsDirectory & "<br>"

OutPutFile.WriteLine "<hr>" End Function

Function GetAdmins(CompName) Dim Admins,Admin

Dim AdsInfo

Set Admins = GetObject("WinNT://" & CompName & "/Administrators") OutPutFile.WriteLine "<h3>2 - Members of the local " _

& "administrators group</h3>"

OutPutFile.WriteLine "<table border=1><tr><td><b>Name</ b></td><td><b>Type</b></td><td><b>

Description</b></td></tr>"

For Each Admin in Admins.Members

Set AdsInfo = GetObject(Admin.adspath)

OutPutFile.WriteLine "<tr><td>" & AdsInfo.Name & "</td><td>" _

& AdsInfo.Class & "</td><td>" & AdsInfo.Description & "</td></tr>" Next OutPutFile.WriteLine "</table>" OutPutFile.WriteLine "<hr>" End Function Function Services(CompName,SelectServices) Dim Service,srvc,State,Strg

OutPutFile.WriteLine "<h3>3 - Status of vital services</h3>" OutPutFile.WriteLine "<table border=1><tr><td><b>Service Name</b></td><td><b>Display Name</b></td><td>

<b>Status</b></td></tr>"

For Each Service in SelectServices

Strg = "<tr><td>" & Service & "</td><td></ td><td><b><font color=FF0000>NOT PRESENT</font></b></ td></tr>"

ADSIobj.Filter = Array("Service") For Each srvc in ADSIobj

Select Case srvc.Status

Case 1 State = "<font color=FF0000>STOPPED</font>"

Case 2 State = "<font color=FF0000>START_PENDING</font>" Case 3 State = "<font color=FF0000>STOP_PENDING</font>" Case 4 State = "RUNNING"

Case 5 State = "<font color=FF0000>CONTINUE_PENDING</font>"

Case 6 State = "<font color=FF0000>PAUSE_PENDING</font>" Case 7 State = "<font color=FF0000>PAUSED</font>"

Case Else State = "<font color=FF0000>ERROR</font>" End Select

If LCase(srvc.Name) = LCase(Service) Then Strg = _ "<tr><td>" & srvc.Name & "</td><td>" &

srvc.DisplayName _

& "</td><td>" & State & "</tr></td>" Next

OutPutFile.WriteLine Strg Next

OutPutFile.WriteLine "</table>" OutPutFile.WriteLine "<hr>"

End Function

Function AdminShares(CompName) Dim Shares

OutPutFile.WriteLine "<h3>4 - Status of administrative shares</h3>"

Shares = True

If WshFso.FolderExists("\\" & CompName & "\c$") = True Then OutPutFile.WriteLine "C$ share exists<br>"

Else

Shares = False

OutPutFile.WriteLine "<font color=red>C$ share is not " _ & "accessible</font><br>"

End If

If WshFso.FolderExists("\\" & CompName & "\admin$") = True Then OutPutFile.WriteLine "admin$ share exists<br>"

Else

Shares = False

OutPutFile.WriteLine "<font color=red>admin$ share is not " _ & "accessible</font><br>"

End If

If Shares = False Then

OutPutFile.WriteLine "<br>"

OutPutFile.WriteLine "<font color=red>Shares made not be " _ & "accessible due to the folowing reasons:</font><br>"

OutPutFile.WriteLine "<font color=red>a - You do not have " _ & "admin rights on this box</font><br>"

offline</font><br>"

OutPutFile.WriteLine "<font color=red>c - Server service is not " _

& "running</font><br>"

OutPutFile.WriteLine "<font color=red>d - Shares have been " _

& "disabled</font><br>"

OutPutFile.WriteLine "<font color=red>e - remote machine's " _

& "operating system is not NT-based</font><br>" End If

OutPutFile.WriteLine "<hr>" End Function

Function GetTime(CompName)

OutPutFile.WriteLine "<h3>5 - Current date and time</h3>" OutPutFile.WriteLine "Current date and time of a domain controller<br>"

WshShell.Run ComSpec & " /c net time /DOMAIN:" & Domain & " >" _ & PathToScript & "\time.txt",6,True

Set DumpFile = WshFso.OpenTextFile(PathToScript & "\time.txt", 1, True)

Do While DumpFile.AtEndOfStream <> True CurLine = DumpFile.ReadLine

If InStr(CurLine,"Current") <> 0 Then OutPutFile.WriteLine CurLine & "<br>" End If

Loop

DumpFile.Close

_

& "troubleshooting<br>"

WshShell.Run ComSpec & " /c net time \\" & CompName " _ & " >" & PathToScript & "\time.txt",6,True

Set DumpFile = WshFso.OpenTextFile(PathToScript & "\time.txt", 1, True)

Do While DumpFile.AtEndOfStream <> True CurLine = DumpFile.ReadLine

If InStr(CurLine,"Current") <> 0 Then OutPutFile.WriteLine CurLine & "<br>" End If Loop DumpFile.Close OutPutFile.WriteLine "<hr>" End Function Function Ping(CompName)

OutPutFile.WriteLine "<h3>7 - Ping test (DNS name resolution)</h3>"

OutPutFile.WriteLine "<h4>If you get no reply on the ping yet other data is

retrieved on this page then there is most likely a problem with a static DNS entry.

This needs to be fixed before anything else. You MUST VERIFY the machine is running

DHCP before

you modify the static DNS entry!!!!</h4>"

WshShell.Run ComSpec & " /c ping " & CompName & " >" & PathToScript & _

Set DumpFile = WshFso.OpenTextFile(PathToScript & "\ping.txt", 1, True)

Do While DumpFile.AtEndOfStream <> True

OutPutFile.WriteLine DumpFile.ReadLine & "<br>" Loop

Set DumpFile = Nothing OutPutFile.WriteLine "<hr>" End Function

Function GetNBTstat(CompName) Dim User

User = "Nobody Logged On"

WshShell.Run ComSpec & " /c nbtstat -a " & CompName & " >" & PathToScript & "\nbt.txt",6,True

Set DumpFile = WshFso.OpenTextFile(PathToScript & "\nbt.txt", 1, True)

Do While DumpFile.AtEndOfStream <> True CurLine = DumpFile.ReadLine If InStr(CurLine,"---") <> 0 Then CurLine = DumpFile.ReadLine CompName = Trim(Left(CurLine,InStr(CurLine,"<")-1)) End If If InStr(CurLine,"<03>") <> 0 Then If Trim(Left(CurLine,InStr(CurLine,"<03>")-1)) <> _ UCase(CompName) and _ Trim(Left(CurLine,InStr(CurLine,"<03>")-1)) <> _ UCase(CompName) & "$" Then

End If End If

If InStr(CurLine,"<1E>") <> 0 Then

If Trim(Left(CurLine,InStr(CurLine,"<1E>")-1)) <> UCase(CompName)

and Trim(Left(CurLine,InStr(CurLine,"<1E>")-1)) <> UCase(CompName) & "$" Then Domain = Trim(Left(CurLine,InStr(CurLine,"<1E>")-1)) End If End If Loop

OutPutFile.WriteLine "<h3>6 - NetBIOS Info</h3>"

OutPutFile.WriteLine "Current User Logged on = " & User & " (this value may

not be accurate, it depends on the box's messenger service)<br>" OutPutFile.WriteLine "Domain machine is joined to = " & Domain & "<br>"

DumpFile.Close

OutPutFile.WriteLine "<hr>" End Function

Function GetNIC(CompName)

OutPutFile.WriteLine "<h3>9 - Network Card Configuration</h3>" For Each Instance in wmi.ExecQuery("Select * From Win32_" & _ "NetworkAdapterConfiguration Where IPenabled = 'True'")

OutPutFile.WriteLine "<table border=1><tr><td><b>" & _ "Attribute</b></td><td><b>Value</b></td></tr>"

& Instance.Caption & "</td></tr>"

OutPutFile.WriteLine "<tr><td>DHCP Enabled</td><td>" _ & Instance.DhcpEnabled & "</td></tr>"

OutPutFile.WriteLine "<tr><td>IP address</td><td>" _ & Instance.IPAddress(0) & "</td></tr>"

OutPutFile.WriteLine "<tr><td>Subnet Mask</td><td>" _ & Instance.IPSubnet(0) & "</td></tr>"

OutPutFile.WriteLine "<tr><td>MAC Address</td><td>" _ & Instance.MACAddress & "</td></tr>"

OutPutFile.WriteLine "<tr><td>DNS HostName</td><td>" _ & Instance.DNSHostname & "</td></tr>"

OutPutFile.WriteLine "<tr><td>DNS Servers(in order)</td><td>" _

& Instance.DNSServerSearchOrder(0) & " : " _ & Instance.DNSServerSearchOrder(1) & "</td></tr>" OutPutFile.WriteLine "<tr><td>Primary WINS</td><td>" _ & Instance.WINSPrimaryServer & "</td></tr>"

OutPutFile.WriteLine "<tr><td>Secondary WINS</td><td>" _ & Instance.WINSSecondaryServer & "</td></tr>"

OutPutFile.WriteLine "</table>" Next

OutPutFile.WriteLine "<hr>" End Function

Function GetRegQuota(CompName)

OutPutFile.WriteLine "<h3>8 - Registry size information</h3>" For each Instance in wmi.InstancesOf("Win32_Registry")

OutPutFile.WriteLine "Current Registry size is " _ & Instance.CurrentSize & " MB's.<br>"

OutPutFile.WriteLine "Maximum Registry size is " _ & Instance.MaximumSize & " MB's.<br>"

If Instance.MaximumSize - Instance.CurrentSize < 8 Then OutPutFile.WriteLine "<font color=red><b>The Registry quota on " _

& CompName & " may need to be increased!!!</font></b><br>" End If Next OutPutFile.WriteLine "<hr>" End Function Function GetHW(CompName) Dim stuff

OutPutFile.WriteLine "<h3>10 - Hardware Information</h3>" For Each Instance in wmi.ExecQuery("Select * From Win32_" & _ "LogicalDisk Where DeviceID = 'C:'")

OutPutFile.WriteLine "Total Drive space available on C: is " & Left(Instance.

FreeSpace/1000000,InStr(Instance.FreeSpace/1000000, ".")-1) & " Megabytes.<br>"

stuff = ((Instance.Size - Instance.FreeSpace)/Instance.Size)*100

OutPutFile.WriteLine "The C: drive is " _

& Left(stuff,InStr(stuff, ".")-1) & "% full.<br>" Next

For Each Instance in wmi.ExecQuery("Select * From Win32_ComputerSystem")

OutPutFile.WriteLine "Computer Manufacturer = " _ & Instance.Manufacturer & "<br>"

OutPutFile.WriteLine "Computer Model = " & Instance.Model & "<br>"

OutPutFile.WriteLine "Total Physical Memory = " & Left

(Instance.TotalPhysicalMemory/1000000,InStr(Instance.TotalPhysicalMemo ry/1000000,".")-1)

& " MB's" & "<br>" Next

For Each Instance in wmi.ExecQuery("Select * From Win32_" & _ "SystemEnclosure")

OutPutFile.WriteLine "Asset Tag = " & Instance.SMBIOSassettag " _

& "<br>"

OutPutFile.WriteLine "Serial Number = " & Instance.serialnumber " _

& "<br>" Next

For Each Instance in wmi.ExecQuery("Select * From Win32_Processor")

OutPutFile.WriteLine "Processor Name = " & Instance.Name & "<br>"

OutPutFile.WriteLine "Processor Clock Speed = " _ & Instance.CurrentClockSpeed & " MHz<br>"

OutPutFile.WriteLine "Processor Voltage = " _ & Instance.CurrentVoltage & " Volts<br>"

OutPutFile.WriteLine "Current Processor Load = " _ & Instance.LoadPercentage & "%<br>"

Next

End Function Function GetSW(CompName) Dim oReg Dim NavParent,PatternDate,NavDir,NavVer,IEVersion,program,installed, Version,ProgramName

OutPutFile.WriteLine "<h3>11 - Software Information</h3>"

Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!//" _

& CompName & "/root/default:StdRegProv") oReg.getstringvalue 2147483650,"SOFTWARE\INTEL\LANDesk\VirusProtect6\CurrentVersion\", "Parent",NavParent oReg.getstringvalue 2147483650,"SOFTWARE\Symantec\SharedDefs\", _ & "NAVCORP_70",PatternDate oReg.getstringvalue 2147483650,"SOFTWARE\Symantec\InstalledApps\" & _ ","NAV",NavDir If UCase(Left(NavDir,1)) = "C" Then

NavVer = WshFso.GetFileVersion("\\" & CompName & "\c$\" _ & Right(NavDir,Len(NavDir)-3) & "\vpc32.exe")

OutPutFile.WriteLine "Norton Antivirus Version = " & NavVer _

& "<br>" End If

PatternDate = Right(PatternDate,12)

OutPutFile.WriteLine "Norton Antivirus Parent Server = " & NavParent _

OutPutFile.WriteLine "Norton Antivirus Definition Date = " _ & Mid(PatternDate,5,2) & "/" & Mid(PatternDate,7,2) & "/" & Mid(PatternDate,1,4) & " Revision " & Right(PatternDate,3) & "<br>" oReg.getstringvalue 2147483650,"SOFTWARE\Microsoft\Internet Explorer\" & _

","Version",IEVersion

OutPutFile.WriteLine "<p>Internet Explorer Version = " & IEVersion

OutPutFile.WriteLine "<p>Installed Programs(from Add/Remove Programs applet)</

p>"

OutPutFile.WriteLine "<table border=1><tr><td><b>Program Name</b></td><td><b>Version(if available)</b></td></

In document Oreilly Windows Server Hacks pdf (Page 98-123)