Computer Inventory with AutoIT

Article Index

 

I've used the following AutoIT program many times to retrieve inventory information from a PC.  It grabs a load of information and will look for installed programs or all installed programs.  It will send the information to an email address, save it to a file, or both.  It needs an INI file (below) in the same folder where the program is executed.  I used Koda to create the GUI and I used the work of a few others that I found on the internet and included them in the script.

You will need to edit the script to include the SMTP server of your choice.

Save the following in the same folder as the compiled program. Name the file: Get_Inv.ini

[admin]
email=Your_Email@Address
[search]
file0=Avast
file1=Office
[Internet]
require=1
 
[Information]
In the 'search' section, list the programs to check to see if they are installed on the computer. If the program is not found, nothing will be shown in the list.
To list all the installed programs, type 'All' in the first field, 'file0'.
List as many programs as needed.  Just add another line and increment the number.
Example:
file2=Cisco
file3=Symantec
file4=Junos
etc.
 
Internet is required (1) to send an email.  To only save a file locally, it must be '0'. If there are values other than these two, the program will not run. The local file will be saved in the same folder from where the program is run.


Below is the source code for AutoIT.  If there are any questions, post them in the forum.

 =============


#cs ----------------------------------------------------------------------------
 
 AutoIt Version: 3.3.10.2
 Author:         myName
 
 Script Function:
    Template AutoIt script.
 
#ce ----------------------------------------------------------------------------
 
; Script Start - Add your code below here
#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <FileConstants.au3>
#include <MsgBoxConstants.au3>
#include <Constants.au3>
#include <String.au3>
#include <Array.au3>
#include <Inet.au3>
#Include<file.au3>
 
#Region ### START Koda GUI section ### Form=
$Form1_1 = GUICreate("Get Inventory...", 247, 143, 270, 600)
$Label1 = GUICtrlCreateLabel("Computer Name", 13, 16, 77, 17)
$Button1 = GUICtrlCreateButton("Send Inventory", 74, 104, 99, 25)
$Input1 = GUICtrlCreateInput(@ComputerName, 101, 16, 137, 21, BitOR($GUI_SS_DEFAULT_INPUT,$ES_READONLY))
$Checkbox1 = GUICtrlCreateCheckbox("Save Locally?", 75, 48, 97, 17, BitOR($GUI_SS_DEFAULT_CHECKBOX,$BS_RIGHTBUTTON))
GUICtrlSetTip(-1, "Save in same folder where this is running")
$Label2 = GUICtrlCreateLabel("Internet Connection Required for Email", 30, 72, 190, 17)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
 
 Global $inifile = "\Get_Inv.ini"
 
if  FileExists (@ScriptDir&$inifile) Then
    ;MsgBox(0,"T","Exists")
Else
    $createini = MsgBox(4,"Error","The Config File doesn't exist.  Shall I create one?  If Yes, you will need to edit it before running the program again.")
    if $createini = 6 Then
        SplashTextOn ("Creating...","Creating Config file.  The file needs to be edited before continuing so I'm exiting the program.", 300, 100)
        IniWrite (@ScriptDir&$inifile,"admin","email","This email address is being protected from spambots. You need JavaScript enabled to view it.")
        IniWrite (@ScriptDir&$inifile,"search","file0","Edit me")
        IniWrite (@ScriptDir&$inifile,"search","file1","Edit me")
        IniWrite (@ScriptDir&$inifile,"Internet","req","1")
        sleep (3000)
        SplashOff()
        Exit
    ElseIf $createini = 7 Then
        SplashTextOn ("Exiting...","No Config file.  I'm exiting the program.", 300, 100)
        sleep (2000)
        SplashOff()
        Exit
    Else
        Exit
    EndIf
 
EndIf
 
Global $reqinternet = IniRead(@ScriptDir&$inifile,"Internet","require","")
if $reqinternet = 1 Then
    ;MsgBox (0,"T",$reqinternet)
Elseif $reqinternet = 0 Then
        SplashTextOn ("Internet is not required...","Check the Config file.  No email will be sent and the config file saved in the App folder.", 300, 100)
        sleep (10000)
        SplashOff()
Else
    ;MsgBox(0,'T',$reqinternet)
    SplashTextOn ("Exiting...","Error in the Config file.  I'm exiting the program.", 300, 100)
    sleep (2000)
    SplashOff()
EndIf
 
if $reqinternet = 1 Then
    checkinternet()
EndIf
 
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        case $button1
            Serial_Number()
 
