Initial project setup: automated PXE server provisioning
Reorganized from OneDrive export into a clean project structure: - autoinstall/: cloud-init user-data and meta-data for Ubuntu 24.04 autoinstall - playbook/: Ansible playbook for PXE server config (dnsmasq, Apache, Samba, iPXE) - unattend/: Windows unattend.xml sample for image deployment - build-usb.sh: builds a bootable USB with Ubuntu installer + CIDATA partition - download-packages.sh: downloads all offline .deb dependencies via Docker Key improvements over original: - Fully air-gapped: all packages bundled offline, no WiFi needed - Hardware-agnostic network config (wildcard NIC matching) - Removed plaintext WiFi credentials - Single USB build process (was 15+ manual steps) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
30
.gitignore
vendored
Normal file
30
.gitignore
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# Large binary files — download/build these, don't commit them
|
||||||
|
*.deb
|
||||||
|
*.zip
|
||||||
|
*.wim
|
||||||
|
*.iso
|
||||||
|
*.efi
|
||||||
|
*.sdi
|
||||||
|
|
||||||
|
# OneDrive download artifacts
|
||||||
|
OneDrive_*/
|
||||||
|
|
||||||
|
# Error folders from OneDrive download
|
||||||
|
__*/
|
||||||
|
___*.txt
|
||||||
|
|
||||||
|
# Original OneDrive folder structure (reorganized into autoinstall/ and playbook/)
|
||||||
|
WestJeff*/
|
||||||
|
|
||||||
|
# Duplicate at root (canonical copy in unattend/)
|
||||||
|
/FlatUnattendW10.xml
|
||||||
|
|
||||||
|
# Offline packages (built by download-packages.sh)
|
||||||
|
offline-packages/
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Secrets
|
||||||
|
secrets.md
|
||||||
0
autoinstall/meta-data
Normal file
0
autoinstall/meta-data
Normal file
106
autoinstall/user-data
Normal file
106
autoinstall/user-data
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
#cloud-config
|
||||||
|
autoinstall:
|
||||||
|
version: 1
|
||||||
|
|
||||||
|
# Locale, keyboard, timezone
|
||||||
|
locale: en_US.UTF-8
|
||||||
|
keyboard:
|
||||||
|
layout: us
|
||||||
|
variant: ""
|
||||||
|
timezone: America/New_York
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
# Uses a broad match so any wired NIC gets the static PXE address.
|
||||||
|
# No WiFi needed — all packages are on the CIDATA partition.
|
||||||
|
network:
|
||||||
|
version: 2
|
||||||
|
ethernets:
|
||||||
|
any-eth:
|
||||||
|
match:
|
||||||
|
name: "en*"
|
||||||
|
addresses:
|
||||||
|
- 10.9.100.1/24
|
||||||
|
dhcp4: false
|
||||||
|
dhcp6: false
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
# Storage configuration
|
||||||
|
storage:
|
||||||
|
layout:
|
||||||
|
name: lvm
|
||||||
|
match:
|
||||||
|
size: largest
|
||||||
|
swap:
|
||||||
|
size: 0
|
||||||
|
|
||||||
|
# User identity
|
||||||
|
identity:
|
||||||
|
hostname: pxeserver
|
||||||
|
username: pxe
|
||||||
|
password: "$6$rounds=656000$TpsuBw0N85085mpx$KtKsCwFlowg4NY41gUqx5ljef8cJ8uPFfgg43MyCPWByfXkhM5XushcdtkNps6lKeQFQZtli/QU.s52AUc7XC."
|
||||||
|
|
||||||
|
# Installer-stage late commands
|
||||||
|
late-commands:
|
||||||
|
# Install deb packages from CIDATA USB
|
||||||
|
- |
|
||||||
|
curtin in-target --target=/target -- bash -c '
|
||||||
|
mkdir -p /mnt/cidata
|
||||||
|
CIDATA_DEV=$(blkid -L CIDATA)
|
||||||
|
if [ -n "$CIDATA_DEV" ]; then
|
||||||
|
mount "$CIDATA_DEV" /mnt/cidata
|
||||||
|
if compgen -G "/mnt/cidata/packages/*.deb" > /dev/null; then
|
||||||
|
cp /mnt/cidata/packages/*.deb /tmp/
|
||||||
|
dpkg -i /tmp/*.deb 2>/dev/null || true
|
||||||
|
dpkg -i /tmp/*.deb 2>/dev/null || true
|
||||||
|
if command -v nmcli >/dev/null; then
|
||||||
|
systemctl enable NetworkManager
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
umount /mnt/cidata
|
||||||
|
fi
|
||||||
|
'
|
||||||
|
|
||||||
|
# Create first-boot.sh
|
||||||
|
- |
|
||||||
|
curtin in-target --target=/target -- bash -c '
|
||||||
|
cat <<"EOF" > /opt/first-boot.sh
|
||||||
|
#!/bin/bash
|
||||||
|
CIDATA_DEV=$(blkid -L CIDATA)
|
||||||
|
if [ -n "$CIDATA_DEV" ]; then
|
||||||
|
mkdir -p /mnt/usb
|
||||||
|
mount "$CIDATA_DEV" /mnt/usb
|
||||||
|
# Install all offline .deb packages (ansible, dnsmasq, apache2, samba, etc.)
|
||||||
|
if compgen -G "/mnt/usb/packages/*.deb" > /dev/null; then
|
||||||
|
dpkg -i /mnt/usb/packages/*.deb 2>/dev/null || true
|
||||||
|
dpkg -i /mnt/usb/packages/*.deb 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
# Run the Ansible playbook
|
||||||
|
if [ -f /mnt/usb/playbook/pxe_server_setup.yml ]; then
|
||||||
|
cd /mnt/usb/playbook
|
||||||
|
ansible-playbook -i localhost, -c local pxe_server_setup.yml
|
||||||
|
fi
|
||||||
|
umount /mnt/usb
|
||||||
|
fi
|
||||||
|
# Disable rc.local to prevent rerunning
|
||||||
|
sed -i "s|^/opt/first-boot.sh.*|# &|" /etc/rc.local
|
||||||
|
lvextend -r -l +100%FREE /dev/mapper/ubuntu--vg-ubuntu--lv || true
|
||||||
|
EOF
|
||||||
|
'
|
||||||
|
- curtin in-target --target=/target -- chmod +x /opt/first-boot.sh
|
||||||
|
|
||||||
|
# Create rc.local without unintended indentation
|
||||||
|
- |
|
||||||
|
curtin in-target --target=/target -- bash -c '
|
||||||
|
cat <<"EOF" > /etc/rc.local
|
||||||
|
#!/bin/bash
|
||||||
|
/opt/first-boot.sh > /var/log/first-boot.log 2>&1 &
|
||||||
|
exit 0
|
||||||
|
EOF
|
||||||
|
'
|
||||||
|
- curtin in-target --target=/target -- chmod +x /etc/rc.local
|
||||||
|
|
||||||
|
user-data:
|
||||||
|
disable_root: false
|
||||||
|
|
||||||
|
refresh-installer:
|
||||||
|
update: yes
|
||||||
196
build-usb.sh
Executable file
196
build-usb.sh
Executable file
@@ -0,0 +1,196 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# build-usb.sh — Build a bootable PXE-server installer USB
|
||||||
|
#
|
||||||
|
# Creates a two-partition USB:
|
||||||
|
# Partition 1: Ubuntu Server 24.04 installer (ISO contents)
|
||||||
|
# Partition 2: CIDATA volume (autoinstall config, .debs, playbook)
|
||||||
|
#
|
||||||
|
# The target machine boots from this USB, Ubuntu auto-installs with
|
||||||
|
# cloud-init (user-data/meta-data from CIDATA), installs offline .debs,
|
||||||
|
# and on first boot runs the Ansible playbook to configure PXE services.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# sudo ./build-usb.sh /dev/sdX /path/to/ubuntu-24.04-live-server-amd64.iso
|
||||||
|
#
|
||||||
|
# WARNING: This will ERASE the target USB device.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
AUTOINSTALL_DIR="$SCRIPT_DIR/autoinstall"
|
||||||
|
PLAYBOOK_DIR="$SCRIPT_DIR/playbook"
|
||||||
|
OFFLINE_PKG_DIR="$SCRIPT_DIR/offline-packages"
|
||||||
|
|
||||||
|
# --- Validate arguments ---
|
||||||
|
if [ $# -ne 2 ]; then
|
||||||
|
echo "Usage: sudo $0 /dev/sdX /path/to/ubuntu-24.04.iso"
|
||||||
|
echo ""
|
||||||
|
echo "Available removable devices:"
|
||||||
|
lsblk -d -o NAME,SIZE,TRAN,RM | grep -E '^\S+\s+\S+\s+(usb)\s+1'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
USB_DEV="$1"
|
||||||
|
ISO_PATH="$2"
|
||||||
|
|
||||||
|
# Safety checks
|
||||||
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
|
echo "ERROR: Must run as root (sudo)."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -b "$USB_DEV" ]; then
|
||||||
|
echo "ERROR: $USB_DEV is not a block device."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$ISO_PATH" ]; then
|
||||||
|
echo "ERROR: ISO not found at $ISO_PATH"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify it's a removable device (safety against wiping system disks)
|
||||||
|
REMOVABLE=$(lsblk -nd -o RM "$USB_DEV" 2>/dev/null || echo "0")
|
||||||
|
if [ "$REMOVABLE" != "1" ]; then
|
||||||
|
echo "WARNING: $USB_DEV does not appear to be a removable device."
|
||||||
|
read -rp "Are you SURE you want to erase $USB_DEV? (type YES): " CONFIRM
|
||||||
|
if [ "$CONFIRM" != "YES" ]; then
|
||||||
|
echo "Aborted."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify required source files exist
|
||||||
|
if [ ! -f "$AUTOINSTALL_DIR/user-data" ]; then
|
||||||
|
echo "ERROR: user-data not found at $AUTOINSTALL_DIR/user-data"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$AUTOINSTALL_DIR/meta-data" ]; then
|
||||||
|
echo "ERROR: meta-data not found at $AUTOINSTALL_DIR/meta-data"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$PLAYBOOK_DIR/pxe_server_setup.yml" ]; then
|
||||||
|
echo "ERROR: pxe_server_setup.yml not found at $PLAYBOOK_DIR/"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "============================================"
|
||||||
|
echo "PXE Server USB Builder"
|
||||||
|
echo "============================================"
|
||||||
|
echo "USB Device : $USB_DEV"
|
||||||
|
echo "ISO : $ISO_PATH"
|
||||||
|
echo "Source Dir : $SCRIPT_DIR"
|
||||||
|
echo ""
|
||||||
|
echo "This will ERASE all data on $USB_DEV."
|
||||||
|
read -rp "Continue? (y/N): " PROCEED
|
||||||
|
if [[ ! "$PROCEED" =~ ^[Yy]$ ]]; then
|
||||||
|
echo "Aborted."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Unmount any existing partitions ---
|
||||||
|
echo ""
|
||||||
|
echo "[1/6] Unmounting existing partitions on $USB_DEV..."
|
||||||
|
for part in "${USB_DEV}"*; do
|
||||||
|
umount "$part" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
|
||||||
|
# --- Write ISO to USB ---
|
||||||
|
echo "[2/6] Writing Ubuntu ISO to $USB_DEV (this may take several minutes)..."
|
||||||
|
dd if="$ISO_PATH" of="$USB_DEV" bs=4M status=progress oflag=sync
|
||||||
|
sync
|
||||||
|
|
||||||
|
# --- Find the end of the ISO to create CIDATA partition ---
|
||||||
|
echo "[3/6] Creating CIDATA partition after ISO data..."
|
||||||
|
|
||||||
|
# Get ISO size in bytes and calculate the start sector for the new partition
|
||||||
|
ISO_SIZE=$(stat -c%s "$ISO_PATH")
|
||||||
|
SECTOR_SIZE=512
|
||||||
|
# Start the CIDATA partition 1MB after the ISO ends (alignment)
|
||||||
|
START_SECTOR=$(( (ISO_SIZE / SECTOR_SIZE) + 2048 ))
|
||||||
|
|
||||||
|
# Use sfdisk to append a new partition
|
||||||
|
echo " ISO size: $((ISO_SIZE / 1024 / 1024)) MB"
|
||||||
|
echo " CIDATA partition starts at sector $START_SECTOR"
|
||||||
|
|
||||||
|
# Add a new partition using sfdisk --append
|
||||||
|
echo "${START_SECTOR},+,L" | sfdisk --append "$USB_DEV" --no-reread 2>/dev/null || true
|
||||||
|
partprobe "$USB_DEV"
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
# Determine the new partition name (could be sdX3, sdX4, etc.)
|
||||||
|
CIDATA_PART=""
|
||||||
|
for part in "${USB_DEV}"[0-9]*; do
|
||||||
|
# Find the partition that starts at or after our start sector
|
||||||
|
PART_START=$(sfdisk -d "$USB_DEV" 2>/dev/null | grep "$part" | grep -o 'start=[[:space:]]*[0-9]*' | grep -o '[0-9]*')
|
||||||
|
if [ -n "$PART_START" ] && [ "$PART_START" -ge "$START_SECTOR" ]; then
|
||||||
|
CIDATA_PART="$part"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Fallback: use the last partition
|
||||||
|
if [ -z "$CIDATA_PART" ]; then
|
||||||
|
CIDATA_PART=$(lsblk -ln -o NAME "$USB_DEV" | tail -1)
|
||||||
|
CIDATA_PART="/dev/$CIDATA_PART"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " CIDATA partition: $CIDATA_PART"
|
||||||
|
|
||||||
|
# --- Format CIDATA partition ---
|
||||||
|
echo "[4/6] Formatting $CIDATA_PART as FAT32 (label: CIDATA)..."
|
||||||
|
mkfs.vfat -F 32 -n CIDATA "$CIDATA_PART"
|
||||||
|
|
||||||
|
# --- Mount and copy files ---
|
||||||
|
echo "[5/6] Copying autoinstall config, packages, and playbook to CIDATA..."
|
||||||
|
MOUNT_POINT=$(mktemp -d)
|
||||||
|
mount "$CIDATA_PART" "$MOUNT_POINT"
|
||||||
|
|
||||||
|
# Copy cloud-init files
|
||||||
|
cp "$AUTOINSTALL_DIR/user-data" "$MOUNT_POINT/"
|
||||||
|
cp "$AUTOINSTALL_DIR/meta-data" "$MOUNT_POINT/"
|
||||||
|
|
||||||
|
# Copy offline .deb packages into packages/ subdirectory
|
||||||
|
mkdir -p "$MOUNT_POINT/packages"
|
||||||
|
DEB_COUNT=0
|
||||||
|
|
||||||
|
if [ -d "$OFFLINE_PKG_DIR" ]; then
|
||||||
|
for deb in "$OFFLINE_PKG_DIR"/*.deb; do
|
||||||
|
if [ -f "$deb" ]; then
|
||||||
|
cp "$deb" "$MOUNT_POINT/packages/"
|
||||||
|
DEB_COUNT=$((DEB_COUNT + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
echo " Copied $DEB_COUNT .deb packages to packages/"
|
||||||
|
|
||||||
|
# Copy playbook directory
|
||||||
|
cp -r "$PLAYBOOK_DIR" "$MOUNT_POINT/playbook"
|
||||||
|
echo " Copied playbook/"
|
||||||
|
|
||||||
|
# List what's on CIDATA
|
||||||
|
echo ""
|
||||||
|
echo " CIDATA contents:"
|
||||||
|
ls -lh "$MOUNT_POINT/" | sed 's/^/ /'
|
||||||
|
|
||||||
|
# --- Cleanup ---
|
||||||
|
echo ""
|
||||||
|
echo "[6/6] Syncing and unmounting..."
|
||||||
|
sync
|
||||||
|
umount "$MOUNT_POINT"
|
||||||
|
rmdir "$MOUNT_POINT"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "============================================"
|
||||||
|
echo "USB build complete!"
|
||||||
|
echo "============================================"
|
||||||
|
echo ""
|
||||||
|
echo "Next steps:"
|
||||||
|
echo " 1. Insert USB into target machine"
|
||||||
|
echo " 2. Boot from USB (F12 / boot menu)"
|
||||||
|
echo " 3. Ubuntu will auto-install and configure the PXE server"
|
||||||
|
echo " 4. After reboot, move the NIC to the isolated PXE network"
|
||||||
|
echo ""
|
||||||
83
download-packages.sh
Executable file
83
download-packages.sh
Executable file
@@ -0,0 +1,83 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# download-packages.sh — Download all .deb packages needed for offline PXE server setup
|
||||||
|
#
|
||||||
|
# Run this on a machine with internet access running Ubuntu 24.04 (Noble).
|
||||||
|
# It downloads every .deb needed by the Ansible playbook into a local directory,
|
||||||
|
# which then gets bundled onto the installer USB.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./download-packages.sh [output_directory]
|
||||||
|
#
|
||||||
|
# Default output: ./offline-packages/
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
OUT_DIR="${1:-./offline-packages}"
|
||||||
|
mkdir -p "$OUT_DIR"
|
||||||
|
|
||||||
|
# Packages installed by the Ansible playbook (pxe_server_setup.yml)
|
||||||
|
PLAYBOOK_PACKAGES=(
|
||||||
|
ansible
|
||||||
|
dnsmasq
|
||||||
|
apache2
|
||||||
|
samba
|
||||||
|
unzip
|
||||||
|
ufw
|
||||||
|
cron
|
||||||
|
)
|
||||||
|
|
||||||
|
# Packages installed during autoinstall late-commands (NetworkManager, WiFi, etc.)
|
||||||
|
# These are already in your ubuntu_playbook/*.deb files, but we can refresh them here too.
|
||||||
|
AUTOINSTALL_PACKAGES=(
|
||||||
|
network-manager
|
||||||
|
wpasupplicant
|
||||||
|
wireless-tools
|
||||||
|
linux-firmware
|
||||||
|
firmware-sof-signed
|
||||||
|
)
|
||||||
|
|
||||||
|
ALL_PACKAGES=("${PLAYBOOK_PACKAGES[@]}" "${AUTOINSTALL_PACKAGES[@]}")
|
||||||
|
|
||||||
|
echo "============================================"
|
||||||
|
echo "Offline Package Downloader"
|
||||||
|
echo "============================================"
|
||||||
|
echo "Output directory: $OUT_DIR"
|
||||||
|
echo ""
|
||||||
|
echo "Packages to resolve:"
|
||||||
|
printf ' - %s\n' "${ALL_PACKAGES[@]}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Update package cache
|
||||||
|
echo "[1/3] Updating package cache..."
|
||||||
|
sudo apt-get update -qq
|
||||||
|
|
||||||
|
# Simulate install to find all dependencies
|
||||||
|
echo "[2/3] Resolving dependencies..."
|
||||||
|
DEPS=$(apt-get install --simulate "${ALL_PACKAGES[@]}" 2>&1 \
|
||||||
|
| grep "^Inst " \
|
||||||
|
| awk '{print $2}' \
|
||||||
|
| sort -u)
|
||||||
|
|
||||||
|
DEP_COUNT=$(echo "$DEPS" | wc -l)
|
||||||
|
echo " Found $DEP_COUNT packages (including dependencies)"
|
||||||
|
|
||||||
|
# Download all packages
|
||||||
|
echo "[3/3] Downloading packages to $OUT_DIR..."
|
||||||
|
cd "$OUT_DIR"
|
||||||
|
apt-get download $DEPS 2>&1 | tail -5
|
||||||
|
|
||||||
|
DEB_COUNT=$(ls -1 *.deb 2>/dev/null | wc -l)
|
||||||
|
TOTAL_SIZE=$(du -sh . | cut -f1)
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "============================================"
|
||||||
|
echo "Download complete!"
|
||||||
|
echo "============================================"
|
||||||
|
echo " Packages: $DEB_COUNT"
|
||||||
|
echo " Total size: $TOTAL_SIZE"
|
||||||
|
echo " Location: $OUT_DIR/"
|
||||||
|
echo ""
|
||||||
|
echo "Next: copy these into your ubuntu_playbook/ directory"
|
||||||
|
echo " cp $OUT_DIR/*.deb /path/to/ubuntu_playbook/"
|
||||||
|
echo ""
|
||||||
2
playbook/inventory.ini
Normal file
2
playbook/inventory.ini
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[pxe_servers]
|
||||||
|
localhost ansible_connection=local
|
||||||
272
playbook/pxe_server_setup.yml
Normal file
272
playbook/pxe_server_setup.yml
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
---
|
||||||
|
- name: PXE Server Setup (Ubuntu with dnsmasq)
|
||||||
|
hosts: localhost
|
||||||
|
connection: local
|
||||||
|
become: yes
|
||||||
|
gather_facts: yes
|
||||||
|
|
||||||
|
pre_tasks:
|
||||||
|
- name: "Verify required packages are installed (pre-installed from offline .debs)"
|
||||||
|
command: dpkg -s {{ item }}
|
||||||
|
loop:
|
||||||
|
- dnsmasq
|
||||||
|
- apache2
|
||||||
|
- samba
|
||||||
|
- unzip
|
||||||
|
- ufw
|
||||||
|
- cron
|
||||||
|
- ansible
|
||||||
|
register: pkg_check
|
||||||
|
failed_when: false
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: "Warn about missing packages"
|
||||||
|
debug:
|
||||||
|
msg: "WARNING: {{ item.item }} is not installed! Install offline .debs first."
|
||||||
|
loop: "{{ pkg_check.results }}"
|
||||||
|
when: item.rc != 0
|
||||||
|
|
||||||
|
vars:
|
||||||
|
tftp_dir: "/srv/tftp"
|
||||||
|
web_root: "/var/www/html"
|
||||||
|
samba_share: "/srv/samba/winpeapps"
|
||||||
|
usb_mount: "/mnt/usb/playbook" # where your USB is mounted
|
||||||
|
image_types:
|
||||||
|
- geastandardpbr
|
||||||
|
- geaengineerpbr
|
||||||
|
- geashopfloorpbr
|
||||||
|
- gestandardlegacy
|
||||||
|
- geengineerlegacy
|
||||||
|
- geshopfloorlegacy
|
||||||
|
deploy_subdirs:
|
||||||
|
- Applications
|
||||||
|
- Control
|
||||||
|
- "Operating Systems"
|
||||||
|
- "Out-of-box Drivers"
|
||||||
|
- Packages
|
||||||
|
- Tools
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: "Gather minimal network facts"
|
||||||
|
ansible.builtin.setup:
|
||||||
|
filter:
|
||||||
|
- ansible_interfaces
|
||||||
|
- ansible_default_ipv4
|
||||||
|
|
||||||
|
- name: "Bring up all ethernet-like interfaces"
|
||||||
|
command: ip link set dev {{ item }} up
|
||||||
|
loop: "{{ ansible_interfaces | select('match','^e(th|n)') | list }}"
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- name: "Determine PXE interface"
|
||||||
|
set_fact:
|
||||||
|
pxe_iface: >-
|
||||||
|
{{ (ansible_interfaces
|
||||||
|
| select('match','^e(th|n)')
|
||||||
|
| reject('equalto','lo')
|
||||||
|
| reject('equalto', ansible_default_ipv4.interface)
|
||||||
|
| list
|
||||||
|
)
|
||||||
|
| first
|
||||||
|
| default(ansible_default_ipv4.interface) }}
|
||||||
|
|
||||||
|
- name: "Debug: final pxe_iface choice"
|
||||||
|
debug:
|
||||||
|
msg: "Using {{ pxe_iface }} for DHCP/TFTP"
|
||||||
|
|
||||||
|
- name: "Configure dnsmasq for DHCP and TFTP"
|
||||||
|
copy:
|
||||||
|
dest: /etc/dnsmasq.conf
|
||||||
|
backup: yes
|
||||||
|
content: |
|
||||||
|
port=0
|
||||||
|
interface={{ pxe_iface }}
|
||||||
|
bind-interfaces
|
||||||
|
dhcp-range=10.9.100.10,10.9.100.100,12h
|
||||||
|
dhcp-option=3,10.9.100.1
|
||||||
|
dhcp-option=6,8.8.8.8
|
||||||
|
enable-tftp
|
||||||
|
tftp-root={{ tftp_dir }}
|
||||||
|
dhcp-boot=ipxe.efi
|
||||||
|
|
||||||
|
- name: "Create TFTP directory"
|
||||||
|
file:
|
||||||
|
path: "{{ tftp_dir }}"
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
owner: nobody
|
||||||
|
group: nogroup
|
||||||
|
|
||||||
|
- name: "Create Win11 directory structure"
|
||||||
|
file:
|
||||||
|
path: "{{ web_root }}/win11/{{ item }}"
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
loop:
|
||||||
|
- "EFI/Boot"
|
||||||
|
- "EFI/Microsoft/Boot"
|
||||||
|
- "Boot"
|
||||||
|
- "sources"
|
||||||
|
|
||||||
|
- name: "Create Altiris iPXE directory"
|
||||||
|
file:
|
||||||
|
path: "{{ web_root }}/Altiris/iPXE"
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: "Create GetPxeScript.aspx"
|
||||||
|
copy:
|
||||||
|
dest: "{{ web_root }}/Altiris/iPXE/GetPxeScript.aspx"
|
||||||
|
backup: yes
|
||||||
|
content: |
|
||||||
|
#!ipxe
|
||||||
|
|
||||||
|
set server 10.9.100.1
|
||||||
|
|
||||||
|
kernel http://${server}/win11/wimboot gui
|
||||||
|
|
||||||
|
initrd http://${server}/win11/EFI/Microsoft/Boot/boot.stl EFI/Microsoft/Boot/Boot.stl
|
||||||
|
initrd http://${server}/win11/EFI/Microsoft/Boot/BCD EFI/Microsoft/Boot/BCD
|
||||||
|
initrd http://${server}/win11/EFI/Boot/bootx64.efi EFI/Boot/bootx64.efi
|
||||||
|
initrd http://${server}/win11/Boot/boot.sdi Boot/boot.sdi
|
||||||
|
initrd http://${server}/win11/sources/boot.wim sources/boot.wim
|
||||||
|
|
||||||
|
boot
|
||||||
|
|
||||||
|
- name: "Ensure Apache listens on port 4433"
|
||||||
|
lineinfile:
|
||||||
|
path: /etc/apache2/ports.conf
|
||||||
|
line: "Listen 4433"
|
||||||
|
backup: yes
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: "Create VirtualHost for Altiris iPXE on 4433"
|
||||||
|
copy:
|
||||||
|
dest: /etc/apache2/sites-available/altiris-ipxe.conf
|
||||||
|
backup: yes
|
||||||
|
content: |
|
||||||
|
<VirtualHost *:4433>
|
||||||
|
DocumentRoot {{ web_root }}
|
||||||
|
<Directory "{{ web_root }}/Altiris/iPXE">
|
||||||
|
Options Indexes FollowSymLinks
|
||||||
|
AllowOverride None
|
||||||
|
Require all granted
|
||||||
|
AddType text/plain .aspx
|
||||||
|
</Directory>
|
||||||
|
</VirtualHost>
|
||||||
|
|
||||||
|
- name: "Enable Altiris iPXE site"
|
||||||
|
command: a2ensite altiris-ipxe.conf
|
||||||
|
args:
|
||||||
|
creates: /etc/apache2/sites-enabled/altiris-ipxe.conf
|
||||||
|
|
||||||
|
- name: "Reload Apache to apply changes"
|
||||||
|
systemd:
|
||||||
|
name: apache2
|
||||||
|
state: reloaded
|
||||||
|
|
||||||
|
- name: "Create Samba share root"
|
||||||
|
file:
|
||||||
|
path: "{{ samba_share }}"
|
||||||
|
state: directory
|
||||||
|
mode: '0777'
|
||||||
|
|
||||||
|
- name: "Configure Samba share"
|
||||||
|
blockinfile:
|
||||||
|
path: /etc/samba/smb.conf
|
||||||
|
backup: yes
|
||||||
|
block: |
|
||||||
|
[winpeapps]
|
||||||
|
path = {{ samba_share }}
|
||||||
|
browseable = yes
|
||||||
|
read only = no
|
||||||
|
guest ok = yes
|
||||||
|
|
||||||
|
- name: "Create image-type top-level directories"
|
||||||
|
file:
|
||||||
|
path: "{{ samba_share }}/{{ item }}"
|
||||||
|
state: directory
|
||||||
|
mode: '0777'
|
||||||
|
loop: "{{ image_types }}"
|
||||||
|
|
||||||
|
- name: "Create Deploy subdirectories for each image type"
|
||||||
|
file:
|
||||||
|
path: "{{ samba_share }}/{{ item.0 }}/Deploy/{{ item.1 }}"
|
||||||
|
state: directory
|
||||||
|
mode: '0777'
|
||||||
|
with_nested:
|
||||||
|
- "{{ image_types }}"
|
||||||
|
- "{{ deploy_subdirs }}"
|
||||||
|
|
||||||
|
- name: "Copy WinPE & boot files from USB"
|
||||||
|
copy:
|
||||||
|
src: "{{ usb_mount }}/{{ item.src }}"
|
||||||
|
dest: "{{ web_root }}/win11/{{ item.dest }}"
|
||||||
|
mode: '0644'
|
||||||
|
loop:
|
||||||
|
- { src: "wimboot", dest: "wimboot" }
|
||||||
|
- { src: "boot.stl", dest: "EFI/Microsoft/Boot/boot.stl" }
|
||||||
|
- { src: "BCD", dest: "EFI/Microsoft/Boot/BCD" }
|
||||||
|
- { src: "bootx64.efi", dest: "EFI/Boot/bootx64.efi" }
|
||||||
|
- { src: "boot.sdi", dest: "Boot/boot.sdi" }
|
||||||
|
- { src: "boot.wim", dest: "sources/boot.wim" }
|
||||||
|
|
||||||
|
- name: "Copy iPXE binaries from USB"
|
||||||
|
copy:
|
||||||
|
src: "{{ usb_mount }}/{{ item }}"
|
||||||
|
dest: "{{ tftp_dir }}/{{ item }}"
|
||||||
|
mode: '0755'
|
||||||
|
loop:
|
||||||
|
- ipxe.efi
|
||||||
|
|
||||||
|
- name: "Restart and enable services"
|
||||||
|
systemd:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: restarted
|
||||||
|
enabled: yes
|
||||||
|
loop:
|
||||||
|
- dnsmasq
|
||||||
|
- apache2
|
||||||
|
- smbd
|
||||||
|
|
||||||
|
- name: "Allow necessary firewall ports (UFW)"
|
||||||
|
ufw:
|
||||||
|
rule: allow
|
||||||
|
port: "{{ item }}"
|
||||||
|
proto: "{{ 'udp' if item in ['67','69'] else 'tcp' }}"
|
||||||
|
loop:
|
||||||
|
- 67
|
||||||
|
- 69
|
||||||
|
- 80
|
||||||
|
- 4433
|
||||||
|
- 445
|
||||||
|
|
||||||
|
- name: "Enable UFW firewall"
|
||||||
|
ufw:
|
||||||
|
state: enabled
|
||||||
|
policy: allow
|
||||||
|
|
||||||
|
- name: "Schedule dnsmasq restart 15s after reboot"
|
||||||
|
cron:
|
||||||
|
name: "Restart dnsmasq after reboot"
|
||||||
|
user: root
|
||||||
|
special_time: "reboot"
|
||||||
|
job: "/bin/sleep 15 && /usr/bin/systemctl restart dnsmasq.service"
|
||||||
|
|
||||||
|
- name: "Configure static IP for PXE interface"
|
||||||
|
copy:
|
||||||
|
dest: /etc/netplan/50-cloud-init.yaml
|
||||||
|
backup: yes
|
||||||
|
content: |
|
||||||
|
network:
|
||||||
|
version: 2
|
||||||
|
renderer: networkd
|
||||||
|
ethernets:
|
||||||
|
{{ pxe_iface }}:
|
||||||
|
dhcp4: no
|
||||||
|
addresses: [10.9.100.1/24]
|
||||||
|
notify: "Apply netplan"
|
||||||
|
|
||||||
|
handlers:
|
||||||
|
- name: "Apply netplan"
|
||||||
|
command: netplan apply
|
||||||
129
setup-guide-original.txt
Normal file
129
setup-guide-original.txt
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
Purpose
|
||||||
|
Document a repeatable, “build-from-scratch” procedure for deploying an Ubuntu-based PXE boot server that can host GE Aerospace Windows PE images.
|
||||||
|
|
||||||
|
Prerequisites
|
||||||
|
Hardware: Server or PC with ≥ 8 GB RAM, ≥ 250 GB disk, and one NIC (one for build / Internet, one for isolated PXE LAN)
|
||||||
|
|
||||||
|
https://myaccess.microsoft.us/@ge.onmicrosoft.us#/access-packages/active
|
||||||
|
|
||||||
|
EPM Rufus Exception Request
|
||||||
|
EPM DT Functions
|
||||||
|
DLP - Encrypted Removable (USB) Long Term Access
|
||||||
|
|
||||||
|
Software:
|
||||||
|
|
||||||
|
Ubuntu Server 24.04 ISO
|
||||||
|
|
||||||
|
Rufus (latest)
|
||||||
|
|
||||||
|
playbook folder containing pxe_server_setup.yml and supporting files
|
||||||
|
|
||||||
|
GE Aerospace Media Creator LITE (for caching WinPE images)
|
||||||
|
|
||||||
|
Two USB thumb drives (one ≥ 8 GB for Ubuntu install; one ≥ 32 GB for WinPE media)
|
||||||
|
|
||||||
|
Step-by-Step Procedure
|
||||||
|
Create the Ubuntu Server installer USB
|
||||||
|
1.1 Download Ubuntu Server 24.04 from https://ubuntu.com/download/server.
|
||||||
|
1.2 Download and run Rufus (https://rufus.ie/en/).
|
||||||
|
1.3 Insert an empty USB, select it in Rufus.
|
||||||
|
1.4 Click Select, browse to the Ubuntu ISO, then click Start.
|
||||||
|
1.5 When Rufus finishes, copy your playbook folder to the root of that same USB, then eject it safely.
|
||||||
|
|
||||||
|
Install Ubuntu on the PXE server
|
||||||
|
2.1 Insert the USB into the target machine and power on.
|
||||||
|
2.2 Press F12 (or the vendor’s one-time boot key) and choose the USB device.
|
||||||
|
2.3 Follow Ubuntu’s installer;
|
||||||
|
Network configuration screen.
|
||||||
|
Select the fist option select give it random network and IPv4 address
|
||||||
|
Then select WiFi and choose the guest network.
|
||||||
|
Follow the prompts and enter the information for your network.
|
||||||
|
Click done.
|
||||||
|
|
||||||
|
You do not need a proxy hit done.
|
||||||
|
For mirror address add nothing and hit done. The download should start.
|
||||||
|
|
||||||
|
After that select next
|
||||||
|
You'll be in file system summary: Hit done, box will pop up "confirm destructive action" select "continue"
|
||||||
|
|
||||||
|
Configure your profile. Done
|
||||||
|
Skip the upgrade to ubuntu pro
|
||||||
|
No ssh
|
||||||
|
Don't select featured server snaps just select done
|
||||||
|
|
||||||
|
Ubuntu will install…..then reboot your system
|
||||||
|
2.4 Create a user (e.g., pxe) with a simple, temporary password (change later).
|
||||||
|
|
||||||
|
Prepare the OS
|
||||||
|
3.1 Log in as the user you created.
|
||||||
|
|
||||||
|
3.2 Update the system:
|
||||||
|
|
||||||
|
bash
|
||||||
|
Copy
|
||||||
|
sudo apt update && sudo apt upgrade -y
|
||||||
|
|
||||||
|
3.3 Install Ansible:
|
||||||
|
|
||||||
|
bash
|
||||||
|
Copy
|
||||||
|
sudo apt install ansible -y
|
||||||
|
Mount the installer USB and run the playbook
|
||||||
|
|
||||||
|
4.1 Identify the USB device:
|
||||||
|
|
||||||
|
bash
|
||||||
|
Copy
|
||||||
|
lsblk
|
||||||
|
Note the device (e.g., /dev/sda1).
|
||||||
|
|
||||||
|
4.2 Mount it and run the playbook:
|
||||||
|
|
||||||
|
bash
|
||||||
|
Copy
|
||||||
|
sudo mkdir -p /mnt/usb
|
||||||
|
sudo mount /dev/sda1 /mnt/usb
|
||||||
|
cd /mnt/usb/playbook
|
||||||
|
ansible-playbook pxe_server_setup.yml
|
||||||
|
|
||||||
|
|
||||||
|
4.3 When Ansible finishes, umount the USB:
|
||||||
|
|
||||||
|
bash
|
||||||
|
Copy
|
||||||
|
cd ~
|
||||||
|
sudo umount /mnt/usb
|
||||||
|
|
||||||
|
Cache Windows PE images
|
||||||
|
5.1 On a separate workstation, use GE Aerospace Media Creator LITE to cache all desired images (or start with one).
|
||||||
|
5.2 Create a WinPE USB using the same tool and eject it safely.
|
||||||
|
|
||||||
|
Import WinPE content to the PXE share
|
||||||
|
6.1 Insert the WinPE USB into the PXE server.
|
||||||
|
6.2 Find the new device (e.g., /dev/sdb2) with lsblk.
|
||||||
|
6.3 Mount it and copy files:
|
||||||
|
|
||||||
|
bash
|
||||||
|
Copy
|
||||||
|
sudo mkdir -p /mnt/usb2
|
||||||
|
sudo mount /dev/sdb2 /mnt/usb2
|
||||||
|
sudo cp -r /mnt/usb2/. /srv/samba/winpeapps/standard
|
||||||
|
sudo umount /mnt/usb2
|
||||||
|
Finalise and isolate
|
||||||
|
|
||||||
|
7.1 Reboot the server:
|
||||||
|
|
||||||
|
bash
|
||||||
|
Copy
|
||||||
|
sudo reboot
|
||||||
|
|
||||||
|
7.2 After it comes back up, move the primary NIC from the Internet-enabled network to the isolated switch that will serve PXE clients.
|
||||||
|
|
||||||
|
6. Verification
|
||||||
|
Connect a test workstation to the isolated switch.
|
||||||
|
|
||||||
|
In BIOS/UEFI, set Network Boot (PXE) as first boot, then boot.
|
||||||
|
|
||||||
|
Confirm the client pulls an IP from the PXE server and sees the WinPE menu.
|
||||||
|
|
||||||
|
Launch a WinPE image to ensure TFTP, HTTP (NBD), and SMB shares respond correctly.
|
||||||
222
unattend/FlatUnattendW10.xml
Normal file
222
unattend/FlatUnattendW10.xml
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<unattend xmlns="urn:schemas-microsoft-com:unattend"
|
||||||
|
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
|
||||||
|
<!-- 1. windowsPE is intentionally empty -->
|
||||||
|
<settings pass="windowsPE" />
|
||||||
|
|
||||||
|
<!-- 2. Offline servicing (drivers) -->
|
||||||
|
<settings pass="offlineServicing">
|
||||||
|
<component name="Microsoft-Windows-PnpCustomizationsNonWinPE"
|
||||||
|
processorArchitecture="amd64"
|
||||||
|
publicKeyToken="31bf3856ad364e35"
|
||||||
|
language="neutral"
|
||||||
|
versionScope="nonSxS">
|
||||||
|
<DriverPaths>
|
||||||
|
<PathAndCredentials wcm:action="add" wcm:keyValue="1">
|
||||||
|
<Path>W:\Drivers</Path>
|
||||||
|
</PathAndCredentials>
|
||||||
|
<PathAndCredentials wcm:action="add" wcm:keyValue="2">
|
||||||
|
<Path>W:\Deploy\Applications\extra\printdrivers\BROTHER\UNIV-PS-01181\PS\64</Path>
|
||||||
|
</PathAndCredentials>
|
||||||
|
<PathAndCredentials wcm:action="add" wcm:keyValue="3">
|
||||||
|
<Path>W:\Deploy\Applications\extra\printdrivers\HP</Path>
|
||||||
|
</PathAndCredentials>
|
||||||
|
<PathAndCredentials wcm:action="add" wcm:keyValue="4">
|
||||||
|
<Path>W:\Deploy\Applications\extra\printdrivers\XEROX\UNIV_5.1035.2.0_PS_x64_Driver</Path>
|
||||||
|
</PathAndCredentials>
|
||||||
|
</DriverPaths>
|
||||||
|
</component>
|
||||||
|
</settings>
|
||||||
|
|
||||||
|
<!-- 3. specialize: computer naming + RunSynchronous all in ONE component -->
|
||||||
|
<settings pass="specialize">
|
||||||
|
<!-- 3a. Shell-Setup for naming/owner/org -->
|
||||||
|
<component name="Microsoft-Windows-Shell-Setup"
|
||||||
|
processorArchitecture="amd64"
|
||||||
|
publicKeyToken="31bf3856ad364e35"
|
||||||
|
language="neutral"
|
||||||
|
versionScope="nonSxS">
|
||||||
|
<ComputerName>H%serialnumber%</ComputerName>
|
||||||
|
<RegisteredOrganization>GE Aerospace</RegisteredOrganization>
|
||||||
|
<RegisteredOwner>GE</RegisteredOwner>
|
||||||
|
<TimeZone>Eastern Standard Time</TimeZone>
|
||||||
|
</component>
|
||||||
|
|
||||||
|
<!-- 3b. RunSynchronous for all of your installers, copies, etc. -->
|
||||||
|
<component name="Microsoft-Windows-Deployment"
|
||||||
|
processorArchitecture="amd64"
|
||||||
|
publicKeyToken="31bf3856ad364e35"
|
||||||
|
language="neutral"
|
||||||
|
versionScope="nonSxS">
|
||||||
|
<RunSynchronous>
|
||||||
|
<!-- EAP-PEAP MSI -->
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>1</Order>
|
||||||
|
<Path>msiexec /i "C:\Deploy\Applications\extra\wireless\EAP-PEAP.msi" /quiet /norestart</Path>
|
||||||
|
<Description>Install EAP-PEAP</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
|
||||||
|
<!-- Wi-Fi profiles -->
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>2</Order>
|
||||||
|
<Path>cmd /c netsh wlan add profile filename="C:\Deploy\Applications\extra\wireless\BLUESSO.xml" user=all</Path>
|
||||||
|
<Description>Add BLUESSO WiFi profile</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>3</Order>
|
||||||
|
<Path>cmd /c netsh wlan add profile filename="C:\Deploy\Applications\extra\wireless\WiFi-Profile.xml" user=all</Path>
|
||||||
|
<Description>Add generic WiFi profile</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
|
||||||
|
<!-- Certificates -->
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>4</Order>
|
||||||
|
<Path>cmd /c certutil -addstore Root "C:\Deploy\Applications\GE_External_Root_CA_2_1.cer"</Path>
|
||||||
|
<Description>Install External Root Certificate</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>5</Order>
|
||||||
|
<Path>cmd /c certutil -addstore CA "C:\Deploy\Applications\GE_External_Intermediate_CA_2_1.cer"</Path>
|
||||||
|
<Description>Install External Intermediate Certificate</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>6</Order>
|
||||||
|
<Path>cmd /c certutil -addstore Root "C:\Deploy\Applications\GE_Enterprise_Root_CA_2_1.cer"</Path>
|
||||||
|
<Description>Install Enterprise Root Certificate</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>7</Order>
|
||||||
|
<Path>cmd /c certutil -addstore CA "C:\Deploy\Applications\GE_Enterprise_Device_Issuing_CA_2_1.cer"</Path>
|
||||||
|
<Description>Install Enterprise Device Issuing Certificate</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>8</Order>
|
||||||
|
<Path>cmd /c certutil -addstore CA "C:\Deploy\Applications\GE_Enterprise_Server_Issuing_CA_2_1.cer"</Path>
|
||||||
|
<Description>Install Enterprise Server Issuing Certificate</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>9</Order>
|
||||||
|
<Path>cmd /c certutil -addstore CA "C:\Deploy\Applications\GE_Enterprise_Smart_Card_Issuing_CA_2_1.cer"</Path>
|
||||||
|
<Description>Install SmartCard Issuing Certificate</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>10</Order>
|
||||||
|
<Path>cmd /c certutil -addstore CA "C:\Deploy\Applications\GE_Enterprise_User_Issuing_CA_2_1.cer"</Path>
|
||||||
|
<Description>Install User Issuing Certificate</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>11</Order>
|
||||||
|
<Path>cmd /c certutil -addstore Root "C:\Deploy\Applications\GE_Aerospace_Enterprise_Root_CA_1.cer"</Path>
|
||||||
|
<Description>Install Aerospace Enterprise Root CA</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>12</Order>
|
||||||
|
<Path>cmd /c certutil -addstore Root "C:\Deploy\Applications\ZscalerCommercialCertificate-2048-SHA256.crt"</Path>
|
||||||
|
<Description>Install Zscaler Certificate</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
|
||||||
|
<!-- Fonts -->
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>13</Order>
|
||||||
|
<Path>cmd /c copy "C:\Deploy\Applications\extra\fonts\3OF9.TTF" "%WINDIR%\Fonts\" /Y</Path>
|
||||||
|
<Description>Copy 3OF9 Font</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>14</Order>
|
||||||
|
<Path>cmd /c reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" /v "3 of 9 Barcode" /t REG_SZ /d "3OF9.TTF" /f</Path>
|
||||||
|
<Description>Register 3OF9 Barcode Font</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>15</Order>
|
||||||
|
<Path>cmd /c copy "C:\Deploy\Applications\extra\fonts\Code39AzaleaNarrow3.ttf" "%WINDIR%\Fonts\" /Y</Path>
|
||||||
|
<Description>Copy Code39 Azalea Narrow Font</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>16</Order>
|
||||||
|
<Path>cmd /c reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" /v "Code39AzaleaNarrow3" /t REG_SZ /d "Code39AzaleaNarrow3.ttf" /f</Path>
|
||||||
|
<Description>Register Code39 Azalea Narrow Font</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>17</Order>
|
||||||
|
<Path>cmd /c copy "C:\Deploy\Applications\extra\fonts\Code39Azalea.ttf" "%WINDIR%\Fonts\" /Y</Path>
|
||||||
|
<Description>Copy Code39 Azalea Font</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>18</Order>
|
||||||
|
<Path>cmd /c reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" /v "Code39Azalea" /t REG_SZ /d "Code39Azalea.ttf" /f</Path>
|
||||||
|
<Description>Register Code39 Azalea Font</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
|
||||||
|
<!-- OpenText installers -->
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>19</Order>
|
||||||
|
<Path>C:\Deploy\Applications\extra\opentext\opentext_hostexplorer_sp1_15.0_v01.exe /quiet /norestart</Path>
|
||||||
|
<Description>Install OpenText HostExplorer SP1</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>20</Order>
|
||||||
|
<Path>C:\Deploy\Applications\extra\opentext\J2SE_Runtime_Environment_1.6.0_22_Static_Config_V2_Co-Exist.EXE /silent /norestart</Path>
|
||||||
|
<Description>Install J2SE Runtime Environment 1.6.0_22</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>21</Order>
|
||||||
|
<Path>C:\Deploy\Applications\extra\opentext\unattended.bat</Path>
|
||||||
|
<Description>Install J2SE Runtime Environment 1.6.0_22</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
|
||||||
|
<!-- Adobe -->
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>22</Order>
|
||||||
|
<Path>msiexec /i "C:\Deploy\Applications\extra\adobe\AcroRead.msi" TRANSFORMS="C:\Deploy\Applications\extra\adobe\AcroRead.mst" /quiet /norestart</Path>
|
||||||
|
<Description>Install Adobe</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>23</Order>
|
||||||
|
<Path>msiexec /p "C:\Deploy\Applications\extra\adobe\AcroRdrDCUpd2500120531.msp" /quiet /norestart</Path>
|
||||||
|
<Description>Apply Adobe Reader Update</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
</RunSynchronous>
|
||||||
|
</component>
|
||||||
|
</settings>
|
||||||
|
|
||||||
|
<!-- 4. oobeSystem: hide OEM/EULA screens -->
|
||||||
|
<settings pass="oobeSystem">
|
||||||
|
<component name="Microsoft-Windows-Shell-Setup"
|
||||||
|
processorArchitecture="amd64"
|
||||||
|
publicKeyToken="31bf3856ad364e35"
|
||||||
|
language="neutral"
|
||||||
|
versionScope="nonSxS">
|
||||||
|
<OOBE>
|
||||||
|
<HideEULAPage>true</HideEULAPage>
|
||||||
|
<HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
|
||||||
|
<HideOnlineAccountScreens>false</HideOnlineAccountScreens>
|
||||||
|
<HideWirelessSetupInOOBE>false</HideWirelessSetupInOOBE>
|
||||||
|
<HideLocalAccountScreen>true</HideLocalAccountScreen>
|
||||||
|
<NetworkLocation>Work</NetworkLocation>
|
||||||
|
<ProtectYourPC>3</ProtectYourPC>
|
||||||
|
<SkipUserOOBE>false</SkipUserOOBE>
|
||||||
|
<SkipMachineOOBE>false</SkipMachineOOBE>
|
||||||
|
</OOBE>
|
||||||
|
<FirstLogonCommands>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>1</Order>
|
||||||
|
<CommandLine>C:\Deploy\Applications\extra\zscaler\zscaler.bat</CommandLine>
|
||||||
|
<Description>Install Zscaler Client Connector</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>2</Order>
|
||||||
|
<CommandLine>shutdown -a</CommandLine>
|
||||||
|
<Description>Cancel any scheduled shutdown from Office installation</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>3</Order>
|
||||||
|
<CommandLine>cmd /c cd C:\Deploy\Applications\extra\office && install.bat</CommandLine>
|
||||||
|
<Description>Install Office</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
</FirstLogonCommands>
|
||||||
|
</component>
|
||||||
|
</settings>
|
||||||
|
|
||||||
|
</unattend>
|
||||||
Reference in New Issue
Block a user