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

Need VBscript to write PC inventory to text file at logon

Status
Not open for further replies.

RabidAlien

IS-IT--Management
Feb 10, 2011
8
0
0
US
Hey, first wanted to say that I've browsed the livin' daylights out of these forums, and have learned a TON from them! That being said, I'm about the noob-iest (yep, just made that up) scripter you've ever met, and my boss wants me to learn. His idea of "teaching" is to assign tasks, such as "write a script to copy all files/folders/permissions/settings from one fileserver to another, oh, and we're changing where some folders reside and resetting permissions on others..." or "write a script that will pull inventory from a PC and put it on a server so that exec-level users (ie....VP) can see who's got what under the hood of their towers, but it can't write to Excel since we want the servers included." Blah. This last one has been kicking my butt. Basically, we need something that writes to a text-file as a scheduled action whenever a user logs in, overwriting the data that's already in the existing text file, for about 75 PC's. It needs to pull username, PC name, manufacturer, model, serial number, processor, memory, hard drive free/total space (for two partitions, C: and D:, respectively), OS, service pack, IP Address, and date of latest inventory. I'll figure out the merge-text-to-excel bit later. I don't have a gift for languages, so learning this is kicking my butt!

Here's what I have so far (if I take out the hard drive stuff, it sorta works...):

Code:
Option Explicit

'On Error Resume Next
Dim objFSO, wshNetwork, strComputer, objWMIService, colItems, strSerialNumber, strFileName, strResults, objItem, objOutputFile, strCPUDetails

Set objFSO = CreateObject("Scripting.FileSystemObject")

' To convert to a logon script that runs without user interaction, add a rem in front of the strComputer = InputBox
' line below and remove the rem from the strComputer = "." line below that. This will then only check the PC on which
' the script runs
Set WshNetwork = WScript.CreateObject("WScript.Network")
strComputer = "."

' Get the serial number first to see if it already exists in the spreadsheet
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_BIOS",,48)
For Each objItem In colItems
      strSerialNumber = "" & Trim(objItem.SerialNumber)
Next
Set objWMIService = Nothing
Set colItems = Nothing

strFileName = "O:\IT_Department\Inventory\" & strSerialNumber & ".txt"

' Create Excel Spreadsheet
strResults = "Computername;Username;Manufacturer;Model;Serial Number;CPU;Operating System;Service Pack;Total Memory;IP Address;Audit Date" & VbCrLf

' Get Computer System Details
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_ComputerSystem",,48)
For Each objItem In colItems
      strResults = strResults & Trim(objItem.Caption)  & ";" & Trim(objItem.UserName) & ";" & Trim(objItem.Manufacturer) & ";" & Trim(objItem.Model)
Next
Set objWMIService = Nothing
Set colItems = Nothing
'
'Output the Serial Number
strResults = strResults & ";" & strSerialNumber

'
' Get CPU Details
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor",,48)
For Each objItem In colItems
      strCPUDetails = Trim(objItem.Name)
Next
Set objWMIService = Nothing
Set colItems = Nothing
strResults = strResults & ";" & strCPUDetails
'
' Get OS Details
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)
For Each objItem In colItems
    strResults = strResults & ";" & Trim(objItem.Caption) & ";" & Trim(objItem.CSDVersion) & ";" & Trim(FormatNumber(objItem.TotalVisibleMemorySize/1024,0))
Next
Set objWMIService = Nothing
Set colItems = Nothing
'
'Hard Drive Partition Info

'
' Get IP Address
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration", "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
      strIPAddress = Join(objItem.IPAddress, ",")
Next
Set objWMIService = Nothing
Set colItems = Nothing
'
' Get & Writeout current Date
strResults = strResults & ";" & Trim(Day(Now) & "-" & Month(Now) & "-" & Year(Now))

Set objOutputFile = objFSO.CreateTextFile(strFileName, True)
objOutputFile.Write strResults
objOutputFile.Close

Set objOutputFile = Nothing
Set objFSO = Nothing
 
Kewl, thanks, I'll give it a shot.

Pillage, then burn.

Argue not with dragons, for thou art crunchy and taste good with BBQ sauce.
 
Sorry its been so long, as I said I'm working on this between "oh crap" projects/fixes. Finally got the script working, used yours as a template, and to answer some questions I had on my own. Thanks for the help!

Code:
'HAMMERED TOGETHER BY KIRK LOWRY, 3/1/2011
'FEEL FREE TO USE/ADJUST TO YOUR NEEDS!

'Option Explicit
'On Error Resume Next