EndSwitch
WEnd
 
func sendtomail($includeemail,$includebody)
    if $reqinternet = 1 Then
        checkinternet()
    EndIf
 
    ;##################################
    ; Variables
    ;##################################
 
    $SmtpServer = "emailserver.com"     ; address for the smtp-server to use - REQUIRED
    $FromName = "Inventory Script"                      ; name from who the email was sent
    $FromAddress = "This email address is being protected from spambots. You need JavaScript enabled to view it." ; address from where the mail should come
    $ToAddress = $includeemail   ; destination address of the email - REQUIRED
    $Subject = @ComputerName&" Inventory"      ; subject from the email - can be anything you want it to be
    $Body = $includebody                              ; the messagebody from the mail - can be left blank but then you get a blank mail
    $AttachFiles = ""                       ; the file(s) you want to attach seperated with a ; (Semicolon) - leave blank if not needed
    $CcAddress = ""       ; address for cc - leave blank if not needed
    $BccAddress = ""     ; address for bcc - leave blank if not needed
    $Importance = "Normal"                  ; Send message priority: "High", "Normal", "Low"
    $Username = "This email address is being protected from spambots. You need JavaScript enabled to view it."                    ; username for the account used from where the mail gets sent - REQUIRED
    $Password = "emailpassword"                  ; password for the account used from where the mail gets sent - REQUIRED
    $IPPort = 465                            ; port used for sending the mail
    $ssl = 1                                ; enables/disables secure socket layer sending - put to 1 if using httpS
    ;$IPPort=465                          ; GMAIL port used for sending the mail
    ;~ $ssl=1                               ; GMAILenables/disables secure socket layer sending - put to 1 if using httpS
 
    ;##################################
    ; Script
    ;##################################
    Global $oMyRet[2]
    Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")
    $rc = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl)
    SplashOff()
    If @error Then
        MsgBox(0, "Error sending message", "Error code:" & @error & "  Description:" & $rc)
    Else
        MsgBox(0,"Successful","Message Sent")
    EndIf
 
EndFunc
 
