From 79bf5bc1711c35571850ab371727cfc8fc408571 Mon Sep 17 00:00:00 2001 From: Katsuhiro Watanabe Date: Thu, 12 Jun 2025 16:28:13 +0900 Subject: [PATCH] Support offline OS and driver catalogs, and add post-network script execution - Add support for importing offline OS catalogs in - Get-OSDCloudOperatingSystems.ps1 - Get-OSDCloudOperatingSystemsIndexMap.ps1 - Get-OSDCloudOperatingSystemsIndexes.ps1 - Add offline driver catalog support in OSDCloud.DriverPack.ps1 - Add post-network script execution and optional supression of module auto-update in - Initialize-OSDCloudStartNet.ps1 - OSDCloudTemplate.ps1 - removed: Improve Save-WebFile.ps1 by checking HTTP headers before download Due to conflicts with PR #316 affecting Save-WebFile.ps1, my changes have been removed to maintain consistency with the upstream implementation. --- .../OSDCloud.DriverPack.ps1 | 12 +++- Public/OSDCloudSetup/OSDCloudTemplate.ps1 | 3 +- .../Get-OSDCloudOperatingSystems.ps1 | 16 +++-- .../Get-OSDCloudOperatingSystemsIndexMap.ps1 | 16 ++++- .../Get-OSDCloudOperatingSystemsIndexes.ps1 | 24 +++++++- .../Initialize-OSDCloudStartnet.ps1 | 59 +++++++++++++++---- 6 files changed, 105 insertions(+), 25 deletions(-) diff --git a/Public/OSDCloudDriverPack/OSDCloud.DriverPack.ps1 b/Public/OSDCloudDriverPack/OSDCloud.DriverPack.ps1 index 5576d6e3f..edb01c7a9 100644 --- a/Public/OSDCloudDriverPack/OSDCloud.DriverPack.ps1 +++ b/Public/OSDCloudDriverPack/OSDCloud.DriverPack.ps1 @@ -67,7 +67,17 @@ function Get-OSDCloudDriverPacks { #> [CmdletBinding()] param () - $Results = Import-Clixml -Path "$(Get-OSDModulePath)\cache\driverpack-catalogs\build-driverpacks.xml" + $DriverCatalogXML = Get-PSDrive -PSProvider FileSystem | Where-Object {$_.Name -ne 'C'} | ForEach-Object { + Get-ChildItem "$($_.Root)OSDCloud\Catalogs" -Include "build-driverpacks.xml" -File -Force -Recurse -ErrorAction Ignore + } + if ($DriverCatalogXML) { + foreach ($Item in $DriverCatalogXML) { + Write-Warning "$($Item.FullName) is imported instead of the cache under $(Get-OSDModulePath)." + $Results = Import-Clixml -Path $Item.FullName + } + } else { + $Results = Import-Clixml -Path "$(Get-OSDModulePath)\cache\driverpack-catalogs\build-driverpacks.xml" + } $Results } function Save-OSDCloudDriverPack { diff --git a/Public/OSDCloudSetup/OSDCloudTemplate.ps1 b/Public/OSDCloudSetup/OSDCloudTemplate.ps1 index 9f2c65753..edc7d4a5c 100644 --- a/Public/OSDCloudSetup/OSDCloudTemplate.ps1 +++ b/Public/OSDCloudSetup/OSDCloudTemplate.ps1 @@ -1014,7 +1014,8 @@ Windows Registry Editor Version 5.00 'Config\Scripts\SetupComplete', 'Config\Scripts\Shutdown', 'Config\Scripts\Startup', - 'Config\Scripts\StartNet' + 'Config\Scripts\StartNet', + 'Config\Scripts\StartNet2' ) if ($Name -match 'public') { diff --git a/Public/OSDCloudTS/Get-OSDCloudOperatingSystems.ps1 b/Public/OSDCloudTS/Get-OSDCloudOperatingSystems.ps1 index 377e63705..3973b801f 100644 --- a/Public/OSDCloudTS/Get-OSDCloudOperatingSystems.ps1 +++ b/Public/OSDCloudTS/Get-OSDCloudOperatingSystems.ps1 @@ -16,12 +16,18 @@ function Get-OSDCloudOperatingSystems { [System.String] $OSArch = 'x64' ) - $FullResults = Get-Content -Path "$(Get-OSDModulePath)\cache\archive-cloudoperatingsystems\CloudOperatingSystems.json" | ConvertFrom-Json - if ($OSArch -eq 'x64'){ - $Results = $FullResults | Where-Object {$_.Architecture -eq "x64"} + $OfflineCatalog = Get-PSDrive -PSProvider FileSystem | Where-Object {$_.Name -ne 'C'} | ForEach-Object { + Get-ChildItem "$($_.Root)OSDCloud\Catalogs" -Include "CloudOperatingSystems.json" -File -Force -Recurse -ErrorAction Ignore } - elseif ($OSArch -eq "arm64"){ - $Results = Get-Content -Path "$(Get-OSDModulePath)\cache\archive-cloudoperatingsystems\CloudOperatingSystemsARM64.json" | ConvertFrom-Json + if ($OfflineCatalog) { + foreach ($Item in $OfflineCatalog) { + Write-Warning "$($Item.FullName) is imported instead of the cache under $(Get-OSDModulePath)." + $FullResults = Get-Content -Path "$($Item.FullName)" | ConvertFrom-Json -ErrorAction "Stop" + } + $Results = $FullResults | Where-Object {$_.Architecture -eq $OSArch} + } else { + $FullResults = Get-Content -Path "$(Get-OSDModulePath)\cache\archive-cloudoperatingsystems\CloudOperatingSystems.json" | ConvertFrom-Json + $Results = $FullResults | Where-Object {$_.Architecture -eq $OSArch} } $Results } \ No newline at end of file diff --git a/Public/OSDCloudTS/Get-OSDCloudOperatingSystemsIndexMap.ps1 b/Public/OSDCloudTS/Get-OSDCloudOperatingSystemsIndexMap.ps1 index 8897ee096..28dbfa13d 100644 --- a/Public/OSDCloudTS/Get-OSDCloudOperatingSystemsIndexMap.ps1 +++ b/Public/OSDCloudTS/Get-OSDCloudOperatingSystemsIndexMap.ps1 @@ -21,9 +21,19 @@ function Get-OSDCloudOperatingSystemsIndexMap { $OSArch = 'x64' ) - $indexMapPath = "$(Get-OSDModulePath)\cache\archive-cloudoperatingindexmap\CloudOperatingIndexMap.json" - $Results = Get-Content -Path $indexMapPath | ConvertFrom-Json + $OfflineCatalog = Get-PSDrive -PSProvider FileSystem | Where-Object {$_.Name -ne 'C'} | ForEach-Object { + Get-ChildItem "$($_.Root)OSDCloud\Catalogs" -Include "CloudOperatingIndexMap.json" -File -Force -Recurse -ErrorAction Ignore + } + if ($OfflineCatalog) { + foreach ($Item in $OfflineCatalog) { + Write-Warning "$($Item.FullName) is imported instead of the cache under $(Get-OSDModulePath)." + $indexMapPath = (Get-Item -Path "$($Item.FullName)").FullName + } + } else { + $indexMapPath = "$(Get-OSDCachePath)\archive-cloudoperatingindexmap\CloudOperatingIndexMap.json" + } + $Results = Get-Content -Path $indexMapPath -Encoding UTF8 | ConvertFrom-Json # as of OSD 25.6.10.1 encoding of the json is UTF8 $Results = $Results | Where-Object { $_.Architecture -eq $OSArch } return $Results -} \ No newline at end of file +} diff --git a/Public/OSDCloudTS/Get-OSDCloudOperatingSystemsIndexes.ps1 b/Public/OSDCloudTS/Get-OSDCloudOperatingSystemsIndexes.ps1 index 5ca1b0f67..37c73f9cb 100644 --- a/Public/OSDCloudTS/Get-OSDCloudOperatingSystemsIndexes.ps1 +++ b/Public/OSDCloudTS/Get-OSDCloudOperatingSystemsIndexes.ps1 @@ -19,10 +19,30 @@ function Get-OSDCloudOperatingSystemsIndexes { ) if ($OSArch -eq 'x64') { - $Results = Get-Content -Path "$(Get-OSDModulePath)\cache\archive-cloudoperatingsystems\CloudOperatingSystemsIndexes.json" | ConvertFrom-Json + $OfflineCatalog = Get-PSDrive -PSProvider FileSystem | Where-Object {$_.Name -ne 'C'} | ForEach-Object { + Get-ChildItem "$($_.Root)OSDCloud\Catalogs" -Include "CloudOperatingSystemsIndexes.json" -File -Force -Recurse -ErrorAction Ignore + } + if ($OfflineCatalog) { + foreach ($Item in $OfflineCatalog) { + Write-Warning "$($Item.FullName) is imported instead of the cache under $(Get-OSDModulePath)." + $Results = Get-Content -Path "$($Item.FullName)" | ConvertFrom-Json -ErrorAction "Stop" + } + } else { + $Results = Get-Content -Path "$(Get-OSDCachePath)\archive-cloudoperatingsystems\CloudOperatingSystemsIndexes.json" | ConvertFrom-Json + } } elseif ($OSArch -eq "ARM64") { - $Results = Get-Content -Path "$(Get-OSDModulePath)\cache\archive-cloudoperatingsystems\CloudOperatingSystemsARM64Indexes.json" | ConvertFrom-Json + $OfflineCatalog = Get-PSDrive -PSProvider FileSystem | Where-Object {$_.Name -ne 'C'} | ForEach-Object { + Get-ChildItem "$($_.Root)OSDCloud\Catalogs" -Include "CloudOperatingSystemsARM64Indexes.json" -File -Force -Recurse -ErrorAction Ignore + } + if ($OfflineCatalog) { + foreach ($Item in $OfflineCatalog) { + Write-Warning "$($Item.FullName) is imported instead of the cache under $(Get-OSDModulePath)." + $Results = Get-Content -Path "$($Item.FullName)" | ConvertFrom-Json -ErrorAction "Stop" + } + } else { + $Results = Get-Content -Path "$(Get-OSDCachePath)\archive-cloudoperatingsystems\CloudOperatingSystemsARM64Indexes.json" | ConvertFrom-Json + } } return $Results diff --git a/Public/OSDCloudTS/Initialize-OSDCloudStartnet.ps1 b/Public/OSDCloudTS/Initialize-OSDCloudStartnet.ps1 index 90f96619b..462aeaea0 100644 --- a/Public/OSDCloudTS/Initialize-OSDCloudStartnet.ps1 +++ b/Public/OSDCloudTS/Initialize-OSDCloudStartnet.ps1 @@ -142,20 +142,53 @@ function Initialize-OSDCloudStartnet { } } - # Check if the OSD Module in the PowerShell Gallery is newer than the installed version - $TimeSpan = New-TimeSpan -Start $Global:StartnetStart -End (Get-Date) - Write-Host -ForegroundColor DarkGray "$($TimeSpan.ToString("mm':'ss")) Updating OSD PowerShell Module" - $PSModuleName = 'OSD' - $InstalledModule = Get-Module -Name $PSModuleName -ListAvailable -ErrorAction Ignore | Sort-Object Version -Descending | Select-Object -First 1 - $GalleryPSModule = Find-Module -Name $PSModuleName -ErrorAction Ignore -WarningAction Ignore - - # Install the OSD module if it is not installed or if the version is older than the gallery version - if ($GalleryPSModule) { - if (($GalleryPSModule.Version -as [version]) -gt ($InstalledModule.Version -as [version])) { - Write-Host -ForegroundColor DarkGray "$PSModuleName $($GalleryPSModule.Version) [AllUsers]" - Install-Module $PSModuleName -Scope AllUsers -Force -SkipPublisherCheck - Import-Module $PSModuleName -Force + Write-Host -ForegroundColor Cyan '[i] Config Post StartNet Scripts' + $Global:ScriptStartNet2 = Get-PSDrive -PSProvider FileSystem | Where-Object { $_.Name -ne 'C' } | ForEach-Object { + Write-Host -ForegroundColor DarkGray "$($_.Root)OSDCloud\Config\Scripts\StartNet2\*.ps1" + Get-ChildItem "$($_.Root)OSDCloud\Config\Scripts\StartNet2\" -Include "*.ps1" -File -Recurse -Force -ErrorAction Ignore + } + if ($Global:ScriptStartNet2) { + $Global:ScriptStartNet2 = $Global:ScriptStartNet2 | Sort-Object -Property FullName + foreach ($Item in $Global:ScriptStartNet2) { + Write-Host -ForegroundColor Gray "Execute $($Item.FullName)" + & "$($Item.FullName)" + } + $TimeSpan = New-TimeSpan -Start $Global:StartnetStart -End (Get-Date) + Write-Host -ForegroundColor DarkGray "$($TimeSpan.ToString("mm':'ss")) Tried to execute Post StartNet Scripts" + } + + Write-Host -ForegroundColor Cyan '[i] OSD module update' + $Global:OSDModuleUpdate = $true # Default is trying to newer OSD module + $Global:OSDCloudStartnetJson = Get-PSDrive -PSProvider FileSystem | Where-Object {$_.Name -ne 'C'} | ForEach-Object { + Get-ChildItem "$($_.Root)OSDCloud\Config" -Include "Initialize-OSDCloudStartnet.json" -File -Force -Recurse -ErrorAction Ignore + } + if ($Global:OSDCloudStartnetJson ) { + foreach ($Item in $Global:OSDCloudStartnetJson) { + Write-Host -ForegroundColor DarkGray "$($Item.FullName)" + $Global:OSDModuleUpdate = (Get-Content -Path "$($Item.FullName)" | ConvertFrom-Json -ErrorAction "Stop").OSDAutoUpdate + Write-Host -ForegroundColor DarkGray "- OSDAutoUpdate: $($Global:OSDModuleUpdate)" } } + if ($Global:OSDModuleUpdate) { + # Check if the OSD Module in the PowerShell Gallery is newer than the installed version + $TimeSpan = New-TimeSpan -Start $Global:StartnetStart -End (Get-Date) + Write-Host -ForegroundColor DarkGray "$($TimeSpan.ToString("mm':'ss")) Updating OSD PowerShell Module" + $PSModuleName = 'OSD' + $InstalledModule = Get-Module -Name $PSModuleName -ListAvailable -ErrorAction Ignore | Sort-Object Version -Descending | Select-Object -First 1 + $GalleryPSModule = Find-Module -Name $PSModuleName -ErrorAction Ignore -WarningAction Ignore + + # Install the OSD module if it is not installed or if the version is older than the gallery version + if ($GalleryPSModule) { + if (($GalleryPSModule.Version -as [version]) -gt ($InstalledModule.Version -as [version])) { + Write-Host -ForegroundColor DarkGray "$PSModuleName $($GalleryPSModule.Version) [AllUsers]" + Install-Module $PSModuleName -Scope AllUsers -Force -SkipPublisherCheck + Import-Module $PSModuleName -Force + } + } + } else { + # if json contains {"OSDAutoUpdate": false} then not trying to import newer OSD module + $TimeSpan = New-TimeSpan -Start $Global:StartnetStart -End (Get-Date) + Write-Host -ForegroundColor DarkGray "$($TimeSpan.ToString("mm':'ss")) Skip Updating OSD PowerShell Module" + } } }