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.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.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 .
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¶
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é
¶
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 lesetup.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.
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¶
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é
¶
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 fonctionaudit
.
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 fonctionaudit
dans lesetup.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¶
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
.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¶
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¶
Vérifier le contenu du fichier
control
.Vous devez donner un
description
au paquet WAPT, définir leos_target
et leversion
du paquet WAPT.Indication
os_target
pour unix est linux.Avertissement
Le numéro de
version
du logiciel dans votre fichiercontrol
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é¶
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 unsession-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é¶
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.
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.
3.2.12. Importer une tâche planifié dans un paquet WAPT¶
WAPT fonctionne souvent sur le principe de la récurrence, de sorte qu’une action telle qu’un audit est exécutée régulièrement (toutes les deux heures par défaut). Toutefois, cette récurrence n’est pas aussi précise qu’un ordre indiquant que l’action doit être exécutée tous les jours à 19h00 précises. Si vous souhaitez effectuer une action dans un contexte très précis, nous vous suggérons d’intégrer une tâche planifiée dans un paquet WAPT.
3.2.12.1. Créer une tâche planifiée¶
Etape 1 : Lancer le planificateur de tâche
Ouvrez le Planificateur de tâches en recherchant « Planificateur de tâches » dans le menu Démarrer.
Cliquer sur « créer une tâche » dans le panneau de droite.
Étape 2 : Configurer la tâche
Général:
Nommer votre tâche.
Sélectionner l’utilisateur SYSTEM.
Cocher « lancer avec les plus haut privilèges ».
Déclencheurs :
Configurez les déclencheurs en fonction de vos besoins (par exemple, tous les jours à 19h00).
Actions:
Ajoutez les actions que la tâche doit effectuer (par exemple, lancer C:NProgram Files(x86)Nwaptexit.exe).
Étape 3 : Exporter la tâche
Une fois la tâche configurée, cliquez sur « OK » pour l’enregistrer.
Cliquez avec le bouton droit de la souris sur la tâche dans la bibliothèque du planificateur de tâches et sélectionnez « Exporter ».
Enregistrer la tâche au format
filename.xml
.
3.2.12.2. Création d’un paquet Intégration d’une tâche planifiée¶
Étape 1 : Créer un modèle de paquet
Allez dans la console WAPT et accédez à l’onglet WAPT Packages.
Générer un modèle de paquet en sélectionnant
.
Étape 2 : Ajouter le fichier XML
Placez le fichier exporté
filename.xml
à la racine du paquet.
Étape 3 : Configuration du script d’installation
Ouvrez le fichier
setup.py
du paquet.Ajoutez le code suivant, en adaptant le nom de la tâche et le nom du fichier XML :
# -*- coding: utf-8 -*-
from setuphelpers import *
def install():
run('schtasks /CREATE /RU SYSTEM /TN taskname /xml filename.xml')
def uninstall():
run('schtasks /DELETE /TN taskname /F')
Si vous souhaitez planifier une tâche pour un paquet wapt, vous pouvez consulter Déclencher l’utilitaire WAPT Exit avec une tâche planifiée pour plus de détails.
3.2.13. Infrastructure as Code avec les Meta-Paquets¶
La mise en œuvre de Infrastructure as Code (IaC) vous permet de gérer et d’approvisionner votre infrastructure par le biais du code, plutôt que par des processus manuels. Un moyen efficace d’y parvenir est d’utiliser des méta-packages. Un méta-paquet est un paquet unique qui intègre tous les composants nécessaires et effectue des actions basées sur un script. Cette approche rationalise le déploiement et la gestion des logiciels sur différentes machines.
Exemples de méta-paquet :
Installation de logiciels en fonction de l’adresse IP: Vous pouvez cibler toutes les machines dont l’adresse IP commence par 10.10 pour installer un logiciel spécifique.
Cibler les machines d’une unité organisationnelle (OU): Vous pouvez vous concentrer sur toutes les machines d’une OU particulière pour installer certains paquets. Par exemple, vous pourriez vouloir installer un logiciel spécifique sur toutes les machines Debian d’une OU particulière.
Exemple de scripts :
Exemple 1 : Installation basé sur le Chassis Type de la machine
def install():
chassis_types = run_powershell('(Get-WmiObject -Class Win32_SystemEnclosure).ChassisTypes')
if type(chassis_types) != list:
chassis_types = [chassis_types]
nomads_types = [8, 9, 10, 12, 14, 18, 21, 24, 30, 31, 32]
if any(chassis_type in nomads_types for chassis_type in chassis_types):
print("Installing nomads configuration")
WAPT.install("tis-nomads-wua-conf")
else:
print("Installing desktop configuration")
WAPT.install("tis-desktop-wua-conf")
Exemple 2 : Exclure certaines machines spécifique
# -*- coding: utf-8 -*-
from setuphelpers import *
def install():
# Do not install the package tis-package on the following machines
excluded_machines = ['machine25.mydomain.lan', 'machine36.mydomain.lan']
if not get_fqdn() in excluded_machines:
WAPT.install('tis-package')
Exemple 3 : Installation basé sur la plateforme de la machine
if host_info()['platform'] == 'Windows':
WAPT.install('tis-package-for-windows')
Exemple 4 : Conditions d’installation d’un CAB en fonction des versions de Windows.
from setuphelpers import *
def install():
#Installation of the KB5062552 if I am on a Windows 11 22H2 below (10.0.22621.5624) or on a Windows 11 23H2 below (10.0.22631.5624).
version_de_mon_windows = windows_version()
if version_de_mon_windows > WindowsVersions.Windows11 :
#Retrieve the pretty version of the Windows version.
pretty_name = host_info()['windows_version_prettyname']
#Construction of the expected version based on the Windows version (name).
dict_version_pretty_name = {'22H2':"10.0.22621.5624",'23h2': "10.0.22631.5624"}
#If we are on Windows 22H2 or 23H2.
if pretty_name in dict_version_pretty_name:
#calculate the expected Windows version.
expected_version = dict_version_pretty_name[pretty_name]
#If we are not on the expected version, then we install the KB5062552 package.
if Version(version_de_mon_windows) < Version(expected_version):
WAPT.install('mi-kb5062552')
Exemple 5 : Installer 7zip si une version vulnérable est présente dans l’inventaire des logiciels.
from setuphelpers import *
def install():
#Install 7zip if 7zip is already installed and its version is below 24.07.
need_install_7zip = False
for u in installed_softwares('7-zip'):
if Version(u['version']) < Version('24.07'):
need_install_7zip = True
if need_install_7zip:
WAPT.install('tis-7zip')
En utilisant des méta-packages et des scripts, vous pouvez automatiser et rationaliser le déploiement de logiciels dans votre infrastructure, ce qui le rend plus efficace et moins sujet aux erreurs.