Func Serial_Number()
 
    $txtpath = @TempDir
    $txtfile = "\serial.txt"
    $sendfile = "\"&@ComputerName&".txt"
 
    RunWait(@ComSpec & ' /c ' & 'wmic bios get serialnumber /VALUE >> '&$txtpath&$txtfile,"", @SW_HIDE)
    RunWait(@ComSpec & ' /c ' & 'wmic computersystem get model /VALUE >> '&$txtpath&$txtfile,"", @SW_HIDE)
    RunWait(@ComSpec & ' /c ' & 'wmic computersystem get manufacturer /VALUE >> '&$txtpath&$txtfile,"", @SW_HIDE)
    addproductid($txtpath&$txtfile)
    RunWait(@ComSpec & ' /c ' & 'wmic computersystem get name /VALUE >> '&$txtpath&$txtfile,"", @SW_HIDE)
    RunWait(@ComSpec & ' /c ' & 'wmic cpu get name /VALUE >> '&$txtpath&$txtfile,"", @SW_HIDE)
    calcgb($txtpath&$txtfile,1)
 
    $file=($txtpath&$txtfile)
    $filewr=($txtpath&$sendfile)
    $fileread= FileRead($file)
    $filechange1 = StringReplace($fileread,@CRLF,",")
    $filechange2 = StringReplace ($filechange1,",,,,,",@crlf)
    $filechange3 = StringReplace ($filechange2,",,","")
    $filechange = StringReplace ($filechange3,",",@CRLF,1)
 
    SplashTextOn ("Processing...","Please wait...",200,70)
    RunWait(@ComSpec & ' /c ' & 'wmic product list brief /format:list > '&$txtpath&"\plist.txt","", @SW_HIDE)
    SplashOff()
    SplashTextOn ("Working...","Please wait...",200,70)
 
    $fopn = FileOpen($filewr,$FO_APPEND)
    FileWrite ($fopn,$filechange)
 
    FileWriteLine($fopn, @OSVersion&" "&@OSArch)
    FileWriteLine($fopn, "OS Build:"&@OSBuild)
    FileWriteLine($fopn, "Service Pack:"&@OSServicePack)
    FileWriteLine($fopn,"Date and Time: "&@MON&"/"&@MDAY&"/"&@YEAR&"  "&@HOUR&":"&@MIN&":"&@SEC&@CRLF&"**************************")
 
    $fopnav = FileOpen($txtpath&"\plist.txt",$FO_APPEND)
    ;Look for installed apps in registry
    $subkey = "None"
    $i=1
    While $subkey <> ""
        $subkey = RegEnumKey("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall",$i)
        ;MsgBox (0,"Subkey # " &$i&" Under uninstall",$subkey)
        $removejunklines = StringInStr($subkey,"{")
        if $removejunklines = 0 Then
            FileWriteLine ($fopnav,"REG:"&$subkey&@CRLF)
        EndIf
        $i+= 1
    WEnd
 
    $searchnum = 0
    $searchname = "file"
    FileSetPos($fopnav,0,$FILE_BEGIN)
    while $searchname <> ""
        $searchname = IniRead(@ScriptDir&$inifile,"search","file"&$searchnum,"")
        ;MsgBox(0,"TTT",$searchname&"--file"&$searchnum)
        if $searchname = "" then ExitLoop
        ; find line with search string
        $iLine = 0
        $sLine = ''
        $iValid = 0
        $x = 0
        while $x < 1
            $iLine += 1
            $sLine = FileReadLine ($fopnav)
            if @error = -1 then
                if $searchname = "All" Then
                    ExitLoop 2
                EndIf
                ;MsgBox (0,"TITLE",@error)
                ;FileWriteLine ($fopn,$searchname&" Not Found: "&@CRLF)
                ;FileWriteLine ($fopn,"======================")
                FileSetPos($fopnav,0,$FILE_BEGIN)
                ExitLoop
            EndIf
            if $searchname <> "All" Then
                ;test line for $search string until the flag iValid is set
                if StringInStr ($sLine, $searchname) And Not $iValid Then
                    $iValid = 1
                    ;ContinueLoop
                EndIf
            Else
                $iValid = 1
            EndIf
 
            if $iValid Then
                $iValid += 1
                $appwrite = $sLine
                $removeREG = StringInStr($appwrite,"REG:")
                if $removeREG <> 0 Then
                    if $searchname = "All" then
                        FileWriteLine ($fopn,"Found: "&$appwrite)
                    Else
                        FileWriteLine ($fopn,$searchname&" Found: "&$appwrite)
                    EndIf
                    FileWriteLine ($fopn,"======================")
                    $iValid= 0
                    ContinueLoop
                EndIf
 
                $removestr = StringInStr($appwrite,"Identifying")
                $removeven = StringInStr($appwrite,"Vendor")
                if $removestr = 0 AND $removeven = 0 Then
                    if $searchname = "All" then
                        FileWriteLine ($fopn,"Found: "&$appwrite)
                    else
                        FileWriteLine ($fopn,$searchname&" Found: "&$appwrite)
                    EndIf
                EndIf
                if $iValid > 4 then
                    ;Reset valid count
                    FileWriteLine ($fopn,"======================")
                    $iValid = 0
                    ;ExitLoop
                EndIf
 
            EndIf
 
        WEnd
        $searchnum = $searchnum+1
    WEnd
 
    ;send email (email address, body)
    $emailname = IniRead(@ScriptDir&$inifile,"admin","email","")
    FileSetPos($fopn,0, $FILE_BEGIN)
    $emailbody = FileRead($fopn)
    if $reqinternet = 1 Then
        checkinternet()
        SplashTextOn ("Working...","Trying to send email...",200,70)
        sendtomail($emailname,$emailbody)
    EndIf
    SplashOff()
    FileClose($fopn)
    FileClose($fopnav)
    $savefile = GUICtrlRead($Checkbox1)
    if $savefile = 1 OR $reqinternet = 0 Then
        FileCopy(@TempDir&$sendfile,@ScriptDir&$sendfile, $FC_OVERWRITE)
        FileDelete($filewr) ; Inventory File
    Else
        FileDelete($filewr) ; Inventory File
    EndIf
    FileDelete ($file) ; Generated File
    FileDelete ($txtpath&"\plist.txt") ; Generated File
    ; -------------------
    ; PROGRAM ENDS
    ; -------------------
 
EndFunc
 



