cproudlock 453b42a159 Shopfloor: 05-OfficeShortcuts.ps1 baseline (Excel/Word/PowerPoint)
Office Click-to-Run installs the binaries when an Office-bearing ppkg
is selected (e.g. GCCH_Prod_SFLD_StdOffice-x86_*) but doesn't create
desktop shortcuts - operators only see Office in the Start Menu's
Microsoft 365 folder. This baseline script fills that gap.

Self-detects Office by EXE existence at C:\\Program Files\\Microsoft
Office\\root\\Office16\\ or the (x86) equivalent. No Office found =
silent no-op, so it's safe to run on every PC type (Display kiosks,
Wax/Trace, Keyence, etc.) without needing a per-type filter.

Creates Excel.lnk / Word.lnk / PowerPoint.lnk in two places:
- C:\\Users\\Public\\Desktop\\  - visible to all users immediately
- C:\\Users\\Default\\AppData\\Roaming\\Microsoft\\Windows\\Start
  Menu\\Programs\\  - inherited by every NEW user profile created
  on the device (Azure AD operator logons after enrollment)

Numbered 05- so it runs after 00-PreInstall and 04-NetworkAndWinRM
in the Shopfloor baseline sequence. Idempotent - WScript.Shell's
CreateShortcut overwrites existing .lnks each run.

Outlook / OneNote / Access / Publisher intentionally not shortcutted
(scope decision; can be added by extending the $officeApps array).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 10:11:08 -04:00

GE Aerospace PXE Boot Server

Automated, air-gapped PXE boot server for deploying GE Aerospace Windows images. Built on Ubuntu 24.04 Server with zero-touch provisioning via autoinstall and Ansible.

Overview

This project provides a complete, repeatable build process for a PXE boot server that serves Windows PE images to client machines on an isolated network. Everything runs offline after initial setup — no internet required on the target server.

Boot Chain

Client PXE boot (UEFI Secure Boot)
  -> iPXE (TFTP, Broadcom-signed for Secure Boot)
  -> iPXE boot menu (HTTP, port 4433)
  -> User selects boot option:
     ├── Windows PE  -> wimboot -> boot.wim -> startnet.cmd -> Samba share -> Image deployment
     ├── Clonezilla  -> vmlinuz/initrd -> Disk cloning/imaging
     ├── Blancco     -> Native kernel + initramfs -> NIST 800-88 drive erasure
     └── Memtest86+  -> Memory diagnostics

Services

Service Port Purpose
dnsmasq 67/udp DHCP (10.9.100.10-100, 12h lease)
dnsmasq 69/udp TFTP (serves ipxe.efi)
Apache 80/tcp HTTP (wimboot, WinPE boot files, proxy)
Apache 4433/tcp iPXE boot script (GetPxeScript.aspx)
Samba 445/tcp Deployment content + Clonezilla + Blancco
Flask Webapp 9009/tcp Web management interface

Network

  • PXE server IP: 10.9.100.1/24
  • DHCP range: 10.9.100.10 - 10.9.100.100
  • Firewall: UFW deny-by-default, only service ports open (22, 67, 69, 80, 445, 4433, 9009)

Quick Start

Prerequisites

On your workstation (internet-connected):

  • Ubuntu 24.04 (or Linux Mint / similar) for downloading packages
  • Ubuntu Server 24.04 ISO
  • GE Aerospace Media Creator LITE (for WinPE images)
  • USB drive >= 8 GB (32+ GB if bundling WinPE images)

GE Access Packages (MyAccess portal):

  • EPM Rufus Exception Request
  • EPM DT Functions
  • DLP - Encrypted Removable (USB) Long Term Access

Step 1: Download Offline Packages

./download-packages.sh

Downloads all .deb packages and Python wheels for offline installation (~140 MB of debs, ~20 MB of wheels).

Step 2: Prepare Boot Tools (optional)

./prepare-boot-tools.sh /path/to/blancco.iso /path/to/clonezilla.zip /path/to/memtest.bin

Extracts and configures boot tool files (Blancco, Clonezilla, Memtest86+). Automatically patches Blancco's config.img to auto-save erasure reports to the PXE server's Samba share.

Step 3: Build the USB

sudo ./build-usb.sh /dev/sdX /path/to/ubuntu-24.04-live-server-amd64.iso

Creates a bootable USB with two partitions:

  • Partition 1: Ubuntu Server installer
  • Partition 2: CIDATA (autoinstall config, offline .debs, pip wheels, Ansible playbook, webapp, boot tools)

Step 4: Install on Target Server

  1. Insert USB into the target machine
  2. Press F12 and boot from USB
  3. Ubuntu auto-installs with no interaction
  4. After reboot, the first-boot script:
    • Installs all offline .deb packages
    • Runs the Ansible playbook (configures dnsmasq, Apache, Samba, UFW, webapp)
    • Configures static IP 10.9.100.1/24
  5. Move the server's wired NIC to the isolated PXE switch

