When testing software installations or troubleshooting system modifications, developers often need to identify exactly what changes an installer makes to both the filesystem and Windows registry. This is particularly valuable for:
- Software packaging and deployment
- Conflict resolution between applications
- Clean uninstall verification
- Malware analysis
Windows includes several utilities that can help track system changes:
Using System Restore Points
# Create a restore point manually
Checkpoint-Computer -Description "Pre-installation state" -RestorePointType MODIFY_SETTINGS
Registry Export Method
# Export registry before and after installation
reg export HKLM\Software before.reg
reg export HKCU before_user.reg
# After installation
reg export HKLM\Software after.reg
reg export HKCU after_user.reg
Here's a more automated approach using PowerShell:
function Get-SystemSnapshot {
param([string]$SnapshotName)
$snapshotPath = "C:\Snapshots\$SnapshotName"
New-Item -ItemType Directory -Path $snapshotPath -Force
# Capture filesystem info
Get-ChildItem -Path "C:\Program Files\", "C:\Program Files (x86)\", "C:\Windows\" -Recurse -Force |
Select-Object FullName, LastWriteTime, Length |
Export-Clixml -Path "$snapshotPath\Files.xml"
# Capture registry info
reg export HKLM "$snapshotPath\HKLM.reg"
reg export HKCU "$snapshotPath\HKCU.reg"
reg export HKCR "$snapshotPath\HKCR.reg"
# Capture installed programs
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Export-Clixml -Path "$snapshotPath\Programs.xml"
}
For more sophisticated comparison needs, consider these tools:
- Process Monitor - Real-time filesystem and registry monitoring
- Total Uninstall - Professional-grade installation monitoring
- Regshot - Lightweight registry/filesystem snapshot tool
Here's how to compare two snapshots programmatically:
function Compare-Snapshots {
param([string]$BeforePath, [string]$AfterPath)
# Compare files
$beforeFiles = Import-Clixml -Path "$BeforePath\Files.xml"
$afterFiles = Import-Clixml -Path "$AfterPath\Files.xml"
$fileChanges = Compare-Object -ReferenceObject $beforeFiles -DifferenceObject $afterFiles -Property FullName, LastWriteTime, Length
# Compare registry (basic text diff)
$registryChanges = Compare-Object -ReferenceObject (Get-Content "$BeforePath\HKLM.reg") -DifferenceObject (Get-Content "$AfterPath\HKLM.reg")
return @{
Files = $fileChanges
Registry = $registryChanges
}
}
Let's walk through tracking a silent installation of Notepad++:
# Take pre-install snapshot
Get-SystemSnapshot -SnapshotName "PreNotepadPP"
# Run silent install
Start-Process "npp.installer.exe" -ArgumentList "/S" -Wait
# Take post-install snapshot
Get-SystemSnapshot -SnapshotName "PostNotepadPP"
# Compare changes
$changes = Compare-Snapshots -BeforePath "C:\Snapshots\PreNotepadPP" -AfterPath "C:\Snapshots\PostNotepadPP"
# Export results
$changes.Files | Export-Csv -Path "C:\Snapshots\NotepadPP_Changes.csv" -NoTypeInformation
When performing these operations:
- Run tools with elevated privileges when needed
- Be cautious with registry exports containing sensitive data
- Store snapshots in secure locations
- Clean up temporary files after analysis
When deploying or analyzing Windows applications, understanding what files and registry keys an installer modifies is crucial for:
- Debugging installation issues
- Creating clean uninstall routines
- Developing portable applications
- Security auditing
Windows includes several built-in utilities that can help:
# PowerShell script to capture file system state
$timestamp = Get-Date -Format "yyyyMMddHHmmss"
$beforeSnapshot = "C:\snapshots\before_$timestamp.txt"
Get-ChildItem -Recurse C:\ | Out-File $beforeSnapshot
# After installation...
$afterSnapshot = "C:\snapshots\after_$timestamp.txt"
Get-ChildItem -Recurse C:\ | Out-File $afterSnapshot
For more robust analysis, consider these specialized tools:
# Example using Sysinternals Process Monitor filter
procmon.exe /BackingFile install.pml /Quiet /AcceptEula
# Run your installer
# Then stop logging with CTRL+E
To compare registry states:
# Export registry before installation
reg export HKLM before.reg
reg export HKCU before_user.reg
# After installation...
reg export HKLM after.reg
reg export HKCU after_user.reg
# Compare using FC (File Compare)
fc before.reg after.reg > registry_changes.txt
Here's a complete PowerShell solution:
$basePath = "C:\Program Files\YourApp"
$outputFile = "C:\changes_report_$(Get-Date -Format 'yyyyMMdd').html"
# Capture initial state
$beforeFiles = Get-ChildItem -Recurse -Path $basePath | Select-Object FullName,LastWriteTime,Length
$beforeReg = reg export "HKLM\Software\YourCompany" "before.reg" 2>&1
# Installation happens here...
# Capture post-installation state
$afterFiles = Get-ChildItem -Recurse -Path $basePath | Select-Object FullName,LastWriteTime,Length
$afterReg = reg export "HKLM\Software\YourCompany" "after.reg" 2>&1
# Generate comparison report
Compare-Object $beforeFiles $afterFiles -Property FullName -PassThru |
Where-Object {$_.SideIndicator -eq "=>"} |
ConvertTo-Html -Title "Installation Changes Report" |
Out-File $outputFile
For enterprise environments, WMI provides powerful monitoring:
$query = @"
SELECT * FROM __InstanceOperationEvent WITHIN 1
WHERE TargetInstance ISA 'CIM_DataFile'
AND TargetInstance.Drive='C:'
AND TargetInstance.Path='\\Program Files\\YourApp\\'
"@
Register-WmiEvent -Query $query -Action {
param($event)
$target = $event.SourceEventArgs.NewEvent.TargetInstance
"[$(Get-Date)] $($target.FileName) was $($event.SourceEventArgs.NewEvent.__CLASS)" |
Out-File "C:\file_changes.log" -Append
}
- Run comparisons on clean systems
- Close unnecessary applications
- Perform multiple test runs
- Document baseline system state