func checkinternet()
    $x = 0
    While $x = 0
        ;--------------------------------------------------------------------------------------------
        ;check $ret[0] for trueness, and $ret[1] for type of connection according to variables provided...
        ;--------------------------------------------------------------------------------------------
        $INTERNET_CONNECTION_MODEM          = 0x1
        $INTERNET_CONNECTION_LAN            = 0x2
        $INTERNET_CONNECTION_PROXY          = 0x4
        $INTERNET_CONNECTION_MODEM_BUSY     = 0x8
        $INTERNET_RAS_INSTALLED             = 0x10
        $INTERNET_CONNECTION_OFFLINE        = 0x20
        $INTERNET_CONNECTION_CONFIGURED     = 0x40
 
        $ret = DllCall("WinInet.dll","int","InternetGetConnectedState","int_ptr",0,"int",0)
 
        If $ret[0] then
            ;check type of connection
            $sX = "Connected !" & @LF & "------------------" & @LF
            If BitAND($ret[1], $INTERNET_CONNECTION_MODEM)      Then $sX = $sX & "MODEM" & @LF
            If BitAND($ret[1], $INTERNET_CONNECTION_LAN)        Then $sX = $sX & "LAN" & @LF
            If BitAND($ret[1], $INTERNET_CONNECTION_PROXY)      Then $sX = $sX & "PROXY" & @LF
            If BitAND($ret[1], $INTERNET_CONNECTION_MODEM_BUSY) Then $sX = $sX & "MODEM_BUSY" & @LF
            If BitAND($ret[1], $INTERNET_RAS_INSTALLED)         Then $sX = $sX & "RAS_INSTALLED" & @LF
            If BitAND($ret[1], $INTERNET_CONNECTION_OFFLINE)    Then $sX = $sX & "OFFLINE" & @LF
            If BitAND($ret[1], $INTERNET_CONNECTION_CONFIGURED) Then $sX = $sX & "CONFIGURED" & @LF
        Else
            $x = 0
            MsgBox(0,"Not Connected","Please connect to the internet before continuing.")
            ;$sX = "Not Connected"
            ContinueLoop
 
        Endif
 
        ;SplashTextOn("Connected...","Connection Detected",200,100)
        ;sleep (1000)
        ;SplashOff()
        $x=1
        ;MsgBox(4096,$ret[0] & ":" & $ret[1],$sX)
 
     WEnd
 
EndFunc
 
