Report configuration drift
Compare declared settings without confusing a missing key with a false or zero value.
Desired state defines the scope
Configuration drift is a difference between an observed setting and an explicit desired value. Load current.json and desired.json as hashtables, then inspect only keys declared by the desired configuration. Unrelated local keys remain outside this rule's scope.
ConvertFrom-Json -AsHashtable makes property lookup convenient when the setting name is stored in a variable. Check key presence separately from its value. A false boolean, zero, or empty string may be a legitimate stored setting; testing the value's truthiness cannot tell you whether the key exists.
$settings = Get-Content '/home/user/current.json' -Raw | ConvertFrom-Json -AsHashtable
$settings.Contains('BackupEnabled')
Describe the difference
A missing desired key produces Missing, with a null Actual value. A present key with a different value produces Changed. Matching keys produce no finding. Keep Actual and Expected as their original scalar values, so false remains a boolean rather than the text false.
This dataset uses flat scalar settings with consistent types and casing. A real policy for nested objects, arrays, or case-sensitive strings needs a more specific comparison contract; this exercise does not pretend that one -ne check covers every schema.
Reporting drift is separate from applying changes. Leave both input files untouched. Later lessons introduce previewable and repeatable updates inside the browser filesystem.
Get-Content '/home/user/desired.json' -Raw | ConvertFrom-Json -AsHashtable
Put it into practice.
Compare only keys declared in desired.json against current.json. Emit Key, State, Actual, Expected for differences: Missing if the key is absent (Actual null), Changed if a present scalar value differs. Preserve scalar types and leave both files unchanged. Do not flag unrelated local keys.
See an explained solution
$actual = Get-Content '/home/user/current.json' -Raw | ConvertFrom-Json -AsHashtable
$desired = Get-Content '/home/user/desired.json' -Raw | ConvertFrom-Json -AsHashtable
foreach ($key in $desired.Keys) {
if (-not $actual.Contains($key)) { [pscustomobject]@{ Key=$key; State='Missing'; Actual=$null; Expected=$desired[$key] } }
elseif ($actual[$key] -ne $desired[$key]) { [pscustomobject]@{ Key=$key; State='Changed'; Actual=$actual[$key]; Expected=$desired[$key] } }
}
Key presence and value comparison answer different questions. BackupEnabled is Changed, not Missing; LocalNote is preserved because the desired policy does not manage it.