Package: windows-tools.signtool
windows_toolsCollection of useful python functions around Microsoft Windowswindows_tools is a set of various recurrent functions amongstantivirus: antivirus state and list of installed AV enginesbitlocker: drive encryption status and protector key retrievalbitness: simple bitness identificationfile_utils: file ownership handling, NTFS & ReFS ACL handling, file listing with permission fixesimpersonate: python Runas implementationinstalled_software: list of installed software from registry, 32 and 64 bitslogical_disk: logical disk listingmisc: basic time related functions to convert windows ticks into epoch / date stringsoffice: microsoft Office version identification, works for click & run, O365 and legacypowershell: powershell wrapper to identify interpreter and run scripts or commandsproduct_key: windows product key retrievalregistry: registry 32 and 64 bit APIsecurityprivilege: enable / disable various security privileges for userserver: windows server identificationsigntool: Easily sign executables with Authenticodeupdates: get all installed windows updates based on COM, WMI and registry retrieval methodsusers: user lookup for SID/PySID/usernamevirtualization: virtualization platform identification for guestwindows_firewall: windows firewall state retrievalwmi_queries: windows WMI query wrapper, wmi timezone convertersIt is compatible with Python 3.5+ and is tested on Windows only (obviously).SetupYou may install the wholewindows_toolspackage or any subpackage using the following commandspip install windows_tools
pip install windows_tools.<subpackage>UsageantivirusThe antivirus package tries to list installed Antivirus products via the SecurityCenter API (using WMI calls).
Since SecurityCenter API does not exist on Windows Servers, we also need to check for installed antivirus software using the uninstall registry keys.
These checks are more fuzzy, but allow to detect the following products:avastaviraavg technologiesbitdefenderdr webesetf-secureg data softwarekasperskymcafeepanda securitysophostrend micromalwarebytesvipresentinel oneOn top of that list, it will detect any installed software containing "antivirus/antiviral/antimalware" in the name.Please report back if your antivirus is not detected, so we can improve the fuzzy detection here.Usageimport windows_tools.antivirus

result = windows_tools.antivirus.get_installed_antivirus_software()resultwill contain a list of dict like[{
        'name': 'Windows Defender',
        'version': None,
        'publisher': None,
        'enabled': False,
        'is_up_to_date': True,
        'type': 'Windows Defender / Security Essentials'
    }, {
        'name': 'Malwarebytes version 4.4.6.132',
        'version': '4.4.6.132',
        'publisher': 'Malwarebytes',
        'enabled': None,
        'is_up_to_date': None,
        'type': None
    }
]WarningKeysenabled,is_up_to_dateandtypeare only filled via securityCenter API*.
Keysversionandpublisherare only filled via installed software list.
The only guaranteed filled key will always benamebitlockerBitlocker can only work on NTFS or ReFS formatted disks.
Bitlocker keys can only be retrieved on local disks.Usageimport windows_tools.bitlocker

