Files
usmt-dash/Config/usmt-dash.psd1
T
Johan Sandoval 41ff9e2b49 Demo: migrations follow the schedule, worked by a simulated team
Each device now migrates on the day of its date tag instead of on a
looping 24-hour clock: earlier days are finished, today's devices go
through backup and restore during working hours, later days haven't
started. The few that don't finish have a cause the dashboard shows
(broken client, broken WMI, low disk, a USMT error, unreachable PC).

A simulated team keeps two weeks of working days tagged. During working
hours it adds devices, reschedules or drops one, tags stuck PCs with
their problem, then fixes them and moves them to a new day; each morning
finished days are closed out and a new day is scheduled. Actions print
in the worker terminal as [Team] lines. Settings live in Demo.Team.

The visitor sandbox now keeps per-tag edits laid over the live roster,
so the team's changes keep showing around a visitor's own edits.

Overview calendar: today is a filled badge on the date number, so it no
longer looks like the selected day (outline plus tint).
2026-10-07 20:41:07 +00:00

166 lines
7.9 KiB
PowerShell

@{
# =====================================================================================
# 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
# Completed pairs and Skip USMT devices skip network checks in the sweep, so they're
# pinged this often to keep "last online" / "days offline" current (every other device
# is pinged every cycle).
# Cycles only run in business hours plus the midnight pitstop: 60 = hourly, plus midnight.
PresenceSweepMinutes = 60
# While a cycle runs, the rows swept so far are published this often, so the
# dashboard updates live instead of only when the cycle finishes
LivePublishSeconds = 10
}
# -------------------------------------------------------------------------------------
# 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' }
)
}
# Attached monitors (count + model names). Needs the WmiMonitorID class enabled in
# hardware inventory (root\wmi). SCCM stores its string properties as comma-separated
# character codes, which the provider decodes. Set Enabled = $false if not collected.
Monitors = @{
Enabled = $true
View = 'v_GS_WMIMONITORID'
NameColumn = 'UserFriendlyName0'
ManufacturerColumn = 'ManufacturerName0'
# Skip the built-in panel of laptops (instance names containing these)
InternalPattern = 'LGD|SDC|BOE|AUO|CMN|SHP'
}
}
# -------------------------------------------------------------------------------------
# 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
PresenceSweepMinutes = 60 # completed / Skip USMT devices: hourly, like Live (the demo runs all day)
LivePublishSeconds = 4 # publish swept rows this often during a cycle
# When the demo worker runs (outside these hours it sleeps, with the midnight pitstop),
# same format as Worker.BusinessHours. Set Enabled = $false to run around the clock.
BusinessHours = @{
Enabled = $true
Start = '06:00'
End = '21:00'
Weekdays = @(0, 1, 2, 3, 4, 5, 6) # every day
}
# The simulated team: date tags cover the next DaysAhead working days (each day's devices
# migrate during WorkStart-WorkEnd) and the last DaysKept days until they're closed out.
# Every ActionEveryMinutes (a random pick in the range) someone changes the roster.
Team = @{
WorkStart = '07:30'
WorkEnd = '17:00'
Weekdays = @(1, 2, 3, 4, 5) # Monday to Friday
DaysAhead = 10 # two weeks of working days, today included
DaysKept = 3
DevicesPerDay = 12
ActionEveryMinutes = @(4, 12)
}
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
}
}