Step 5: Access the Web Interface

Open http://10.9.100.1:9009 from any machine on the isolated network.

Web Management Interface

The Flask webapp (port 9009) provides a browser-based management UI:

  • Dashboard — Service status overview, disk usage, connected DHCP clients
  • Image Import — Import WinPE deployment images from USB drives
  • Unattend Editor — Edit Windows unattend.xml files per image type (XML syntax highlighting)
  • startnet.cmd Editor — Modify the startnet.cmd inside boot.wim without Windows (uses wimtools)
  • Clonezilla Backups — Upload, download, and manage disk backup images
  • Blancco Reports — View, download, and manage drive erasure reports (auto-collected via Samba)
  • Image Config — Per-image configuration editor (drivers, OS packages, hardware models)
  • Enrollment — Upload, download, and manage GCCH bulk enrollment packages
  • Audit Log — Activity history for all write operations (imports, edits, deletes)

Image Types Supported

Image Type Domain Description
gea-standard geaerospace.com Standard desktop
gea-engineer geaerospace.com Engineering desktop
gea-shopfloor geaerospace.com Shop floor kiosk
ge-standard ge.com Standard desktop
ge-engineer ge.com Engineering desktop
ge-shopfloor-lockdown ge.com Shop floor (locked)
ge-shopfloor-mce ge.com Shop floor (MCE)

Project Structure

pxe-server/
├── autoinstall/
│   ├── user-data                 # Cloud-init autoinstall config + first-boot script
│   └── meta-data                 # Cloud-init metadata (required, empty)
├── playbook/
│   ├── pxe_server_setup.yml      # Ansible playbook: all server configuration
│   ├── inventory.ini             # Ansible inventory
│   ├── startnet.cmd              # WinPE startup script (injected into boot.wim)
│   ├── blancco-init.sh           # Custom initramfs for Blancco PXE boot
│   ├── blancco-preferences.xml   # Blancco auto-report preferences
│   ├── check-bios.cmd            # Pre-imaging BIOS update checker
│   ├── FlatUnattendW10-shopfloor.xml  # Shopfloor unattend.xml
│   └── shopfloor-setup/          # PC type setup scripts (Standard, CMM, Display, etc.)
├── webapp/
│   ├── app.py                    # Flask application (~1600 lines)
│   ├── requirements.txt          # Python deps (flask, lxml)
│   ├── static/
│   │   ├── ge-aerospace-logo.svg # GE Aerospace branding
│   │   ├── favicon.ico           # Browser favicon
│   │   ├── app.js                # Frontend JavaScript
│   │   ├── bootstrap.min.css     # Bootstrap 5 (bundled offline)
│   │   ├── bootstrap.bundle.min.js
│   │   ├── bootstrap-icons.min.css
│   │   └── fonts/                # Icon fonts (woff/woff2)
│   └── templates/
│       ├── base.html             # Layout with GE branding and sidebar nav
│       ├── dashboard.html        # Service status and overview
│       ├── import.html           # USB image import wizard
│       ├── unattend_editor.html  # XML editor for unattend files
│       ├── startnet_editor.html  # startnet.cmd WIM editor
│       ├── image_config.html     # Per-image driver and hardware config
│       ├── enrollment.html       # GCCH bulk enrollment packages
│       ├── backups.html          # Clonezilla backup management
│       ├── reports.html          # Blancco erasure reports
│       └── audit.html            # Activity audit log
├── docs/
│   └── shopfloor-display-imaging-guide.md  # End-user imaging guide
├── unattend/
│   └── FlatUnattendW10.xml       # Windows unattend.xml template
├── boot-tools/                   # Extracted boot tool files (gitignored)
│   ├── blancco/                  # Blancco Drive Eraser (Arch Linux-based)
│   ├── clonezilla/               # Clonezilla Live
│   └── memtest/                  # Memtest86+
├── offline-packages/             # .deb files (gitignored, built by download-packages.sh)
├── pip-wheels/                   # Python wheels (gitignored, built by download-packages.sh)
├── download-packages.sh          # Downloads offline .debs + pip wheels
├── build-usb.sh                  # Builds the installer USB (2-partition)
├── prepare-boot-tools.sh         # Extracts and patches boot tool files
├── build-proxmox-iso.sh          # Builds self-contained Proxmox installer ISO
├── test-vm.sh                    # KVM test environment for validation
├── test-lab.sh                   # Full PXE lab with server + client VMs
├── startnet-template.cmd         # startnet.cmd template (synced with playbook copy)
├── Download-Drivers.ps1          # Download hardware drivers from GE CDN (Windows)
├── Upload-Image.ps1              # Upload MCL cache to PXE server via SMB (Windows)
├── download-drivers.py           # Download Dell drivers directly from dell.com
├── sync_hardware_models.py       # Sync hardware model configs across images
├── SETUP.md                      # Detailed setup guide
└── setup-guide-original.txt      # Original manual setup notes (reference)

