# ── Feature metadata ────────────────────────────────────────────────────────── # $FeatureMeta is read by configure.ps1 for discovery, display, and config UI. # Invoke-Feature is called by runner.ps1 on each scheduled cycle. $FeatureMeta = @{ Name = 'DynamicLock' Description = 'Disable Dynamic Lock while on a specific network; re-enable after disconnecting' Settings = @( @{ Key = 'network' Label = 'DNS Suffix' Type = 'string' Default = 'h.arnemoerman.be' Description = 'Connection-specific DNS suffix of the target network (e.g. h.arnemoerman.be)' }, @{ Key = 'revertAfterMinutes' Label = 'Revert After (minutes)' Type = 'int' Default = 10 Description = 'Re-enable Dynamic Lock after being disconnected for this many minutes' } ) } # ── Feature implementation ──────────────────────────────────────────────────── function Invoke-Feature { param( [hashtable]$Config, [hashtable]$State ) if (-not $State) { $State = @{} } if (-not $State.ContainsKey('isConnected')) { $State['isConnected'] = $false } if (-not $State.ContainsKey('lastConnectedTime')) { $State['lastConnectedTime'] = $null } if (-not $State.ContainsKey('dynamicLockDisabled')) { $State['dynamicLockDisabled'] = $false } $regPath = 'HKCU:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' $isConnected = Test-DnsSuffixConnected -Suffix $Config['network'] if ($isConnected) { $State['isConnected'] = $true $State['lastConnectedTime'] = (Get-Date).ToString('o') if (-not $State['dynamicLockDisabled']) { if (-not (Test-Path $regPath)) { New-Item -Path $regPath -Force | Out-Null } Set-ItemProperty -Path $regPath -Name 'EnableGoodbye' -Value 0 -Type DWord $State['dynamicLockDisabled'] = $true Write-Log -Level Info ` -Message "Dynamic Lock disabled (connected to '$($Config['network'])')" ` -Feature 'DynamicLock' } } else { $State['isConnected'] = $false # If we disabled Dynamic Lock earlier, check whether we've been away long enough to re-enable if ($State['dynamicLockDisabled'] -and $null -ne $State['lastConnectedTime']) { try { $lastConnected = [datetime]::Parse($State['lastConnectedTime']) $minutesGone = ((Get-Date) - $lastConnected).TotalMinutes if ($minutesGone -ge [double]$Config['revertAfterMinutes']) { if (-not (Test-Path $regPath)) { New-Item -Path $regPath -Force | Out-Null } Set-ItemProperty -Path $regPath -Name 'EnableGoodbye' -Value 1 -Type DWord $State['dynamicLockDisabled'] = $false Write-Log -Level Info ` -Message ("Dynamic Lock re-enabled (disconnected for {0} min, threshold {1} min)" -f [int]$minutesGone, $Config['revertAfterMinutes']) ` -Feature 'DynamicLock' } else { Write-Log -Level Info ` -Message ("Waiting to re-enable Dynamic Lock ({0}/{1} min elapsed)" -f [int]$minutesGone, $Config['revertAfterMinutes']) ` -Feature 'DynamicLock' } } catch { Write-Log -Level Warn ` -Message "Could not parse lastConnectedTime '$($State['lastConnectedTime'])': $_" ` -Feature 'DynamicLock' } } else { Write-Log -Level Info ` -Message "Not connected to '$($Config['network'])'; Dynamic Lock state unchanged." ` -Feature 'DynamicLock' } } return $State }