Generalize USMT Dash and add a containerized demo mode

Remove all environment-specific data and make the dashboard adoptable
anywhere, then add a demo that runs the real PowerShell services.

- Strip cached device data, internal knowledge-base articles and
  screenshots, server/site names and the old project notes; replace the
  knowledge base with generic sample articles and diagrams
- Move every environment value into Config/usmt-dash.psd1
- Route all infrastructure access in the worker and Get-Software.ps1
  through a provider (Providers/SCCM.ps1), with a config-driven asset
  inventory view instead of a hard-coded custom class
- Add Providers/Demo.ps1: a deterministic simulated fleet whose
  migrations progress in real time, and Demo/New-DemoData.ps1 to seed it
- Server: -Demo makes the API read-only; add get-config and get-logs;
  serve static files only from web/, Documentation/ and an allowlist of
  Data/ files with a path-traversal guard; gzip large responses
- Mirror both services' console output to Data/Logs via a Write-Host
  proxy, and add a terminal panel to the dashboard that streams it
- Demo sandbox (web/demo/demo.js): visitor changes to tags, articles and
  images are kept in the visitor's browser and echoed in the terminals;
  nothing a visitor does reaches the server
- Vendor marked, highlight.js and html2pdf.js instead of loading CDNs
- Dockerfile and compose file for hosting the demo (Coolify-ready)
This commit is contained in:
Johan Sandoval committed 2026-10-06 15:20:43 +00:00
commit 1c531bc2ab
56 files changed
+10232

No files matched your search

+121
View File
@@ -0,0 +1,121 @@
@{
# =====================================================================================
# USMT Dash configuration
#
# Every environment-specific value lives in this file. To adopt the dashboard in your
# own environment, copy this file, fill in the SCCM section, and run the two services:
#
# .\USMT-Worker.ps1 # data collector (keep running)
# .\USMT-Server.ps1 # web server + JSON API (keep running)
#
# Pass -Demo to either script (or set Mode = 'Demo', or env USMT_MODE=Demo) to run
# against the built-in simulated fleet instead of real infrastructure.
# Pass -ConfigPath to point at a different config file.
# =====================================================================================
# 'Live' = query real infrastructure through the provider below.
# 'Demo' = simulated fleet, read-only API, visitor changes stay in the browser.
Mode = 'Live'
# Data source adapter used in Live mode. Loaded from .\Providers\<Provider>.ps1
Provider = 'SCCM'
Server = @{
Port = 8080
# HttpListener prefix. '*' binds every interface (may need a URL ACL on Windows:
# netsh http add urlacl url=http://*:8080/ user=DOMAIN\svc-account)
Prefix = 'http://*:{0}/'
}
Worker = @{
# Seconds between cycles during business hours
CycleSeconds = 180
# Outside business hours the worker sleeps until the next morning, with a
# midnight "pitstop" that runs the daily software/advanced-info refresh.
BusinessHours = @{
Enabled = $true
Start = '07:30'
End = '17:30'
Weekdays = @(1, 2, 3, 4, 5) # 0 = Sunday ... 6 = Saturday
}
# Flush the local DNS client cache at the start of each cycle (Windows only)
FlushDnsEachCycle = $true
# Devices whose admin share hangs; disk and log checks are skipped for these
DiskSkipList = @()
# How long a cached software inventory is considered fresh
SoftwareCacheHours = 24
# A task-sequence log modified within this window counts as "active"
ActiveLogHours = 24
}
# -------------------------------------------------------------------------------------
# SCCM / ConfigMgr provider (.\Providers\SCCM.ps1)
# -------------------------------------------------------------------------------------
SCCM = @{
SiteCode = 'ABC'
ProviderMachineName = 'sccm01.corp.example.com' # SMS Provider for the CMSite PSDrive
SqlServer = 'sccm01.corp.example.com' # Site database server
Database = 'CM_ABC'
# Where the worker looks for USMT progress logs on each device (relative to the
# admin share below). First folder containing a matching log wins.
AdminShare = 'C$'
LogFolders = @('Windows\CCM\Logs\SMSTSLog', 'Windows\CCM\Logs')
ScanStateLog = 'scanstateprogress'
LoadStateLog = 'loadstateprogress'
# Many organizations extend hardware inventory with a custom class that holds
# asset/location details (room, department, mount type, ...). Map that class here.
# Set Enabled = $false if you don't have one - those fields will show "N/A".
AssetInventory = @{
Enabled = $true
View = 'v_GS_ASSET_INFO0' # primary inventory view
FallbackView = '' # optional older/secondary view, queried only if the primary has no row
# Dashboard field = column in the view
Columns = @{
Updated = 'Date_Updated0'
Location = 'Location0'
Vanity = 'VanityLocation0'
Department = 'Department0'
Building = 'Building0'
Mount = 'Mount_Type0'
PrimaryUser = 'Primary_User0'
PhoneExt = 'Phone_Extension0'
InfoBy = 'Info_Entered_By0'
Notes = 'Notes0'
}
# Boolean (1/0) columns that describe what kind of space the device is in.
# Any column set to 1 adds its label to the "Room Type" field.
RoomTypes = @(
@{ Label = 'Conference Room'; Column = 'ConferenceRoom0' }
@{ Label = 'Hoteling Desk'; Column = 'HotelingDesk0' }
@{ Label = 'Training Room'; Column = 'TrainingRoom0' }
@{ Label = 'Reception'; Column = 'Reception0' }
@{ Label = 'Shared Space'; Column = 'SharedSpace0' }
)
}
}
# -------------------------------------------------------------------------------------
# Demo provider (.\Providers\Demo.ps1) - simulated fleet used by the public demo
# -------------------------------------------------------------------------------------
Demo = @{
DeviceCount = 200 # tracked source devices seeded at startup
CycleSeconds = 45 # cooldown between cycles (business hours are ignored)
DelayMsPerDevice = 35 # artificial per-device latency so the progress bar moves
LifecycleHours = 24 # how long one simulated migration takes, start to finish
Verbose = $true # run the worker with -v style tracing
}
# Console output from both services is mirrored to Data\Logs\*.log as JSON lines so the
# dashboard's terminal panel can stream it.
Logging = @{
Enabled = $true
MaxLines = 3000
}
}