# Seeds Data\ with a simulated fleet for demo mode: tracking tags (Tracked-Devices.json), # the app blacklist, and a pre-warmed software cache so the first worker cycle is quick. # Run before starting the services. -Force wipes any existing state first. param( [switch]$Force, [string]$ConfigPath ) $root = Split-Path $PSScriptRoot -Parent . (Join-Path $root "Lib/Common.ps1") $config = Import-DashConfig -Path $ConfigPath -Demo $v = $false . (Join-Path $root "Providers/Demo.ps1") . (Join-Path $root "Lib/Common.ps1") # re-import so nothing in the provider shadows the helpers $dataDir = Join-Path $root "Data" if ($Force -and (Test-Path $dataDir)) { Get-ChildItem $dataDir -Recurse -File | Remove-Item -Force } if (-not (Test-Path $dataDir)) { New-Item -ItemType Directory -Path $dataDir | Out-Null } $trackedPath = Join-Path $dataDir "Tracked-Devices.json" if ((Test-Path $trackedPath) -and -not $Force) { Write-Host "Demo data already present (use -Force to reseed)." -ForegroundColor DarkGray return } $count = [int]$config.Demo.DeviceCount Write-Host "Seeding demo fleet ($count tracked devices)..." -ForegroundColor Cyan # --- 1. Generate source devices --- function New-FleetName([int]$i, [string]$prefix) { return "$prefix-$(New-DemoSerial "fleet$i")" } $skipPublic = [System.Collections.Generic.List[string]]::new() $skipLaptops = [System.Collections.Generic.List[string]]::new() $pool = [System.Collections.Generic.List[string]]::new() $i = 0 while ($skipPublic.Count -lt 14) { $skipPublic.Add((New-FleetName ($i++) "PUBDT")) } while ($skipLaptops.Count -lt 16) { $skipLaptops.Add((New-FleetName ($i++) (Get-DemoPick "lt$i" 'p' @("PRVLT", "PRVLT", "PRVLT", "PUBLT")))) } while ($pool.Count -lt ($count - $skipPublic.Count - $skipLaptops.Count - 3)) { $r = Get-DemoRand "mix$i" 'prefix' $prefix = if ($r -lt 0.55) { "PRVDT" } elseif ($r -lt 0.80) { "PUBDT" } elseif ($r -lt 0.95) { "PRVLT" } else { "PUBLT" } $pool.Add((New-FleetName ($i++) $prefix)) } # Manual "Source, Destination" pairs - hardware exceptions with no SCCM association $manual = @() for ($m = 0; $m -lt 3; $m++) { $src = New-FleetName ($i++) "PRVDT" $dst = New-FleetName ($i++) "PRVDT" $manual += "$src, $dst" } # --- 2. Date-batch tags (recent and upcoming working days; the worker keeps them current) --- $dateTags = Get-DemoDateTags [System.IO.File]::WriteAllText((Join-Path $dataDir "Demo-Dates.json"), (@{ Tags = $dateTags } | ConvertTo-Json), [System.Text.Encoding]::UTF8) $tags = [ordered]@{} foreach ($t in $dateTags) { $tags[$t] = [System.Collections.Generic.List[string]]::new() } for ($n = 0; $n -lt $pool.Count; $n++) { $tags[$dateTags[$n % $dateTags.Count]].Add($pool[$n]) } $tags["Manual Pairs"] = [System.Collections.Generic.List[string]]::new([string[]]$manual) # Department tags overlap the date batches, like a tech grouping their own work $byDept = @{} foreach ($d in $pool) { $dep = (Get-DemoProfile $d).Department.Name if (-not $byDept.ContainsKey($dep)) { $byDept[$dep] = [System.Collections.Generic.List[string]]::new() } $byDept[$dep].Add($d) } foreach ($pair in @(@("Accounting", "Accounting"), @("Sales Floor", "Sales"), @("Exec Suite", "Executive"))) { if ($byDept.ContainsKey($pair[1])) { $tags[$pair[0]] = [System.Collections.Generic.List[string]]::new([string[]]@($byDept[$pair[1]] | Select-Object -First 12)) } } $tags["Broken WMI"] = [System.Collections.Generic.List[string]]::new([string[]]@($pool | Where-Object { (Get-DemoRand $_ 'wmi') -lt 0.03 } | Select-Object -First 5)) $tags["Bad Client"] = [System.Collections.Generic.List[string]]::new([string[]]@($pool | Where-Object { (Get-DemoRand $_ 'badclient') -lt 0.03 } | Select-Object -First 4)) $tags["Public PCs"] = $skipPublic $tags["Laptops"] = $skipLaptops $skipTags = @("Public PCs", "Laptops") $tracked = [ordered]@{} foreach ($t in $tags.Keys) { $tracked[$t] = [ordered]@{ devices = @($tags[$t]); skipUSMT = ($skipTags -contains $t) } } ($tracked | ConvertTo-Json -Depth 5) | Set-Content -Path $trackedPath -Encoding UTF8 # --- 3. Blacklist / suite rules --- Copy-Item (Join-Path $PSScriptRoot "Blacklisted-Apps.txt") (Join-Path $dataDir "Blacklisted-Apps.txt") -Force $blacklist = @(Get-Content (Join-Path $dataDir "Blacklisted-Apps.txt") | Where-Object { $_.Trim() -ne "" } | ForEach-Object { $_.Trim() }) # --- 4. Pre-warmed software cache (the worker would otherwise build it one device at a time) --- $allDevices = [System.Collections.Generic.List[string]]::new() foreach ($d in ($pool + $skipPublic + $skipLaptops)) { $allDevices.Add($d) $p = Get-DemoProfile $d if (-not $p.NoAssoc -and -not ($skipPublic -contains $d) -and -not ($skipLaptops -contains $d)) { $allDevices.Add((Get-DemoDestName $d)) } } foreach ($pair in $manual) { $allDevices.AddRange([string[]]@($pair -split '\s*,\s*')) } $stamp = (Get-Date).ToString("o") $cache = [ordered]@{} foreach ($d in $allDevices) { $rows = foreach ($row in (Get-InstalledSoftware -ComputerName $d)) { $isSpecialty = $true foreach ($bad in $blacklist) { if ($row.Name -like $bad) { $isSpecialty = $false; break } } [PSCustomObject]@{ Name = $row.Name; Version = $row.Version; Publisher = $row.Publisher; Source = $row.Source; InstallDate = $row.InstallDate; IsSpecialty = $isSpecialty } } $cache[$d] = [PSCustomObject]@{ Timestamp = $stamp; Data = @($rows) } } [System.IO.File]::WriteAllText((Join-Path $dataDir "Software-Cache.json"), ($cache | ConvertTo-Json -Depth 6 -Compress), [System.Text.Encoding]::UTF8) # --- 5. Empty state for the rest --- Set-Content -Path (Join-Path $dataDir "Completed.json") -Value "[]" -Encoding UTF8 Set-Content -Path (Join-Path $dataDir "Data.json") -Value "[]" -Encoding UTF8 Set-Content -Path (Join-Path $dataDir "Advanced-Cache.json") -Value "{}" -Encoding UTF8 Set-Content -Path (Join-Path $dataDir "Worker-State.json") -Value '{"Status":"Preparing...","Current":0,"Total":0,"LastUpdated":"Never","NextCycle":"Calculating...","LastDuration":"N/A"}' -Encoding UTF8 Set-Content -Path (Join-Path $dataDir "Whitelisted-IPs.txt") -Value "" -Encoding UTF8 $unique = @($tracked.Values | ForEach-Object { $_.devices } | ForEach-Object { $_ }) | Select-Object -Unique Write-Host "Seeded $($tracked.Count) tags, $(@($unique).Count) roster entries, $($cache.Count) software inventories." -ForegroundColor Green