3. Comment coder les paquets WAPT

3.1. Exemples simples de fonctions d’aide à l’installation couramment utilisées

Présentation de plusieurs fonctions implémentées dans Setuphelpers et fréquemment utilisées pour développer des paquets WAPT.

3.1.1. Test et manipulation de dossiers et de fichiers

3.1.1.1. Création récursive d’un chemin

La commande makepath crée la variable de chemin pour C:\Program Files (x86)\Mozilla\Firefox.

makepath(programfiles,'Mozilla','Firefox')

3.1.1.2. Création et destruction de répertoires

La commande mkdirs crée le répertoire C:\test.

mkdirs('C:\\test')

La commande remove_tree détruit le répertoire C:\tmp\target.

remove_tree(r'C:\tmp\target')

3.1.1.3. Vérifier si un chemin est un fichier ou un dossier

La commande isdir vérifie si C:\Program Files (x86)\software is a directory.

isdir(makepath(programfiles32,'software')):
    print('The directory exists')

La commande isfile vérifie si C:\Program Files (x86)\software\file is a file.

isfile(makepath(programfiles32,'software','file')):
    print('file exist')

3.1.1.4. Vérifier si un répertoire est vide

La commande dir_is_empty vérifie que le répertoire C:\Program Files (x86)\software is empty.

dir_is_empty(makepath(programfiles32,'software')):
    print('dir is empty')

3.1.1.5. Copier un fichier

La commande filecopyto copie file.txt dans le répertoire C:\Program Files (x86)\software directory.

filecopyto('file.txt',makepath(programfiles32,'software'))

3.1.1.6. Copier un répertoire

La commande copytree2 copie le dossier C:\projet directory.

copytree2('sources','C:\\projet')

3.1.2. Manipulation des clés de registre

3.1.2.1. Vérifier l’existence d’une clé de registre

Commande registry_readstring vérifie si la clé de registre {8A69D345-D564-463c-AFF1-A69D9E530F96} existe dans le chemin de registre SOFTWARE\Google\Update\Clients of HKEY_LOCAL_MACHINE.

if registry_readstring(HKEY_LOCAL_MACHINE, "SOFTWARE\\Google\\Update\\Clients\\{8A69D345-D564-463c-AFF1-A69D9E530F96}", 'pv'):
    print('key exist')

3.1.2.2. Afficher la valeur d’une clé de registre

Commande registry_readstring lit la valeur {8A69D345-D564-463c-AFF1-A69D9E530F96} stockée dans le chemin du registre SOFTWARE\Google\Update\Clients of HKEY_LOCAL_MACHINE.

print(registry_readstring(HKEY_LOCAL_MACHINE, r'SOFTWARE\Google\Update\Clients\{8A69D345-D564-463c-AFF1-A69D9E530F96}', 'pv'))

3.1.2.3. Modifier la valeur d’une clé de registre

Commande registry_setstring modifie la valeur de la clé de registre TOUVersion stockée dans le chemin d’accès au registre SOFTWARE\Microsoft\Windows Live of HKEY_CURRENT_USER.

