Check application installed if not, download and install it

Please use the procedure to download any application whether .exe or .msi from valid URL and get installed on your endpoint if the application is not installed previously :slight_smile:

Please run the script as System User

Usage Instructions:
ApplicationName=‘program name to check whether already installed or not
URL=r’enter your valid URL
SilentCommand=‘enter silent commands
DownloadPath=‘download path
FileName=‘file name you wish to save by’ - Please don’t keep the extension
Extension=‘extension with DOT

Eample,
ApplicationName=‘7-Zip
URL=r’http://www.7-zip.org/a/7z1604-x64.msi
SilentCommand=‘/qn
DownloadPath=‘%temp%
FileName=‘7z1604-x64’ - Please don’t keep the extension
Extension=‘.msi

ApplicationName='<i><b>7-Zip</b><i>'
URL=r'<i><b>http://www.7-zip.org/a/7z1604-x64.msi</b><i>'
SilentCommand='<i><b>/qn</b><i>'
DownloadPath='<i><b>%temp%</b><i>'
FileName='<i><b>7z1604-x64</b><i>'
Extension='<i><b>.msi</b><i>'

## Execute CMD
def ExecuteCMD(CMD, OUT = False):
    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()
    RET = OBJ.returncode
    if RET == 0:
        if OUT == True:
            if out != '':
                return out.strip()
            else:
                return True
        else:
            return True
    return False

## If pattern is given, converts to real path
def PaternPath(DownloadPath):
    import os
    if not os.path.isdir(DownloadPath):
        return ExecuteCMD('echo '+DownloadPath, True)
    return DownloadPath

## Downloads application
def Download(Path, URL, FileName, Extension):
    import urllib2
    import os
    fn = FileName+Extension
    fp = os.path.join(Path, fn)
    req = urllib2.Request(URL, headers={'User-Agent' : "Magic Browser"})
    con = urllib2.urlopen(req)
    with open(fp, 'wb') as f:
        while True:
            chunk=con.read(100*1000*1000)
            if chunk:
                f.write(chunk)
            else:
                break
    if os.path.exists(fp):
        return fp
    return False

## Install Application with Silent Command
def Install(FilePath, SilentCommand):
    if not (FilePath[-4:-1]+FilePath[-1]).lower()=='.msi':
        return ExecuteCMD('"'+FilePath+'" '+SilentCommand)
    else:
        return ExecuteCMD('msiexec /i "'+FilePath+'" '+SilentCommand)

## Check whether the app is installed
def CheckApp(AppName):
    import _winreg
    import os
    AppName = AppName.lower()
    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, 'DisplayVersion')
                        _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)

    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)

    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)

    lr = []
    rs = 0
    for i in fList:
        a, b = i
        if AppName in a.lower():
            lr.append('success: {} is installed'.format(a))
            lr.append('{:<25}{:5}'.format(a, b))
            rs += 1
        else:
            rs += 0
    if rs:
        return True
    return False

import os
if not CheckApp(ApplicationName):
    Path=PaternPath(DownloadPath)
##    print Path
    FilePath=Download(Path, URL, FileName, Extension)
##    print FilePath
    if Install(FilePath, SilentCommand):
        print FilePath+' is installed now successfully :)'
    os.remove(FilePath)
else:
    print ApplicationName+' is already installed'

Script File:
20170324-Download-and-Install-Package.json

Sample Output:
If application is not installed then

If application is already installed then

Check application installed if not, download and install.png

Check application installed if not, download and install1.png

20170324-Download-and-Install-Package.json (6.99 KB)

Hi,
sorry, I tried to modify your script to install my software, no effect,
then tried directly your script on a win32 7 computer, no effect, nothing install and procedure says “finished”.

Hi @rbo,

Please share your script that you have tried on the ITSM

I will check and analyze the cause of the issue and let you know the solution.

Thank you.

I tried your script, directly, without modification.

Hi @rbo,

please try with the 32-bit package, there in the script, I have used 64-bit package only. You have tried with 32-bit windows 7 for installing 64-bit package, so you are getting the result ‘finished success’ only.
so kindly change the parameters as follows after importing the JSON file into the ITSM script editor. the parameters set is completely changed for the 32-bit 7-Zip package.

ApplicationName=‘7-Zip
URL=r’http://www.7-zip.org/a/7z1604.msi
SilentCommand=’/qn
DownloadPath=’%temp%
FileName=‘7z1604
Extension=’.msi

