registry_scripts
napt.build.registry_scripts
Registry-based detection and requirements script generation for Intune Win32 apps.
This module generates PowerShell detection and requirements scripts for MSI and EXE installers deployed as Intune Win32 apps. Scripts check Windows uninstall registry keys for installed software and version information using CMTrace-formatted logging.
Detection Logic
- Checks HKLM and HKCU uninstall registry keys
- Uses architecture-aware registry views (32-bit, 64-bit, or both)
- Matches by DisplayName (using AppName from recipe or MSI ProductName)
- Compares version (exact or minimum version match based on config)
- Exits 0 if detected, 1 if not detected
Requirements Logic
- Same registry scanning as detection
- If installed version < target version: outputs "Required" and exits 0
- Otherwise: outputs nothing and exits 0
Installer Type Filtering
Scripts filter registry entries based on installer type to prevent false matches when both MSI and EXE versions of software exist:
- MSI installers (strict): Only matches registry entries with WindowsInstaller=1. Prevents false matches with EXE versions.
- Non-MSI installers (permissive): Matches ANY registry entry. Handles EXE installers that run embedded MSIs internally.
Logging
- Primary: C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\
- Fallback: C:\ProgramData\NAPT\ (system) or %LOCALAPPDATA%\NAPT\ (user)
- Log rotation: 2-file rotation (.log and .log.old), configurable max size (default: 3MB)
- Format: CMTrace for compatibility with Intune diagnostics
Example
Generate detection and requirements scripts:
from pathlib import Path
from napt.build.registry_scripts import (
DetectionConfig,
RequirementsConfig,
generate_detection_script,
generate_requirements_script,
)
det_config = DetectionConfig(
app_name="Google Chrome",
version="131.0.6778.86",
)
generate_detection_script(det_config, Path("detection.ps1"))
req_config = RequirementsConfig(
app_name="Google Chrome",
version="131.0.6778.86",
)
generate_requirements_script(req_config, Path("requirements.ps1"))
Note
Scripts are saved as siblings to the packagefiles directory to prevent them from being included in the .intunewin package. They should be uploaded separately to Intune alongside the package.
DetectionConfig
dataclass
Configuration for registry-based detection script generation.
Attributes:
| Name | Type | Description |
|---|---|---|
app_name |
str
|
Application name to search for in registry DisplayName. |
version |
str
|
Expected version string to match. |
log_format |
LogFormat
|
Log format (currently only "cmtrace" supported). |
log_level |
LogLevel
|
Minimum log level (INFO, WARNING, ERROR, DEBUG). |
log_rotation_mb |
int
|
Maximum log file size in MB before rotation. |
exact_match |
bool
|
If True, version must match exactly. If False, minimum version comparison (remote >= expected). |
app_id |
str
|
Application ID (used for fallback if app_name sanitization results in empty string). |
is_msi_installer |
bool
|
If True, only match MSI-based registry entries. If False, only match non-MSI entries. This prevents false matches when both MSI and EXE versions of software exist with the same DisplayName. |
expected_architecture |
ArchitectureMode
|
Architecture filter for registry view selection. - "x86": Check only 32-bit registry view - "x64": Check only 64-bit registry view - "arm64": Check only 64-bit registry view (ARM64 uses 64-bit registry) - "any": Check both 32-bit and 64-bit views (permissive) |
use_wildcard |
bool
|
If True, use PowerShell -like operator for DisplayName matching (supports * and ? wildcards). If False, use exact -eq match. |
Source code in napt/build/registry_scripts.py
RequirementsConfig
dataclass
Configuration for registry-based requirements script generation.
Attributes:
| Name | Type | Description |
|---|---|---|
app_name |
str
|
Application name to search for in registry DisplayName. |
version |
str
|
Target version string (requirement met if installed < this). |
log_format |
LogFormat
|
Log format (currently only "cmtrace" supported). |
log_level |
LogLevel
|
Minimum log level (INFO, WARNING, ERROR, DEBUG). |
log_rotation_mb |
int
|
Maximum log file size in MB before rotation. |
app_id |
str
|
Application ID (used for fallback if app_name sanitization results in empty string). |
is_msi_installer |
bool
|
If True, only match MSI-based registry entries. If False, only match non-MSI entries. This prevents false matches when both MSI and EXE versions of software exist with the same DisplayName. |
expected_architecture |
ArchitectureMode
|
Architecture filter for registry view selection. - "x86": Check only 32-bit registry view - "x64": Check only 64-bit registry view - "arm64": Check only 64-bit registry view (ARM64 uses 64-bit registry) - "any": Check both 32-bit and 64-bit views (permissive) |
use_wildcard |
bool
|
If True, use PowerShell -like operator for DisplayName matching (supports * and ? wildcards). If False, use exact -eq match. |
Source code in napt/build/registry_scripts.py
generate_detection_script
Generates PowerShell detection script for Intune Win32 app.
Creates a PowerShell script that checks Windows uninstall registry keys for software installation and version. The script uses CMTrace-formatted logging with verbose output, includes log rotation logic, and performs write permission testing with automatic fallback to alternate log locations if primary locations are unavailable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
DetectionConfig
|
Detection configuration (app name, version, logging settings). |
required |
output_path
|
Path
|
Path where the detection script will be saved. |
required |
Returns:
| Type | Description |
|---|---|
Path
|
Path to the generated detection script. |
Raises:
| Type | Description |
|---|---|
OSError
|
If the script file cannot be written. |
Example
Generate script with default settings:
Source code in napt/build/registry_scripts.py
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | |
generate_requirements_script
Generates PowerShell requirements script for Intune Win32 app.
Creates a PowerShell script that checks Windows uninstall registry keys for software installation and determines if an older version is installed. The script outputs "Required" if installed version < target version, nothing otherwise. Always exits with code 0 so Intune can evaluate STDOUT.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
RequirementsConfig
|
Requirements configuration (app name, version, logging settings). |
required |
output_path
|
Path
|
Path where the requirements script will be saved. |
required |
Returns:
| Type | Description |
|---|---|
Path
|
Path to the generated requirements script. |
Raises:
| Type | Description |
|---|---|
OSError
|
If the script file cannot be written. |
Example
Generate script with default settings:
Source code in napt/build/registry_scripts.py
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | |