ITSM -Device heath report in CSV file format

Hi,

Please use the script to get Procedure Finished Success, Procedure Finished Fail, Installed Critical and Security Patches and Hard Disk Properties.

Note:
Please modify the variables as per your concern
sendmail=1 ## [1- sends csv reports in email or 0- prints output in execution logs ] if sendmail=1 then user have to set the required information to send out a email from the code .
msgbody='Hi,

Please find the attachment for the Computer Health Report in CSV file format.

Thank you.’
emailto=[‘purushothaman.ramasamy@comodo.com’]
emailfrom=‘testcomodomail1@gmail.com’
password=‘C0m0d0@123’
smtpserver=‘smtp.gmail.com
port=587


sendmail=1 ## [1 sends mail or 0 does not send mail] if sendmail=1 then user have to set the required information to send out a email from the code.
msgbody='Hi,

Please find the attachment for the Computer Health Report in CSV file format.

Thank you.'
emailto=['purushothaman.ramasamy@comodo.com']
emailfrom='testcomodomail1@gmail.com'
password='C0m0d0@123'
smtpserver='smtp.gmail.com'
port=587

import os
import re
import random

## get computer name
def computername():
    import os
    return os.environ['COMPUTERNAME']

## get ip address
def ipaddress():
    import socket
    return socket.gethostbyname(socket.gethostname())

## function to email with attachment
def emailreport(subject, emailto,emailfrom,fileToSend,password,smtpserver,port,msgbody):
    import smtplib
    import mimetypes
    from email.mime.multipart import MIMEMultipart
    from email import encoders
    from email.message import Message
    from email.mime.audio import MIMEAudio
    from email.mime.base import MIMEBase
    from email.mime.image import MIMEImage
    from email.mime.text import MIMEText
    import os
    msg = MIMEMultipart()
    msg["From"] = emailfrom
    msg["To"] = ",".join(emailto)
    msg["Subject"] = subject
    msg.preamble = subject
    body = MIMEText(msgbody)
    msg.attach(body)       
    with open(fileToSend, 'rb') as fp:
        record = MIMEBase('text', 'octet-stream')
        record.set_payload(fp.read())
        encoders.encode_base64(record)
        record.add_header('Content-Disposition', 'attachment', filename=os.path.basename(fileToSend))
        msg.attach(record)
    try:
        server = smtplib.SMTP(smtpserver,port)
        server.ehlo()
        server.starttls()
        server.login(emailfrom, password)
        server.sendmail(emailfrom, emailto, msg.as_string())
        server.quit()
        return "the email report has been sent to "+msg["To"]
    except Exception as e:
        return e

## function to execute commands
def ecmd(CMD):
    import ctypes
    class disable_file_system_redirection:
        _disable = ctypes.windll.kernel32.Wow64DisableWow64FsRedirection
        _revert = ctypes.windll.kernel32.Wow64RevertWow64FsRedirection
        def __enter__(self):
            self.old_value = ctypes.c_long()
            self.success = self._disable(ctypes.byref(self.old_value))
        def __exit__(self, type, value, traceback):
            if self.success:
                self._revert(self.old_value)
    from subprocess import PIPE, Popen
    with disable_file_system_redirection():
        OBJ = Popen(CMD, shell = True, stdout = PIPE, stderr = PIPE)
    out, err = OBJ.communicate()
    return out.strip()


temp=str(random.randint(2017, 3000))+'.txt'
ptemp=str(random.randint(2017, 3000))+'p.txt'
if 'PROGRAMFILES(X86)' in os.environ.keys():
    pmlpath=os.path.join(os.environ['PROGRAMFILES(X86)'], 'COMODO\\Comodo ITSM\\pmlogs')
    prlpath=os.path.join(os.environ['PROGRAMFILES(X86)'], 'COMODO\\Comodo ITSM\\rmmlogs')
else:
    pmlpath=os.path.join(os.environ['PROGRAMFILES'], 'COMODO\\Comodo ITSM\\pmlogs')
    prlpath=os.path.join(os.environ['PROGRAMFILES'], 'COMODO\\Comodo ITSM\\rmmlogs')

