Harvest provtool diagnostics, enable ETW channel, skip Timeclock machine#
run-enrollment.ps1: - Enable Provisioning-Diagnostics-Provider/Admin event log before invoking provtool (was disabled by default; no diagnostics survived early runs). - After provtool returns, copy C:\ProgramData\Microsoft\Provisioning\* into C:\Logs\PPKG\ and snapshot HKLM\...\Sessions\* as provisioning-sessions.json, plus export the Admin event channel to Provisioning-Diagnostics-Admin.evtx. Gives us reviewable state without relying on provtool's failure-only diagnostic bundle. - provtool arg order is positional path + /quiet + /source BPRT (verified against ProvEventLog from the PS cmdlet internal call). startnet.cmd / startnet-template.cmd: - Standard-Timeclock sub-type skips the machine-number prompt. Timeclock PCs do not use a machine number so forcing a prompt wasted tech time and left MACHINENUM at the 9999 default anyway. Machine sub-type is unaffected.
This commit is contained in:
@@ -59,7 +59,18 @@ $provtool = Join-Path $env:SystemRoot 'System32\provtool.exe'
|
||||
# internally (observed in ProvEventLog.txt): positional path, then /quiet,
|
||||
# then /source. No /log: or /ppkg: prefix - those are not valid provtool
|
||||
# flags and caused 0x80004005 E_FAIL in the first test.
|
||||
#
|
||||
# /source BPRT keeps us in the bulk-provisioning code path used by the
|
||||
# automatic OOBE PPKG runtime. PSCmdlet would give richer ETW/event-log
|
||||
# diagnostics, but may change which actions in the PPKG actually execute
|
||||
# (not verified against Microsoft docs). Stay on BPRT and enable logging
|
||||
# manually below.
|
||||
$provArgs = @("`"$($ppkgFile.FullName)`"", "/quiet", "/source", "BPRT")
|
||||
|
||||
# Enable the Provisioning-Diagnostics-Provider Admin channel so events
|
||||
# from the BPRT run land somewhere we can export afterward. This is
|
||||
# idempotent - running each time is safe.
|
||||
wevtutil.exe set-log 'Microsoft-Windows-Provisioning-Diagnostics-Provider/Admin' /enabled:true 2>$null | Out-Null
|
||||
Log "Installing provisioning package via provtool.exe (no PowerShell timeout)..."
|
||||
Log "Command: $provtool $($provArgs -join ' ')"
|
||||
Log "PPKG diagnostic logs -> $ppkgLogDir (provtool writes them automatically)"
|
||||
@@ -74,6 +85,64 @@ try {
|
||||
Log "ERROR: Failed to launch provtool.exe: $_"
|
||||
}
|
||||
|
||||
# --- Harvest Windows' own provisioning diagnostics into $ppkgLogDir ---
|
||||
# provtool.exe /quiet does not drop a zip bundle on success, so the real
|
||||
# detail lives under C:\ProgramData\Microsoft\Provisioning\, in the
|
||||
# registry under HKLM\Software\Microsoft\Provisioning\Sessions\*, and in
|
||||
# the Provisioning-Diagnostics-Provider event log. Copy/export all three
|
||||
# into our log dir so they ride back with the shopfloor logs bundle.
|
||||
Log "Harvesting Windows provisioning diagnostics to $ppkgLogDir..."
|
||||
try {
|
||||
$provData = 'C:\ProgramData\Microsoft\Provisioning'
|
||||
if (Test-Path $provData) {
|
||||
Copy-Item -Path (Join-Path $provData '*') -Destination $ppkgLogDir `
|
||||
-Recurse -Force -ErrorAction SilentlyContinue
|
||||
Log " copied $provData -> $ppkgLogDir"
|
||||
} else {
|
||||
Log " $provData not present (provtool may not have touched it)"
|
||||
}
|
||||
} catch {
|
||||
Log " WARN: ProgramData copy threw: $_"
|
||||
}
|
||||
|
||||
try {
|
||||
$sessions = Get-ChildItem 'HKLM:\Software\Microsoft\Provisioning\Sessions' -ErrorAction SilentlyContinue
|
||||
if ($sessions) {
|
||||
$snap = $sessions | ForEach-Object {
|
||||
$props = Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue
|
||||
if ($props) {
|
||||
[pscustomobject]@{
|
||||
Session = $_.PSChildName
|
||||
BeginTime = $props.BeginTime
|
||||
LastRunTime = $props.LastRunTime
|
||||
RebootCount = $props.RebootCount
|
||||
State = $props.State
|
||||
StateValue = $props.StateValue
|
||||
}
|
||||
}
|
||||
}
|
||||
$snap | ConvertTo-Json -Depth 3 |
|
||||
Out-File -FilePath (Join-Path $ppkgLogDir 'provisioning-sessions.json') -Encoding UTF8
|
||||
Log " wrote provisioning-sessions.json ($($snap.Count) session(s))"
|
||||
foreach ($s in $snap) {
|
||||
Log " session $($s.Session): State=$($s.State) RebootCount=$($s.RebootCount)"
|
||||
}
|
||||
} else {
|
||||
Log " no sessions under HKLM:\Software\Microsoft\Provisioning\Sessions"
|
||||
}
|
||||
} catch {
|
||||
Log " WARN: session snapshot threw: $_"
|
||||
}
|
||||
|
||||
try {
|
||||
$evtx = Join-Path $ppkgLogDir 'Provisioning-Diagnostics-Admin.evtx'
|
||||
if (Test-Path $evtx) { Remove-Item $evtx -Force -ErrorAction SilentlyContinue }
|
||||
$null = & wevtutil.exe epl 'Microsoft-Windows-Provisioning-Diagnostics-Provider/Admin' $evtx 2>&1
|
||||
if (Test-Path $evtx) { Log " exported $evtx" }
|
||||
} catch {
|
||||
Log " WARN: wevtutil export threw: $_"
|
||||
}
|
||||
|
||||
# --- Set OOBE complete (only reached if PPKG didn't trigger immediate reboot) ---
|
||||
Log "Setting OOBE as complete..."
|
||||
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\OOBE" /v OOBEComplete /t REG_DWORD /d 1 /f | Out-Null
|
||||
|
||||
@@ -137,8 +137,9 @@ if "%standard_choice%"=="1" set PCSUBTYPE=Timeclock
|
||||
if "%standard_choice%"=="2" set PCSUBTYPE=Machine
|
||||
if "%PCSUBTYPE%"=="" goto standard_menu
|
||||
|
||||
REM --- Machine number (Standard only) ---
|
||||
REM --- Machine number (Standard-Machine only; Timeclock PCs do not use one) ---
|
||||
set MACHINENUM=9999
|
||||
if "%PCSUBTYPE%"=="Timeclock" goto skip_standard_menu
|
||||
echo.
|
||||
set /p MACHINENUM=Enter machine number (digits, or Enter for 9999):
|
||||
if "%MACHINENUM%"=="" set MACHINENUM=9999
|
||||
|
||||
Reference in New Issue
Block a user