registry_setstring(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows Live\\Common",'TOUVersion','16.0.0.0', type=REG_SZ)

3.1.3. Création et destruction de raccourcis

Avec WAPT setuphelper, il est possible de créer différents types de raccourcis.

3.1.3.1. Création d’un raccourci sur le bureau pour tous les utilisateurs

La commande create_desktop_shortcut crée le raccourci WAPT Console Management dans le répertoire C:NUsersNPublic pointant vers C:\Users\Public directory pointing to C:\Program Files (x86)\wapt\waptconsole.exe; le raccourci est disponible pour tous les utilisateurs.

create_desktop_shortcut(r'WAPT Console Management',target=r'C:\Program Files (x86)\wapt\waptconsole.exe')

3.1.3.2. Suppression d’un raccourci sur le bureau pour tous les utilisateurs

Commande remove_desktop_shortcut supprime le raccourci WAPT Console Management du dossier C:\Users\Public ; le raccourci est supprimé pour tous les utilisateurs.

remove_desktop_shortcut('WAPT Console Management')

Firefox place un raccourci sur le bureau de tous les utilisateurs, nous allons le supprimer.

Nous allons utiliser la fonction remove_desktop_shortcut :

  • Modifiez votre setup.py et utilisez la fonction comme ceci.

    # -*- coding: utf-8 -*-
    from *SetupHelpers* import *
    
    uninstallkey = []
    
    def install():
        install_exe_if_needed("Firefox Setup 45.5.0esr.exe",silentflags="-ms",key='Mozilla Firefox 45.5.0 ESR (x64 fr)',min_version="45.5.0")
        remove_desktop_shortcut('Firefox')
    
  • Si vous redémarrez l’installation à partir de PyScripter, vous remarquerez que le raccourci « tous les utilisateurs » a disparu.

3.1.3.3. Créer un raccourci de menu pour une application

La commande create_programs_menu_shortcut crée le raccourci WAPT Console Management dans le menu de démarrage pointant vers C:\Program Files (x86)\wapt\waptconsole.exe; le raccourci est disponible pour tous les utilisateurs.

create_programs_menu_shortcut(r'WAPT Console Management',target=r'C:\Program Files (x86)\wapt\waptconsole.exe')

3.1.3.4. Suppression d’un raccourci de menu pour une application

Commande remove_programs_menu_shortcut supprime le raccourci WAPT Console Management du menu de démarrage.

remove_programs_menu_shortcut('WAPT Console Management')

3.1.3.5. Création d’un raccourci sur le bureau pour un utilisateur connecté

Indication

Ces fonctions sont utilisées dans le contexte session_setup.

La commande create_user_desktop_shortcut crée le raccourci WAPT Console Management sur le bureau de l’utilisateur, pointant vers C:\Program Files (x86)\wapt\waptconsole.exe.

create_user_desktop_shortcut(r'WAPT Console Management',target=r'C:\Program Files (x86)\wapt\waptconsole.exe')

3.1.3.6. Suppression d’un raccourci de bureau pour un utilisateur connecté

Commande remove_user_desktop_shortcut supprime le raccourci WAPT Console Management du bureau de l’utilisateur connecté.

remove_user_desktop_shortcut('WAPT Console Management')

3.1.3.7. Création d’un raccourci de menu vers une application pour un utilisateur spécifique

Indication

Ces fonctions sont utilisées dans le contexte session_setup.

La commande create_user_programs_menu_shortcut crée le raccourci WAPT Console Management dans le menu de démarrage de l’utilisateur pointant vers C:\Program Files (x86)\wapt\waptconsole.exe.

create_user_programs_menu_shortcut(r'WAPT Console Management',target=r'C:\Program Files (x86)\wapt\waptconsole.exe')

3.1.3.8. Suppression d’un raccourci de menu vers une application pour un utilisateur spécifique

Commande remove_user_programs_menu_shortcut supprime le raccourci WAPT Console Management du menu de démarrage de l’utilisateur connecté.

remove_user_programs_menu_shortcut('WAPT Console Management')

3.1.4. Manipulation des fichiers ini

3.1.4.1. Lecture d’une valeur dans une section d’un fichier ini

La commande inifile_readstring lit une valeur à partir d’une clé et d’une section d’un fichier ini.

inifile_readstring("file.ini","global","key")

3.1.4.2. Écriture d’une valeur dans une section d’un fichier ini

La commande inifile_writestring modifie une valeur à partir d’une clé et d’une section d’un fichier ini.

inifile_writestring("file.ini","global","key","value")

3.1.4.3. Suppression d’une clé dans une section d’un fichier ini

La commande inifile_deleteoption supprime une clé dans une section donnée d’un fichier ini.

inifile_deleteoption("file.ini","global","key")

3.1.4.4. Suppression d’une section entière d’un fichier ini

La commande inifile_deletesection supprime une section d’un fichier ini et tout son contenu.

inifile_deletesection("file.ini","global")

3.1.5. Environnement Windows/ Logiciels/ Services

3.1.5.1. Récupération de la version d’un fichier

La commande get_file_properties affiche les propriétés du paquet.

get_file_properties(makepath(programfiles32,'InfraRecorder','infrarecorder.exe'))['ProductVersion']

3.1.5.2. Vérification de la version de Windows

La commande windows_version vérifie que la version de Windows est strictement inférieure à 6.2.0.

windows_version()<Version('6.2.0'):

Indication

Pour plus d’informations, vous pouvez consulter le site Microsoft Windows version number.

3.1.5.3. Vérification de l’architecture 64 bits

La commande iswin64 vérifie que l’architecture du système est de 64bits.

if iswin64():
    print('Pc x64')
else:
    print('Pc not x64')

3.1.5.4. Vérification de la variable Program Files

  • programfiles;

    print(programfiles())
    
  • programfiles32;

    print(programfiles32())
    
  • programfiles64;

    print(programfiles64())
    

Chaque commande renvoie un emplacement ProgramFiles différent.

Par exemple, la commande programfiles64 renvoie le répertoire Program Files natif, par exemple C:\Program Files (x86) sur l’architecture win64 ou win32 et programfiles() renvoie le chemin du répertoire Program Files 32bit, par exemple Programs Files (x86) sur l’architecture win64, et Programs Files sur l’architecture win32.

3.1.5.5. Vérification de la variable AppData

user_appdata/ user_local_appdata

Indication

Ces fonctions sont utilisées avec session_setup

La commande user_appdata renvoie le chemin du profil AppData itinérant de l’utilisateur connecté (C:\Users\%username%\AppData\Roaming).

print(user_appdata())

Commande user_local_appdata renvoie le chemin du profil local AppData de l’utilisateur connecté (C:\Users\%username%\AppData\Local).

print(user_local_appdata())

3.1.5.6. Désactivation temporaire de la redirection de fichiers wow3264

Commande disable_file_system_redirection désactive la redirection wow3264 dans le contexte actuel.

with disable_file_system_redirection():
    filecopyto('file.txt',system32())

3.1.5.7. Obtenir l’utilisateur actuellement connecté

La commande get_current_user affiche le nom d’utilisateur actuellement connecté.

print(get_current_user())

3.1.5.8. Obtention du nom de l’ordinateur

Commande get_computername indique le nom de l’ordinateur.

print(get_computername())

3.1.5.9. Obtention du domaine AD auquel l’ordinateur est rattaché

Commande get_domain_fromregistry renvoie le FQDN de l’ordinateur.

get_domain_fromregistry()

3.1.6. Actions sur les logiciels installés

3.1.6.1. Vérification des logiciels installés

La commande installed_softwares renvoie la liste des logiciels installés sur l’ordinateur à partir du registre dans un tableau.

installed_softwares('winscp')
[{'install_location': u'C:\\Program Files\\WinSCP\\', 'version': u'5.9.2', 'name': u'WinSCP 5.9.2', 'key': u'winscp3_is1', 'uninstall_string': u'"C:\\Program Files\\WinSCP\\unins000.exe"', 'publisher': u'Martin Prikryl', 'install_date': u'20161102', 'system_component': 0}]

3.1.6.2. Obtenir la commande de désinstallation à partir du registre

Commande uninstall_cmd renvoie la commande de désinstallation silencieuse.

uninstall_cmd('winscp3_is1')
"C:\Program Files\WinSCP\unins000.exe" /SILENT

3.1.6.3. Désinstallation d’un logiciel

for to_uninstall in installed_softwares(name="winscp"):
      if Version(to_uninstall["version"]) < Version(control.get_software_version()):
          print(f"Removing: {to_uninstall['name']} ({to_uninstall['version']})")
          killalltasks(ensure_list(control.impacted_process))
          run(uninstall_cmd(to_uninstall["key"]))
          wait_uninstallkey_absent(to_uninstall["key"])
  • Pour chaque élément de la liste retournée par installed_softwares contenant le mot-clé winscp.

  • Si la version est inférieure à la valeur de control.get_software_version.

  • Un message s’affiche pour indiquer quel logiciel et quelle version sont en train d’être désinstallés.

  • killalltasks(ensure_list(control.impacted_process)) arrête tous les processus associés au logiciel avant la désinstallation. Cela permet de s’assurer que le logiciel n’est pas utilisé.

  • run(uninstall_cmd(to_uninstall[“key”])) exécute la commande de désinstallation du logiciel. la fonction wait_uninstallkey_absent est utilisée pour s’assurer que la clé est complètement désinstallée pour s’assurer que le logiciel est désinstallé.

3.1.6.4. Tâches de mise à mort (Killing tasks)

Commande killalltasks tue toutes les tâches portant le nom spécifié.

killalltasks('firefox')

3.1.7. Utilisation des champs du fichier de contrôle

Il est possible d’utiliser les informations du fichier de contrôle sur setup.py.

3.1.7.1. Obtenir la version des paquets

def setup():
    print(control['version'])

Commande print(control['version']) affiche la valeur de la version du fichier control.

def setup():
    print(control['version'].split('-',1)[0])

Commande print(control['version'].split('-',1)[0]) affiche le numéro de version du logiciel sans le numéro de version du WAPT à partir du fichier control.

3.1.7.2. Obtenir les noms des titres des logiciels

3.1.8. Gérer un paquet WAPT avec un autre paquet WAPT

3.1.8.1. Installation d’un paquet

WAPT.install('tis-scratch')

La commande install installe un paquet WAPT sur l’ordinateur sélectionné.

3.1.8.2. Suppression d’un paquet

WAPT.remove('tis-scratch')

Commande remove désinstalle un paquet WAPT de l’ordinateur sélectionné.

3.1.8.3. Oubli d’un paquet

WAPT.forget_packages('tis-scratch')

La commande forget_packages informe l’agent WAPT d’oublier un paquet WAPT sur l’ordinateur sélectionné.

Indication

Si le résultat souhaité est de supprimer tis-scratch, vous devez soit réinstaller le paquet (wapt-get install « tis-scratch ») puis le supprimer (wapt-get remove « tis-scratch »), soit le supprimer manuellement à partir du menu du Panneau de configuration Ajouter/supprimer des programmes.

3.2. Améliorer mon paquet

3.2.1. Copier un fichier

Il est possible de configurer Firefox avec un fichier policies.json. Voir https://github.com/mozilla/policy-templates/blob/master/README.md.

Ce fichier DOIT être placé dans le dossier distribution à la racine de Firefox.

Pour vous aider à créer ce fichier policies.json, vous pouvez utiliser le générateur de politique d’entreprise <https://addons.mozilla.org/fr/firefox/addon/enterprise-policy-generator/>`_ pour Firefox.

Lorsque vous avez généré votre fichier policies.json, placez-le dans c:\waptdev\prefix-firefox-esr-wapt\policies.json.

Le dossier distribution à la racine de Firefox peut ne pas exister, nous allons donc tester son existence et le créer avec la commande mkdirs s’il n’existe pas :

if not isdir(r'C:\Program Files\Mozilla Firefox\distribution'):
    mkdirs(r'C:\Program Files\Mozilla Firefox\distribution')

Important

Si vous avez des barres obliques inverses dans votre chemin, vous devez toujours mettre un r devant la chaîne, comme dans l’exemple précédent.

Vous devrez également utiliser la fonction filecopyto pour copier le fichier policies.json :

filecopyto('policies.json',r'C:\Program Files\Mozilla Firefox\distribution')

Indication

Il n’est pas nécessaire d’indiquer le chemin complet du fichier source puisque le fichier policies.json est à la racine du paquetage WAPT, nous utilisons donc le chemin relatif.

Modifiez votre setup.py :

# -*- coding: utf-8 -*-
from setuphelpers import *

uninstallkey = []

def install():
    install_exe_if_needed("Firefox Setup 45.5.0esr.exe",silentflags="-ms",key='Mozilla Firefox 45.5.0 ESR (x64 fr)',min_version="45.5.0")
    remove_desktop_shortcut('Firefox')

    if not isdir(r'C:\Program Files\Mozilla Firefox\distribution'):
        mkdirs(r'C:\Program Files\Mozilla Firefox\distribution')

    filecopyto('policies.json',r'C:\Program Files\Mozilla Firefox\distribution')

Votre paquet est maintenant prêt à appliquer une configuration. Vous pouvez lancer une installation avec PyScripter et valider que le paquet fonctionne selon votre objectif.

Enfin, lancez votre Firefox pour vérifier qu’il fonctionne pour vos utilisateurs.

3.2.2. Désinstallation des versions indésirables

Indication

À chaque étape de ces exemples, vous pouvez effectuer une installation pour tester le résultat.

Dans notre cas, nous voulons désinstaller la version non ESR de Firefox.

Nous allons rechercher les autres logiciels installés sur l’hôte pour vérifier si une version non-esr de Firefox est installée.

Pour reproduire notre exemple, téléchargez et installez la dernière version grand public de Firefox :

  • Pour rechercher une version indésirable de Firefox, nous utiliserons la fonction installed_softwares. Cette fonction renvoie une liste de dictionnaires contenant les propriétés des logiciels :

    print(installed_softwares('Firefox'))
    
    [
       {
     'install_date': '',
       'install_location': 'C:\\Program Files\\Mozilla Firefox',
       'key': 'Mozilla Firefox 78.7.1 ESR (x64 fr)',
       'name': 'Mozilla Firefox 78.7.1 ESR (x64 fr)',
       'publisher': 'Mozilla',
       'system_component': 0,
       'uninstall_string': '"C:\\Program Files\\Mozilla Firefox\\uninstall\\helper.exe"',
       'version': '78.7.1',
       'win64': True
     },
    
       {
      'install_date': '',
        'install_location': 'C:\Program Files (x86)\\Mozilla Firefox',
        'key': 'Mozilla Firefox 79.0 (x86 fr)',
        'name': 'Mozilla Firefox 79.0 (x86 fr)',
        'publisher': 'Mozilla',
        'system_component': 0,
        'uninstall_string': '"C:\Program Files (x86)\\Mozilla Firefox\\uninstall\\helper.exe"',
        'version': '79.0',
        'win64': False
      }
    ]
    
  • Vérifiez le nom de chaque logiciel.

    for uninstall in installed_softwares('Mozilla Firefox'):
        print(uninstall['name'])
    
  • Affiche le nom de chaque logiciel trouvé.

    for uninstall in installed_softwares('Mozilla Firefox'):
        if not 'ESR' in uninstall['name']:
            print(uninstall['name'])
    
  • Afficher le nom de chaque logiciel trouvé qui ne contient pas la chaîne ESR dans son nom et sa clé de désinstallation.

    for uninstall in installed_softwares('Mozilla Firefox'):
        if not 'ESR' in uninstall['name']:
            print(uninstall['name'])
            print('Uninstall ' + uninstall['key'])
    

Nous allons maintenant utiliser une astuce WAPT en utilisant la fonction uninstall_cmd :

  • Install cmd accepte une clé de désinstallation comme argument et envoie la commande à exécuter pour lancer la désinstallation silencieuse.

    for uninstall in installed_softwares('Mozilla Firefox'):
        if not 'ESR' in uninstall['name']:
            print(uninstall['name'])
            print('Uninstall ' + uninstall['key'])
            silent_uninstall = uninstall_cmd(uninstall['key'])
            print('Run ' + silent_uninstall)
    
  • Lancez la désinstallation.

    for uninstall in installed_softwares('Mozilla Firefox'):
        if not 'ESR' in uninstall['name']:
            print(uninstall['name'])
            print('Uninstall ' + uninstall['key'])
            silent_uninstall = uninstall_cmd(uninstall['key'])
            print('Run ' + silent_uninstall)
            run(silent_uninstall)
    

Nous pouvons également désinstaller le service de maintenance de Mozilla :

for uninstall in installed_softwares('MozillaMaintenanceService'):
    run(uninstall_cmd(uninstall['key']))
  • Enfin, modifiez votre setup.py :

    # -*- coding: utf-8 -*-
    from setuphelpers import *
    
    uninstallkey = []
    
    def install():
        #Install firefox if necessary
        install_exe_if_needed("Firefox Setup 45.5.0esr.exe",silentflags="-ms",key='Mozilla Firefox 45.5.0 ESR (x64 fr)',min_version="45.5.0")
    
        #Removal of the firefox shortcut on the all user desktop
        remove_desktop_shortcut('Firefox')
    
        #Creation of the distribution folder if it does not exist
        if not isdir(r'C:\Program Files\Mozilla Firefox\distribution'):
            mkdirs(r'C:\Program Files\Mozilla Firefox\distribution')
    
        #Copy of the policies.json file found at the root of the package in the destination of the distribution folder
        filecopyto('policies.json',r'C:\Program Files\Mozilla Firefox\distribution')
    
        #For each Mozilla Firefox installed
        for uninstall in installed_softwares('Mozilla Firefox'):
            #If the software does not have the word ESR in the name
            if not 'ESR' in uninstall['name']:
                print(uninstall['name'])
                print('Uninstall ' + uninstall['key'])
    
                #Looking for how we can uninstall it silently
                silent_uninstall = uninstall_cmd(uninstall['key'])
                print('Run ' + silent_uninstall)
    
                #We launch the previous command.
                run(silent_uninstall)
    
        #Uninstalling mozilla maintenance service
        for uninstall in installed_softwares('MozillaMaintenanceService'):
            run(uninstall_cmd(uninstall['key']))
    

Votre code gère maintenant la désinstallation des versions indésirables de Firefox.

3.2.3. Amélioration de setup.py pour utiliser des variables

Exemples d’utilisation de variables :

version_firefox = "45.0"

uninstallkey = "Mozilla Firefox " + version_firefox + " ESR (x64 fr)"
print(uninstallkey)

uninstallkey = "Mozilla Firefox %s ESR (x64 fr)" % (version_firefox)
print(uninstallkey)

uninstallkey = "Mozilla Firefox {} ESR (x64 fr)".format(version_firefox)
print(uninstallkey)

uninstallkey = f"Mozilla Firefox {version_firefox} ESR (x64 fr)"
print(uninstallkey)

Important

Le dernier exemple est le meilleur, mais cette opération ne fonctionne qu’avec Python3.

Nous pouvons maintenant utiliser des variables dans notre setup.py :

# -*- coding: utf-8 -*-
from setuphelpers import *

uninstallkey = []

def install():

    version_firefox = "45.5.0"

    #Install firefox if necessary
    install_exe_if_needed("Firefox Setup %sesr.exe" % version_firefox,silentflags="-ms",key='Mozilla Firefox %s ESR (x64 fr)' % version_firefox,min_version=version_firefox)

    #Removal of the firefox shortcut on the all user desktop
    remove_desktop_shortcut('Firefox')

    distribution_folder=r'C:\Program Files\Mozilla Firefox\distribution'

    #Creation of the distribution folder if it does not exist
    if not isdir(distribution_folder):
        mkdirs(distribution_folder)

    ... The rest of the code does not change ...

Indication

Vous pouvez récupérer le numéro de version indiqué dans le fichier control comme suit :

version_firefox = control.get_software_version()

3.2.4. Personnaliser l’environnement de l’utilisateur

Il est parfois nécessaire de personnaliser un logiciel dans le contexte de l’utilisateur pour définir des paramètres spécifiques ou pour se conformer aux règles et préférences de l’Organisation :

  • Création d’un raccourci vers le bureau de l’utilisateur avec des arguments spécifiques.

  • Modifier les clés du registre Windows de l’utilisateur.

  • Modifier les fichiers, les paramètres du navigateur de l’utilisateur.

  • Configurer des raccourcis vers l’ensemble des modèles de documents, de feuilles de calcul ou de présentations de l’organisation dans les suites Office afin d’encourager ou de garantir le respect des lignes directrices éditoriales et graphiques.

  • Configuration du courrier électronique ou de la messagerie instantanée de l’utilisateur à partir du principal référentiel de données utilisateur de l’organisation (annuaire LDAP, base de données, etc.).

  • Personnalisation d’une suite bureautique ou d’un logiciel d’entreprise sur la base du principal référentiel de données utilisateur de l’organisation (annuaire LDAP, base de données, etc.).

La fonction session_setup bénéficie de la puissance de python pour atteindre un haut niveau d’automatisation.

3.2.4.1. Principes de session_setup

La fonction WAPT session_setup est exécutée pour chaque utilisateur :

C:\Program Files (x86)\wapt\wapt-get.exe session-setup ALL

L’appel de cette fonction exécute le script session_setup défini dans chaque paquetage WAPT installé sur l’ordinateur.

L’agent WAPT stocke dans sa base de données locale (C:\Program Files (x86)\wapt\waptdb.sqlite) les jeux d’instructions de tous les paquets WAPT.

Attention

Le script session_setup n’est lancé qu’une fois par version du paquet WAPT et par utilisateur.

L’agent WAPT stocke dans sa base de données locale %appdata%\wapt\waptsession.sqlite les instances des scripts session_setup qui ont déjà été jouées.

Exemple de sortie de wapt-get session-setup ALL :

Note

L’utilisateur connecté session_setup a déjà été lancé précédemment.

wapt-get session-setup ALL

Configuring tis-7zip ... No session-setup. Done
Configuring tis-ccleaner ... Already installed. Done
Configuring tis-vlc ... No session-setup. Done
Configuring tis-tightvnc ... No session-setup. Done
Configuring tis-paint.net ... No session-setup. Done
Configuring wsuser01.mydomain.lan ... No session-setup. Done

3.2.4.2. Utilisation de session_setup

Les scripts session_setup sont situés dans la section def session_setup() du fichier setup.py :

Exemple :

def session_setup():
  registry_setstring(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows Live\\Common",'TOUVersion','16.0.0.0', type=REG_SZ)

Attention

Avec session_setup, il n’est pas possible d’appeler les fichiers contenus dans le paquet WAPT.

Pour appeler des fichiers externes lors de la désinstallation, copiez et collez les fichiers nécessaires dans un dossier externe pendant le processus d’installation du paquet (exemple : c:Ncachefile).

3.2.4.3. Exemple : création d’un raccourci personnalisé sur le bureau

L’une des possibilités offertes par Setuphelpers est d’ajouter des raccourcis personnalisés sur les bureaux des utilisateurs, au lieu d’un raccourci commun à tous les utilisateurs.

Pour cela, nous utiliserons la fonction create_user_desktop_shortcut() pour créer des raccourcis contenant le nom d’utilisateur et passant un site web comme argument à Firefox.

# -*- coding: utf-8 -*-
from setuphelpers import *

uninstallkey = []

def install():
    install_exe_if_needed("Firefox Setup 45.5.0esr.exe",silentflags="-ms",key='Mozilla Firefox 45.4.0 ESR (x64 fr)',min_version="45.5.0")

def session_setup():
  create_user_desktop_shortcut("Mozilla Firefox de %s" % get_current_user(),r'C:\Program Files\Mozilla Firefox\firefox.exe',arguments="-url https://tranquil.it")
  • Lancez maintenant la session-setup directement depuis PyScripter.

    PyScripter - Exécution de l'installation de la session

    PyScripter - Exécution de l’installation de la session

  • Enfin, vérifiez que l’icône est bien présente sur le bureau.

3.2.5. Utilisation des fonctions d’audit pour la conformité

Note

Cette fonctionnalité est disponible dans la version Enterprise.

La fonction d’audit permet d’effectuer des contrôles réguliers des configurations des postes de travail et de centraliser les résultats de ces contrôles dans la console WAPT. Cette fonction vous permet de vous assurer que votre base installée d’hôtes correspond à votre ensemble de règles de conformité au fil du temps.

Par exemple, vous pouvez :

  • Vérifier régulièrement la liste des administrateurs locaux sur les ordinateurs de bureau.

  • S’assurer au fil du temps de la bonne configuration d’un logiciel critique.

  • Vérifier régulièrement la présence de la bonne version d’un logiciel.

  • Vérifier les paramètres de sécurité d’un poste de travail.

La fonction audit bénéficie de la profondeur et de l’étendue des bibliothèques python pour des niveaux inégalés de précision et de finesse pour vos besoins d’audit.

3.2.5.1. Principe de fonctionnement

Les tâches audit sont lancées une fois après chaque wapt-get upgrade, puis régulièrement comme défini par l’attribut audit_schedule.

Pour lancer manuellement un contrôle d’audit, vous pouvez également utiliser la commande suivante :

wapt-get audit

Note

Par défaut, la fonction audit ne sera pas lancée si l’audit n’est pas nécessaire.

Pour forcer l’exécution, vous pouvez lancer la commande suivante :

wapt-get audit -f

Le script audit est défini dans le setup.py du paquet avec une fonction def audit() :

Dans cet exemple, nous améliorons le paquet Firefox étudié précédemment dans cette documentation.

  • Ajoutez la fonction audit dans le setup.py.

    def audit():
        if isfile(r'C:\Program Files\Mozilla Firefox\distribution\policies.json'):
            print('File policies.json found')
            return "OK"
        else:
            print('File policies.json not found')
            return "ERROR"
    
  • Lancez l’audit à partir de PyScripter.

    PyScripter - Exécuter un audit
  • Testez avec le fichier puis supprimez le fichier C:\Program Files\Mozilla Firefox\distribution\policies.json et testez à nouveau avec PyScripter.

Vous pouvez voir directement le statut de l’audit dans la console WAPT (Cliquez sur le paquet puis sur la colonne audit) :

Vérification du statut d'un audit dans la console WAPT

Vérification du statut d’un audit dans la console WAPT

La fonction d’audit renvoie l’une de ces trois valeurs :

  • OK;

  • WARNING;

  • ERROR.

Attention

Avec la fonction audit, il n’est pas possible d’utiliser les fichiers contenus dans les paquets WAPT.

Pour utiliser les fichiers intégrés dans le paquet WAPT qui seront utilisés pour un audit, vous DEVEZ donner l’instruction de copier le(s) fichier(s) dans un dossier temporaire lors de l’installation du paquet WAPT.

3.2.5.2. Planification d’un audit

Les tâches audit sont lancées une fois après chaque mise à jour, puis régulièrement comme défini avec la valeur audit_schedule.

La valeur est contenue dans le fichier control du paquet WAPT.

Par défaut, si audit_schedule est vide, la tâche d’audit peut être lancée manuellement depuis la console WAPT ou automatiquement si vous avez défini l’option waptaudit_task_period dans le wapt-get.ini de l’agent WAPT. Pour plus d’informations sur cette dernière méthode, veuillez consulter cette documentation.

Dans le cas contraire, la périodicité peut être indiquée de plusieurs manières :

  • Un nombre entier (en minutes).

  • Un nombre entier suivi d’une lettre (m = minutes, h = heures, d = jours, w = semaines).

3.2.5.3. Comportement par défaut de la fonction d’audit

Par défaut, la seule fonction d’audit vérifie la présence de UninstallKey pour son paquet WAPT.

De cette manière, WAPT s’assure que le logiciel est toujours présent sur l’hôte, conformément à la configuration de l’hôte.

3.2.6. L’audit des configurations pour assurer la conformité

Note

Cette fonctionnalité est disponible dans la version Enterprise.

La fonction audit_data permet d’effectuer des vérifications régulières des configurations de bureau et de centraliser les résultats de ces vérifications dans la console WAPT. Il y a une historisation et vous pouvez crypter vos données et les décrypter avec votre certificat WAPT.

Par exemple, vous pouvez :

  • Modifier le mot de passe d’un administrateur, crypter des informations et les afficher sur la console WAPT.

  • Vérifiez régulièrement les modifications dont votre ordinateur a besoin, comme l’inventaire CVE ou GLPI.

  • Vérifier les paramètres de sécurité d’un poste de travail et faire l’historique des problèmes.

    La fonction audit_data n’est utilisable que dans la fonction audit.

3.2.6.1. Principe de fonctionnement

Les fonctions audit_data sont lancées si elles sont définies dans la section def audit() du fichier setup.py.

On the server side, audit data is stored in the HostAuditData table. The content of the table can be queried using the Reporting tab in the WAPT Console. The Data is automatically purged according to expiration date. When WAPT host update_status() is launched, the newer audit data is sent to the WAPT Server.

Côté client, les données d’audit sont stockées dans la base de données hôte avec une date d’expiration (date_expiration) et le nombre maximum (max_count) des données stockées est défini dans le code.

Dans cet exemple, nous vérifions l’IP publique de l’ordinateur.

  • Ajoutez la fonction audit_data à l’intérieur de la fonction audit dans le setup.py.

    def audit():
      ip = wgets('https://api.ipify.org',verify_cert=False)
      print(f'My public IP address is: {ip}')
      WAPT.write_audit_data_if_changed('Public IP','log for %s' % get_computername(),ip,max_count=5)
      return 'OK'
    

Voici les fonctions liées à audit_data :

def write_audit_data_if_changed(self, section, key, value, ptype=None, value_date=None, expiration_date=None, max_count=2, keep_days=None):
"""Write data only if different from last one
"""
def write_audit_data(self, section, key, value, ptype=None, value_date=None, expiration_date=None, max_count=2, keep_days=None):
"""Stores in database a metrics, removes expired ones

    Args:
        section (str)
        key (str)
        value (any)
        value_date
        expiration_date (str) : expiration date of the new value
        max_count (int) : keep at most max_count value. remove oldest one.
        keep_days (int) : set the expiration date to now + keep_days days. override expiration_date arg if not None

    Returns:
        None
"""
def read_audit_data(self, section, key, default=None, ptype=None):
    """Retrieve the latest value associated with section/key from database"""

def read_audit_data_set(self, section, key):
    """Retrieve all the values associated with section/key from database"""

def delete_audit_data(self, section, key):

def read_audit_data_since(self, last_query_date=None):
    """Retrieve all the values since a date from database"""

3.2.7. Mise à jour automatique d’un logiciel

Note

Cette partie de la documentation s’adresse aux utilisateurs avancés de WAPT.

Les fonctions update_package sont très pratiques, elles permettent de gagner beaucoup de temps lorsqu’il s’agit de mettre à jour un paquet WAPT avec la version la plus récente d’un logiciel.

3.2.7.1. Principe de fonctionnement

La fonction update_package va :

  • Obtenir en ligne la dernière version du logiciel.

  • Télécharger la dernière version des binaires du logiciel.

  • Supprimer les anciennes versions des binaires du logiciel.

  • Mettez à jour le numéro de version du logiciel dans le fichier control.

Si vous basez votre fonction install sur le numéro de version contenu dans le fichier control, alors vous n’avez même pas besoin de modifier votre fichier setup.py.

Vous n’avez qu’à faire vos tests habituels d’assurance qualité avant de build-upload votre nouveau paquet.

3.2.7.2. Exemple

Voici le script update_package pour firefox-esr comme exemple :

def update_package():
      import re,requests,glob

      #Retrieving the last file name
      url = requests.head('https://download.mozilla.org/?product=firefox-esr-latest&os=win64',proxies={}).headers['Location']
      filename = url.rsplit('/',1)[1].replace('%20',' ')

      #download of it if is not in the package
      if not isfile(filename):
          print('Downloading %s from %s'%(filename,url))
          wget(url,filename)

      #removing old exe with wrong name
      for fn in glob.glob('*.exe'):
          if fn != filename:
              remove_file(fn)

      # updates control version from filename, increment package version.
      control.version = '%s-0'%(re.findall('Firefox Setup (.*)esr\.exe',filename)[0])
      control.save_control_to_wapt()

Vous pouvez lancer le update_package dans PyScripter :

PyScripter - Exécuter une mise à jour du paquet-source

PyScripter - Exécuter une mise à jour du paquet-source

Vous trouverez de nombreux exemples inspirants de scripts update_package dans les paquets hébergés dans le Tranquil IT store.

3.2.8. Déployer un logiciel portable avec WAPT

Un bon exemple de paquet WAPT est un paquet logiciel autonome/ portable :

  • Créez le dossier du logiciel dans C:\Program Files (x86).

  • Copiez le logiciel dans ce dossier.

  • Créer le raccourci vers l’application.

  • Gérer le processus de désinstallation de l’application.

  • Fermez l’application si elle est en cours d’exécution.

3.2.8.1. Exemple avec ADWCleaner

Tout d’abord, téléchargez Adwcleaner.

Vous pouvez ensuite générer votre modèle de paquet, veuillez vous référer à la documentation pour la création de paquets depuis la console WAPT.

Le fichier C:\waptdev\tis-adwcleaner-wapt sont créés.

Vous trouverez ici un exemple de paquet portable qui reprend presque toutes les fonctions WAPT d’un setup.py :

from setuphelpers import *

uninstallkey = []

exe_name = 'AdwCleaner.exe'
path_adw = makepath(programfiles,'AdwCleaner')
path_exe = makepath(path_adw,exe_name)
nameshortcut = 'AdwCleaner'

def install():
    mkdirs(path_adw)
    filecopyto(exe_name,path_exe)
    create_desktop_shortcut(nameshortcut,path_exe)

def uninstall():
    remove_tree(path_adw)
    remove_desktop_shortcut(nameshortcut,path_exe)

def audit():
    if not isfile(path_exe):
        print('File not found')
        return "OK"
    else:
        print('File Found')
        return "ERROR"

def update_package():
    wget('https://downloads.malwarebytes.com/file/AdwCleaner',exe_name)
    control.version = get_file_properties(exe_name)['FileVersion'] + '-0'
    control.save_control_to_wapt()

3.2.9. Ensemble des paquets .msu de Windows Update

Indication

Pré-requis : pour construire des paquets WAPT, l’environnement de développement WAPT DOIT être installé.

Entre les versions du Patch Tuesday, Microsoft peut publier des KB supplémentaires ou des mises à jour critiques qui devront être transmises rapidement aux hôtes.

À cette fin, WAPT fournit un modèle de paquet pour les fichiers .msu.

Dans cet exemple, nous utilisons la KB4522355 téléchargée depuis le site web du catalogue Microsoft.

  • Téléchargez le paquet KB4522355 MSU à partir du site Web du catalogue Microsoft.

  • Create a WAPT package template from the downloaded .msu file. In the WAPT Console, click on Tools ‣ Package Wizard.

    PyScripter - Fenêtre de la console WAPT pour la création d'un modèle de paquetage

    PyScripter - Fenêtre de la console WAPT pour la création d’un modèle de paquetage

  • Sélectionnez le paquet .msu téléchargé et remplissez les champs requis.

    Informations nécessaires à la création du paquet MSU

    Informations nécessaires à la création du paquet MSU

  • Cliquez sur Make and edit (recommandé) pour lancer la personnalisation du paquet.

  • L’IDE du paquet WAPT est lancé en utilisant le code source du modèle prédéfini .msu.

  • Comme d’habitude avec les paquets WAPT, testez, puis construisez, puis signez, puis téléchargez et enfin affectez les paquets WAPT souhaités à vos hôtes sélectionnés et c’est fait !

  • Si le KB est inclus dans le Patch Tuesday suivant, vous pouvez sélectionner les hôtes sur lesquels le package a été appliqué et oublier le package KB sur les hôtes.

3.2.10. Ensemble de paquets Linux simples

Avant de commencer, nous supposons plusieurs conditions :

  • Vous disposez d’une interface graphique sur votre système Linux que vous utilisez pour développer et tester des paquets.

  • Vous avez installé le paquet vscode depuis le dépôt Tranquil IT.

  • Votre utilisateur s’appelle linuxuser et est membre du groupe sudoers.

3.2.10.1. Création d’un modèle de base à partir de votre ordinateur linux

  • Démarrer un utilitaire de ligne de commande.

  • En tant qu”utilisateur Linux, créez un modèle de paquet WAPT.

    wapt-get make-template <template_name>
    

    Avertissement

    Ne lancez pas cette commande en tant que root ou avec un sudo.

    Lorsque vous créez un modèle, il y a plusieurs fichiers dans le dossier .vscode à l’intérieur du dossier WAPT :

    • settings.json;

    • launch.json.

    Exemple avec VLC :

    wapt-get make-template "tis-vlc"
    
    Using config file: /opt/wapt/wapt-get.ini
    Template created. You can build the WAPT package by launching
    /opt/wapt//wapt-get.py build-package /home/linuxuser/waptdev/tis-vlc-wapt
    You can build and upload the WAPT package by launching
    /opt/wapt//wapt-get.py build-upload /home/linuxuser/waptdev/tis-vlc-wapt
    

    Indication

    Tous les paquets WAPT sont stockés dans le home de linuxuser (home de l’utilisateur actuellement connecté).

  • VSCode se charge et ouvre le projet de paquetage WAPT.

Ouverture de VSCode avec focus sur le fichier *setup*

Ouverture de VSCode avec focus sur le fichier setup

  • Vérifier le contenu du fichier control.

    Vous devez donner un description au paquet WAPT, définir le os_target et le version du paquet WAPT.

    Indication

    os_target pour unix est linux.

    Avertissement

    Le numéro de version du logiciel dans votre fichier control DOIT commencer à 0, et non le numéro de version du titre du logiciel, car le numéro de version peut ne pas être le même que celui affiché dans le dépôt DEB / YUM.

    • Fichier original control.

      package           : tis-vlc
      version           : 0-0
      architecture      : all
      section           : base
      priority          : optional
      maintainer        : user
      description       : automatic package for vlc
      
    • Fichier control modifié.

      package           : tis-vlc
      version           : 0
      architecture      : all
      section           : base
      priority          : optional
      maintainer        : Tranquil-IT Systems
      description       : VLC for linux
      target_os         : linux
      min_wapt_version  : 1.8
      

    Note

    Il convient de noter qu’une sous-version -1 a été ajoutée. Il s’agit de la version d’emballage du paquet WAPT.

    Il permet au développeur du paquet WAPT de publier plusieurs versions du même logiciel, ce qui est très utile pour un développement rapide et itératif.

  • Modifiez le code dans le fichier setup.py en conséquence.

    :emphasize-lines: 8
    # -*- coding: utf-8 -*-
    from setuphelpers import *
    
    uninstallkey = []
    
    def install():
        apt_install('vlc')
    
  • Sauvegarder le paquet.

3.2.10.2. Gestion de la désinstallation

  • Modifier le fichier setup.py lors d’une désinstallation.

def uninstall():
apt_remove('vlc')
  • Lancer un remove à partir du VSCode Run Configurations.

    Après la désinstallation, le logiciel est correctement supprimé

    Après la désinstallation, le logiciel est correctement supprimé

  • Vérifiez que le logiciel a été correctement supprimé.

    dpkg -l | grep vlc
    

Indication

Dans la fonction uninstall(), il n’est pas possible d’appeler les fichiers inclus dans le paquet WAPT. Pour appeler les fichiers du paquetage, il est nécessaire de copier/coller les fichiers dans un répertoire temporaire lors de l’installation du paquetage.

3.2.10.3. Gestion de la configuration de la session

  • Modifier le fichier setup.py avec un session-setup ;

    Dans cet exemple, nous allons créer un fichier vlcrc par défaut dans le profil de l’utilisateur.

    def session_setup():
      vlcrc_content="""[qt] # Qt interface
    qt-notification=0
    qt-privacy-ask=0
    metadata-network-access=0
    """
    
      vlcdir = os.path.join(os.environ['HOME'], '.config', 'vlc')
      path_vlrc = makepath(vlcdir,'vlcrc')
      ensure_dir(vlcdir)
      if not isfile(path_vlrc):
          with open(makepath(vlcdir,'vlcrc')) as f:
              f.write(vlcrc_content)
    
  • Lancer une session-setup à partir du VSCode Run Configurations.

    Après la désinstallation, le logiciel est correctement supprimé

    Après la désinstallation, le logiciel est correctement supprimé

3.2.10.4. Construire et télécharger le paquet WAPT

Vous trouverez le paquet WAPT dans votre dossier ~/waptdev.

Vous devez transférer le dossier des paquets WAPT vers l’hôte Windows qui possède la clé privée que vous utilisez pour signer vos paquets WAPT.

Dans ce cas, veuillez vous référer à la documentation pour construire et télécharger des paquets depuis la console WAPT.

3.2.11. Cryptage des données sensibles contenues dans un paquet WAPT

Note

Cette partie de la documentation s’adresse aux utilisateurs avancés de WAPT.

Cette fonction n’est disponible que dans la version Enterprise.

3.2.11.1. Quel est l’objectif de cette démarche ?

Avec WAPT, l’intégrité du paquet est assurée. Un paquet dont le contenu a été modifié sans être re-signé sera systématiquement refusé par le client WAPT.

En revanche, le contenu d’un paquet WAPT n’est pas crypté et sera lisible par tous. Ce modèle technique de transparence apporte néanmoins de nombreux avantages.

Cela peut être gênant dans le cas d’un paquet contenant un mot de passe, une clé de licence ou toute autre donnée sensible ou confidentielle.

Heureusement, nous avons une solution !

3.2.11.2. Principe de fonctionnement

Lorsqu’un agent WAPT s’enregistre auprès du serveur WAPT, il génère une paire clé privée/certificat public dans C:\Program Files (x86)\wapt\private.

  • Le certificat est envoyé au serveur WAPT avec l’inventaire lorsque le client WAPT est enregistré pour la première fois.

  • La clé privée est conservée par l’agent et n’est lisible que localement par les Administrateurs locaux.

Nous allons donc crypter les données sensibles contenues dans le paquet avec le certificat appartenant à l’hébergeur.

Lors de l’installation, l’agent WAPT sera en mesure de décrypter les données sensibles à l’aide de sa clé privée.

Dans ce mode de fonctionnement, le serveur WAPT et les référentiels secondaires n’ont pas connaissance des données sensibles.

3.2.11.3. Cas pratique

Vous trouverez ici un exemple de paquet WAPT dans lequel nous cryptons une chaîne de texte dans une fonction update_package et décryptons ensuite ce texte dans la fonction install.

Dans cet exemple, la fonction update_package nous permet de parcourir la base de données du serveur WAPT pour récupérer le certificat de chaque hôte, puis de crypter le texte sensible avec ce certificat.

Le texte crypté pour chaque hôte est alors stocké dans un fichier encrypt-txt.json à la racine du paquetage WAPT.

Lorsque le paquet WAPT est installé, l’agent WAPT prend le texte crypté et le déchiffre à l’aide de sa propre clé privée.

Vous pouvez le tester par vous-même en téléchargeant le paquet d’exemple tis-encrypt-sample.

Attention

La sortie python (journal d’installation du paquet WAPT) est lisible par les utilisateurs sur l’hôte, donc vous ne devriez pas afficher le texte déchiffré avec une impression pendant l’installation.