Skip to content

Instantly share code, notes, and snippets.

@MarcelMeurer
Created March 20, 2026 08:20
Show Gist options
  • Select an option

  • Save MarcelMeurer/fc4b8d14ae0a469c83cdc0511fc07607 to your computer and use it in GitHub Desktop.

Select an option

Save MarcelMeurer/fc4b8d14ae0a469c83cdc0511fc07607 to your computer and use it in GitHub Desktop.
NVMe handler for v6+ hosts in Hydra (only to use with a script collection)
param(
[string] $Mode,
[bool] $DoNotRestart = $false,
[string] $LogDir = "$env:windir\system32\logfiles"
)
function LogWriter($message) {
$message = "$(Get-Date ([datetime]::UtcNow) -Format "o") $message"
write-host($message)
if ([System.IO.Directory]::Exists($LogDir)) { try { write-output($message) | Out-File $LogFile -Append } catch {} }
}
function Read-IniFile($path) {
$ini = @{}
$section = ""
foreach ($line in [System.IO.File]::ReadAllLines($path, [System.Text.Encoding]::Unicode)) {
if ($line -match "^\[(.+)\]") {
$section = $matches[1]
$ini[$section] = @{}
}
elseif ($line -match "^(.+?)=(.*)$" -and $section) {
$ini[$section][$matches[1]] = $matches[2]
}
}
return $ini
}
function Write-IniFile($path, $ini) {
$lines = @()
foreach ($section in $ini.Keys) {
$lines += "[$section]"
foreach ($key in $ini[$section].Keys) {
$lines += "$key=$($ini[$section][$key])"
}
$lines += ""
}
$iniFile = Get-Item -Path $path -Force -ErrorAction SilentlyContinue
if ($iniFile) {
$iniFile.Attributes = $iniFile.Attributes -band (-bnot [System.IO.FileAttributes]::Hidden)
}
[System.IO.File]::WriteAllText($path, ($lines -join "`r`n"), [System.Text.Encoding]::Unicode)
if ($iniFile) {
$iniFile.Attributes = $iniFile.Attributes -bor [System.IO.FileAttributes]::Hidden
}
}
function Add-ShutdownScript($iniPath, $scriptFile, $parameters) {
$ini = if (Test-Path $iniPath) { Read-IniFile $iniPath } else { @{} }
if (-not $ini.ContainsKey("Shutdown")) { $ini["Shutdown"] = @{} }
$exists = $ini["Shutdown"].Keys | Where-Object {
$_ -match "^\d+CmdLine$" -and $ini["Shutdown"][$_] -eq $scriptFile
}
if ($exists) { return $false }
$index = ($ini["Shutdown"].Keys | Where-Object { $_ -match "^\d+CmdLine$" } |
ForEach-Object { [int]($_ -replace "CmdLine", "") } |
Measure-Object -Maximum).Maximum
$index = if ($ini["Shutdown"].Count -eq 0) { 0 } else { $index + 1 }
$ini["Shutdown"]["${index}CmdLine"] = $scriptFile
$ini["Shutdown"]["${index}Parameters"] = $parameters
Write-IniFile $iniPath $ini
return $true
}
function Remove-ShutdownScript($iniPath, $scriptFile) {
if (-not (Test-Path $iniPath)) { return $false }
$ini = Read-IniFile $iniPath
if (-not $ini.ContainsKey("Shutdown")) { return $false }
$foundIndex = $ini["Shutdown"].Keys | Where-Object {
$_ -match "^\d+CmdLine$" -and $ini["Shutdown"][$_] -eq $scriptFile
} | ForEach-Object { $_ -replace "CmdLine", "" } | Select-Object -First 1
if ($null -eq $foundIndex) { return $false }
$ini["Shutdown"].Remove("${foundIndex}CmdLine")
$ini["Shutdown"].Remove("${foundIndex}Parameters")
Write-IniFile $iniPath $ini
return $true
}
function RedirectPageFileTo($drive) {
LogWriter("Redirecting pagefile to drive $($drive):")
$CurrentPageFile = Get-WmiObject -Query 'select * from Win32_PageFileSetting'
if ($null -ne $CurrentPageFile -and $CurrentPageFile.Name -ne "") {
LogWriter("Existing pagefile name: '$($CurrentPageFile.Name)', max size: $($CurrentPageFile.MaximumSize)")
if ($CurrentPageFile) {
try {
$CurrentPageFile.delete()
LogWriter("Pagefile deleted")
}
catch {
LogWriter("Pagefile deletion error: $_")
}
}
$CurrentPageFile = Get-WmiObject -Query 'select * from Win32_PageFileSetting'
if ($null -eq $CurrentPageFile) {
LogWriter("Pagefile deletion successful")
}
else {
LogWriter("Pagefile deletion failed")
}
}
Set-WMIInstance -Class Win32_PageFileSetting -Arguments @{name = "$($drive):\pagefile.sys"; InitialSize = 0; MaximumSize = 0 }
$CurrentPageFile = Get-WmiObject -Query 'select * from Win32_PageFileSetting'
if ($null -eq $CurrentPageFile) {
LogWriter("Pagefile not found")
}
else {
LogWriter("New pagefile name: '$($CurrentPageFile.Name)', max size: $($CurrentPageFile.MaximumSize)")
}
}
$LogFile = $LogDir + "\AVD.NvemPreparation.log"
$targetScriptFile = ($env:windir + "\AVD.NVMEPageFileHandling.ps1")
$iniPath = "$env:windir\System32\GroupPolicy\Machine\Scripts\psscripts.ini"
$services = @(
"WindowsAzureGuestAgent"
"RDAgentBootLoader"
)
$ErrorActionPreference = "Stop"
$runAsWell=$false
if ($mode -like "installandrun") {
$runAsWell=$true
$mode="install"
}
if ($mode -like "install") {
LogWriter("Copy script to windir")
Copy-Item "$($MyInvocation.InvocationName)" -Destination $targetScriptFile
LogWriter("Creating schedule task to run the script at startup")
$action = New-ScheduledTaskAction -Execute "Powershell.exe" -Argument "-executionPolicy Unrestricted -File `"$targetScriptFile`" -Mode `"NVMEPageFileHandling`""
$trigger = New-ScheduledTaskTrigger -AtStartup
$principal = New-ScheduledTaskPrincipal 'NT Authority\SYSTEM' -RunLevel Highest
$settingsSet = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit 0
$task = New-ScheduledTask -Action $action -Principal $principal -Trigger $trigger -Settings $settingsSet
Register-ScheduledTask -TaskName 'ITPC-AVD-NVMEPageFileHandling' -InputObject $task -ErrorAction Ignore
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
do {
$task = Get-ScheduledTask -TaskName "ITPC-AVD-NVMEPageFileHandling" -ErrorAction SilentlyContinue
if (!$task) { Start-Sleep -Seconds 1 }
} until ($task -or $stopwatch.Elapsed.TotalSeconds -ge 30)
if ($task) {
}
else {
throw "ITPC-AVD-NVMEPageFileHandling could not be created"
}
LogWriter("Preparing services")
foreach ($svc in $services) {
if (Get-Service -Name $svc -ErrorAction SilentlyContinue) {
LogWriter("Setting service $svc to disabled")
Set-Service -Name $svc -StartupType Disabled
}
}
LogWriter("Configuring shutdown/restart entry point")
$folder = Split-Path -Path $iniPath -Parent
if (-not (Test-Path $folder)) {
New-Item -Path $folder -ItemType Directory -Force | Out-Null
}
if (-not (Test-Path $iniPath)) {
New-Item -Path $iniPath -ItemType File | Out-Null
}
if (Add-ShutdownScript $iniPath $targetScriptFile "-mode Shutdown") {
LogWriter("Shutdown entry added to scripts.ini")
}
else {
LogWriter("Shutdown entry already exists in scripts.ini")
}
$gptPath = "$env:windir\System32\GroupPolicy\gpt.ini"
if (-not (Test-Path $gptPath)) {
$gptContent = "[General]`r`ngPCMachineExtensionNames=[{42B5FAAE-6536-11D2-AE5A-0000F87571E3}{827D319E-6EAC-11D2-A4EA-00C04F79F83A}]`r`nVersion=1`r`n"
[System.IO.File]::WriteAllText($gptPath, $gptContent, [System.Text.Encoding]::Unicode)
LogWriter("Creating gpt.ini")
}
$scriptIniPath = "$env:windir\System32\GroupPolicy\Machine\Scripts\scripts.ini"
if (-not (Test-Path $scriptIniPath)) {
[System.IO.File]::WriteAllText($scriptIniPath, "", [System.Text.Encoding]::Unicode)
LogWriter("Creating scripts.ini")
}
LogWriter("Running gpupdate")
& gpupdate.exe /target:computer /force
if ($runAsWell) {
LogWriter("Running script")
& $targetScriptFile -DoNotRestart $DoNotRestart
}
}
elseif ($mode -like "uninstall") {
LogWriter("Deleting schedule task")
Stop-ScheduledTask -TaskName "ITPC-AVD-NVMEPageFileHandling" -ErrorAction SilentlyContinue
Unregister-ScheduledTask -TaskName "ITPC-AVD-NVMEPageFileHandling" -confirm:$false -ErrorAction SilentlyContinue
LogWriter("Preparing services to start automatically")
foreach ($svc in $services) {
if (Get-Service -Name $svc -ErrorAction SilentlyContinue) {
LogWriter("Setting service $svc to Automatic")
Set-Service -Name $svc -StartupType Automatic
Start-Service -Name $svc -ErrorAction SilentlyContinue
}
}
LogWriter("Removing shutdown entry from scripts.ini")
if (Remove-ShutdownScript $iniPath $targetScriptFile) {
LogWriter("Shutdown entry removed from scripts.ini")
}
else {
LogWriter("Shutdown entry not found in scripts.ini")
}
LogWriter("Running gpupdate")
& gpupdate.exe /target:computer /force
}
elseif ($mode -like "ShutDown") {
LogWriter("Starting NVME Pagefile Handling on shutdown/reboot")
try {
foreach ($svc in $services2) {
$regPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$svc"
$startValue = (Get-ItemProperty -Path $regPath -Name Start).Start
if ($startValue -ne 4) {
LogWriter("Setting service $svc to disabled")
Set-Service -Name $svc -StartupType Disabled
}
}
}
catch {
LogWriter("Service $svc not found: $_")
}
LogWriter("NVME Pagefile Handling on shutdown/reboot completed")
}
else {
$doNotStartServices = $false
try {
LogWriter("Starting NVME Pagefile Handling")
$tempDrive = ""
$disks = @(Get-Disk | Where-Object { $_.FriendlyName -like "*Microsoft NVMe Direct Disk v2*" })
if ($disks -and $disks.Count -gt 0) {
LogWriter("Found NVMe disk")
$disk = $disks[0]
$partitions = $disk | Get-Partition | where-object { $_.DriveLetter }
if (-not $partitions) {
if (-not $tempDrive) {
$used = @((Get-Volume).DriveLetter)
$tempDrive = [char[]](67..90) | Where-Object { $_ -notin $used } | Select-Object -First 1
}
LogWriter("The NVMe disk has no partitions. Create and mount a partition as $($tempDrive):\")
$baseHklm = "hklm:\Software\ITProCloud\WVD.Runtime"
$lastStart = [datetime]::MinValue
if (Test-Path $baseHklm) {
try {
$value = (Get-ItemProperty -Path $baseHklm -Name "NVMe-Handling.LastStart" -ErrorAction Stop)."NVMe-Handling.LastStart"
$lastStart = [datetime]::Parse($value, [System.Globalization.CultureInfo]::InvariantCulture, [System.Globalization.DateTimeStyles]::RoundtripKind)
}
catch {}
}
if (-not (Test-Path $baseHklm)) { New-Item -Path $baseHklm -Force | Out-Null }
$newTimestamp = (Get-Date).ToUniversalTime().ToString("o")
$seconds = [int64]([datetime]::Parse($newTimestamp, [System.Globalization.CultureInfo]::InvariantCulture, [System.Globalization.DateTimeStyles]::RoundtripKind) - $lastStart).TotalSeconds
if ($seconds -gt 180) {
$disk | Initialize-Disk -PartitionStyle GPT -PassThru -ErrorAction SilentlyContinue
$disk | New-Partition -UseMaximumSize -DriveLetter $tempDrive | Format-Volume -FileSystem NTFS -NewFileSystemLabel "Temporary Storage" -force -Confirm:$false
LogWriter("Configuring pagefile to use $($tempDrive):\")
RedirectPageFileTo $tempDrive
if ($DoNotRestart -eq $false) {
LogWriter("Restarting computer to move the pagefile")
$doNotStartServices = $true
Restart-Computer -Force
}
else {
LogWriter("DoNotRestart is set to true. Skipping restart")
}
}
else {
throw "Last disk modification happens less the 180 seconds ago. We may run into an issue. Quittung disk modification to prevent endless loops"
}
Set-ItemProperty -Path $baseHklm -Name "NVMe-Handling.LastStart" -Value $newTimestamp -Type String
}
else {
LogWriter("NVMe disk is has a partition. Nothing to do")
}
}
else {
LogWriter("No NVMe disk found")
}
}
catch {
LogWriter("Error: $_")
}
finally {
if ($doNotStartServices -eq $false) {
LogWriter("Starting services")
foreach ($svc in $services) {
if (Get-Service -Name $svc -ErrorAction SilentlyContinue) {
LogWriter("Starting service $svc")
try {
Set-Service -Name $svc -StartupType Automatic
Start-Service -Name $svc
}
catch {
LogWriter("Cannot start service $($svc): $_")
}
}
}
}
LogWriter("Preparing services")
foreach ($svc in $services) {
if (Get-Service -Name $svc -ErrorAction SilentlyContinue) {
LogWriter("Setting service $svc to disabled")
Set-Service -Name $svc -StartupType Disabled -ErrorAction SilentlyContinue
}
}
LogWriter("NVME Pagefile Handling completed")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment