Provisioning scripts for powershell for use with Proxmox CloudInit.
  • PowerShell 100%
Find a file
2026-05-15 20:14:02 +02:00
archive First init of last iteration v6. 2026-05-15 20:14:02 +02:00
ArfNet-ApplyBGInfo.ps1 First init of last iteration v6. 2026-05-15 20:14:02 +02:00
ArfNet-Interactive.ps1 First init of last iteration v6. 2026-05-15 20:14:02 +02:00
ArfNet-Provision-Run.reg First init of last iteration v6. 2026-05-15 20:14:02 +02:00
ArfNet-Provision-System-Task.xml First init of last iteration v6. 2026-05-15 20:14:02 +02:00
ArfNet-Provision-System.ps1 First init of last iteration v6. 2026-05-15 20:14:02 +02:00
ArfNet-Provision-Task.xml First init of last iteration v6. 2026-05-15 20:14:02 +02:00
ArfNet-Provision.ps1 First init of last iteration v6. 2026-05-15 20:14:02 +02:00
ArfNet-UserLaunch.ps1 First init of last iteration v6. 2026-05-15 20:14:02 +02:00
README.md First init of last iteration v6. 2026-05-15 20:14:02 +02:00
Register-ArfNetProvisionTask.ps1 First init of last iteration v6. 2026-05-15 20:14:02 +02:00

ArfNet-PVE — Windows VM provisioning

PowerShell tooling for Windows 10/11 VMs on Proxmox with a config-2 drive.

On Windows 10 22H2, even Administrator accounts (without a true elevated SYSTEM token) cannot reliably Set-Date, write RealTimeIsUniversal under HKLM, or change IP/hostname. Those operations run as SYSTEM at startup. BGInfo and desktop apps run as the logged-on user (roadmaster).

Two scheduled tasks

Task When Runs as Script Does
ArfNet-Provision-System Startup (+30s) SYSTEM ArfNet-Provision-System.ps1 Config-drive hostname/IP, fixed time, UTC registry, disable NTP
ArfNet-Provision User logon (+10s) .\roadmaster ArfNet-Provision.ps1 Triggers system task, BGInfo wallpaper, user launch apps
Log Written by
C:\Scripts\Provision-System.log SYSTEM task (time, identity)
C:\Scripts\Provision.log User logon task
C:\Scripts\BGInfo.log ArfNet-ApplyBGInfo.ps1
C:\Scripts\UserLaunch.log ArfNet-UserLaunch.ps1

Legacy scripts are in archive/. Do not deploy them with the current scripts.

Flow

flowchart TD
    Boot([Boot]) --> Sys[ArfNet-Provision-System / SYSTEM]
    Sys --> Id{Config drive differs?}
    Id -->|IP/name| Apply[Set IP / rename + reboot]
    Apply --> Boot
    Id -->|No| Time[Set time + UTC registry]
    Logon([User logon roadmaster]) --> User[ArfNet-Provision.ps1]
    User --> Trigger[Start system task]
    Trigger --> BGInfo[BGInfo wallpaper]
    BGInfo --> Apps[User launch apps]

Repository layout

Path Description
ArfNet-Provision-System.ps1 Privileged: identity, time (SYSTEM only)
ArfNet-Provision.ps1 User session: BGInfo + user launch
ArfNet-UserLaunch.ps1 Per-app delays + two executables
ArfNet-ApplyBGInfo.ps1 BGInfo in user HKCU + wallpaper refresh
ArfNet-Interactive.ps1 Session helpers
Register-ArfNetProvisionTask.ps1 Registers both tasks
ArfNet-Provision-System-Task.xml SYSTEM startup task XML
ArfNet-Provision-Task.xml User logon task XML
archive/ Superseded scripts

VM install

  1. Copy to C:\Scripts\:

    ArfNet-Provision-System.ps1
    ArfNet-Provision.ps1
    ArfNet-UserLaunch.ps1
    ArfNet-ApplyBGInfo.ps1
    ArfNet-Interactive.ps1
    Register-ArfNetProvisionTask.ps1
    ArfNet-Provision-System-Task.xml
    ArfNet-Provision-Task.xml
    
  2. Edit settings in ArfNet-Provision-System.ps1 (time, NIC) and ArfNet-UserLaunch.ps1 (apps). Set .\roadmaster in XML / register script if needed.

  3. Register tasks (elevated PowerShell):

    cd C:\Scripts
    .\Register-ArfNetProvisionTask.ps1 -LogonUser ".\roadmaster"
    
  4. Install BGInfo at C:\Program Files\BGInfo\ with Default.bgi (wallpaper enabled in the .bgi).

