#########################Configuration#Section##########################################################################
# This Monitor will allow you to keep track up to 10 applications
# To monitor an application please change the VerifyIfApplicationXIsPresent value from "no" to "yes" and then provide the application name in the next variable
# The monitor will verify if the application is installed on the endpoint and if is not, he will trigger the remediation procedure that will install the application.
# In the remediation procedure please make sure that you associate the same number with your application

VerifyIfApplication1IsPresent = "yes"
Application1Name = "Sharepoint Client Components"
VerifyIfApplication2IsPresent = "yes"
Application2Name = "7-Zip 19.00(x64)"
VerifyIfApplication3IsPresent = "no"
Application3Name = ""
VerifyIfApplication4IsPresent = "no"
Application4Name = ""
VerifyIfApplication5IsPresent = "no"
Application5Name = ""
VerifyIfApplication6IsPresent = "no"
Application6Name = ""
VerifyIfApplication7IsPresent = "no"
Application7Name = ""
VerifyIfApplication8IsPresent = "no"
Application8Name = ""
VerifyIfApplication9IsPresent = "no"
Application9Name = ""
VerifyIfApplication10IsPresent = "no"
Application10Name = ""
########################################################################################################################
import os
import ctypes
import re
import time
import socket
try:
	import winreg as _winreg
except ImportError:
	try:
		import _winreg
	except ImportError:
		pass
import shutil
import ssl
try:
	import urllib.request as urllib2
except ImportError:
	try:
		import urllib2
	except ImportError:
		pass
import getpass
import sys
import datetime

i=0
j=0
allowtorun=0
min = '5' 
datenow = datetime.datetime.now()
datestamp = datenow + datetime.timedelta(minutes = int(min) -1)

def GetWindowsEdition(Key_name):
	val = ""
	try:
		reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
		ok = _winreg.OpenKey(reg, Key_name, 0, _winreg.KEY_WOW64_32KEY | _winreg.KEY_READ)
		val = _winreg.QueryValueEx(ok, "ProductName")[0]
		_winreg.CloseKey(ok)
		return val
	except Exception as exception:
		val = "Windows Registry Exception: " + str(exception)
		return val

WindowsVersion = GetWindowsEdition('SOFTWARE\Microsoft\Windows NT\CurrentVersion')

class disable_file_system_redirection:
	if not ("XP" in WindowsVersion or "2008" in WindowsVersion):
		try:
			_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)
		except:
			pass

# Create 'TimeStampStatus' file and write current time
def WriteTimeStampToTheTimeStampFile(datetowrite):
	Path_for_time_stamp_file = r""
	Os_Path = r"{0}\Program Files (x86)".format(os.environ['systemdrive'])
	if os.path.exists(Os_Path):
		Path_for_time_stamp_file = r"{0}\Program Files (x86)\ITarian\Endpoint Manager\rmmlogs\TimeStampStatus.txt".format(os.environ['systemdrive'])
	else:
		Path_for_time_stamp_file = r"{0}\Program Files\ITarian\Endpoint Manager\rmmlogs\TimeStampStatus.txt".format(os.environ['systemdrive'])
	open(Path_for_time_stamp_file, "w+").write(str(datetowrite.strftime("%y-%m-%d %H:%M:%S")))

# read 'TimeStampStatus' file
def readTimeStampStatus():
	Path_for_time_stamp_file = r""
	Os_Path = r"{0}\Program Files (x86)".format(os.environ['systemdrive'])
	if os.path.exists(Os_Path):
		Path_for_time_stamp_file = r"{0}\Program Files (x86)\ITarian\Endpoint Manager\rmmlogs\TimeStampStatus.txt".format(os.environ['systemdrive'])
	else:
		Path_for_time_stamp_file = r"{0}\Program Files\ITarian\Endpoint Manager\rmmlogs\TimeStampStatus.txt".format(os.environ['systemdrive'])
	vartime = open(Path_for_time_stamp_file, "r")
	time = vartime.read()
	return time

