Updates group: - Dell drivers and BIOS: check Dell's catalogs against all three driver maps and models.txt, download with a shared speed cap, repack, preview, apply with backups and rollback. - iPXE boot files: check GitHub for the signed Secure Boot set, verify the sha256 and each file's signer, install atomically, roll back. Includes the by-hand procedure. - Blancco: upload a release, stage it, test-boot it from the menu, activate, roll back. - BPRT sync: validate a batch uploaded from the MediaCreator Lite cache (scripts/windows/Sync-BPRT.ps1 or a zip), show the diff, swap with the site overlay files kept. Images: one sidebar entry per image with Overview, Drivers, Unattend and OS and Packages tabs. Every save shows a diff first, keeps the file's format, makes a backup and can be undone. Driver lint runs inline. Enrollment: upload standard/engineer MCL packages, one per tenant/purpose, with archive and restore. Hardware coverage counts engineer as Win11.
89 lines
4.4 KiB
HTML
89 lines
4.4 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}Hardware Coverage - PXE Server Manager{% endblock %}
|
|
|
|
{% macro driver_badge(d) -%}
|
|
{% if d.status == 'ok' %}<span class="badge badge-success" title="{{ d.file }}">OK</span>
|
|
{% elif d.status == 'no-entry' %}<span class="badge badge-danger" title="No HardwareDriver.json entry matches this model">Missing</span>
|
|
{% elif d.status == 'zip-missing' %}<span class="badge badge-danger" title="Entry {{ d.file }} matches, but the zip is not on the server">Zip missing</span>
|
|
{% else %}<span class="text-muted">-</span>{% endif %}
|
|
{%- endmacro %}
|
|
|
|
{% macro bios_badge(b) -%}
|
|
{% if b.status == 'current' %}<span class="badge badge-success">{{ b.target }} (current)</span>
|
|
{% elif b.status == 'update' %}<span class="badge badge-info" title="{{ b.file }}">Flashes to {{ b.target }}</span>
|
|
{% elif b.status == 'file-missing' %}<span class="badge badge-danger" title="{{ b.file }} not in the BIOS folder">File missing</span>
|
|
{% else %}<span class="badge badge-danger">No BIOS entry</span>{% endif %}
|
|
{%- endmacro %}
|
|
|
|
{# A newer Dell pack/BIOS for the file this model uses, from the last Updates > Dell scan. #}
|
|
{% macro update_hint(found, file) -%}
|
|
{% if file and file | lower in found %}
|
|
<div class="mt-1"><a href="{{ url_for('dell_updates.page') }}" class="badge badge-info text-decoration-none" title="{{ file }}: Dell has {{ found[file | lower] or 'a newer version' }}. Open Updates to download it.">Update {{ found[file | lower] }}</a></div>
|
|
{% endif %}
|
|
{%- endmacro %}
|
|
|
|
{% block content %}
|
|
<div class="page-header">
|
|
<h1><i class="bi bi-cpu"></i> Hardware Coverage</h1>
|
|
<div class="header-actions">
|
|
<span class="badge badge-secondary badge-lg">{{ rows | length }} model{{ 's' if rows | length != 1 }} seen</span>
|
|
</div>
|
|
</div>
|
|
|
|
<p class="text-muted">
|
|
Every model that has booted WinPE here, as reported by the machine itself (WMI model, Dell system SKU,
|
|
BIOS version), checked against each image's driver map and the WinPE BIOS manifest. A model missing a
|
|
Win11 driver pack or a BIOS entry also shows on the Technician To-Do until it is added or dismissed.
|
|
</p>
|
|
|
|
<div class="section-card">
|
|
{% if rows %}
|
|
<div class="table-container">
|
|
<table class="data-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Model (WMI)</th>
|
|
<th>System SKU</th>
|
|
<th>BIOS seen</th>
|
|
{% for image, os_label in images %}<th title="{{ image }}">{{ image | replace('gea-', '') }} <span class="text-muted">({{ os_label }})</span></th>{% endfor %}
|
|
<th>BIOS update</th>
|
|
<th>Last seen</th>
|
|
<th class="text-end"></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for r in rows %}
|
|
<tr title="Serials: {{ r.serials | join(', ') }}{% if r.pctypes %} | Types: {{ r.pctypes | join(', ') }}{% endif %}">
|
|
<td>
|
|
<span class="mono">{{ r.model }}</span>
|
|
{% if r.manufacturer %}<div class="small text-muted">{{ r.manufacturer }}</div>{% endif %}
|
|
</td>
|
|
<td class="mono">{{ r.skus | join(', ') or '-' }}</td>
|
|
<td class="mono">{{ r.last_bios_version or '-' }}</td>
|
|
{% for image, os_label in images %}<td>{{ driver_badge(r.drivers[image]) }}{{ update_hint(hints.drivers, r.drivers[image].file) }}</td>{% endfor %}
|
|
<td>{{ bios_badge(r.bios) }}{{ update_hint(hints.bios, r.bios.file) }}</td>
|
|
<td class="mono text-nowrap">{{ r.last_seen | local_dt }}<div class="small text-muted">{{ r.count }} boot{{ 's' if r.count != 1 }}</div></td>
|
|
<td class="text-end text-nowrap">
|
|
{% if r.gap %}
|
|
<form method="post" action="{{ url_for('hardware_dismiss') }}" style="display:inline;">
|
|
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
|
|
<input type="hidden" name="model" value="{{ r.model }}">
|
|
<input type="hidden" name="done" value="{{ '0' if r.dismissed else '1' }}">
|
|
<button type="submit" class="pxe-btn pxe-btn-ghost btn-row-action">{{ 'Reopen' if r.dismissed else 'Dismiss' }}</button>
|
|
</form>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="text-center text-muted py-5">
|
|
<p class="mb-1">No machines have reported yet.</p>
|
|
<p class="small">Models appear here the next time a machine boots WinPE from this server.</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endblock %}
|