func calcgb($pathtxt,$str2src)
    if $str2src = 1 Then
        $str2srcname = "TotalPhysicalMemory="
        $str2len = 20
        $str2dec = 3
    Else
        $str2srcname = "Size="
        $str2len = 5
        $str2dec = 0
    EndIf
 
    $filepk=($pathtxt)
    $fopnpk = FileOpen($filepk,$FO_APPEND)
    ; ---------MAYBE------------
    ; Check the drive type for C:\
    $sInfo = DriveGetType("C:\")
    if $sInfo <> "" Then
        ;MsgBox($MB_SYSTEMMODAL, "", "Drive Type: " & $sInfo)
        ;write a line
        FileWrite ($fopnpk,@CRLF&@CRLF&"Drive Type="&$sInfo&@CRLF&@CRLF&@CRLF)
    EndIf
    ; Check the SSD status for C:\
    $sInfo = DriveGetType("C:\", $DT_SSDSTATUS)
    if $sInfo <> "" Then
        ;MsgBox($MB_SYSTEMMODAL, "", "Drive SSD: " & $sInfo)
        ;write a line
        FileWrite ($fopnpk,@CRLF&@CRLF&"Drive Type (SSD)="&$sInfo&@CRLF&@CRLF&@CRLF)
    EndIf
    ; Check the SSD status for disk 0
    $sInfo = DriveGetType(0, $DT_SSDSTATUS)
    if $sInfo <> "" Then
        ;MsgBox($MB_SYSTEMMODAL, "", "Drive SSD: " & $sInfo)
        ;write a line
        FileWrite ($fopnpk,@CRLF&@CRLF&"Drive Status (SSD)="&$sInfo&@CRLF&@CRLF&@CRLF)
    EndIf
    ; Check the bus type status for disk 0
    $sInfo = DriveGetType(0, $DT_BUSTYPE)
    if $sInfo <> "" Then
        ;MsgBox($MB_SYSTEMMODAL, "", "Drive Bus: " & $sInfo)
        ;write a line
        FileWrite ($fopnpk,@CRLF&@CRLF&"Drive Bus="&$sInfo&@CRLF&@CRLF&@CRLF)
    EndIf
 
    Local $iTotalSpace = DriveSpaceTotal(@HomeDrive & "\") ; Find the total disk space of the home drive, generally this is the C:\ drive.
    $TotalSpace = round($iTotalSpace/1000,$str2dec)
    ; MsgBox(0, "", "Total Space: " & $TotalSpace &"GB")
    FileWrite ($fopnpk,@CRLF&@CRLF&"Total Disk Space="&$TotalSpace&" GB"&@CRLF&@CRLF&@CRLF)
 
    Local $RAMARR = MemGetStats()
    $TotalRAM = round($RAMARR[1]/1000000,$str2dec)
    ;MsgBox(0, "", "Total physical RAM (GB): " & $TotalRAM)
    FileWrite ($fopnpk,@CRLF&@CRLF&"Total RAM="&$TotalRAM&" GB"&@CRLF&@CRLF&@CRLF)
 
    FileClose($fopnpk)
 
EndFunc
 
func addproductid($pathtxt)
    $productkey = RegRead("HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\BIOS\","SystemSKU")
    ;MsgBox (0,"TTT",$productkey)
    if $productkey = "" Then
        $productkey = "Not Found"
    EndIf
    $filepk=($pathtxt)
    $fopnpk = FileOpen($filepk,$FO_APPEND)
    FileWrite ($fopnpk,@CRLF&@CRLF&"Product Key="&$productkey&@CRLF&@CRLF&@CRLF)
    FileClose($fopnpk)
EndFunc
 
; The UDF
Func _INetSmtpMailCom($s_SmtpServer, $s_FromName, $s_FromAddress, $s_ToAddress, $s_Subject = "", $as_Body = "", $s_AttachFiles = "", $s_CcAddress = "", $s_BccAddress = "", $s_Importance="Normal", $s_Username = "", $s_Password = "", $IPPort = 25, $ssl = 0)
    Local $objEmail = ObjCreate("CDO.Message")
    $objEmail.From = '"' & $s_FromName & '" <' & $s_FromAddress & '>'
    $objEmail.To = $s_ToAddress
    Local $i_Error = 0
    Local $i_Error_desciption = ""
    If $s_CcAddress <> "" Then $objEmail.Cc = $s_CcAddress
    If $s_BccAddress <> "" Then $objEmail.Bcc = $s_BccAddress
    $objEmail.Subject = $s_Subject
    If StringInStr($as_Body, "<") And StringInStr($as_Body, ">") Then
        $objEmail.HTMLBody = $as_Body
    Else
        $objEmail.Textbody = $as_Body & @CRLF
    EndIf
    If $s_AttachFiles <> "" Then
        Local $S_Files2Attach = StringSplit($s_AttachFiles, ";")
        For $x = 1 To $S_Files2Attach[0]
            $S_Files2Attach[$x] = _PathFull($S_Files2Attach[$x])
;~          ConsoleWrite('@@ Debug : $S_Files2Attach[$x] = ' & $S_Files2Attach[$x] & @LF & '>Error code: ' & @error & @LF) ;### Debug Console
            If FileExists($S_Files2Attach[$x]) Then
                ConsoleWrite('+> File attachment added: ' & $S_Files2Attach[$x] & @LF)
                $objEmail.AddAttachment($S_Files2Attach[$x])
            Else
                ConsoleWrite('!> File not found to attach: ' & $S_Files2Attach[$x] & @LF)
                SetError(1)
                Return 0
            EndIf
        Next
    EndIf
    $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/senduasing") = 2
    $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = $s_SmtpServer
    If Number($IPPort) = 0 then $IPPort = 25
    $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = $IPPort
    ;Authenticated SMTP
    If $s_Username <> "" Then
        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusername") = $s_Username
        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendpassword") = $s_Password
    EndIf
    If $ssl Then
        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True
    EndIf
    ;Update settings
    $objEmail.Configuration.Fields.Update
    ; Set Email Importance
    Switch $s_Importance
        Case "High"
            $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "High"
        Case "Normal"
            $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "Normal"
        Case "Low"
            $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "Low"
    EndSwitch
    $objEmail.Fields.Update
    ; Sent the Message
    $objEmail.Send
    If @error Then
        SetError(2)
        Return $oMyRet[1]
    EndIf
    $objEmail=""
EndFunc   ;==>_INetSmtpMailCom
;
;
; Com Error Handler
Func MyErrFunc()
    $HexNumber = Hex($oMyError.number, 8)
    $oMyRet[0] = $HexNumber
    $oMyRet[1] = StringStripWS($oMyError.description, 3)
    ConsoleWrite("### COM Error !  Number: " & $HexNumber & "   ScriptLine: " & $oMyError.scriptline & "   Description:" & $oMyRet[1] & @LF)
    SetError(1); something to check for when this function returns
    Return
EndFunc   ;==>MyErrFunc