with open(os.path.join(os.environ['TEMP'], 'report.csv'), 'wb') as c1:
    c1.write('Completed Maintenance Procedures
')

    ## procedure logs
    pfiles=os.listdir(prlpath)
    with open(os.path.join(os.environ['TEMP'], ptemp), 'wb') as fw:
        for file in pfiles:
            if file.startswith('Rmm_dll'):
                with open(os.path.join(prlpath,file), 'rb') as f:
                    while True:
                        line=f.readline()
                        if line:
                            if 'MsgProcedureRule/name: ' in line or 'status: PROCEDURE_FINISHED_SUCCESS' in line or 'status: PROCEDURE_FINISHED_FAIL' in line:
                                fw.write(line)
                        else:
                            break
    with open(os.path.join(os.environ['TEMP'], ptemp), 'rb') as fr:
        read=fr.read()
        item=''
        c1.write('|Finished Success
')
        for i in re.findall('MsgProcedureRule/name:.*
.*status:\sPROCEDURE_FINISHED_SUCCESS',read):
            ob=re.search('MsgProcedureRule/name:.*
', i)
            if ob:
                t1=ob.group()
                if t1 and 'MsgProcedureRule/name:.*' not in t1 and 'MsgProcedureRule/name: \'' not in t1:
                    if t1 not in item:
                        item+=t1
                        t1=t1.replace('MsgProcedureRule/name: ', '')
                        t1=t1.replace(' 
', '')
                        t1=t1.replace('|', '')
                        c1.write('||'+t1+'
')
        item1=''
        c1.write('|Finished Fail
')
        for j in re.findall('MsgProcedureRule/name:.*
.*status:\sPROCEDURE_FINISHED_FAIL',read):
            ob=re.search('MsgProcedureRule/name:.*
', j)
            if ob:
                v1=ob.group()
                if v1 and 'MsgProcedureRule/name:.*' not in v1 and 'MsgProcedureRule/name: \'' not in v1:
                    if v1 not in item1 and v1 not in item:
                        item1+=v1
                        v1=v1.replace('MsgProcedureRule/name: ', '')
                        v1=v1.replace(' 
', '')
                        v1=v1.replace('|', '')
                        c1.write('||'+v1+'
')
    ## remove the temp file of pmlogs
    os.remove(os.path.join(os.environ['TEMP'], ptemp))

    c1.write('

Completed Critical and Security Patches Installed
')
    ## patch management logs
    tempd=os.path.join(os.environ['temp'], 'templogs.txt')
    tempm=os.path.join(os.environ['temp'], 'tempm.txt')
    templ=os.path.join(os.environ['temp'], 'templ.txt')
    logfiles=[os.path.join(pmlpath, i) for i in os.listdir(pmlpath) if i.startswith('PatchInventoryCollector.log')]
    with open(tempd, 'wb') as w:        
        for i in logfiles:
            with open(i, 'rb') as r:
                 w.write(r.read())
    string=''
    with open(tempd) as r:
        while True:
            line=r.readline()
            if line:
                if 'Total Installed OS Patches:' in line or '] called' in line:
                    string+=line+'||'
            else:
                break
    i=0
    a,b='',''
    ls=string.split('||')
    while i+1<len(ls):
        if 'Total' in ls[i]:
            if 'called' in ls[i+1]:
                key=(ls[i].split()[1].split(':')[0], ls[i+1].split()[1].split(':')[0])
                if key[0]==key[1]:
                    a,b=key
                break
        i+=1

    if key:
        with open(tempm, 'wb')as w:
            with open(tempd) as r:
                ob=re.search('.*'+a+'.*(
.*)+.*'+b+'.*', r.read())
                if ob:
                    w.write(ob.group())

    os.remove(tempd)

    with open(templ, 'w') as w:
        with open(tempm) as r:
            while True:
                line=r.readline()
                if line:
                    if 'Metadata' in line or 'Title:' in line or 'Patch Primary Category: "Security Updates"' in line or 'Patch Primary Category: "Critical Updates"' in line:
                        w.write(line)
                else:
                    break

    os.remove(tempm)

    with open(templ) as fr:
        for i in re.findall('Title:.*
.*Updates"',fr.read()):
            ob=re.search('".*\(.*\)"', i)
            if ob:
                t1=ob.group()
                if t1:
                    c1.write('|'+t1[1:-1]+'
')

    os.remove(templ)

    c1.write('

Hard Disk Drive Health
')
    ## disk properties
    alldrives=[a.strip().split() for a in ecmd('wmic logicaldisk where drivetype=3 get deviceid, freespace, size').split('
') if len(a.strip().split())==3][1:]
    d={}
    ld=re.findall('Disk\s[0-9]+', ecmd('echo list disk |diskpart'))
    for i in ld:
        f=os.path.join(os.environ['TEMP'], ''.join(i.split())+'.txt')
        with open(f, 'w') as wr:
            wr.write(r'''select %s
list volume'''%(i))
        lv=re.findall(r'Volume\s[0-9]+\s+[A-Z]', ecmd('diskpart /s '+f))
        os.remove(f)
        templist=[]
        for j in lv:
            vob=re.search('Volume\s[0-9]+\s+', j)
            dl=j.replace(vob.group(), '')+':'
            templist.append(dl)
        d[i]=templist
    dd={}
    for j in d:
        tf=0
        tt=0
        for i in alldrives:
            if i[0] in d[j]:
                tf+=int(i[1])
                tt+=int(i[2])
        dd[j]=[round(float(tt)/(1024*1024*1024), 2), round(float(tf)/(1024*1024*1024), 2), round((float(tt-tf)/tt)*100, 2)]
    for i in dd:
        c1.write('|'+i+'
||Total Space|'+str(dd[i][0])+' GB'+'
||Free Space|'+str(dd[i][1])+' GB'+'
||Disk % Utilized|'+str(dd[i][2])+' %'+'

')


fileToSend=os.path.join(os.environ['TEMP'], 'report.csv')
subject='%s %s Health Report CSV'%(computername(), ipaddress())
if sendmail==1:
    print emailreport(subject,emailto,emailfrom,fileToSend,password,smtpserver,port,msgbody)
else:
    with open(fileToSend) as fr:
        print fr.read().replace('|', '  ')
## remove the csv file
os.remove(os.path.join(os.environ['TEMP'], 'report.csv'))


Sample Mail:

CSV Separator:

Use ‘|’ as a separator when you open the csv [output file]

20170612-ITSM-Computer-Health-Report—Email.json (12.8 KB)

hi
i think this should be improved for send email, it can be optional.
like sendemail=1 send email, else print.

2017/06/03 02:53:02 PM Failed Traceback (most recent call last): File "<string>", line 167, in <module> NameError: name 'key' is not defined

Hi @Sergey

Let us check this issue and update you.

Hi @phcsolutions

Thank you for your ideas on improving script results. We will update you once done.

When do you create procedures parameters functionality?

Hi @Sergey

I have escalated your request. Our support team will reach out shortly to clarify with you.

Thanks
Kannan

Hi @phcsolutions and @Sergey

We have fixed the issue and improved the script as per your requests. Please refer updated script in the initial post again.

Thanks

Hello @Sergey

The Feature request: manually enter script parameters was released this Saturday. Kindly refer to the wiki guide below.

https://wiki.comodo.com/frontend/web/topic/how-to-create-and-run-procedures-with-parameters