Looking for your feedback.

Thank you.

1 question, how do you get the “7_zip” application name, is there any importance to not write what you want ?

I dont suceed with my .msi (I send you url by PM if you can test).

Hi @rbo,

Yes, It is important because, by the application name only our script checks the endpoint s/w inventory to identify whether the software is installed or not.
the script is not a case sensitive so that you can give the name as “7-Zip” (upper) or “7-zip” (lower) in the script, either will be working fine. But giving the name “7_zip” will not be working fine in the script.

Please send me the URL for your .msi package, we will check and let you know the result as soon as possible.

Thank you.

Hi @rbo,

Thank you for your patient and cooperation

Please try your package with the new script, updated in the very first conversation.

hi. @rbo @Purushothaman
in case rbo still have problem
i did bit changes in this script, and also included run-uninstall option, that might help option.

##########TO EDIT ##################################################################
url=‘http://download.piriform.com/ccsetup531.exe
SilentCommand=’/S’ ## Provide Silent Installation Command, DON’t include blank space before command
UnInstallAppExecutable = ‘uninst.exe’
UnInstallSilentCommand=’ /S’ ## Provide Silent UnInstallation Command (UnInstallAppExecutable), include blank space before command if required, if no auo command than keep ‘’
AppName = ‘CCleaner’ ## Provide the Application Name here to check if its installed
AppFolder = ‘CCleaner’ ## Provide the Application Folder sequence name created inside Program Files, where [AppExecutable] should exist, example ‘Comodo\Nat’
AppExecutable =‘CCleaner.exe’ ##Provide executable app after install To Run command
RunCommand=’ /AUTO’ ## Provide (silent) command you want to run for installed app (AppExecutable), include blank space before command if required, if no auo command than keep ‘’
Uninstall = ‘0’ ## 1=yes uninstall after run.
#################################################################################################
########## NOT ADVISED TO EDIT ##################################################################
import os
import urllib
import subprocess
import re
import _winreg
import os.path
import ctypes;
global temp
temp=os.environ[‘TEMP’]
setup=url.split(’/’)[-1]
Extension=url.split(’.’)[-1]
R32bit=os.path.join(os.environ[‘PROGRAMFILES(X86)’],AppFolder,AppExecutable)
R64bit=os.path.join(os.environ[‘PROGRAMW6432’],AppFolder,AppExecutable)
Rsystemdrive = os.path.join(os.path.abspath(os.sep),AppName,AppExecutable)
U32bit=os.path.join(os.environ[‘PROGRAMFILES(X86)’],AppFolder,UnInstallAppExecutable)
U64bit=os.path.join(os.environ[‘PROGRAMW6432’],AppFolder,UnInstallAppExecutable)
Usystemdrive = os.path.join(os.path.abspath(os.sep),AppName,UnInstallAppExecutable)
InstallAppPath = os.path.join(os.environ[‘TEMP’],setup)
#################################################################################################
key = getattr(_winreg,“HKEY_LOCAL_MACHINE”)
subkey = _winreg.OpenKey(key, “Software\Microsoft\Windows\CurrentVersion\Policies\System” )
(uac, type) = _winreg.QueryValueEx(subkey,“EnableLUA”)
#################################################################################################
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)

if uac == 1:
print(“User Access Control is Enabled, let me Disable”);
with disable_file_system_redirection():
setuacd=os.popen(‘REG ADD “HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System” /V “EnableLUA” /t REG_DWORD /d 0 /F’).read();
print(setuacd);
elif uac == 0:
print(“User Access Control is Disabled”);
else:
print(‘User Access Control - Error code returned’);
####################################################################################
def downloadFile(DownTo, fromURL):
try:
fileName = fromURL.split(’/’)[-1]
DownTo = os.path.join(DownTo, fileName)
with open(DownTo, ‘wb’) as f:
f.write(urllib.urlopen(fromURL).read())
if os.path.isfile(DownTo):
return ‘{} - {}KB’.format(DownTo, os.path.getsize(DownTo)/1000)
except:
return ‘Please Check URL or Download Path!’

