#Get-MetisDrivers.ps1
## normally bcd edit allow unsigned drivers ... on github Voyager SDK every reboot ... kills bitlocker secboot.. etc...
### required wdk winget install Microsoft.WindowsSDK.10.0.22621
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Downloads, unpacks, and test-signs Axelera Metis M.2 AIPU drivers locally.
.DESCRIPTION
Step 1 of Axelera Metis driver installation:
- Downloads MetisDriver and optionally Switchtec-kmdf archives
- Extracts to a staging directory
- Generates a self-signed test certificate (if not already present)
- Signs all .sys/.cat/.inf driver files with the local cert
- Enables TESTSIGNING boot mode if not already active
.PARAMETER DestDir
Directory where archives and unpacked drivers will be staged.
Default: $env:USERPROFILE\MetisDrivers
.PARAMETER IncludeSwitchtec
Switch to also download the Switchtec-kmdf driver (required only for
the 4-Metis PCIe board, not needed for single M.2 Metis).
.PARAMETER CertSubject
Subject name for the generated test-signing certificate.
Default: "MetisTestSign"
.EXAMPLE
# Single M.2 Metis (most common homelab case)
.\Get-MetisDrivers.ps1
.EXAMPLE
# 4-port PCIe board
.\Get-MetisDrivers.ps1 -IncludeSwitchtec
.EXAMPLE
# Custom staging directory
.\Get-MetisDrivers.ps1 -DestDir D:\Drivers\Metis -IncludeSwitchtec
#>
[CmdletBinding()]
param(
[string]$DestDir = "$env:USERPROFILE\MetisDrivers",
[switch]$IncludeSwitchtec,
[string]$CertSubject = "MetisTestSign"
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
function Write-Step([string]$Msg) {
Write-Host "`n==> $Msg" -ForegroundColor Cyan
}
function Write-OK([string]$Msg) {
Write-Host " [OK] $Msg" -ForegroundColor Green
}
function Write-Warn([string]$Msg) {
Write-Host " [!!] $Msg" -ForegroundColor Yellow
}
# ---------------------------------------------------------------------------
# URLs
# ---------------------------------------------------------------------------
$BaseUrl = "https://software.axelera.ai/artifactory/axelera-win/driver/1.3.x"
$Downloads = [ordered]@{
"MetisDriver-1.3.1.zip" = "$BaseUrl/MetisDriver-1.3.1.zip"
"switchtec-kmdf-0.7_2019.zip" = "$BaseUrl/switchtec-kmdf-0.7_2019.zip"
}
# ---------------------------------------------------------------------------
# 0. Preflight
# ---------------------------------------------------------------------------
Write-Step "Preflight checks"
# Ensure WDK signtool is available (ships with Windows SDK / WDK)
$SignTool = (Get-Command signtool.exe -ErrorAction SilentlyContinue)?.Source
if (-not $SignTool) {
# Fallback: search common SDK paths
$CandidatePaths = @(
"${env:ProgramFiles(x86)}\Windows Kits\10\bin\*\x64\signtool.exe"
"${env:ProgramFiles}\Windows Kits\10\bin\*\x64\signtool.exe"
)
$SignTool = Resolve-Path $CandidatePaths -ErrorAction SilentlyContinue |
Sort-Object -Descending |
Select-Object -First 1 -ExpandProperty Path
}
if (-not $SignTool) {
Write-Warn "signtool.exe not found. Install the Windows SDK / WDK."
Write-Warn " winget install Microsoft.WindowsSDK.10.0.22621"
Write-Warn "Continuing — signing step will be skipped."
}
else {
Write-OK "signtool: $SignTool"
}
# Makecert / New-SelfSignedCertificate availability
$HasPKI = [bool](Get-Command New-SelfSignedCertificate -ErrorAction SilentlyContinue)
Write-OK "New-SelfSignedCertificate available: $HasPKI"
# ---------------------------------------------------------------------------
# 1. Create staging directory
# ---------------------------------------------------------------------------
Write-Step "Creating staging directory: $DestDir"
$null = New-Item -ItemType Directory -Force -Path $DestDir
$ArchiveDir = Join-Path $DestDir "archives"
$ExtractDir = Join-Path $DestDir "extracted"
$null = New-Item -ItemType Directory -Force -Path $ArchiveDir, $ExtractDir
Write-OK "Directories ready."
# ---------------------------------------------------------------------------
# 2. Download archives
# ---------------------------------------------------------------------------
Write-Step "Downloading driver archives"
$ToDownload = @("MetisDriver-1.3.1.zip")
if ($IncludeSwitchtec) { $ToDownload += "switchtec-kmdf-0.7_2019.zip" }
foreach ($FileName in $ToDownload) {
$Url = $Downloads[$FileName]
$OutFile = Join-Path $ArchiveDir $FileName
if (Test-Path $OutFile) {
Write-Warn "$FileName already present — skipping download."
continue
}
Write-Host " Downloading $FileName ..." -NoNewline
try {
$ProgressPreference = 'SilentlyContinue' # dramatically faster Invoke-WebRequest
Invoke-WebRequest -Uri $Url -OutFile $OutFile -UseBasicParsing
$ProgressPreference = 'Continue'
Write-Host " done." -ForegroundColor Green
}
catch {
Write-Host " FAILED." -ForegroundColor Red
Write-Warn "Could not download $FileName : $_"
Write-Warn "Download manually from: $Url"
}
}
# ---------------------------------------------------------------------------
# 3. Extract archives
# ---------------------------------------------------------------------------
Write-Step "Extracting archives"
Get-ChildItem -Path $ArchiveDir -Filter "*.zip" | ForEach-Object {
$Zip = $_.FullName
$Target = Join-Path $ExtractDir $_.BaseName
if (Test-Path $Target) {
Write-Warn "$($_.Name) already extracted — skipping."
return
}
Write-Host " Expanding $($_.Name) ..."
Expand-Archive -Path $Zip -DestinationPath $Target -Force
Write-OK "Extracted to: $Target"
}
# ---------------------------------------------------------------------------
# 4. Create / retrieve test-signing certificate
# ---------------------------------------------------------------------------
Write-Step "Test-signing certificate"
$CertStore = "Cert:\LocalMachine\My"
$ExistingCert = Get-ChildItem $CertStore |
Where-Object { $_.Subject -like "*$CertSubject*" } |
Select-Object -First 1
if ($ExistingCert) {
Write-OK "Re-using existing cert: $($ExistingCert.Thumbprint)"
$Cert = $ExistingCert
}
elseif ($HasPKI) {
Write-Host " Creating self-signed certificate '$CertSubject' ..."
$Cert = New-SelfSignedCertificate `
-Subject "CN=$CertSubject" `
-Type CodeSigningCert `
-CertStoreLocation $CertStore `
-KeySpec Signature `
-HashAlgorithm SHA256 `
-NotAfter (Get-Date).AddYears(10)
# Also install into Trusted Publishers + Root so Windows trusts test-signed drivers
$CertPEM = Export-Certificate -Cert $Cert -FilePath (Join-Path $DestDir "$CertSubject.cer") -Type CERT
Import-Certificate -FilePath $CertPEM.FullName -CertStoreLocation "Cert:\LocalMachine\Root" | Out-Null
Import-Certificate -FilePath $CertPEM.FullName -CertStoreLocation "Cert:\LocalMachine\TrustedPublisher" | Out-Null
Write-OK "Certificate created and installed. Thumbprint: $($Cert.Thumbprint)"
}
else {
Write-Warn "Cannot create certificate (New-SelfSignedCertificate unavailable)."
Write-Warn "Signing step will be skipped."
$Cert = $null
}
# ---------------------------------------------------------------------------
# 5. Sign drivers
# ---------------------------------------------------------------------------
Write-Step "Signing driver files"
if ($SignTool -and $Cert) {
$DriverFiles = Get-ChildItem -Path $ExtractDir -Recurse -Include "*.sys","*.cat","*.dll" |
Where-Object { -not $_.PSIsContainer }
if ($DriverFiles.Count -eq 0) {
Write-Warn "No signable driver files found in $ExtractDir"
}
else {
foreach ($File in $DriverFiles) {
Write-Host " Signing: $($File.Name) ..."
& $SignTool sign `
/sha1 $Cert.Thumbprint `
/fd sha256 `
/tr "http://timestamp.digicert.com" `
/td sha256 `
/v $File.FullName 2>&1 | ForEach-Object { " $_" }
if ($LASTEXITCODE -ne 0) {
Write-Warn "signtool returned $LASTEXITCODE for $($File.Name) — check output above."
}
else {
Write-OK $File.Name
}
}
}
}
elseif (-not $SignTool) {
Write-Warn "Skipping signing: signtool.exe not found."
}
elseif (-not $Cert) {
Write-Warn "Skipping signing: no certificate available."
}
# ---------------------------------------------------------------------------
# 6. Enable TESTSIGNING boot mode
# ---------------------------------------------------------------------------
Write-Step "Boot configuration — TESTSIGNING"
$BcdOutput = & bcdedit /enum '{current}' 2>&1
$IsTestSign = $BcdOutput -match "testsigning\s+Yes"
if ($IsTestSign) {
Write-OK "TESTSIGNING already enabled."
}
else {
Write-Host " Enabling TESTSIGNING ..."
& bcdedit /set testsigning on | Out-Null
if ($LASTEXITCODE -eq 0) {
Write-OK "TESTSIGNING enabled. A reboot is required before installing the driver."
}
else {
Write-Warn "bcdedit failed (LASTEXITCODE=$LASTEXITCODE). Run as Administrator?"
}
}
# Also disable Secure Boot enforcement for test-signed drivers (Disable Integrity Checks)
# Only uncomment if you are on a non-Secure-Boot system / dev machine:
# & bcdedit /set nointegritychecks on
# ---------------------------------------------------------------------------
# 7. Summary
# ---------------------------------------------------------------------------
Write-Step "Summary"
Write-Host ""
Write-Host " Staging root : $DestDir" -ForegroundColor White
Write-Host " Archives : $ArchiveDir" -ForegroundColor White
Write-Host " Extracted : $ExtractDir" -ForegroundColor White
if ($Cert) {
Write-Host " Cert thumbprint: $($Cert.Thumbprint)" -ForegroundColor White
}
Write-Host ""
Write-Host " Next steps:" -ForegroundColor Yellow
Write-Host " 1. Reboot if TESTSIGNING was just enabled." -ForegroundColor Yellow
Write-Host " 2. In Device Manager, right-click the Metis" -ForegroundColor Yellow
Write-Host " device -> Update driver -> Browse my computer" -ForegroundColor Yellow
Write-Host " -> point at: $ExtractDir\MetisDriver-1.3.1" -ForegroundColor Yellow
if ($IncludeSwitchtec) {
Write-Host " 3. Repeat for the Switchtec controller using:" -ForegroundColor Yellow
Write-Host " $ExtractDir\switchtec-kmdf-0.7_2019" -ForegroundColor Yellow
}
Write-Host ""