Testing with KVM

A test VM script is included for validating the full provisioning pipeline without dedicated hardware:

# Download Ubuntu Server ISO
wget -O ~/Downloads/ubuntu-24.04.3-live-server-amd64.iso \
  https://releases.ubuntu.com/noble/ubuntu-24.04.3-live-server-amd64.iso

# Launch test VM (requires libvirt/KVM)
sudo ./test-vm.sh ~/Downloads/ubuntu-24.04.3-live-server-amd64.iso

# Watch install progress
sudo virsh console pxe-test

# Clean up when done
sudo ./test-vm.sh --destroy

The test VM creates an isolated libvirt network (10.9.100.0/24) and runs the full autoinstall + Ansible provisioning.

Proxmox Deployment

A single ISO can be built for deploying the PXE server in a Proxmox VM:

Build the ISO

# Prerequisites (on build workstation)
sudo apt install xorriso p7zip-full

# Build the installer ISO
./build-proxmox-iso.sh /path/to/ubuntu-24.04-live-server-amd64.iso

This creates pxe-server-proxmox.iso containing the Ubuntu installer, autoinstall config, all offline packages, the Ansible playbook, webapp, and boot tools.

Deploy on Proxmox

  1. Upload pxe-server-proxmox.iso to Proxmox storage (Datacenter -> Storage -> ISO Images)
  2. Create a new VM:
    • OS: Linux 6.x kernel
    • BIOS: OVMF (UEFI) or SeaBIOS
    • Memory: 4096 MB
    • CPU: 2+ cores
    • Disk: 40+ GB (VirtIO SCSI)
    • Network: Bridge connected to your isolated PXE network
  3. Attach the ISO as CD-ROM and start the VM
  4. Ubuntu auto-installs with zero interaction (~10-15 minutes)
  5. After reboot, first-boot configures all PXE services automatically
  6. Access the web interface at http://10.9.100.1:9009

Import WinPE Images

After the server is running, import deployment images via the web interface at http://10.9.100.1:9009/import or by mounting a USB drive with WinPE content.

Samba Shares

Share Path Purpose
winpeapps /srv/samba/winpeapps WinPE deployment images
clonezilla /srv/samba/clonezilla Clonezilla disk backup images
blancco-reports /srv/samba/blancco-reports Blancco erasure reports (auto)
enrollment /srv/samba/enrollment GCCH bulk enrollment packages
image-upload /home/pxe/image-upload Image upload staging area

All shares use guest access (no authentication) for ease of use on the isolated network.

Blancco Drive Erasure

Blancco Drive Eraser 7.15.1 boots via a native Ubuntu kernel with a custom initramfs (blancco-init.sh) that downloads and mounts the Blancco rootfs over HTTP. XML erasure reports are automatically saved to the PXE server's Samba share (blancco-reports). The server supports BMC cloud licensing for Blancco activation over WiFi.

Reports are viewable and downloadable from the web interface at http://10.9.100.1:9009/reports.

Notes

  • Run download-packages.sh before building USB — it downloads all offline .deb packages including wimtools (needed for startnet.cmd editing)
  • The webapp uses session-based CSRF tokens on all POST forms and API endpoints

Commit History

Commit Description
5791bd1 Initial project setup: automated PXE server provisioning
cee4ecd Add web management UI, offline packages, WinPE consolidation
f614596 Fix unattend.xml path to match actual image structure
e7313c2 Add multi-boot PXE menu, Clonezilla backups, GE Aerospace branding
89b5834 Add wimtools and startnet.cmd editor for boot.wim modification
05dbb7e Add Blancco erasure reports Samba share and webapp viewer
ef75839 Auto-patch Blancco config.img for network report storage
92c9b0f Fix review findings: offline assets, security, audit logging
725c8f4 Change webapp to port 9009, add test VM script
f3a384f Add Proxmox ISO builder, CSRF protection, boot-files integration
1a5c4f7 Eliminate USB requirement for WinPE PXE boot
dd2fec5 Blancco PXE boot via Ubuntu kernel switch_root
86660a0 Remove UEFI HTTP Boot config from dnsmasq
6d0e6ee BIOS check fix, parallel downloads, shopfloor hardening
7616549 Shopfloor PC type system, webapp enhancements
b7cd097 Blancco 7.15.1 upgrade: native kernel boot, BMC cloud licensing
163e58a Fix dnsmasq reboot cron: use /etc/cron.d/ instead of crontab
Description
PXE Boot Server Setup - Automated Ubuntu PXE server for deploying GE Aerospace Windows images
Readme 2.8 MiB
Languages
PowerShell 51.9%
Python 15.6%
Shell 11.4%
HTML 10.8%
Batchfile 7.1%
Other 3.2%