Collects BIOS serial numbers from all domain-joined Windows machines automatically as they log in. The serial numbers are needed for NETSetup customer configuration files (Customers/*.cs).

The Script

Save the following as \\<DC>\NETLOGON\Collect-Serial.ps1:

# Collect-Serial.ps1 — GPO login script
# Writes BIOS serial number to a central share per machine
$serial = (Get-CimInstance Win32_BIOS).SerialNumber
$name = $env:COMPUTERNAME
$outDir = "\\<DC>\SerialNumbers$"
if (!(Test-Path $outDir)) { New-Item -ItemType Directory -Path $outDir -Force }
"$name=$serial" | Out-File "$outDir\$name.txt" -Force

Replace <DC> with the domain controller name (e.g. StaudtAGDC).

Setup

1. Create the shared folder on the DC

New-Item -ItemType Directory -Path C:\SerialNumbers -Force
New-SmbShare -Name "SerialNumbers$" -Path "C:\SerialNumbers" -FullAccess "Domain Admins" -ChangeAccess "Domain Users"

2. Copy the script to NETLOGON

Copy-Item Collect-Serial.ps1 "\\<DC>\NETLOGON\Collect-Serial.ps1"

3. Create a GPO

  1. Open Group Policy Management (gpmc.msc)

  2. Create a new GPO (e.g. "Collect Serial Numbers") and link it to the domain or target OU

  3. Edit the GPO:

    • For per-user collection:
      User Configuration > Policies > Windows Settings > Scripts (Logon/Logoff) > Logon
      Add \\<DC>\NETLOGON\Collect-Serial.ps1

    • For per-machine collection (recommended):
      Computer Configuration > Policies > Windows Settings > Scripts (Startup/Shutdown) > Startup
      Add \\<DC>\NETLOGON\Collect-Serial.ps1

  4. Run gpupdate /force on the DC

4. Collect results

After machines log in / reboot, the share \\<DC>\SerialNumbers$ will contain one file per machine:

STAUDT44.txt    -> STAUDT44=CZC1234567
STAUDT45.txt    -> STAUDT45=8CGO1234AB
StaudtNB01.txt  -> StaudtNB01=5CD9876543
...

5. Update customer config

Use the collected serial numbers to update the Customers/<Customer>.cs file, replacing placeholder values (single letters like b, c, d) with real serial numbers.

Regenerate the config JSON:

dotnet run Customers/<Customer>.cs

Quick alternative (no GPO)

Run this directly on the DC to query all currently online machines:

$computers = (Get-ADComputer -Filter *).Name
& 'C:\netsetup\scripts\Query-Hardware.ps1' -ComputerName $computers -OutputFormat Json
Note
This only reaches machines that are online and have WinRM enabled.