Installation Detection Mechanisms
Relevant source files
The following files were used as context for generating this wiki page:
The auto-opsi-repo project implements multi-layered installation detection to ensure software packages are only installed when necessary and verified successfully after deployment. This system prevents redundant installations by comparing the currently installed software version against the desired version defined in the package metadata.
Detection logic exists in two distinct phases:
- Server-side Verification: The Python builder validates version strings and metadata during the package creation process.
- Client-side Execution: A PowerShell runtime script (
runtime.ps1) executes on the Windows target to identify existing installations using registry keys, file versions, or custom scripts.
Sources: README.md:129-137, builder/templates/runtime.ps1:1-5
Detection Architecture
The system uses a config.json file, generated during the build process, to pass detection parameters to the client-side PowerShell environment. This configuration includes regex patterns, version replacements, and the chosen detection method.
The diagram shows the flow of detection configuration from the server-side catalog to the client-side execution logic.
Sources: builder/builder/opsi.py:73-82, builder/templates/runtime.ps1:4-6
Supported Detection Methods
The project supports four primary detection methods configured via the detection block in catalog/packages.yaml.
Registry Detection
This is the default method for most applications. It iterates through both 64-bit and 32-bit views of the HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall registry key. It matches the DisplayName property against a provided regular expression.
- Logic: Scans registry subkeys for a matching
DisplayName. - Version Extraction: Retrieves the
DisplayVersionproperty. Ifversion_from_display_name_regexis defined, it extracts the version string directly from theDisplayName. - Normalization: Applies
version_replacementsto map vendor-specific version separators (e.g., replacing.windows.with.).
Sources: builder/templates/runtime.ps1:7-40, README.md:129-134, catalog/packages.yaml:126-128
MSI Detection
A specialized version of registry detection that matches a specific MSI product_code against the subkey names in the Uninstall registry hive.
Sources: builder/templates/runtime.ps1:19, README.md:129-130
File Version Detection
Used for ZIP-based or portable applications where no registry entry is created. It expands environment variables in a provided path and retrieves the ProductVersion from the file's version information.
Sources: builder/templates/runtime.ps1:48-52, README.md:130-131
Custom Detection
Allows administrators to provide a detection.script override. This script is a Jinja2-templated OPSI snippet that takes full control over the detection logic and conditional invocation of installation steps.
Sources: builder/builder/opsi.py:43-47, README.md:143-146
Version Comparison Logic
The AtLeast function in runtime.ps1 determines if an installation is required. It performs a numeric comparison of version strings to handle cases where the installed version is equal to or newer than the package version.
| Condition | Action |
|---|---|
InstalledVersion returns null | Proceed with installation |
InstalledVersion < DesiredVersion | Proceed with installation (Upgrade) |
InstalledVersion >= DesiredVersion | Skip installation |
| Version format is non-numeric | Proceed with installation (Conservative failure) |
Sources: builder/templates/runtime.ps1:57-71, README.md:135-136
Configuration Parameters
The following table summarizes the configuration fields used in the detection process as defined in the source files.
| Field | Source File | Description |
|---|---|---|
method | catalog/packages.yaml | One of: registry, msi, file_version, custom. |
display_name_regex | catalog/packages.yaml | Regex to match the application in the registry. |
path | catalog/packages.yaml | File path for file_version detection. |
version_from_display_name_regex | catalog/packages.yaml | Regex to extract version from the name string. |
version_replacements | catalog/packages.yaml | Dictionary of string replacements for version strings. |
product_code | catalog/packages.yaml | The GUID for MSI-based detection. |
Sources: catalog/packages.yaml:263-265, builder/templates/runtime.ps1:22-31, builder/builder/opsi.py:73-82
Summary of Execution Flow
When a package is deployed, the OPSI script calls the PowerShell helper functions. The flow ensures that the system identifies the specific instance of the software and validates its version before and after the installer runs.
The sequence diagram illustrates the interaction between the OPSI control script and the PowerShell runtime during a typical deployment.
Sources: builder/templates/runtime.ps1:48-83, builder/builder/opsi.py:53-56