'Dim colItems, objFSO, wshNetwork, objWMIService, colItems, strFileName, strResults, objItem, objOutputFile, strUserName, strComputer, strIPAddress, intFreeSpace, intTotalSpace
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set WshNetwork = WScript.CreateObject("WScript.Network")
strComputer = "."
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

'defining strUserName
Set colItems = objWMIService.ExecQuery("Select * from Win32_BIOS",,48)
For Each objItem In colItems
      strSerialNumber = "" & Trim(objItem.SerialNumber)
Next

'creating and naming the text file
strFileName = "O:\IT_Department\Inventory\" & strSerialNumber & ".txt"
strResults = "Computername;Username;Manufacturer;Model;Serial Number;CPU;Total Memory;IP Address;Operating System;Service Pack;C Free;C Total;D Free;D Total;Audit Date" & VbCrLf
 
 'Computer Name, User Name, Manufacturer, Model
Set colItems = objWMIService.ExecQuery("Select * from Win32_ComputerSystem",,48)
For Each objItem In colItems
      strResults = strResults & Trim(objItem.Caption)  & "; " & Trim(objItem.UserName) & "; " & Trim(objItem.Manufacturer) & ";"  & Trim(objItem.Model) & "; "
Next

'Serial Number/Service Tag
Set colItems = objWMIService.ExecQuery("Select * from Win32_BIOS",,48)
For Each objItem In colItems
      strResults = strResults & Trim(objItem.SerialNumber) & "; "
Next

'Processor
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor",,48)
For Each objItem In colItems
      strResults = strResults & Trim(objItem.Name) & "; "
Next

'Physical Memory
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)
For Each objItem In colItems
      strResults = strResults & Round(objItem.TotalVisibleMemorySize/1024^3, 1) & "Gb; "
Next

'IP Address
Set colItems = objWMIService.ExecQuery _
    ("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")
for each objitem in colitems
strIPAddress = Join(objitem.IPAddress, ",")
strResults = strResults & Trim(strIPAddress)  & "; "
Next

'Operating System/Service Pack
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)
For Each objItem In colItems
      strResults = strResults & Trim(objItem.Caption)  & "; " & Trim(objItem.CSDVersion) & "; "
Next

'C Drive Free/Total Space
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery _
    ("Select * from Win32_LogicalDisk Where DeviceID = 'C:'")
For Each objDisk in colDisks
    intFreeSpace = objDisk.FreeSpace
    intTotalSpace = objDisk.Size
	strResults = strResults & Round(objDisk.FreeSpace/1024^3, 1)  & "Gb; " & Round(objDisk.Size/1024^3, 1) & "Gb; "
Next

'D Drive Free/Total Space
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery _
    ("Select * from Win32_LogicalDisk Where DeviceID = 'D:'")
For Each objDisk in colDisks
    intFreeSpace = objDisk.FreeSpace
    intTotalSpace = objDisk.Size

	strResults = strResults & Round(objDisk.FreeSpace/1024^3, 1)  & "Gb; " & Round(objDisk.Size/1024^3, 1) & "Gb; "
Next


' Get & Writeout current Date
strResults = strResults & Trim(Date) & ", " & Trim(Time) 



Set objOutputFile = objFSO.CreateTextFile(strFileName, True)
objOutputFile.Write strResults
objOutputFile.Close


Set objOutputFile = Nothing
Set objFSO = Nothing

Pillage, then burn.

Argue not with dragons, for thou art crunchy and taste good with BBQ sauce.
 
Nice! It was meant to be a learning tool. I'm glad you learned from it.

-Geates

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."
- Martin Golding

"There are seldom good technological solutions to behavioral problems."
- Ed Crowley, Exchange guru and technology curmudgeon
 
Having one small problem with the memory section...one of the locations we IT for has about 150 PC's, ranging anywhere from WindowsNT, 95, 98, XP (thankfully they skipped ME) and Windows 7. A good portion of the older machines have less than a Gig of RAM. For some reason, when I run this on a machine with less than a Gig, it shows 0Gb instead of .512Gb. How would I get it to show Mb if less than 1000Mb, or Gb if greater than 1000Mb? I toyed around with an If-Then-ElseIf statement yesterday...unfortunately its on a computer at another location, or I'd post it for someone to look at.

Again, thanks for all the help/pointers!

Pillage, then burn.

Argue not with dragons, for thou art crunchy and taste good with BBQ sauce.
 
change the the [red]operator[/red] to \.

Code:
For Each objItem In colItems
      strResults = strResults & Round(objItem.TotalVisibleMemorySize[red]\[/red]1024^3, 1) & "Gb; "Next



-Geates


"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."
- Martin Golding

"There are seldom good technological solutions to behavioral problems."
- Ed Crowley, Exchange guru and technology curmudgeon
 