def verifyfileexist():
	Path_for_time_stamp_file = ""
	Os_Path = r"{0}\Program Files (x86)".format(os.environ['systemdrive'])
	if os.path.exists(Os_Path):
		Path_for_time_stamp_file = r"{0}\Program Files (x86)\ITarian\Endpoint Manager\rmmlogs\TimeStampStatus.txt".format(os.environ['systemdrive'])
	else:
		Path_for_time_stamp_file = r"{0}\Program Files\ITarian\Endpoint Manager\rmmlogs\TimeStampStatus.txt".format(os.environ['systemdrive'])
	return Path_for_time_stamp_file

def alert(arg):
    sys.stderr.write("%d%d%d" % (arg, arg, arg))

## detect all installed software through registry key            
def DNDS(rtkey, pK, kA):
	ln = []
	lv = []
	try:
		oK = _winreg.OpenKey(rtkey, pK, 0, kA)
		i = 0
		while True:
			try:
				bkey = _winreg.EnumKey(oK, i)
				vkey = os.path.join(pK, bkey)
				oK1 = _winreg.OpenKey(rtkey, vkey, 0, kA)
				try:
					tls = []
					DN, bla = _winreg.QueryValueEx(oK1, 'DisplayName')
					DV, bla = _winreg.QueryValueEx(oK1, 'UninstallString')
					_winreg.CloseKey(oK1)
					ln.append(DN)
					lv.append(DV)
				except:
					pass
				i += 1
			except:
				break
		_winreg.CloseKey(oK)
		return zip(ln, lv)
	except:
		return zip(ln, lv)