def install():
import subprocess
sp = subprocess.Popen(InstallAppPath+r’ '+SilentCommand, stdout=subprocess.PIPE)
out,err = sp.communicate()
rc = sp.returncode
if rc==0:
print out
print ‘Installed Successfully {}…’.format(setup)
else:
print ‘Application Return code is’
print rc
print err
return()

##############################
##os.chdir(path)
##code={0:‘Success’,1:‘Error.’,2:‘Administrator access rights are required.’,3:‘The command line parameters are invalid.’,4:‘Was cancelled by user.’,5:‘Unsupported Windows version.’,6:‘Error creating log file.’,7:‘Another instance is already running.’,8:‘Low free space on the disk.’,9:‘The computer has been turned off or rebooted.’}
##comandrun = subprocess.Popen(AppExecutable+RunCommand, stdout=subprocess.PIPE)
##############################
def run(path):
comandrun = subprocess.Popen(path+RunCommand, stdout=subprocess.PIPE)
out,err = comandrun.communicate()
rc = comandrun.returncode
if rc==0:
print out
print ‘Completed Run Command {}…’.format(AppName)
else:
print err
print 'Application Return code is ’
print rc
return()
########
def uninstall(path):
print command_path+RunCommand
remove= subprocess.Popen(path+UnInstallSilentCommand, stdout=subprocess.PIPE)
out,err = remove.communicate()
rc = remove.returncode
if rc==0:
print out
print ‘Application Un-Installed {}…’.format(AppName)
else:
print 'Application Return code is ’
print rc
print err
print ‘uninstallation has been failed’
return()

##run - UNInstall PATH##
if os.path.exists(R32bit):
command_path=R32bit
uninstall_path=U32bit
elif os.path.exists(R64bit):
command_path=R64bit
uninstall_path=U64bit
else:
command_path=Rsystemdrive
uninstall_path=Usystemdrive

from subprocess import PIPE, Popen
ServiceString = AppName
AppName = AppName.lower()
ServiceString = ServiceString.lower()
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, ‘DisplayVersion’)
_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)

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)

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)

lr = []
rs = 0
for i in fList:
a, b = i
if AppName in a.lower():
lr.append(’{:<25}{:5}’.format(a, b))
rs += 1
else:
rs += 0

if rs > 0:
print ‘Application is Installed, Let me Run {}…’.format(AppName)
print command_path+RunCommand
run(command_path)
else:
print 'fail: Sorry, {} is not installed, let me Download, Install and Run '.format(AppName)

download - Install - Run

print downloadFile(temp,url)
install()
run(command_path)
##Remove Temp file - Downloaded Setup
if  os.path.exists(InstallAppPath):
    os.chdir(temp)
    os.remove(setup)

if Uninstall == ‘1’:
uninstall(uninstall_path)

if uac == 1:
print(“UAC was enabled, so Let me Enable UAC”);
with disable_file_system_redirection():
setuace=os.popen(‘REG ADD “HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System” /V “EnableLUA” /t REG_DWORD /d 1 /F’).read();
print(setuace);

attached json

20170706-Check-Ccleaner-is-installed—and-run.json (12 KB)

I have an application I would like to automate via this script which requires user intervention. First is the UAC prompt in which ‘yes’ needs to be clicked. Second- the app has it’s own splash screen wehe there is an INSTALL button to click or ‘Customize this install’. I’m only interested in the default installation. How do I create kind of like an answer file to append to the script or is it perhaps doable with some more parameters appended?.

thanks
Evo

BTW I do understand the paramater /qn is supposed to suppress user intervention - it’s just that this particular script did not work for the app I tried to install. The log files show it ‘started’ but never progressed any further. I do see the file downloaded locally.

It’s an Aconis Backup agent via a Comodo1 device.

@Damon C In this case a Windows agent.

Hi @evoevoevo
Another forumer recently requested a script that is sort of similar to what you are trying to do. The requested script has already been made available, perhaps you would like to test it if it meets your requirements?

Hi @evoevoevo

We will analyze and update the script request once it has been completed.

Thank you

Hi @evoevoevo ,

Refer the attached JSON file for checking the Acronis backup software installed, if not download and install it.Please let us know and provide your feedback to us.

Thank you

20180409-Check-if-acronis-application-installed-if-not-download-and-install-it.json (9.94 KB)

The first attempt at the script above failed with some errors, I’ll try again tomorrow on a clean machine before posting any further confirmation. I’ll also try the other one Rick posted above as well - although what I’m trying to do is install this file from a particular URL from which i provide. Thanks!!

Hi @evoevoevo

Sorry for your inconvenience.Could you please check this updated JSON file and let us know your feedback to us.

Thank you

20180410-Check-if-acronis-application-installed-if-not-download-and-install-it.json (9.98 KB)