I mispoke. The operator your have results in a float - not an integer. Make the division and then formatNumber function to display the result how you want to.
Code:
fltMemory = (1024^2) / (1024^3)
if (fltMemory >= 1) then
   fltMemory = formatNumber(fltMemory, 1)
else
   fltMemory = formatNumber(fltMemory, 3, 0)
end if

strMemory = cstr(fltMemory) & "Gb; "

-Geates

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."
- Martin Golding

"There are seldom good technological solutions to behavioral problems."
- Ed Crowley, Exchange guru and technology curmudgeon
 
Gotcha, thanks for the update. I was scratching my head on the "/" vs "\"!!! Here's what I've got for the Physical Memory portion now, and have tested it on a 2Gb system and a 512Mb system...the 512Mb returns an answer of .498Gb (or something to that effect, after factoring in onboard video memory), so I'll keep tweaking it to get it to return in Mb:

Code:
'Physical Memory
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)
For Each objItem In colItems
fltMemory = (objItem.TotalVisibleMemorySize/1024^2)
if (fltMemory >= 1) then
   fltMemory = formatNumber(fltMemory, 1)
else
   fltMemory = formatNumber(fltMemory, 3, 0)
end if
      strResults = strResults &cstr(fltMemory) & "Gb; "
Next

Pillage, then burn.

Argue not with dragons, for thou art crunchy and taste good with BBQ sauce.
 
Okay, Geates, you officially rock, in case nobody's told you lately! Did some mad-scientist shifting/tweaking/modding, and Frankenstein's monster officially lives! The script now shows the appropriate Gb or Mb, depending on how much actual memory is in the machine.

Code:
'Physical Memory
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)
For Each objItem In colItems
fltMemory = (objItem.TotalVisibleMemorySize/1024^2)
if (fltMemory >= 1) then
   fltMemory = formatNumber(fltMemory, 1)
   strResults = strResults &cstr(fltMemory) & "Gb; "
else
   fltMemory = formatNumber(objItem.TotalVisibleMemorySize/1024^1)
   strResults = strResults &cstr(fltMemory) & "Mb; "
end if
Next

Next, I just need to apply the same to the hard drive partitions, and I'm 100% in business! Again, you have my eternal thanks (that and $4 will buy you a gallon of gas)!!! I'll post the entire working code when I get time to jazz up the partitions section.

Pillage, then burn.

Argue not with dragons, for thou art crunchy and taste good with BBQ sauce.
 
byte = 1
kilobyte = 1024 bytes (1024^1)
megabyte = 1024 kilobytes (1024^2)
gigabyte = 1024 megabytes (1024^3)
terabyte = 1024 gigabytes (1024^4)
...

FYI: Make sure you use the correct expression. In the final example you posted above, you are dividing into megabytes (1024^2) but are displaying it as Gb.

-Geates

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."
- Martin Golding

"There are seldom good technological solutions to behavioral problems."
- Ed Crowley, Exchange guru and technology curmudgeon
 
When I divide by 1024^3, referencing the TotalVisibleMemorySize from Win32_OperatingSystem, I think it reads in Kb to begin with. On my 2Gb system, using 1024^3 returns "0Gb", whereas 1024^2 returns 2Gb. Testing on the 512Mb system, using 1024^1 returns 512Mb. I thought it was strange, too, since I had assumed that all WMI classes would output in bytes.

Pillage, then burn.

Argue not with dragons, for thou art crunchy and taste good with BBQ sauce.
 
Okay, got it finished. Had to iron out a few wrinkles, and there's probably easier ways to do it, but here's the final code if anyone needs. Modify to suit your particular situation! Again, many MANY thanks to Geates!

Code:
'Scrabbled together by Kirk Lowry
'22 May 2011
'modify as required to fit your needs
'Many thanks to Geates from [URL unfurl="true"]www.tek-tips.com[/URL] for his help with this!
'The Cake Is A Lie!!!

'On Error Resume Next

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set WshNetwork = WScript.CreateObject("WScript.Network")
strComputer = "."
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

'defining strUserName
Set colItems = objWMIService.ExecQuery("Select * from Win32_BIOS",,48)
For Each objItem In colItems
      strSerialNumber = "" & Trim(objItem.SerialNumber)
Next

'creating and naming the text file
strFileName = "O:\IT_Department\Inventory\" & strSerialNumber & ".txt"
strResults = "Computername;Username;Manufacturer;Model;Serial Number;CPU;Total Memory;IP Address;Operating System;Service Pack;C Free;C Total;D Free;D Total;Audit Date" & VbCrLf
 
 'Computer Name, User Name, Manufacturer, Model
