12 KiB
NonInteractive Mode - CI/CD & Automation Guide
Overview
NoID Privacy supports fully automated, non-interactive execution for CI/CD pipelines, group policy deployment, and mass system hardening. This guide explains how to run the framework without any interactive prompts.
Configuration-Based Execution
The framework automatically enters non-interactive mode when all required parameters are pre-configured in config.json.
Required Configuration Keys
1. DNS Module - Provider Selection
{
"modules": {
"DNS": {
"enabled": true,
"priority": 3,
"status": "IMPLEMENTED",
"description": "Secure DNS with DoH",
"provider": "Quad9"
}
}
}
Valid provider values:
"Quad9"(default, security-focused, Swiss privacy)"Cloudflare"(fastest resolver)"AdGuard"(ad/tracker blocking)
When provider is set:
- No interactive DNS provider selection prompt
- Direct application of specified provider
2. Privacy Module - Mode Selection
{
"modules": {
"Privacy": {
"enabled": true,
"priority": 4,
"status": "IMPLEMENTED",
"description": "Privacy hardening",
"mode": "MSRecommended"
}
}
}
Valid mode values:
"MSRecommended"(default, fully supported, production-ready)"Strict"(maximum privacy, Teams/Zoom work)"Paranoid"(hardcore, not recommended for production)
When mode is set:
- No interactive privacy mode selection prompt
- Direct application of specified mode with warnings logged
3. Global Options - Automation Settings
{
"options": {
"dryRun": false,
"createBackup": true,
"verboseLogging": false,
"autoReboot": false,
"nonInteractive": true
}
}
Key options:
nonInteractive: Explicitly disable all prompts (optional, auto-detected)autoReboot: Automatically restart after hardening (use with caution)createBackup: Always create backups (highly recommended)
Command-Line Execution
Basic Non-Interactive Execution
# Run all enabled modules from config.json
.\NoIDPrivacy.ps1 -Module All
# Run specific module with provider pre-configured
.\NoIDPrivacy.ps1 -Module DNS
# Run with command-line overrides
.\NoIDPrivacy.ps1 -Module Privacy -DryRun
# Run in verbose mode for logging
.\NoIDPrivacy.ps1 -Module All -VerboseLogging
CI/CD Pipeline Example
Azure DevOps Pipeline
steps:
- task: PowerShell@2
displayName: 'NoID Privacy Hardening'
inputs:
targetType: 'filePath'
filePath: '$(System.DefaultWorkingDirectory)/NoIDPrivacy.ps1'
arguments: '-Module All -VerboseLogging'
errorActionPreference: 'stop'
pwsh: false
condition: succeededOrFailed()
- task: PublishBuildArtifacts@1
displayName: 'Publish Hardening Logs'
inputs:
PathtoPublish: 'Logs'
ArtifactName: 'hardening-logs'
GitHub Actions Workflow
name: Windows Hardening
on:
schedule:
- cron: '0 0 * * 0' # Weekly on Sunday
workflow_dispatch:
jobs:
harden:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Run NoID Privacy
shell: powershell
run: |
.\NoIDPrivacy.ps1 -Module All -VerboseLogging
- name: Upload Logs
if: always()
uses: actions/upload-artifact@v3
with:
name: hardening-logs
path: Logs/
Jenkins Pipeline
pipeline {
agent { label 'windows' }
stages {
stage('Hardening') {
steps {
powershell '''
Set-ExecutionPolicy Bypass -Scope Process -Force
.\\NoIDPrivacy.ps1 -Module All -VerboseLogging
'''
}
}
}
post {
always {
archiveArtifacts artifacts: 'Logs/**/*', fingerprint: true
}
}
}
Group Policy Deployment
Method 1: Startup Script
-
Copy NoID Privacy to network share:
\\domain.local\NETLOGON\NoIDPrivacy\ -
Create GPO startup script:
# Startup-Hardening.ps1 $scriptPath = "\\domain.local\NETLOGON\NoIDPrivacy\NoIDPrivacy.ps1" if (Test-Path $scriptPath) { & $scriptPath -Module All -VerboseLogging } -
Link GPO to target OU
-
Result logged to:
C:\NoIDPrivacy\Logs\
Method 2: Scheduled Task (Recommended)
Deploy via GPO Scheduled Task:
<!-- Task XML for GPO deployment -->
<Task>
<Triggers>
<CalendarTrigger>
<StartBoundary>2025-01-01T03:00:00</StartBoundary>
<ScheduleByWeek>
<DaysOfWeek><Sunday /></DaysOfWeek>
<WeeksInterval>1</WeeksInterval>
</ScheduleByWeek>
</CalendarTrigger>
</Triggers>
<Actions>
<Exec>
<Command>powershell.exe</Command>
<Arguments>-ExecutionPolicy Bypass -File "\\domain.local\NETLOGON\NoIDPrivacy\NoIDPrivacy.ps1" -Module All</Arguments>
</Exec>
</Actions>
</Task>
Verification Without Interaction
Silent Verification
# Run verification and export structured JSON
.\Tools\Verify-Complete-Hardening.ps1 -ExportPath "verification-result.json"
# Parse results programmatically
$verification = Get-Content "verification-result.json" | ConvertFrom-Json
if ($verification.Failed -eq 0) {
Write-Output "All settings verified successfully"
exit 0
} else {
Write-Error "Verification failed: $($verification.Failed) settings did not match expected values"
exit 1
}
Environment Variables (Alternative)
Instead of modifying config.json, use environment variables:
# Set environment variables
$env:NOIDPRIVACY_DNS_PROVIDER = "Quad9"
$env:NOIDPRIVACY_PRIVACY_MODE = "MSRecommended"
$env:NOIDPRIVACY_NONINTERACTIVE = "true"
# Run framework
.\NoIDPrivacy.ps1 -Module All
Note: Environment variables require framework support and are currently a roadmap feature (not yet implemented).
Exit Codes (v2.0.0+)
The framework returns structured exit codes for CI/CD integration:
| Code | Name | Description |
|---|---|---|
| 0 | SUCCESS |
All operations completed successfully |
| 1 | ERROR_GENERAL |
General/unspecified error |
| 2 | ERROR_PREREQUISITES |
System requirements not met (OS, PowerShell, Admin) |
| 3 | ERROR_CONFIG |
Configuration file error (missing, invalid JSON) |
| 4 | ERROR_MODULE |
One or more modules failed during execution |
| 5 | ERROR_FATAL |
Fatal/unexpected exception |
| 10 | SUCCESS_REBOOT |
Success, but reboot is required for changes to take effect |
Example: CI/CD Exit Code Handling
# Run hardening and capture exit code
$process = Start-Process powershell -ArgumentList "-ExecutionPolicy Bypass -File `".\NoIDPrivacy.ps1`" -Module All" -Wait -PassThru
$exitCode = $process.ExitCode
switch ($exitCode) {
0 { Write-Host "SUCCESS: All modules applied" -ForegroundColor Green }
10 { Write-Host "SUCCESS: Reboot required" -ForegroundColor Yellow; Restart-Computer -Force }
2 { Write-Host "FAILED: Prerequisites not met" -ForegroundColor Red; exit 1 }
3 { Write-Host "FAILED: Config error" -ForegroundColor Red; exit 1 }
4 { Write-Host "FAILED: Module errors" -ForegroundColor Red; exit 1 }
5 { Write-Host "FAILED: Fatal exception" -ForegroundColor Red; exit 1 }
default { Write-Host "FAILED: Unknown error ($exitCode)" -ForegroundColor Red; exit 1 }
}
Example: Simple Success/Failure Check
.\NoIDPrivacy.ps1 -Module All
$exitCode = $LASTEXITCODE
if ($exitCode -eq 0 -or $exitCode -eq 10) {
Write-Host "Hardening completed successfully"
if ($exitCode -eq 10) { Write-Host "Reboot recommended" }
}
else {
Write-Host "Hardening failed with exit code: $exitCode"
# Check logs for details
$latestLog = Get-ChildItem "Logs" -Filter "NoIDPrivacy-*.log" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
Get-Content $latestLog.FullName | Select-String "ERROR"
exit $exitCode
}
Best Practices for Automation
1. Always Use DryRun First
# Test configuration without applying
.\NoIDPrivacy.ps1 -Module All -DryRun -VerboseLogging
# Review logs before production run
Get-Content "Logs\NoIDPrivacy-*.log" | Select-String "ERROR|WARNING"
2. Centralized Logging
Configure log aggregation for enterprise deployment:
# Example: Copy logs to central location
$logPath = "C:\NoIDPrivacy\Logs"
$centralPath = "\\fileserver\HardeningLogs\$env:COMPUTERNAME"
if (Test-Path $logPath) {
Copy-Item -Path "$logPath\*" -Destination $centralPath -Recurse -Force
}
3. Rollback Plan
Always maintain rollback capability:
# Before mass deployment, test rollback
.\NoIDPrivacy.ps1 -Module DNS
# Restore from latest backup (uses Core\Rollback.ps1)
.\Core\Rollback.ps1 -RestoreLatest
# Or restore specific module
.\Modules\DNS\Public\Restore-DNSSettings.ps1
# Verify rollback worked
.\Tools\Verify-Complete-Hardening.ps1
Troubleshooting Non-Interactive Mode
Issue: Still Showing Prompts
Cause: Provider/mode not configured in config.json
Solution:
{
"modules": {
"DNS": { "provider": "Quad9" },
"Privacy": { "mode": "MSRecommended" }
}
}
Issue: Script Fails Silently
Cause: Error suppression in CI/CD
Solution:
# Use verbose logging + error action
.\NoIDPrivacy.ps1 -Module All -VerboseLogging -ErrorAction Stop
Issue: Insufficient Permissions
Cause: Not running as Administrator
Solution:
# For scheduled tasks, use SYSTEM account or admin user
# For GPO, startup scripts run as SYSTEM automatically
Complete Example: Enterprise Deployment Script
<#
.SYNOPSIS
Enterprise deployment wrapper for NoID Privacy
.DESCRIPTION
Automated hardening with centralized logging and email reporting
#>
param(
[switch]$DryRun,
[string]$EmailRecipient = "security@company.com"
)
$ErrorActionPreference = "Stop"
$scriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
try {
# Pre-flight checks
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
throw "Must run as Administrator"
}
# Run hardening
Write-Output "Starting NoID Privacy hardening..."
$result = & "$scriptRoot\NoIDPrivacy.ps1" -Module All -DryRun:$DryRun -VerboseLogging
# Collect logs
$logPath = "$scriptRoot\Logs"
$latestLog = Get-ChildItem $logPath -Filter "NoIDPrivacy-*.log" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
# Send report email
$emailBody = @"
NoID Privacy Hardening Report
Computer: $env:COMPUTERNAME
Date: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")
Mode: $(if($DryRun){"DRY RUN"}else{"APPLY"})
Log file attached.
"@
Send-MailMessage -To $EmailRecipient `
-From "hardening@company.com" `
-Subject "Hardening Report - $env:COMPUTERNAME" `
-Body $emailBody `
-Attachments $latestLog.FullName `
-SmtpServer "smtp.company.com"
Write-Output "Hardening completed successfully"
exit 0
}
catch {
Write-Error "Hardening failed: $_"
exit 1
}
Summary
For non-interactive execution:
- ✅ Configure
providerandmodeinconfig.json - ✅ Use
-Module Allparameter - ✅ Enable
-VerboseLoggingfor CI/CD - ✅ Always test with
-DryRunfirst - ✅ Implement centralized logging
- ✅ Plan rollback procedures
The framework is fully automation-ready when configured correctly!