def GetSoftwareUsingRegistry():
	## detect whether the computer is 32 bit or 64 bit
	rK = _winreg.HKEY_LOCAL_MACHINE
	sK = r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
	openedKey = _winreg.OpenKey(rK, sK, 0, _winreg.KEY_READ)
	arch, bla = _winreg.QueryValueEx(openedKey, 'PROCESSOR_ARCHITECTURE')
	arch = str(arch)
	_winreg.CloseKey(openedKey)
	## sorting all collected data from all the way, filtered duplicates and listed the final result!
	if arch == 'AMD64':
		fList = DNDS(_winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', _winreg.KEY_WOW64_32KEY | _winreg.KEY_READ)
		fList.extend(DNDS(_winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', _winreg.KEY_WOW64_64KEY | _winreg.KEY_READ))
		fList.extend(DNDS(_winreg.HKEY_CURRENT_USER, r'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', _winreg.KEY_WOW64_32KEY | _winreg.KEY_READ))
		fList.extend(DNDS(_winreg.HKEY_CURRENT_USER, r'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', _winreg.KEY_WOW64_64KEY | _winreg.KEY_READ))
	else:
		fList = DNDS(_winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', _winreg.KEY_READ)
		fList.extend(DNDS(_winreg.HKEY_CURRENT_USER, r'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', _winreg.KEY_READ))
	fList = set(fList)
	j = 1
	FinalResultAVG = ""
	for i in sorted(fList):
		a, b = i
		try:
			resultavg = '{:<100}'.format(a.encode('utf-8'))
			FinalResultAVG = FinalResultAVG + '\n' + resultavg
		except:
			FinalResultAVG = FinalResultAVG + '\n' + a
		j += 1
	return FinalResultAVG

GetSoftwareUsingRegistryResult = ""
GetSoftwareUsingRegistryResult = GetSoftwareUsingRegistry()

if not os.path.exists(verifyfileexist()):
	if allowtorun==0:
		if VerifyIfApplication1IsPresent is "yes":
			if not Application1Name in GetSoftwareUsingRegistryResult:
			    allowtorun=1
			    i=1
			    print ( Application1Name + ' is NOT present')
	if allowtorun==0:
		if VerifyIfApplication2IsPresent is "yes":
			if not Application2Name in GetSoftwareUsingRegistryResult:
			    allowtorun=1
			    i=1
			    print ( Application2Name + ' is NOT present')
	if allowtorun==0:
		if VerifyIfApplication3IsPresent is "yes":
			if not Application3Name in GetSoftwareUsingRegistryResult:
			    allowtorun=1
			    i=1
			    print ( Application3Name + ' is NOT present')
	if allowtorun==0:
		if VerifyIfApplication4IsPresent is "yes":
			if not Application4Name in GetSoftwareUsingRegistryResult:
			    allowtorun=1
			    i=1
			    print ( Application4Name + ' is NOT present')
	if allowtorun==0:
		if VerifyIfApplication5IsPresent is "yes":
			if not Application5Name in GetSoftwareUsingRegistryResult:
			    allowtorun=1
			    i=1
			    print ( Application5Name + ' is NOT present')
	if allowtorun==0:
		if VerifyIfApplication6IsPresent is "yes":
			if not Application6Name in GetSoftwareUsingRegistryResult:
			    allowtorun=1
			    i=1
			    print ( Application6Name + ' is NOT present')
	if allowtorun==0:
		if VerifyIfApplication7IsPresent is "yes":
			if not Application7Name in GetSoftwareUsingRegistryResult:
			    allowtorun=1
			    i=1
			    print ( Application7Name + ' is NOT present')
	if allowtorun==0:
		if VerifyIfApplication8IsPresent is "yes":
			if not Application8Name in GetSoftwareUsingRegistryResult:
			    allowtorun=1
			    i=1
			    print ( Application8Name + ' is NOT present')
	if allowtorun==0:
		if VerifyIfApplication9IsPresent is "yes":
			if not Application9Name in GetSoftwareUsingRegistryResult:
			    allowtorun=1
			    i=1
			    print ( Application9Name + ' is NOT present')
	if allowtorun==0:
		if VerifyIfApplication10IsPresent is "yes":
			if not Application10Name in GetSoftwareUsingRegistryResult:
			    allowtorun=1
			    i=1
			    print ( Application10Name + ' is NOT present')
	if i==1:
		WriteTimeStampToTheTimeStampFile(datestamp)
		alert(1)
	else:
		alert(0)
else:
	statusdate = datetime.datetime.strptime(readTimeStampStatus(), '%y-%m-%d %H:%M:%S')
	if datenow < statusdate:
		alert(0)
	else:
		if allowtorun==0:
			if VerifyIfApplication1IsPresent is "yes":
				if not Application1Name in GetSoftwareUsingRegistryResult:
					allowtorun=1
					i=1
					print ( Application1Name + ' is NOT present')
		if allowtorun==0:
			if VerifyIfApplication2IsPresent is "yes":
				if not Application2Name in GetSoftwareUsingRegistryResult:
					allowtorun=1
					i=1
					print ( Application2Name + ' is NOT present')
		if allowtorun==0:
			if VerifyIfApplication3IsPresent is "yes":
				if not Application3Name in GetSoftwareUsingRegistryResult:
					allowtorun=1
					i=1
					print ( Application3Name + ' is NOT present')
		if allowtorun==0:
			if VerifyIfApplication4IsPresent is "yes":
				if not Application4Name in GetSoftwareUsingRegistryResult:
					allowtorun=1
					i=1
					print ( Application4Name + ' is NOT present')
		if allowtorun==0:
			if VerifyIfApplication5IsPresent is "yes":
				if not Application5Name in GetSoftwareUsingRegistryResult:
					allowtorun=1
					i=1
					print ( Application5Name + ' is NOT present')
		if allowtorun==0:
			if VerifyIfApplication6IsPresent is "yes":
				if not Application6Name in GetSoftwareUsingRegistryResult:
					allowtorun=1
					i=1
					print ( Application6Name + ' is NOT present')
		if allowtorun==0:
			if VerifyIfApplication7IsPresent is "yes":
				if not Application7Name in GetSoftwareUsingRegistryResult:
					allowtorun=1
					i=1
					print ( Application7Name + ' is NOT present')
		if allowtorun==0:
			if VerifyIfApplication8IsPresent is "yes":
				if not Application8Name in GetSoftwareUsingRegistryResult:
					allowtorun=1
					i=1
					print ( Application8Name + ' is NOT present')
		if allowtorun==0:
			if VerifyIfApplication9IsPresent is "yes":
				if not Application9Name in GetSoftwareUsingRegistryResult:
					allowtorun=1
					i=1
					print ( Application9Name + ' is NOT present')
		if allowtorun==0:
			if VerifyIfApplication10IsPresent is "yes":
				if not Application10Name in GetSoftwareUsingRegistryResult:
					allowtorun=1
					i=1
					print ( Application10Name + ' is NOT present')
		if i==1:
			WriteTimeStampToTheTimeStampFile(datestamp)
			alert(1)
		else:
			alert(0)