Set colItems = objWMIService.ExecQuery("Select * from Win32_ComputerSystem",,48)
For Each objItem In colItems
      strResults = strResults & Trim(objItem.Caption)  & "; " & Trim(objItem.UserName) & "; " & Trim(objItem.Manufacturer) & ";"  & Trim(objItem.Model) & "; "
Next

'Serial Number/Service Tag
Set colItems = objWMIService.ExecQuery("Select * from Win32_BIOS",,48)
For Each objItem In colItems
      strResults = strResults & Trim(objItem.SerialNumber) & "; "
Next

'Processor
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor",,48)
For Each objItem In colItems
      strResults = strResults & Trim(objItem.Name) & "; "
Next

'Physical Memory
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)
For Each objItem In colItems
fltMemory = (objItem.TotalVisibleMemorySize/1024^2)
if (fltMemory >= 1) then
   fltMemory = formatNumber(fltMemory, 1)
   strResults = strResults &cstr(fltMemory) & "Gb RAM; "
else
   fltMemory = formatNumber(objItem.TotalVisibleMemorySize/1024)
   strResults = strResults &cstr(fltMemory) & "Mb RAM; "
end if
Next

'Physical Memory Type
Set colItems = objWMIService.ExecQuery("Select * from Win32_PhysicalMemory",,48)
For Each objItem In colItems
      strResults = strResults & Trim(objItem.Speed) & "; "
Next

'IP Address
Set colItems = objWMIService.ExecQuery _
    ("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")
for each objitem in colitems
strIPAddress = Join(objitem.IPAddress, ",")
strResults = strResults & Trim(strIPAddress)  & "; "
Next

'Operating System/Service Pack
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)
For Each objItem In colItems
      strResults = strResults & Trim(objItem.Caption)  & "; " & Trim(objItem.CSDVersion) & "; "
Next

'C Drive Free Space
Set colDisks = objWMIService.ExecQuery ("Select * from Win32_LogicalDisk Where DeviceID = 'C:'",,48)
For Each objDisk in colDisks
   fltDrive = (objDisk.FreeSpace/1024^3)
      if (fltDrive >= 1) then
   fltDrive = formatNumber(fltDrive, 2)
   strResults = strResults & cstr(fltDrive)  & "Gb; "
      else
   fltDrive = formatNumber(objDisk.FreeSpace/1024^2, 2)
   strResults = strResults & (fltDrive)  & "Mb; "
end if
Next

'C Drive Total Space
Set colDisks = objWMIService.ExecQuery _
    ("Select * from Win32_LogicalDisk Where DeviceID = 'C:'")
For Each objDisk in colDisks
   fltDrive = (objDisk.Size/1024^3)
if (fltDrive >= 1) then
   fltDrive = formatNumber(fltDrive, 2)
   strResults = strResults & cstr(fltDrive)  & "Gb; "
else
   fltDrive = formatNumber(objDisk.FreeSpace/1024^2, 2)
   strResults = strResults & (fltDrive)  & "Mb; "
end if
Next

'D Drive Free Space
Set colDisks = objWMIService.ExecQuery _
    ("Select * from Win32_LogicalDisk Where DeviceID = 'D:'")
For Each objDisk in colDisks
   fltDrive = (objDisk.FreeSpace/1024^3)
if (fltDrive >= 1) then
   fltDrive = formatNumber(fltDrive, 2)
   strResults = strResults & cstr(fltDrive)  & "Gb; "
else
   fltDrive = formatNumber(objDisk.FreeSpace/1024^2, 2)
   strResults = strResults & (fltDrive)  & "Mb; "
end if
Next

'D Drive Total Space
Set colDisks = objWMIService.ExecQuery _
    ("Select * from Win32_LogicalDisk Where DeviceID = 'D:'")
For Each objDisk in colDisks
   fltDrive = (objDisk.Size/1024^3)
if (fltDrive >= 1) then
   fltDrive = formatNumber(fltDrive, 2)
   strResults = strResults & cstr(fltDrive)  & "Gb; "
else
   fltDrive = formatNumber(objDisk.FreeSpace/1024^2, 2)
   strResults = strResults & (fltDrive)  & "Mb; "
end if
Next

' Get & Writeout current Date
strResults = strResults & Trim(Date) & ", " & Trim(Time) 

Set objOutputFile = objFSO.CreateTextFile(strFileName, True)
objOutputFile.Write strResults
objOutputFile.Close

Set objOutputFile = Nothing
Set objFSO = Nothing

Pillage, then burn.

Argue not with dragons, for thou art crunchy and taste good with BBQ sauce.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top