result = windows_tools.bitlocker.get_bitlocker_full_status()resultwill contain a dict as follows containing raw strings frommanage-bdewindows tool:{
	'C:': {
		'status': 'Chiffrement de lecteur BitLocker\xa0: outil de configuration version 10.0.19041\nCopyright (C) 2013 Microsoft Corporation. Tous droits réservés.\n\nVolume C: [Windows ]\n[Volume du système d?exploitation]\n\n    Taille :                     855,14 Go\n    Version de BitLocker :       Aucun\n    État de la conversion :      Intégralement déchiffré\n    Pourcentage chiffré :        0,0%\n    Méthode de chiffrement :     Aucun\n    État de la protection\xa0:      Protection désactivée\n    État du verrouillage :       Déverrouillé\n    Champ d?identification :     Aucun\n    Protecteurs de clés :        Aucun trouvé\n\n', 
		'protectors': None
	},
	'D:': {
		'status': 'Chiffrement de lecteur BitLocker\xa0: outil de configuration version 10.0.19041\nCopyright (C) 2013 Microsoft Corporation. Tous droits réservés.\n\nVolume D: [Étiquette inconnue]\n[Volume de données]\n\n    Taille :                     Inconnu Go\n    Version de BitLocker :       2.0\n    État de la conversion :      Inconnu\n    Pourcentage chiffré :        Inconnu%\n    Méthode de chiffrement :     XTS-AES 128\n    État de la protection\xa0:      Inconnu\n    État du verrouillage :       Verrouillé\n    Champ d?identification :     Inconnu\n    Déverrouillage automatique : Désactivé\n    Protecteurs de clés\xa0:\n        Password\n        Mot de passe numérique\n\n',
		'protectors': 'Chiffrement de lecteur BitLocker\xa0: outil de configuration version 10.0.19041\nCopyright (C) 2013 Microsoft Corporation. Tous droits réservés.\n\nVolume D: [Étiquette inconnue]\nTous les protecteurs de clés\n\n    Password :\n      ID : {SOMEPASS-WORD-ICAN-NNOT-REMEMBERWELL}\n\n    Mot de passe numérique :\n      ID : {SOMEPASS-GUID-ICAN-NNOT-REMEMBERWELL}\n\n'
	}
}You may parse those or simply pretty print since print will not interpret special characters from a dict or multiple variables at once:result = windows_tools.bitlocker.get_bitlocker_full_status()


result = get_bitlocker_full_status()
for drive in result:
    for designation, content in result[drive].items():
        print(designation, content)Warningbitlocker needs to be run as admin.
Running as non administrator will produce the following logsDon't have permission to get bitlocker drive status for C:.
Don't have permission to get bitlocker drive protectors for C:.
Don't have permission to get bitlocker drive status for D:.
Don't have permission to get bitlocker drive protectors for D:.Output shall be{
    'C:': {
        'status': None,
        'protectors': None
    },
    'D:': {
        'status': None,
        'protectors': None
    }
}You can check that you have administrator rights withwindows_utils.usersmodulebitnessfile_utilsimpersonateinstalled_softwarelogical_diskmiscofficepowershellproduct_keyregistrysecurityprivilegeserversigntoolsigntool is designed to make the windows executable signature as simple as possible.Once the Windows SDK is installed on your machine, you can sign any executable with the following commands:from windows_tools.signtool import SignTool
signer = SignTool()
signer.sign(r"c:\path\to\executable", bitness=64)Note that current versions ofsigntool.exethat come with Windows 10 SDK automagically detect hardware EV certificate tokens like Safenet.When using former certificate files in order to sign an executable, one should use the following syntax:from windows_tools.signtool import SignTool
signer = SignTool(certificate=r"c:\path\to\cert.pfx", pkcs12_password="the_certificate_file_password")
signer.sign(r"c:\path\to\executable", bitness=64)If the wrong certificate is used to sign, please opencertmgr.msc, go to Private > Certificates and remove the certificate you don't want.updatesWindows updates can be retrieved via a COM object that talks to Windows Update service, via WMI requests or via registry entries.
All methods can return different results, so they are combined into one function.Usageimport windows_tools.updates

result = windows_tools.updates.get_windows_updates(filter_duplicates=True, include_all_states=False)resultwill contain a list of dict like[{
        'kb': 'KB123456',
        'date': '2021-01-01 00:01:02',
        'title': 'Some update title',
        'description': 'Some update description',
        'supporturl': 'https://support.microsoft.com/someID',
        'operation': 'Installation'
        'result': 'Installed'
    }, {
        'kb': None,
        'date': '2021-01-01 00:01:02',
        'title': 'Windows 10 20H1 update',
        'description': 'Pretty big system update',
        'supporturl': 'https://support.microsoft.com/someID',
        'operation': 'Installation'
        'result': 'Installed'
    }
]Usingfilter_duplicateswill avoid returning multiple times the same KB from different sources.
This setting is enabled by default.The parameterinclude_all_statesset to True will include all updates, even those who failed to install or are superseeded.usersvirtualizationwindows_firewallwmi_queries