Configuration

ArfNet-Provision-System.ps1 (SYSTEM)

Setting Default Purpose
$TargetTime 2025-08-29 08:00:00 Fixed clock
$InterfaceAlias Ethernet NIC name
$IpPrefixLength 16 Prefix for 172.16.x.x

ArfNet-Provision.ps1 (user logon)

Setting Default Purpose
$LogonUser .\roadmaster Must match user task principal
$SystemTaskName ArfNet-Provision-System Started at logon as a fallback

ArfNet-UserLaunch.ps1

Per-program DelaySeconds, Path, Arguments, WorkingDirectory. Set $LogonUser = ".\roadmaster".

Task Scheduler

Imports the bundled XML files via schtasks /Create /XML (same as manual Task Scheduler import):

cd C:\Scripts
.\Register-ArfNetProvisionTask.ps1 -LogonUser ".\roadmaster"

XML files must sit next to the register script or under C:\Scripts\.

Or import XML manually / with schtasks

schtasks /Create /TN "ArfNet-Provision-System" /XML "C:\Scripts\ArfNet-Provision-System-Task.xml" /F
schtasks /Create /TN "ArfNet-Provision" /XML "C:\Scripts\ArfNet-Provision-Task.xml" /F

Edit <UserId>.\roadmaster</UserId> in the user XML before manual import, or pass -LogonUser to the register script (it patches the XML for you).

To replace existing tasks:

schtasks /Delete /TN "ArfNet-Provision-System" /F
schtasks /Delete /TN "ArfNet-Provision" /F
.\Register-ArfNetProvisionTask.ps1 -LogonUser ".\roadmaster"

The register script uses schtasks /Create /XML only. It does not use Register-ScheduledTask / New-ScheduledTask* (those often fail on Windows 10 22H2).

Verify

Get-ScheduledTask ArfNet-Provision-System, ArfNet-Provision | Format-Table TaskName, State
(Get-ScheduledTask ArfNet-Provision-System).Principal.UserId   # NT AUTHORITY\SYSTEM
(Get-ScheduledTask ArfNet-Provision).Principal.UserId          # .\roadmaster

Start-ScheduledTask -TaskName ArfNet-Provision-System
Start-ScheduledTask -TaskName ArfNet-Provision

Get-Content C:\Scripts\Provision-System.log -Tail 10
Get-Content C:\Scripts\Provision.log -Tail 10

Manual testing

# Privileged (run elevated — or use the SYSTEM task)
Start-ScheduledTask -TaskName ArfNet-Provision-System

# User desktop (logged in as roadmaster)
powershell -ExecutionPolicy Bypass -File C:\Scripts\ArfNet-Provision.ps1

Do not expect Set-Date to work in a normal roadmaster PowerShell window on Windows 10 without SYSTEM — that is expected.

Troubleshooting

Symptom Check
Time / IP / hostname not applied Provision-System.log, task principal is NT AUTHORITY\SYSTEM, run Start-ScheduledTask ArfNet-Provision-System
BGInfo log OK, no wallpaper User task principal is .\roadmaster (not HOSTNAME$); Default.bgi has wallpaper enabled; BGInfo.log
Apps not visible Same as BGInfo — must run as desktop user, not SYSTEM
Register script fails Use the XML files directly (schtasks commands above) or Task Scheduler → Import Task
runner=WORKGROUP\HOSTNAME$ in Provision.log Re-import user XML / register with -LogonUser ".\roadmaster"

Notes

  • Windows 10 22H2: UAC splits “Administrator” from true machine privileges; use the SYSTEM task for time and network identity.
  • After rename: RunOnce runs ArfNet-Provision-System.ps1 again after reboot.
  • Settings: keep $TargetTime / NIC values in ArfNet-Provision-System.ps1; app paths in ArfNet-UserLaunch.ps1; $LogonUser in ArfNet-Provision.ps1, user XML, and register script should match.
  • Config drive: volume config-2 or first CD-ROM; scans \openstack\** for hostname: and address 172.16.x.x.