├── core ├── setupspecialize │ ├── setupspecialize.ppkg │ ├── customizations.xml │ └── setupspecialize.xml ├── winpekeyboard │ └── winpekeyboard.ps1 └── vs-projects │ └── OSDCloud │ ├── App.config │ ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ └── Resources.Designer.cs │ ├── App.xaml │ ├── App.xaml.cs │ ├── MainWindow.xaml.cs │ ├── OSDCloud.sln │ └── OSDCloud.csproj ├── public ├── Get-OSDCloudModulePath.ps1 ├── Get-OSDCloudModuleVersion.ps1 ├── Deploy-OSDCloudCLI.ps1 ├── Deploy-OSDCloudGUI.ps1 ├── Deploy-OSDCloud.ps1 ├── Deploy-OSDCloudDR.ps1 ├── Start-OSDCloudWorkflow.ps1 └── Get-OSDCloudInfo.ps1 ├── workflow ├── default │ ├── ux │ │ ├── App.config │ │ ├── Properties │ │ │ ├── Settings.settings │ │ │ ├── Settings.Designer.cs │ │ │ ├── AssemblyInfo.cs │ │ │ └── Resources.Designer.cs │ │ ├── App.xaml │ │ ├── App.xaml.cs │ │ ├── MainWindow.xaml.cs │ │ ├── OSDCloud.sln │ │ └── OSDCloud.csproj │ ├── user-amd64.json │ ├── os-arm64.json │ ├── os-amd64.json │ └── user-arm64.json ├── osdcloud-dr │ └── ux │ │ ├── App.config │ │ ├── Properties │ │ ├── Settings.settings │ │ ├── Settings.Designer.cs │ │ ├── AssemblyInfo.cs │ │ └── Resources.Designer.cs │ │ ├── App.xaml │ │ ├── App.xaml.cs │ │ ├── MainWindow.xaml.cs │ │ ├── OSDCloud.sln │ │ └── OSDCloud.csproj ├── latest │ ├── os-arm64.json │ └── os-amd64.json ├── archive │ ├── os-arm64.json │ ├── tasks │ │ └── task-disk-wipe-and-partition.json │ └── os-amd64.json └── demo │ ├── os-arm64.json │ └── os-amd64.json ├── .github ├── CODEOWNERS └── workflows │ └── publish-module.yaml ├── .gitignore ├── private ├── Use-PEStartupOSK.ps1 ├── steps │ ├── 9-postaction │ │ ├── step-postaction-removeosdcloudtemp.ps1 │ │ ├── step-postaction-removeosdcloudlogs.ps1 │ │ ├── step-postaction-stopcomputer.ps1 │ │ └── step-postaction-restartcomputer.ps1 │ ├── 1-initialization │ │ ├── step-initialize-startosdcloudworkflow.ps1 │ │ └── step-initialize-startosdcloudlogs.ps1 │ ├── 7-update │ │ └── step-update-setupdisplayedeula.ps1 │ ├── 5-drivers │ │ ├── step-drivers-recast-winos.ps1 │ │ ├── step-drivers-addwindowsdriver-net.ps1 │ │ ├── step-drivers-addwindowsdriver-disk.ps1 │ │ ├── step-drivers-addwindowsdriver-scsi.ps1 │ │ ├── step-drivers-addwindowsdriver-msupdate.ps1 │ │ ├── step-drivers-addwindowsdriver-firmware.ps1 │ │ ├── step-drivers-addwindowsdriver-driverpack.ps1 │ │ ├── step-drivers-recast-winre.ps1 │ │ ├── step-drivers-firmware.ps1 │ │ ├── step-drivers-msupdate.ps1 │ │ └── step-drivers-recast-winpe.ps1 │ ├── 4-install │ │ ├── step-install-getwindowsedition.ps1 │ │ ├── step-install-removewindowsimage.ps1 │ │ ├── step-install-restartosdcloudlogs.ps1 │ │ ├── step-install-bcdboot.ps1 │ │ └── step-install-expandwindowsimage.ps1 │ ├── do-not-use │ │ ├── step-labconfig-bypasscpucheck.ps1 │ │ ├── step-drivers-add-specialize-ppkg.ps1 │ │ ├── step-psmodule-save-osd.ps1 │ │ ├── step-osdcloud-logs-stop.ps1 │ │ └── Step-UpdatePSModule.ps1 │ ├── 8-finalize │ │ ├── step-finalize-stoposdcloudworkflow.ps1 │ │ └── step-finalize-exportofflineosinfo.ps1 │ ├── 3-preinstall │ │ ├── step-preinstall-cleardisk.ps1 │ │ ├── step-preinstall-restoreusbdriveletter.ps1 │ │ ├── step-preinstall-enablehighperformance.ps1 │ │ ├── step-preinstall-removeusbdriveletter.ps1 │ │ └── step-preinstall-partitiondisk.ps1 │ ├── 2-validation │ │ ├── step-validate-isdiskready.ps1 │ │ ├── step-validate-iswindowsimageready.ps1 │ │ └── step-validate-isdriverpackready.ps1 │ └── 6-powershell │ │ ├── step-powershell-savemodule.ps1 │ │ └── step-powershell-updatemodule.ps1 ├── Invoke-OSDCloudWorkflowUx.ps1 ├── main │ └── Initialize-OSDCloudModule.ps1 ├── Invoke-OSDCloudPEStartupCommand.ps1 ├── Initialize-OSDCloudWorkflowSettingsOS.ps1 ├── Initialize-OSDCloudWorkflowSettingsUser.ps1 ├── Invoke-OSDCloudPEStartupUpdateModule.ps1 └── Initialize-OSDCloudWorkflowTasks.ps1 ├── public-winpe ├── Use-PEStartupIpconfig.ps1 ├── Use-PEStartupHardware.ps1 ├── Use-PEStartupUpdateModule.ps1 ├── Use-PEStartupHardwareErrors.ps1 ├── Invoke-OSDCloudPEStartup.ps1 └── Use-PEStartupWiFi.ps1 ├── module.json ├── docs ├── Get-OSDCloudInfo.md ├── Get-OSDCloudModulePath.md ├── Get-OSDCloudModuleVersion.md ├── Deploy-OSDCloudCLI.md ├── Deploy-OSDCloudGUI.md ├── Deploy-OSDCloud.md ├── Start-OSDCloudWorkflow.md └── Invoke-OSDCloudPEStartup.md ├── OSDCloud.psm1 └── OSDCloud.psd1 /core/setupspecialize/setupspecialize.ppkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OSDeploy/OSDCloud/HEAD/core/setupspecialize/setupspecialize.ppkg -------------------------------------------------------------------------------- /core/winpekeyboard/winpekeyboard.ps1: -------------------------------------------------------------------------------- 1 | if (Get-Command -Name 'osk.exe') { 2 | Start-Process -FilePath 'osk.exe' -WindowStyle Minimized 3 | } -------------------------------------------------------------------------------- /public/Get-OSDCloudModulePath.ps1: -------------------------------------------------------------------------------- 1 | function Get-OSDCloudModulePath { 2 | [CmdletBinding()] 3 | param () 4 | 5 | return $MyInvocation.MyCommand.Module.ModuleBase 6 | } -------------------------------------------------------------------------------- /public/Get-OSDCloudModuleVersion.ps1: -------------------------------------------------------------------------------- 1 | function Get-OSDCloudModuleVersion { 2 | [CmdletBinding()] 3 | param () 4 | 5 | return $MyInvocation.MyCommand.Module.Version 6 | } -------------------------------------------------------------------------------- /workflow/default/ux/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /workflow/osdcloud-dr/ux/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /core/vs-projects/OSDCloud/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /workflow/default/ux/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /workflow/osdcloud-dr/ux/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /core/vs-projects/OSDCloud/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /workflow/default/ux/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /core/vs-projects/OSDCloud/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /workflow/default/ux/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace OSDCloud 10 | { 11 | /// 12 | /// Interaction logic for App.xaml 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /workflow/osdcloud-dr/ux/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /workflow/osdcloud-dr/ux/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace OSDCloud 10 | { 11 | /// 12 | /// Interaction logic for App.xaml 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # CODEOWNERS - Define code ownership for this repository 2 | # See https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners 3 | 4 | # Default owner for everything 5 | * @OSDeploy 6 | 7 | # Specific ownership for important directories (customize as needed) 8 | # .github/ @OSDeploy 9 | 10 | # Example: assign a different owner for a specific file 11 | # README.md @OSDeploy 12 | -------------------------------------------------------------------------------- /core/vs-projects/OSDCloud/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace OSDCloud 10 | { 11 | /// 12 | /// Interaction logic for App.xaml 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Visual Studio 2 | .vs/ 3 | *.user 4 | *.suo 5 | *.userosscache 6 | *.sln.docstates 7 | 8 | # Build results 9 | [Bb]in/ 10 | [Oo]bj/ 11 | 12 | # Windows 13 | Thumbs.db 14 | Desktop.ini 15 | $RECYCLE.BIN/ 16 | 17 | # OS 18 | .DS_Store 19 | 20 | # Logs 21 | *.log 22 | 23 | # Package distribution 24 | *.tgz 25 | *.tar.gz 26 | *.zip 27 | 28 | # Environment files 29 | .env 30 | .env.* 31 | 32 | # OSDCloud specific 33 | OSDCloud.log 34 | 35 | # Custom 36 | workflow-backup -------------------------------------------------------------------------------- /private/Use-PEStartupOSK.ps1: -------------------------------------------------------------------------------- 1 | function Use-PEStartupOSK { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 6 | $Error.Clear() 7 | #================================================= 8 | $host.ui.RawUI.WindowTitle = '[OSDCloud] Use-PEStartupOSK' 9 | 10 | Start-Process -FilePath 'osk.exe' -WindowStyle Minimized 11 | exit 0 12 | #================================================= 13 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Done" 14 | #================================================= 15 | } -------------------------------------------------------------------------------- /.github/workflows/publish-module.yaml: -------------------------------------------------------------------------------- 1 | name: Publish Module to PSGallery 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | permissions: 7 | contents: write 8 | pull-requests: write 9 | 10 | jobs: 11 | build: 12 | runs-on: windows-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | with: 17 | repository: OSDeploy/OSDCloud 18 | path: OSDCloud 19 | ref: main 20 | 21 | - name: Publish to PowerShell Gallery 22 | run: | 23 | pwsh -Command "Publish-Module -Path ${{ github.workspace }}\OSDCloud -Verbose -Repository PSGallery -NuGetApiKey $env:PSGALLERY_API_KEY" 24 | env: 25 | PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }} -------------------------------------------------------------------------------- /public-winpe/Use-PEStartupIpconfig.ps1: -------------------------------------------------------------------------------- 1 | function Use-PEStartupIpconfig { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 6 | $Error.Clear() 7 | $host.ui.RawUI.WindowTitle = '[OSDCloud] IPConfig - Network Configuration' 8 | #================================================= 9 | Write-Host -ForegroundColor DarkCyan "[$(Get-Date -format G)] ipconfig /all" 10 | ipconfig /all 11 | #================================================= 12 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Done" 13 | #================================================= 14 | } -------------------------------------------------------------------------------- /workflow/default/ux/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace OSDCloud 17 | { 18 | /// 19 | /// Interaction logic for MainWindow.xaml 20 | /// 21 | public partial class MainWindow : Window 22 | { 23 | public MainWindow() 24 | { 25 | InitializeComponent(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /workflow/osdcloud-dr/ux/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace OSDCloud 17 | { 18 | /// 19 | /// Interaction logic for MainWindow.xaml 20 | /// 21 | public partial class MainWindow : Window 22 | { 23 | public MainWindow() 24 | { 25 | InitializeComponent(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /core/vs-projects/OSDCloud/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace OSDCloud 17 | { 18 | /// 19 | /// Interaction logic for MainWindow.xaml 20 | /// 21 | public partial class MainWindow : Window 22 | { 23 | public MainWindow() 24 | { 25 | InitializeComponent(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /public/Deploy-OSDCloudCLI.ps1: -------------------------------------------------------------------------------- 1 | function Deploy-OSDCloudCLI { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $false, 5 | Position = 0, 6 | ValueFromPipelineByPropertyName = $true)] 7 | [System.String] 8 | $Name = 'default' 9 | ) 10 | #================================================= 11 | # Initialize OSDCloudWorkflow 12 | Initialize-OSDCloudWorkflow -Name $Name 13 | #================================================= 14 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Invoke-OSDCloudWorkflow" 15 | $global:OSDCloudWorkflowInit.TimeStart = Get-Date 16 | $OSDCloudWorkflowInit | Out-Host 17 | Invoke-OSDCloudWorkflow 18 | #================================================= 19 | } -------------------------------------------------------------------------------- /core/setupspecialize/customizations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {97a4c0e8-fa6e-4120-8e48-53e2bf5a29ac} 5 | setupspecialize 6 | 1.1 7 | OEM 8 | 0 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | C:\Windows\Temp\osdcloud\SetupSpecialize.cmd 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /module.json: -------------------------------------------------------------------------------- 1 | { 2 | "links": { 3 | "david": "https://linkedin.com/in/davidsegura", 4 | "michael": "https://linkedin.com/in/michael-a-escamilla", 5 | "gary": "https://www.linkedin.com/in/garyblok/", 6 | "nwscug": "https://nwscug.org", 7 | "mmsmoa": "https://mmsmoa.com", 8 | "wpninjasuk": "https://wpninjas.uk", 9 | "wpninjasch": "https://wpninjas.ch", 10 | "discord": "https://discord.com/channels/618712310185197588/621205976351113216" 11 | }, 12 | "module": { 13 | "info": "https://www.osdeploy.com/", 14 | "project": "https://github.com/OSDeploy/OSDCloud", 15 | "docs": "https://github.com/OSDeploy/OSDCloud/tree/main/docs", 16 | "issues": "https://github.com/OSDeploy/OSDCloud/issues", 17 | "powershellgallery": "https://www.powershellgallery.com/packages/OSDCloud" 18 | } 19 | } -------------------------------------------------------------------------------- /private/steps/9-postaction/step-postaction-removeosdcloudtemp.ps1: -------------------------------------------------------------------------------- 1 | function step-postaction-removeosdcloudtemp { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | $Path = 'C:\Windows\Temp\osdcloud' 13 | 14 | if (Test-Path $Path) { 15 | Remove-Item -Path $Path -Recurse -Force -ErrorAction SilentlyContinue 16 | } 17 | #================================================= 18 | # End the function 19 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 20 | Write-Verbose -Message $Message; Write-Debug -Message $Message 21 | #================================================= 22 | } -------------------------------------------------------------------------------- /public-winpe/Use-PEStartupHardware.ps1: -------------------------------------------------------------------------------- 1 | function Use-PEStartupHardware { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 6 | $Error.Clear() 7 | $host.ui.RawUI.WindowTitle = '[OSDCloud] Device Hardware' 8 | #================================================= 9 | $Results = Get-CimInstance -ClassName Win32_PnPEntity | Select-Object Status, DeviceID, Name, Manufacturer, PNPClass, Service | Sort-Object DeviceID 10 | 11 | if ($Results) { 12 | Write-Host -ForegroundColor DarkCyan "[$(Get-Date -format G)] Get-CimInstance Win32_PnPEntity Hardware Devices" 13 | Write-Output $Results | Format-Table -AutoSize 14 | } 15 | else { 16 | exit 0 17 | } 18 | #================================================= 19 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Done" 20 | #================================================= 21 | } -------------------------------------------------------------------------------- /core/setupspecialize/setupspecialize.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | File 12 | All Windows editions 13 | Microsoft-Common-Provisioning.dat 14 | WindowsCommon 15 | 10.0 16 | Selecting this option will display settings that apply to all Windows editions. 17 | 18 | 19 | File 20 | All Windows desktop editions 21 | Microsoft-Desktop-Provisioning.dat 22 | Desktop 23 | 10.0 24 | Selecting this option will display settings that are specific to the desktop editions as well as settings that are common to all Windows editions. 25 | 26 | 27 | -------------------------------------------------------------------------------- /workflow/default/user-amd64.json: -------------------------------------------------------------------------------- 1 | { 2 | "DriverPacks": { 3 | "None": true, 4 | "MSCatalog": false, 5 | "OSDCloud": true, 6 | "Default": "None" 7 | }, 8 | "IsTpmReady": { 9 | "Error": "Device is not fully TPM 2.0 compatible. Autopilot will not work.", 10 | "Success": "TPM is 2.0 an working as expected.\n Autopilot will work.", 11 | "Warning": "Device is not fully TPM 2.0 compatible." 12 | }, 13 | "PSInstallModuleOSD": false, 14 | "PSInstallModuleWindowsAutopilotIntune": false, 15 | "PSUpdateModulePackageManagement": false, 16 | "PSUpdateModulePowershellGet": false, 17 | "RecoveryPartition": { 18 | "Force": false, 19 | "Skip": false, 20 | "ToolTip": "Recovery Partition is created by default, except when deploying to a Virtual Machine. Force will always create the Recovery Partition. Skip will never create the Recovery Partition." 21 | }, 22 | "SkipRecoveryPartition": false, 23 | "UpdateDiskDrivers": true, 24 | "UpdateNetworkDrivers": true, 25 | "UpdateScsiDrivers": true, 26 | "UpdateSystemFirmware": false, 27 | "WinpeRestart": false, 28 | "WinpeShutdown": false 29 | } -------------------------------------------------------------------------------- /workflow/default/ux/OSDCloud.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.11.35312.102 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OSDCloud", "OSDCloud.csproj", "{78491010-EC60-4726-843B-16627447BD36}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {78491010-EC60-4726-843B-16627447BD36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {78491010-EC60-4726-843B-16627447BD36}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {78491010-EC60-4726-843B-16627447BD36}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {78491010-EC60-4726-843B-16627447BD36}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {2A8E0196-C36D-4B42-81CE-C1603625FA60} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /core/vs-projects/OSDCloud/OSDCloud.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.11.35312.102 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OSDCloud", "OSDCloud.csproj", "{78491010-EC60-4726-843B-16627447BD36}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {78491010-EC60-4726-843B-16627447BD36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {78491010-EC60-4726-843B-16627447BD36}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {78491010-EC60-4726-843B-16627447BD36}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {78491010-EC60-4726-843B-16627447BD36}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {2A8E0196-C36D-4B42-81CE-C1603625FA60} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /private/steps/1-initialization/step-initialize-startosdcloudworkflow.ps1: -------------------------------------------------------------------------------- 1 | function step-initialize-startosdcloudworkflow { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $false)] 5 | [string]$WorkflowName = "OSDCloud Workflow" 6 | ) 7 | #================================================= 8 | # Start the step 9 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 10 | Write-Debug -Message $Message; Write-Verbose -Message $Message 11 | 12 | # Get the configuration of the step 13 | $Step = $global:OSDCloudWorkflowCurrentStep 14 | #================================================= 15 | # Delay Start 16 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Starting $WorkflowName in 5 seconds..." 17 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Press CTRL+C to cancel" 18 | Start-Sleep -Seconds 5 19 | #================================================= 20 | # End the function 21 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 22 | Write-Verbose -Message $Message; Write-Debug -Message $Message 23 | #================================================= 24 | } -------------------------------------------------------------------------------- /workflow/osdcloud-dr/ux/OSDCloud.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.11.35312.102 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OSDCloud", "OSDCloud.csproj", "{78491010-EC60-4726-843B-16627447BD36}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {78491010-EC60-4726-843B-16627447BD36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {78491010-EC60-4726-843B-16627447BD36}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {78491010-EC60-4726-843B-16627447BD36}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {78491010-EC60-4726-843B-16627447BD36}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {2A8E0196-C36D-4B42-81CE-C1603625FA60} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /workflow/default/ux/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace OSDCloud.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /workflow/osdcloud-dr/ux/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace OSDCloud.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /core/vs-projects/OSDCloud/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace OSDCloud.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /public-winpe/Use-PEStartupUpdateModule.ps1: -------------------------------------------------------------------------------- 1 | function Use-PEStartupUpdateModule { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $true)] 5 | [System.String] 6 | $Name 7 | ) 8 | #================================================= 9 | $Error.Clear() 10 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 11 | $host.ui.RawUI.WindowTitle = "[OSDCloud] Update PowerShell Module: $Name (close this window to cancel)" 12 | #================================================= 13 | Write-Host -ForegroundColor DarkCyan "[$(Get-Date -format G)] Update PowerShell Module: $Name" 14 | Write-Host -ForegroundColor DarkCyan "[$(Get-Date -format G)] Close this window to cancel (starting in 10 seconds)" 15 | Start-Sleep -Seconds 10 16 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] $Name $($GalleryPSModule.Version) [AllUsers]" 17 | Install-Module $Name -Scope AllUsers -Force -SkipPublisherCheck 18 | Import-Module $Name -Force 19 | #================================================= 20 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Done" 21 | #================================================= 22 | } -------------------------------------------------------------------------------- /private/steps/7-update/step-update-setupdisplayedeula.ps1: -------------------------------------------------------------------------------- 1 | function step-update-setupdisplayedeula { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Updating the OOBE SetupDisplayedEula value in the registry. OK." 14 | $null = reg load HKLM\TempSOFTWARE "C:\Windows\System32\Config\SOFTWARE" 15 | $null = reg add HKLM\TempSOFTWARE\Microsoft\Windows\CurrentVersion\Setup\OOBE /v SetupDisplayedEula /t REG_DWORD /d 0x00000001 /f 16 | $null = reg unload HKLM\TempSOFTWARE 17 | #================================================= 18 | # End the function 19 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 20 | Write-Verbose -Message $Message; Write-Debug -Message $Message 21 | #================================================= 22 | } -------------------------------------------------------------------------------- /public-winpe/Use-PEStartupHardwareErrors.ps1: -------------------------------------------------------------------------------- 1 | function Use-PEStartupHardwareErrors { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 6 | $Error.Clear() 7 | $host.ui.RawUI.WindowTitle = '[OSDCloud] Device Hardware with Issues (automatically close in 5 seconds)' 8 | #================================================= 9 | $Results = Get-CimInstance -ClassName Win32_PnPEntity | Select-Object Status, DeviceID, Name, Manufacturer, PNPClass, Service | Where-Object Status -ne 'OK' | Sort-Object Status, DeviceID 10 | 11 | if ($Results) { 12 | Write-Host -ForegroundColor DarkCyan "[$(Get-Date -format G)] Get-CimInstance Win32_PnPEntity Hardware Devices with Issues" 13 | Write-Host -ForegroundColor DarkCyan "[$(Get-Date -format G)] This window will automatically close in 5 seconds" 14 | Write-Output $Results | Format-Table -AutoSize 15 | Start-Sleep -Seconds 5 16 | } 17 | exit 0 18 | #================================================= 19 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Done" 20 | #================================================= 21 | } -------------------------------------------------------------------------------- /private/steps/5-drivers/step-drivers-recast-winos.ps1: -------------------------------------------------------------------------------- 1 | function step-drivers-recast-winos { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | $LogPath = "C:\Windows\Temp\osdcloud-logs" 13 | 14 | $DriverPath = "C:\Windows\Temp\osdcloud-drivers-recast" 15 | 16 | if (Test-Path -Path $DriverPath) { 17 | if (-not (Test-Path -Path $LogPath)) { 18 | New-Item -ItemType Directory -Path $LogPath -Force | Out-Null 19 | } 20 | Add-WindowsDriver -Path "C:\" -Driver "$DriverPath" -Recurse -ForceUnsigned -LogPath "$LogPath\drivers-recast-winos.log" -ErrorAction SilentlyContinue 21 | } 22 | #================================================= 23 | # End the function 24 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 25 | Write-Verbose -Message $Message; Write-Debug -Message $Message 26 | #================================================= 27 | } -------------------------------------------------------------------------------- /private/steps/5-drivers/step-drivers-addwindowsdriver-net.ps1: -------------------------------------------------------------------------------- 1 | function step-drivers-addwindowsdriver-net { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | $LogPath = "C:\Windows\Temp\osdcloud-logs" 13 | 14 | $DriverPath = "C:\Windows\Temp\osdcloud-drivers-net" 15 | 16 | if (Test-Path -Path $DriverPath) { 17 | if (-not (Test-Path -Path $LogPath)) { 18 | New-Item -ItemType Directory -Path $LogPath -Force | Out-Null 19 | } 20 | Add-WindowsDriver -Path "C:\" -Driver "$DriverPath" -Recurse -ForceUnsigned -LogPath "$LogPath\drivers-net.log" -ErrorAction SilentlyContinue 21 | } 22 | #================================================= 23 | # End the function 24 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 25 | Write-Verbose -Message $Message; Write-Debug -Message $Message 26 | #================================================= 27 | } -------------------------------------------------------------------------------- /private/steps/5-drivers/step-drivers-addwindowsdriver-disk.ps1: -------------------------------------------------------------------------------- 1 | function step-drivers-addwindowsdriver-disk { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | $LogPath = "C:\Windows\Temp\osdcloud-logs" 13 | 14 | $DriverPath = "C:\Windows\Temp\osdcloud-drivers-disk" 15 | 16 | if (Test-Path -Path $DriverPath) { 17 | if (-not (Test-Path -Path $LogPath)) { 18 | New-Item -ItemType Directory -Path $LogPath -Force | Out-Null 19 | } 20 | Add-WindowsDriver -Path "C:\" -Driver "$DriverPath" -Recurse -ForceUnsigned -LogPath "$LogPath\drivers-disk.log" -ErrorAction SilentlyContinue 21 | } 22 | #================================================= 23 | # End the function 24 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 25 | Write-Verbose -Message $Message; Write-Debug -Message $Message 26 | #================================================= 27 | } -------------------------------------------------------------------------------- /private/steps/5-drivers/step-drivers-addwindowsdriver-scsi.ps1: -------------------------------------------------------------------------------- 1 | function step-drivers-addwindowsdriver-scsi { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | $LogPath = "C:\Windows\Temp\osdcloud-logs" 13 | 14 | $DriverPath = "C:\Windows\Temp\osdcloud-drivers-scsi" 15 | 16 | if (Test-Path -Path $DriverPath) { 17 | if (-not (Test-Path -Path $LogPath)) { 18 | New-Item -ItemType Directory -Path $LogPath -Force | Out-Null 19 | } 20 | Add-WindowsDriver -Path "C:\" -Driver "$DriverPath" -Recurse -ForceUnsigned -LogPath "$LogPath\drivers-scsi.log" -ErrorAction SilentlyContinue 21 | } 22 | #================================================= 23 | # End the function 24 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 25 | Write-Verbose -Message $Message; Write-Debug -Message $Message 26 | #================================================= 27 | } -------------------------------------------------------------------------------- /private/steps/5-drivers/step-drivers-addwindowsdriver-msupdate.ps1: -------------------------------------------------------------------------------- 1 | function step-drivers-addwindowsdriver-msupdate { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | $LogPath = "C:\Windows\Temp\osdcloud-logs" 13 | 14 | $DriverPath = "C:\Windows\Temp\osdcloud-drivers-msupdate" 15 | 16 | if (Test-Path -Path $DriverPath) { 17 | if (-not (Test-Path -Path $LogPath)) { 18 | New-Item -ItemType Directory -Path $LogPath -Force | Out-Null 19 | } 20 | Add-WindowsDriver -Path "C:\" -Driver "$DriverPath" -Recurse -ForceUnsigned -LogPath "$LogPath\drivers-msupdate.log" -ErrorAction SilentlyContinue 21 | } 22 | #================================================= 23 | # End the function 24 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 25 | Write-Verbose -Message $Message; Write-Debug -Message $Message 26 | #================================================= 27 | } -------------------------------------------------------------------------------- /private/steps/9-postaction/step-postaction-removeosdcloudlogs.ps1: -------------------------------------------------------------------------------- 1 | function step-postaction-removeosdcloudlogs { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | # Stop Transcript at this point as this file is locked and will cause issues with cleanup 13 | $null = Stop-Transcript -ErrorAction SilentlyContinue 14 | 15 | $LogsPath = "C:\Windows\Temp\osdcloud-logs" 16 | 17 | $Params = @{ 18 | ErrorAction = 'SilentlyContinue' 19 | Force = $true 20 | Path = $LogsPath 21 | Recurse = $true 22 | } 23 | 24 | if (Test-Path $LogsPath) { 25 | Remove-Item @Params | Out-Null 26 | } 27 | #================================================= 28 | # End the function 29 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 30 | Write-Verbose -Message $Message; Write-Debug -Message $Message 31 | #================================================= 32 | } -------------------------------------------------------------------------------- /private/steps/5-drivers/step-drivers-addwindowsdriver-firmware.ps1: -------------------------------------------------------------------------------- 1 | function step-drivers-addwindowsdriver-firmware { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | $LogPath = "C:\Windows\Temp\osdcloud-logs" 13 | 14 | $DriverPath = "C:\Windows\Temp\osdcloud-drivers-firmware" 15 | 16 | if (Test-Path -Path $DriverPath) { 17 | if (-not (Test-Path -Path $LogPath)) { 18 | New-Item -ItemType Directory -Path $LogPath -Force | Out-Null 19 | } 20 | Add-WindowsDriver -Path "C:\" -Driver "$DriverPath" -Recurse -ForceUnsigned -LogPath "$LogPath\drivers-firmware.log" -ErrorAction SilentlyContinue | Out-Null 21 | } 22 | #================================================= 23 | # End the function 24 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 25 | Write-Verbose -Message $Message; Write-Debug -Message $Message 26 | #================================================= 27 | } -------------------------------------------------------------------------------- /private/steps/4-install/step-install-getwindowsedition.ps1: -------------------------------------------------------------------------------- 1 | function step-install-getwindowsedition { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | try { 13 | $WindowsEdition = (Get-WindowsEdition -Path 'C:\' -ErrorAction Stop | Out-String).Trim() 14 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] $WindowsEdition" 15 | $global:OSDCloudWorkflowInvoke.WindowsEdition = $WindowsEdition 16 | } 17 | catch { 18 | Write-Warning "[$(Get-Date -format G)] Unable to get Windows Edition. OK." 19 | Write-Warning "[$(Get-Date -format G)] $_" 20 | } 21 | finally { 22 | $Error.Clear() 23 | } 24 | #================================================= 25 | # End the function 26 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 27 | Write-Verbose -Message $Message; Write-Debug -Message $Message 28 | #================================================= 29 | } -------------------------------------------------------------------------------- /private/steps/5-drivers/step-drivers-addwindowsdriver-driverpack.ps1: -------------------------------------------------------------------------------- 1 | function step-drivers-addwindowsdriver-driverpack { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | $LogPath = "C:\Windows\Temp\osdcloud-logs" 13 | 14 | $DriverPath = "C:\Windows\Temp\osdcloud-driverpack-expand" 15 | 16 | if (Test-Path -Path $DriverPath) { 17 | if (-not (Test-Path -Path $LogPath)) { 18 | New-Item -ItemType Directory -Path $LogPath -Force | Out-Null 19 | } 20 | Add-WindowsDriver -Path "C:\" -Driver "$DriverPath" -Recurse -ForceUnsigned -LogPath "$LogPath\drivers-driverpack.log" -ErrorAction SilentlyContinue | Out-Null 21 | } 22 | #================================================= 23 | # End the function 24 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 25 | Write-Verbose -Message $Message; Write-Debug -Message $Message 26 | #================================================= 27 | } -------------------------------------------------------------------------------- /docs/Get-OSDCloudInfo.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: OSDCloud-help.xml 3 | Module Name: OSDCloud 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-OSDCloudInfo 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Get-OSDCloudInfo [-ProgressAction ] [] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | {{ Fill in the Description }} 21 | 22 | ## EXAMPLES 23 | 24 | ### Example 1 25 | ``` 26 | PS C:\> {{ Add example code here }} 27 | ``` 28 | 29 | {{ Add example description here }} 30 | 31 | ## PARAMETERS 32 | 33 | ### -ProgressAction 34 | {{ Fill ProgressAction Description }} 35 | 36 | ```yaml 37 | Type: ActionPreference 38 | Parameter Sets: (All) 39 | Aliases: proga 40 | 41 | Required: False 42 | Position: Named 43 | Default value: None 44 | Accept pipeline input: False 45 | Accept wildcard characters: False 46 | ``` 47 | 48 | ### CommonParameters 49 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 50 | 51 | ## INPUTS 52 | 53 | ### None 54 | ## OUTPUTS 55 | 56 | ### System.Object 57 | ## NOTES 58 | 59 | ## RELATED LINKS 60 | -------------------------------------------------------------------------------- /workflow/latest/os-arm64.json: -------------------------------------------------------------------------------- 1 | { 2 | "OSActivation.default": "Retail", 3 | "OSActivation.values": [ 4 | "Retail", 5 | "Volume" 6 | ], 7 | "OSEdition.default": "Pro", 8 | "OSEditionId.default": "Professional", 9 | "OSEdition.values": [ 10 | { 11 | "Edition": "Home", 12 | "EditionId": "Core" 13 | }, 14 | { 15 | "Edition": "Pro", 16 | "EditionId": "Professional" 17 | }, 18 | { 19 | "Edition": "Enterprise", 20 | "EditionId": "Enterprise" 21 | } 22 | ], 23 | "OSLanguageCode.default": "en-us", 24 | "OSLanguageCode.values": [ 25 | "ar-sa", 26 | "bg-bg", 27 | "cs-cz", 28 | "da-dk", 29 | "de-de", 30 | "el-gr", 31 | "en-gb", 32 | "en-us", 33 | "es-es", 34 | "es-mx", 35 | "et-ee", 36 | "fi-fi", 37 | "fr-ca", 38 | "fr-fr", 39 | "he-il", 40 | "hr-hr", 41 | "hu-hu", 42 | "it-it", 43 | "ja-jp", 44 | "ko-kr", 45 | "lt-lt", 46 | "lv-lv", 47 | "nb-no", 48 | "uk-ua", 49 | "zh-cn", 50 | "zh-tw" 51 | ], 52 | "OSName.default": "Win11-25H2-arm64", 53 | "OSName.values": [ 54 | "Win11-25H2-arm64" 55 | ] 56 | } -------------------------------------------------------------------------------- /OSDCloud.psm1: -------------------------------------------------------------------------------- 1 | # Get public and private function definition files. 2 | $Private = @( Get-ChildItem -Path $PSScriptRoot\private\*.ps1 -ErrorAction SilentlyContinue -Recurse ) 3 | $Public = @( Get-ChildItem -Path $PSScriptRoot\public\*.ps1 -ErrorAction SilentlyContinue -Recurse ) 4 | $PublicWinPE = @( Get-ChildItem -Path $PSScriptRoot\public-winpe\*.ps1 -ErrorAction SilentlyContinue -Recurse ) 5 | 6 | $FoundErrors = @( 7 | if ($env:SystemDrive -eq 'X:') { 8 | foreach ($Import in @($Private + $Public + $PublicWinPE)) { 9 | try { . $Import.Fullname} 10 | catch { 11 | Write-Error -Message "Failed to import functions from $($Import.Fullname): $_" 12 | $true 13 | } 14 | } 15 | } else { 16 | foreach ($Import in @($Private + $Public)) { 17 | try { . $Import.Fullname} 18 | catch { 19 | Write-Error -Message "Failed to import functions from $($Import.Fullname): $_" 20 | $true 21 | } 22 | } 23 | } 24 | ) 25 | 26 | if ($FoundErrors.Count -gt 0) { 27 | $ModuleName = (Get-ChildItem $PSScriptRoot\*.psd1).BaseName 28 | Write-Warning "Importing module $ModuleName failed. Fix errors before continuing." 29 | break 30 | } 31 | 32 | Export-ModuleMember -Function '*' -Alias '*' -Cmdlet '*' 33 | Initialize-OSDCloudModule -------------------------------------------------------------------------------- /private/steps/do-not-use/step-labconfig-bypasscpucheck.ps1: -------------------------------------------------------------------------------- 1 | function step-labconfig-bypasscpucheck { 2 | [CmdletBinding()] 3 | param ( 4 | [System.Boolean] 5 | $Enabled = $false 6 | ) 7 | #================================================= 8 | # Start the step 9 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 10 | Write-Debug -Message $Message; Write-Verbose -Message $Message 11 | 12 | # Get the configuration of the step 13 | $Step = $global:OSDCloudWorkflowCurrentStep 14 | #================================================= 15 | #region Main 16 | $OfflineRegistryPath = 'HKLM:\OfflineSystem\Setup\LabConfig' 17 | if (-not (Test-Path $OfflineRegistryPath)) { 18 | New-Item -Path $OfflineRegistryPath -Force | Out-Null 19 | } 20 | New-ItemProperty -Path $OfflineRegistryPath -Name 'BypassCPUCheck' -Value 1 -PropertyType DWord -Force | Out-Null 21 | Write-Host -ForegroundColor DarkCyan "[$(Get-Date -format G)] BypassCPUCheck set to 1 in offline registry" 22 | #endregion 23 | #================================================= 24 | # End the function 25 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 26 | Write-Verbose -Message $Message; Write-Debug -Message $Message 27 | #================================================= 28 | } 29 | -------------------------------------------------------------------------------- /docs/Get-OSDCloudModulePath.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: OSDCloud-help.xml 3 | Module Name: OSDCloud 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-OSDCloudModulePath 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Get-OSDCloudModulePath [-ProgressAction ] [] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | {{ Fill in the Description }} 21 | 22 | ## EXAMPLES 23 | 24 | ### Example 1 25 | ``` 26 | PS C:\> {{ Add example code here }} 27 | ``` 28 | 29 | {{ Add example description here }} 30 | 31 | ## PARAMETERS 32 | 33 | ### -ProgressAction 34 | {{ Fill ProgressAction Description }} 35 | 36 | ```yaml 37 | Type: ActionPreference 38 | Parameter Sets: (All) 39 | Aliases: proga 40 | 41 | Required: False 42 | Position: Named 43 | Default value: None 44 | Accept pipeline input: False 45 | Accept wildcard characters: False 46 | ``` 47 | 48 | ### CommonParameters 49 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 50 | 51 | ## INPUTS 52 | 53 | ### None 54 | ## OUTPUTS 55 | 56 | ### System.Object 57 | ## NOTES 58 | 59 | ## RELATED LINKS 60 | -------------------------------------------------------------------------------- /docs/Get-OSDCloudModuleVersion.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: OSDCloud-help.xml 3 | Module Name: OSDCloud 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-OSDCloudModuleVersion 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Get-OSDCloudModuleVersion [-ProgressAction ] [] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | {{ Fill in the Description }} 21 | 22 | ## EXAMPLES 23 | 24 | ### Example 1 25 | ``` 26 | PS C:\> {{ Add example code here }} 27 | ``` 28 | 29 | {{ Add example description here }} 30 | 31 | ## PARAMETERS 32 | 33 | ### -ProgressAction 34 | {{ Fill ProgressAction Description }} 35 | 36 | ```yaml 37 | Type: ActionPreference 38 | Parameter Sets: (All) 39 | Aliases: proga 40 | 41 | Required: False 42 | Position: Named 43 | Default value: None 44 | Accept pipeline input: False 45 | Accept wildcard characters: False 46 | ``` 47 | 48 | ### CommonParameters 49 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 50 | 51 | ## INPUTS 52 | 53 | ### None 54 | ## OUTPUTS 55 | 56 | ### System.Object 57 | ## NOTES 58 | 59 | ## RELATED LINKS 60 | -------------------------------------------------------------------------------- /private/steps/9-postaction/step-postaction-stopcomputer.ps1: -------------------------------------------------------------------------------- 1 | function step-postaction-stopcomputer { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | if ($global:OSDCloudWorkflowInvoke.WinpeRestart) { 14 | Write-Host -ForegroundColor Yellow "[$(Get-Date -format G)] Device will shut down in 30 seconds" 15 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Press CTRL + C to cancel" 16 | #TODO EJECT ISO 17 | # (New-Object -ComObject 'Shell.Application').Namespace(17).Items() | Where-Object { $_.Type -eq 'CD Drive' } | ForEach-Object { $_.InvokeVerb('Eject') } 18 | Start-Sleep -Seconds 30 19 | Stop-Computer 20 | } 21 | #endregion 22 | #================================================= 23 | # End the function 24 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 25 | Write-Verbose -Message $Message; Write-Debug -Message $Message 26 | #================================================= 27 | } -------------------------------------------------------------------------------- /private/steps/9-postaction/step-postaction-restartcomputer.ps1: -------------------------------------------------------------------------------- 1 | function step-postaction-restartcomputer { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | if ($global:OSDCloudWorkflowInvoke.WinpeRestart) { 14 | Write-Host -ForegroundColor Yellow "[$(Get-Date -format G)] Device will restart in 30 seconds" 15 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Press CTRL + C to cancel" 16 | #TODO EJECT ISO 17 | # (New-Object -ComObject 'Shell.Application').Namespace(17).Items() | Where-Object { $_.Type -eq 'CD Drive' } | ForEach-Object { $_.InvokeVerb('Eject') } 18 | Start-Sleep -Seconds 30 19 | Restart-Computer 20 | } 21 | #endregion 22 | #================================================= 23 | # End the function 24 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 25 | Write-Verbose -Message $Message; Write-Debug -Message $Message 26 | #================================================= 27 | } -------------------------------------------------------------------------------- /private/steps/4-install/step-install-removewindowsimage.ps1: -------------------------------------------------------------------------------- 1 | function step-install-removewindowsimage { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | if (Test-Path "C:\OSDCloud") { 14 | try { 15 | Remove-Item -Path "C:\OSDCloud" -Recurse -Force -ErrorAction Stop | Out-Null 16 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Removed C:\OSDCloud" 17 | } 18 | catch { 19 | Write-Host -ForegroundColor DarkYellow "[$(Get-Date -format G)] Unable to remove C:\OSDCloud" 20 | Write-Host -ForegroundColor DarkYellow "[$(Get-Date -format G)] $_" 21 | } 22 | finally { 23 | $Error.Clear() 24 | } 25 | } 26 | #endregion 27 | #================================================= 28 | # End the function 29 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 30 | Write-Verbose -Message $Message; Write-Debug -Message $Message 31 | #================================================= 32 | } -------------------------------------------------------------------------------- /private/steps/8-finalize/step-finalize-stoposdcloudworkflow.ps1: -------------------------------------------------------------------------------- 1 | function step-finalize-stoposdcloudworkflow { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | $global:OSDCloudWorkflowInvoke.TimeEnd = Get-Date 14 | $global:OSDCloudWorkflowInvoke.TimeSpan = New-TimeSpan -Start $global:OSDCloudWorkflowInvoke.TimeStart -End $global:OSDCloudWorkflowInvoke.TimeEnd 15 | $global:OSDCloudWorkflowInvoke | ConvertTo-Json | Out-File -FilePath 'C:\Windows\Temp\osdcloud-logs\OSDCloud.json' -Encoding ascii -Width 2000 -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue 16 | 17 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Completed in $($global:OSDCloudWorkflowInvoke.TimeSpan.ToString("mm' minutes 'ss' seconds'"))" 18 | #================================================= 19 | # End the function 20 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 21 | Write-Verbose -Message $Message; Write-Debug -Message $Message 22 | #================================================= 23 | } -------------------------------------------------------------------------------- /private/steps/do-not-use/step-drivers-add-specialize-ppkg.ps1: -------------------------------------------------------------------------------- 1 | function step-drivers-add-specialize-ppkg { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | Write-Host -ForegroundColor DarkGray 'Add Windows Driver with Offline Servicing (Add-OfflineServicingWindowsDriver)' 14 | Write-Verbose -Message 'https://docs.microsoft.com/en-us/powershell/module/dism/add-windowsdriver' 15 | Write-Host -ForegroundColor DarkGray 'Drivers in C:\Drivers are being added to the offline Windows Image' 16 | Write-Host -ForegroundColor DarkGray 'This process can take up to 20 minutes' 17 | Write-Verbose -Message 'Add-OfflineServicingWindowsDriver' 18 | if ($IsWinPE -eq $true) { 19 | Add-OfflineServicingWindowsDriver 20 | } 21 | #endregion 22 | #================================================= 23 | # End the function 24 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 25 | Write-Verbose -Message $Message; Write-Debug -Message $Message 26 | #================================================= 27 | } -------------------------------------------------------------------------------- /private/steps/3-preinstall/step-preinstall-cleardisk.ps1: -------------------------------------------------------------------------------- 1 | function step-preinstall-cleardisk { 2 | [CmdletBinding()] 3 | param ( 4 | # We should always confirm to Clear-Disk as this is destructive 5 | [System.Boolean] 6 | $Confirm = $true 7 | ) 8 | #================================================= 9 | # Start the step 10 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 11 | Write-Debug -Message $Message; Write-Verbose -Message $Message 12 | 13 | # Get the configuration of the step 14 | $Step = $global:OSDCloudWorkflowCurrentStep 15 | #================================================= 16 | #region Main 17 | # If Confirm is set to false, we need to check if there are multiple disks 18 | if (($Confirm -eq $false) -and (($global:OSDCloudWorkflowInvoke.GetDiskFixed | Measure-Object).Count -ge 2)) { 19 | Write-Warning "[$(Get-Date -format G)] OSDCloud has detected more than 1 Fixed Disk is installed. Clear-Disk with Confirm is required" 20 | $Confirm = $true 21 | } 22 | 23 | Clear-LocalDisk -Force -NoResults -Confirm:$Confirm -ErrorAction Stop 24 | #endregion 25 | #================================================= 26 | # End the function 27 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 28 | Write-Verbose -Message $Message; Write-Debug -Message $Message 29 | #================================================= 30 | } -------------------------------------------------------------------------------- /private/steps/2-validation/step-validate-isdiskready.ps1: -------------------------------------------------------------------------------- 1 | function step-validate-isdiskready { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | $global:OSDCloudWorkflowInvoke.GetDiskFixed = Get-LocalDisk | Where-Object { $_.IsBoot -eq $false } | Sort-Object Number 14 | 15 | if ($global:OSDCloudWorkflowInvoke.GetDiskFixed) { 16 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Fixed Disk is valid. OK." 17 | } 18 | else { 19 | Write-Warning "[$(Get-Date -format G)] Unable to detect a Fixed Disk." 20 | Write-Warning "[$(Get-Date -format G)] WinPE may need additional Disk, SCSI or Raid Drivers." 21 | Write-Warning 'Press Ctrl+C to cancel OSDCloud' 22 | Start-Sleep -Seconds 86400 23 | exit 24 | } 25 | #endregion 26 | #================================================= 27 | # End the function 28 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 29 | Write-Verbose -Message $Message; Write-Debug -Message $Message 30 | #================================================= 31 | } -------------------------------------------------------------------------------- /private/steps/3-preinstall/step-preinstall-restoreusbdriveletter.ps1: -------------------------------------------------------------------------------- 1 | function step-preinstall-restoreusbdriveletter { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | if ($global:OSDCloudWorkflowInvoke.USBPartitions) { 14 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Restoring USB Drive Letters. OK." 15 | foreach ($Item in $global:OSDCloudWorkflowInvoke.USBPartitions) { 16 | $Params = @{ 17 | AssignDriveLetter = $true 18 | DiskNumber = $Item.DiskNumber 19 | PartitionNumber = $Item.PartitionNumber 20 | ErrorAction = 'SilentlyContinue' 21 | } 22 | Add-PartitionAccessPath @Params 23 | Start-Sleep -Seconds 5 24 | } 25 | } 26 | #================================================= 27 | # End the function 28 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 29 | Write-Verbose -Message $Message; Write-Debug -Message $Message 30 | #================================================= 31 | } -------------------------------------------------------------------------------- /private/steps/1-initialization/step-initialize-startosdcloudlogs.ps1: -------------------------------------------------------------------------------- 1 | function step-initialize-startosdcloudlogs { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | $LogsPath = "$env:TEMP\osdcloud-logs" 14 | 15 | $Params = @{ 16 | Path = $LogsPath 17 | ItemType = 'Directory' 18 | Force = $true 19 | ErrorAction = 'SilentlyContinue' 20 | } 21 | 22 | if (-not (Test-Path $Params.Path)) { 23 | New-Item @Params | Out-Null 24 | } 25 | 26 | $TranscriptFullName = Join-Path $LogsPath "transcript-$((Get-Date).ToString('yyyy-MM-dd-HHmmss')).log" 27 | # Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] $TranscriptFullName" 28 | 29 | $null = Start-Transcript -Path $TranscriptFullName -ErrorAction SilentlyContinue 30 | #endregion 31 | #================================================= 32 | # End the function 33 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 34 | Write-Verbose -Message $Message; Write-Debug -Message $Message 35 | #================================================= 36 | } -------------------------------------------------------------------------------- /public/Deploy-OSDCloudGUI.ps1: -------------------------------------------------------------------------------- 1 | function Deploy-OSDCloudGUI { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $false, 5 | Position = 0, 6 | ValueFromPipelineByPropertyName = $true)] 7 | [System.String] 8 | $Name = 'default' 9 | ) 10 | #================================================= 11 | # Initialize OSDCloudWorkflow 12 | Initialize-OSDCloudWorkflow -Name $Name 13 | #================================================= 14 | # Prevents the workflow from starting unless the Start button is clicked in the Ux 15 | $global:OSDCloudWorkflowInit.TimeStart = $null 16 | #================================================= 17 | # OSDCloudWorkflowUx 18 | Invoke-OSDCloudWorkflowUx -Name $Name 19 | #================================================= 20 | # Ensure workflow frontend is triggered before invoking workflow 21 | if ($null -ne $global:OSDCloudWorkflowInit.TimeStart) { 22 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Invoke-OSDCloudWorkflow $Name" 23 | $OSDCloudWorkflowInit | Out-Host 24 | try { 25 | Invoke-OSDCloudWorkflow 26 | } catch { 27 | Write-Warning "Failed to invoke OSDCloud Workflow $Name $_" 28 | break 29 | } 30 | } else { 31 | Write-Host -ForegroundColor DarkCyan "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] OSDCloud Workflow $Name was not started." 32 | } 33 | #================================================= 34 | } -------------------------------------------------------------------------------- /private/steps/4-install/step-install-restartosdcloudlogs.ps1: -------------------------------------------------------------------------------- 1 | function step-install-restartosdcloudlogs { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | $LogsPath = "C:\Windows\Temp\osdcloud-logs" 14 | 15 | $Params = @{ 16 | Path = $LogsPath 17 | ItemType = 'Directory' 18 | Force = $true 19 | ErrorAction = 'SilentlyContinue' 20 | } 21 | 22 | if (-not (Test-Path $Params.Path)) { 23 | New-Item @Params | Out-Null 24 | } 25 | 26 | $null = robocopy "X:\Windows\Temp\osdcloud-logs" "$LogsPath" transcript.log /e /move /ndl /nfl /r:0 /w:0 27 | $TranscriptFullName = Join-Path $LogsPath "transcript-$((Get-Date).ToString('yyyy-MM-dd-HHmmss')).log" 28 | 29 | $null = Start-Transcript -Path $TranscriptFullName -ErrorAction SilentlyContinue 30 | # Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] $TranscriptFullName" 31 | #endregion 32 | #================================================= 33 | # End the function 34 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 35 | Write-Verbose -Message $Message; Write-Debug -Message $Message 36 | #================================================= 37 | } -------------------------------------------------------------------------------- /private/steps/3-preinstall/step-preinstall-enablehighperformance.ps1: -------------------------------------------------------------------------------- 1 | function step-preinstall-enablehighperformance { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | if ($IsOnBattery -eq $true) { 14 | $Win32Battery = (Get-CimInstance -ClassName Win32_Battery -ErrorAction SilentlyContinue | Select-Object -Property *) 15 | if ($Win32Battery.BatteryStatus -eq 1) { 16 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Device has $($Win32Battery.EstimatedChargeRemaining)% battery remaining" 17 | } 18 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] High Performance will not be enabled while on battery" 19 | } 20 | else { 21 | # Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] powercfg.exe -SetActive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c" 22 | powercfg.exe -SetActive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c 23 | } 24 | #endregion 25 | #================================================= 26 | # End the function 27 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 28 | Write-Verbose -Message $Message; Write-Debug -Message $Message 29 | #================================================= 30 | } -------------------------------------------------------------------------------- /workflow/archive/os-arm64.json: -------------------------------------------------------------------------------- 1 | { 2 | "OSActivation.default": "Retail", 3 | "OSActivation.values": [ 4 | "Retail", 5 | "Volume" 6 | ], 7 | "OSEdition.default": "Pro", 8 | "OSEditionId.default": "Professional", 9 | "OSEdition.values": [ 10 | { 11 | "Edition": "Home", 12 | "EditionId": "Core" 13 | }, 14 | { 15 | "Edition": "Pro", 16 | "EditionId": "Professional" 17 | }, 18 | { 19 | "Edition": "Enterprise", 20 | "EditionId": "Enterprise" 21 | } 22 | ], 23 | "OSLanguageCode.default": "en-us", 24 | "OSLanguageCode.values": [ 25 | "ar-sa", 26 | "bg-bg", 27 | "cs-cz", 28 | "da-dk", 29 | "de-de", 30 | "el-gr", 31 | "en-gb", 32 | "en-us", 33 | "es-es", 34 | "es-mx", 35 | "et-ee", 36 | "fi-fi", 37 | "fr-ca", 38 | "fr-fr", 39 | "he-il", 40 | "hr-hr", 41 | "hu-hu", 42 | "it-it", 43 | "ja-jp", 44 | "ko-kr", 45 | "lt-lt", 46 | "lv-lv", 47 | "nb-no", 48 | "nl-nl", 49 | "pl-pl", 50 | "pt-br", 51 | "pt-pt", 52 | "ro-ro", 53 | "ru-ru", 54 | "sk-sk", 55 | "sl-si", 56 | "sr-latn-rs", 57 | "sv-se", 58 | "th-th", 59 | "tr-tr", 60 | "uk-ua", 61 | "zh-cn", 62 | "zh-tw" 63 | ], 64 | "OSName.default": "Win11-25H2-arm64", 65 | "OSName.values": [ 66 | "Win11-25H2-arm64", 67 | "Win11-24H2-arm64", 68 | "Win11-23H2-arm64" 69 | ] 70 | } -------------------------------------------------------------------------------- /workflow/default/os-arm64.json: -------------------------------------------------------------------------------- 1 | { 2 | "OSActivation.default": "Retail", 3 | "OSActivation.values": [ 4 | "Retail", 5 | "Volume" 6 | ], 7 | "OSEdition.default": "Pro", 8 | "OSEditionId.default": "Professional", 9 | "OSEdition.values": [ 10 | { 11 | "Edition": "Home", 12 | "EditionId": "Core" 13 | }, 14 | { 15 | "Edition": "Pro", 16 | "EditionId": "Professional" 17 | }, 18 | { 19 | "Edition": "Enterprise", 20 | "EditionId": "Enterprise" 21 | } 22 | ], 23 | "OSLanguageCode.default": "en-us", 24 | "OSLanguageCode.values": [ 25 | "ar-sa", 26 | "bg-bg", 27 | "cs-cz", 28 | "da-dk", 29 | "de-de", 30 | "el-gr", 31 | "en-gb", 32 | "en-us", 33 | "es-es", 34 | "es-mx", 35 | "et-ee", 36 | "fi-fi", 37 | "fr-ca", 38 | "fr-fr", 39 | "he-il", 40 | "hr-hr", 41 | "hu-hu", 42 | "it-it", 43 | "ja-jp", 44 | "ko-kr", 45 | "lt-lt", 46 | "lv-lv", 47 | "nb-no", 48 | "nl-nl", 49 | "pl-pl", 50 | "pt-br", 51 | "pt-pt", 52 | "ro-ro", 53 | "ru-ru", 54 | "sk-sk", 55 | "sl-si", 56 | "sr-latn-rs", 57 | "sv-se", 58 | "th-th", 59 | "tr-tr", 60 | "uk-ua", 61 | "zh-cn", 62 | "zh-tw" 63 | ], 64 | "OSName.default": "Win11-25H2-arm64", 65 | "OSName.values": [ 66 | "Win11-25H2-arm64", 67 | "Win11-24H2-arm64", 68 | "Win11-23H2-arm64" 69 | ] 70 | } -------------------------------------------------------------------------------- /workflow/demo/os-arm64.json: -------------------------------------------------------------------------------- 1 | { 2 | "OSActivation.default": "Retail", 3 | "OSActivation.values": [ 4 | "Retail", 5 | "Volume" 6 | ], 7 | "OSEdition.default": "Pro", 8 | "OSEditionId.default": "Professional", 9 | "OSEdition.values": [ 10 | { 11 | "Edition": "Home", 12 | "EditionId": "Core" 13 | }, 14 | { 15 | "Edition": "Pro", 16 | "EditionId": "Professional" 17 | }, 18 | { 19 | "Edition": "Enterprise", 20 | "EditionId": "Enterprise" 21 | } 22 | ], 23 | "OSLanguageCode.default": "en-us", 24 | "OSLanguageCode.values": [ 25 | "ar-sa", 26 | "bg-bg", 27 | "cs-cz", 28 | "da-dk", 29 | "de-de", 30 | "el-gr", 31 | "en-gb", 32 | "en-us", 33 | "es-es", 34 | "es-mx", 35 | "et-ee", 36 | "fi-fi", 37 | "fr-ca", 38 | "fr-fr", 39 | "he-il", 40 | "hr-hr", 41 | "hu-hu", 42 | "it-it", 43 | "ja-jp", 44 | "ko-kr", 45 | "lt-lt", 46 | "lv-lv", 47 | "nb-no", 48 | "nl-nl", 49 | "pl-pl", 50 | "pt-br", 51 | "pt-pt", 52 | "ro-ro", 53 | "ru-ru", 54 | "sk-sk", 55 | "sl-si", 56 | "sr-latn-rs", 57 | "sv-se", 58 | "th-th", 59 | "tr-tr", 60 | "uk-ua", 61 | "zh-cn", 62 | "zh-tw" 63 | ], 64 | "OSName.default": "Win11-25H2-arm64", 65 | "OSName.values": [ 66 | "Win11-25H2-arm64", 67 | "Win11-24H2-arm64", 68 | "Win11-23H2-arm64" 69 | ] 70 | } -------------------------------------------------------------------------------- /docs/Deploy-OSDCloudCLI.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: OSDCloud-help.xml 3 | Module Name: OSDCloud 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Deploy-OSDCloudCLI 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Deploy-OSDCloudCLI [[-Name] ] [-ProgressAction ] [] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | {{ Fill in the Description }} 21 | 22 | ## EXAMPLES 23 | 24 | ### Example 1 25 | ```powershell 26 | PS C:\> {{ Add example code here }} 27 | ``` 28 | 29 | {{ Add example description here }} 30 | 31 | ## PARAMETERS 32 | 33 | ### -Name 34 | {{ Fill Name Description }} 35 | 36 | ```yaml 37 | Type: String 38 | Parameter Sets: (All) 39 | Aliases: 40 | 41 | Required: False 42 | Position: 0 43 | Default value: None 44 | Accept pipeline input: True (ByPropertyName) 45 | Accept wildcard characters: False 46 | ``` 47 | 48 | ### -ProgressAction 49 | {{ Fill ProgressAction Description }} 50 | 51 | ```yaml 52 | Type: ActionPreference 53 | Parameter Sets: (All) 54 | Aliases: proga 55 | 56 | Required: False 57 | Position: Named 58 | Default value: None 59 | Accept pipeline input: False 60 | Accept wildcard characters: False 61 | ``` 62 | 63 | ### CommonParameters 64 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 65 | 66 | ## INPUTS 67 | 68 | ### System.String 69 | 70 | ## OUTPUTS 71 | 72 | ### System.Object 73 | ## NOTES 74 | 75 | ## RELATED LINKS 76 | -------------------------------------------------------------------------------- /docs/Deploy-OSDCloudGUI.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: OSDCloud-help.xml 3 | Module Name: OSDCloud 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Deploy-OSDCloudGUI 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Deploy-OSDCloudGUI [[-Name] ] [-ProgressAction ] [] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | {{ Fill in the Description }} 21 | 22 | ## EXAMPLES 23 | 24 | ### Example 1 25 | ```powershell 26 | PS C:\> {{ Add example code here }} 27 | ``` 28 | 29 | {{ Add example description here }} 30 | 31 | ## PARAMETERS 32 | 33 | ### -Name 34 | {{ Fill Name Description }} 35 | 36 | ```yaml 37 | Type: String 38 | Parameter Sets: (All) 39 | Aliases: 40 | 41 | Required: False 42 | Position: 0 43 | Default value: None 44 | Accept pipeline input: True (ByPropertyName) 45 | Accept wildcard characters: False 46 | ``` 47 | 48 | ### -ProgressAction 49 | {{ Fill ProgressAction Description }} 50 | 51 | ```yaml 52 | Type: ActionPreference 53 | Parameter Sets: (All) 54 | Aliases: proga 55 | 56 | Required: False 57 | Position: Named 58 | Default value: None 59 | Accept pipeline input: False 60 | Accept wildcard characters: False 61 | ``` 62 | 63 | ### CommonParameters 64 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 65 | 66 | ## INPUTS 67 | 68 | ### System.String 69 | 70 | ## OUTPUTS 71 | 72 | ### System.Object 73 | ## NOTES 74 | 75 | ## RELATED LINKS 76 | -------------------------------------------------------------------------------- /private/steps/do-not-use/step-psmodule-save-osd.ps1: -------------------------------------------------------------------------------- 1 | function step-powershell-savemodule-osd { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)]" 14 | $PowerShellSavePath = 'C:\Program Files\WindowsPowerShell' 15 | 16 | if (-not (Test-Path "$PowerShellSavePath\Configuration")) { 17 | New-Item -Path "$PowerShellSavePath\Configuration" -ItemType Directory -Force | Out-Null 18 | } 19 | if (-not (Test-Path "$PowerShellSavePath\Modules")) { 20 | New-Item -Path "$PowerShellSavePath\Modules" -ItemType Directory -Force | Out-Null 21 | } 22 | if (-not (Test-Path "$PowerShellSavePath\Scripts")) { 23 | New-Item -Path "$PowerShellSavePath\Scripts" -ItemType Directory -Force | Out-Null 24 | } 25 | 26 | try { 27 | Save-Module -Name OSD -Path "$PowerShellSavePath\Modules" -Force -ErrorAction Stop 28 | } 29 | catch { 30 | Write-Warning "[$(Get-Date -format G)] Unable to Save-Module OSD to $PowerShellSavePath\Modules" 31 | } 32 | #================================================= 33 | # End the function 34 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 35 | Write-Verbose -Message $Message; Write-Debug -Message $Message 36 | #================================================= 37 | } -------------------------------------------------------------------------------- /private/steps/do-not-use/step-osdcloud-logs-stop.ps1: -------------------------------------------------------------------------------- 1 | function step-osdcloud-logs-stop { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | $LogsPath = "C:\Windows\Temp\osdcloud-logs" 14 | 15 | $Params = @{ 16 | Path = $LogsPath 17 | ItemType = 'Directory' 18 | Force = $true 19 | ErrorAction = 'SilentlyContinue' 20 | } 21 | 22 | if (-not (Test-Path $Params.Path)) { 23 | New-Item @Params | Out-Null 24 | } 25 | 26 | # Copy the DISM log to C:\Windows\Temp\osdcloud-logs 27 | if (Test-Path "$env:SystemRoot\logs\dism\dism.log") { 28 | Copy-Item -Path "$env:SystemRoot\logs\dism\dism.log" -Destination 'C:\Windows\Temp\osdcloud-logs\dism.log' -Force | Out-Null 29 | } 30 | 31 | $null = Stop-Transcript -ErrorAction SilentlyContinue 32 | 33 | # Copy existing WinPE Logs to C:\Windows\Temp\osdcloud-logs 34 | if ($env:SystemDrive -eq 'X:') { 35 | $null = robocopy "X:\Windows\Temp\osdcloud-logs" "C:\Windows\Temp\osdcloud-logs" *.* /e /ndl /r:0 /w:0 36 | } 37 | #endregion 38 | #================================================= 39 | # End the function 40 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 41 | Write-Verbose -Message $Message; Write-Debug -Message $Message 42 | #================================================= 43 | } -------------------------------------------------------------------------------- /private/steps/6-powershell/step-powershell-savemodule.ps1: -------------------------------------------------------------------------------- 1 | function step-powershell-savemodule { 2 | [CmdletBinding()] 3 | param ( 4 | $Name = $Step.parameters.name 5 | ) 6 | #================================================= 7 | # Start the step 8 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 9 | Write-Debug -Message $Message; Write-Verbose -Message $Message 10 | 11 | # Get the configuration of the step 12 | $Step = $global:OSDCloudWorkflowCurrentStep 13 | #================================================= 14 | #region Main 15 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)]" 16 | $PowerShellSavePath = 'C:\Program Files\WindowsPowerShell' 17 | 18 | if (-not (Test-Path "$PowerShellSavePath\Configuration")) { 19 | New-Item -Path "$PowerShellSavePath\Configuration" -ItemType Directory -Force | Out-Null 20 | } 21 | if (-not (Test-Path "$PowerShellSavePath\Modules")) { 22 | New-Item -Path "$PowerShellSavePath\Modules" -ItemType Directory -Force | Out-Null 23 | } 24 | if (-not (Test-Path "$PowerShellSavePath\Scripts")) { 25 | New-Item -Path "$PowerShellSavePath\Scripts" -ItemType Directory -Force | Out-Null 26 | } 27 | 28 | try { 29 | Save-Module -Name $Name -Path "$PowerShellSavePath\Modules" -Force -ErrorAction Stop 30 | } 31 | catch { 32 | Write-Warning "[$(Get-Date -format G)] Unable to Save-Module $Name to $PowerShellSavePath\Modules" 33 | } 34 | #================================================= 35 | # End the function 36 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 37 | Write-Verbose -Message $Message; Write-Debug -Message $Message 38 | #================================================= 39 | } -------------------------------------------------------------------------------- /private/Invoke-OSDCloudWorkflowUx.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-OSDCloudWorkflowUx { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $false, 5 | Position = 0, 6 | ValueFromPipeline = $true, 7 | ValueFromPipelineByPropertyName = $true)] 8 | [ValidateNotNullOrEmpty()] 9 | [System.String] 10 | $Name = 'default', 11 | 12 | $Path = "$($MyInvocation.MyCommand.Module.ModuleBase)\workflow" 13 | ) 14 | #================================================= 15 | # Get module details 16 | $ModuleBase = $($MyInvocation.MyCommand.Module.ModuleBase) 17 | $ModuleVersion = $($MyInvocation.MyCommand.Module.Version) 18 | #================================================= 19 | if (-not ($global:OSDCloudWorkflowInit)) { 20 | Initialize-OSDCloudWorkflow 21 | } 22 | 23 | $WorkflowSettingsUxPath = Join-Path $Path (Join-Path $Name 'ux') 24 | $WorkflowSettingsUxDefaultPath = Join-Path $Path (Join-Path 'default' 'ux') 25 | 26 | $OSDCloudUxPath = Join-Path -Path $WorkflowSettingsUxPath -ChildPath "MainWindow.ps1" 27 | if (-not (Test-Path $OSDCloudUxPath)) { 28 | $OSDCloudUxPath = Join-Path -Path $WorkflowSettingsUxDefaultPath -ChildPath "MainWindow.ps1" 29 | } 30 | 31 | if (-not (Test-Path $OSDCloudUxPath)) { 32 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Unable to locate $OSDCloudUxPath" 33 | break 34 | } 35 | 36 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] $OSDCloudUxPath" 37 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Launching OSDCloud $ModuleVersion" 38 | 39 | . $OSDCloudUxPath 40 | #================================================= 41 | } -------------------------------------------------------------------------------- /private/steps/4-install/step-install-bcdboot.ps1: -------------------------------------------------------------------------------- 1 | function step-install-bcdboot { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | $LogPath = "C:\Windows\Temp\osdcloud-logs" 14 | 15 | # Check what architecture we are using 16 | if ($global:OSDCloudWorkflowInit.OSArchitecture -match 'ARM64') { 17 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] X:\Windows\System32\bcdboot.exe C:\Windows /c /v" 18 | $BCDBootOutput = & X:\Windows\System32\bcdboot.exe C:\Windows /c /v 19 | $BCDBootOutput | Out-File -FilePath "$LogPath\bcdboot.log" -Force 20 | } 21 | else { 22 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] C:\Windows\System32\bcdboot.exe C:\Windows /c /v" 23 | $BCDBootOutput = & C:\Windows\System32\bcdboot.exe C:\Windows /c /v 24 | $BCDBootOutput | Out-File -FilePath "$LogPath\bcdboot.log" -Force 25 | } 26 | 27 | #TODO What is "Updated configuration that should clear existing UEFI Boot entires and fix the Dell issue" 28 | # https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/bcdboot-command-line-options-techref-di?view=windows-11 29 | 30 | #endregion 31 | #================================================= 32 | # End the function 33 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 34 | Write-Verbose -Message $Message; Write-Debug -Message $Message 35 | #================================================= 36 | } -------------------------------------------------------------------------------- /private/steps/3-preinstall/step-preinstall-removeusbdriveletter.ps1: -------------------------------------------------------------------------------- 1 | function step-preinstall-removeusbdriveletter { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | <# 14 | https://docs.microsoft.com/en-us/powershell/module/storage/remove-partitionaccesspath 15 | Partition Access Paths are being removed from USB Drive Letters 16 | This prevents issues when Drive Letters are reassigned 17 | #> 18 | 19 | # Store the USB Partitions 20 | $global:OSDCloudWorkflowInvoke.USBPartitions = Get-USBPartition 21 | 22 | # Remove USB Drive Letters 23 | if ($global:OSDCloudWorkflowInvoke.USBPartitions) { 24 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Removing USB Drive Letters. OK." 25 | foreach ($Item in $global:OSDCloudWorkflowInvoke.USBPartitions) { 26 | $Params = @{ 27 | AccessPath = "$($Item.DriveLetter):" 28 | DiskNumber = $Item.DiskNumber 29 | PartitionNumber = $Item.PartitionNumber 30 | ErrorAction = 'SilentlyContinue' 31 | } 32 | Remove-PartitionAccessPath @Params 33 | Start-Sleep -Seconds 3 34 | } 35 | } 36 | #================================================= 37 | # End the function 38 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 39 | Write-Verbose -Message $Message; Write-Debug -Message $Message 40 | #================================================= 41 | } -------------------------------------------------------------------------------- /workflow/latest/os-amd64.json: -------------------------------------------------------------------------------- 1 | { 2 | "OSActivation.default": "Retail", 3 | "OSActivation.values": [ 4 | "Retail", 5 | "Volume" 6 | ], 7 | "OSEdition.default": "Pro", 8 | "OSEditionId.default": "Professional", 9 | "OSEdition.values": [ 10 | { 11 | "Edition": "Home", 12 | "EditionId": "Core" 13 | }, 14 | { 15 | "Edition": "Home N", 16 | "EditionId": "CoreN" 17 | }, 18 | { 19 | "Edition": "Education", 20 | "EditionId": "Education" 21 | }, 22 | { 23 | "Edition": "Education N", 24 | "EditionId": "EducationN" 25 | }, 26 | { 27 | "Edition": "Pro", 28 | "EditionId": "Professional" 29 | }, 30 | { 31 | "Edition": "Pro N", 32 | "EditionId": "ProfessionalN" 33 | }, 34 | { 35 | "Edition": "Enterprise", 36 | "EditionId": "Enterprise" 37 | }, 38 | { 39 | "Edition": "Enterprise N", 40 | "EditionId": "EnterpriseN" 41 | } 42 | ], 43 | "OSLanguageCode.default": "en-us", 44 | "OSLanguageCode.values": [ 45 | "ar-sa", 46 | "bg-bg", 47 | "cs-cz", 48 | "da-dk", 49 | "de-de", 50 | "el-gr", 51 | "en-gb", 52 | "en-us", 53 | "es-es", 54 | "es-mx", 55 | "et-ee", 56 | "fi-fi", 57 | "fr-ca", 58 | "fr-fr", 59 | "he-il", 60 | "hr-hr", 61 | "hu-hu", 62 | "it-it", 63 | "ja-jp", 64 | "ko-kr", 65 | "lt-lt", 66 | "lv-lv", 67 | "nb-no", 68 | "nl-nl", 69 | "pl-pl", 70 | "pt-br", 71 | "pt-pt", 72 | "zh-tw" 73 | ], 74 | "OSName.default": "Win11-25H2-amd64", 75 | "OSName.values": [ 76 | "Win11-25H2-amd64" 77 | ] 78 | } -------------------------------------------------------------------------------- /docs/Deploy-OSDCloud.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: OSDCloud-help.xml 3 | Module Name: OSDCloud 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Deploy-OSDCloud 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Deploy-OSDCloud [[-Name] ] [-CLI] [-ProgressAction ] [] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | {{ Fill in the Description }} 21 | 22 | ## EXAMPLES 23 | 24 | ### Example 1 25 | ```powershell 26 | PS C:\> {{ Add example code here }} 27 | ``` 28 | 29 | {{ Add example description here }} 30 | 31 | ## PARAMETERS 32 | 33 | ### -CLI 34 | {{ Fill CLI Description }} 35 | 36 | ```yaml 37 | Type: SwitchParameter 38 | Parameter Sets: (All) 39 | Aliases: 40 | 41 | Required: False 42 | Position: Named 43 | Default value: None 44 | Accept pipeline input: False 45 | Accept wildcard characters: False 46 | ``` 47 | 48 | ### -Name 49 | {{ Fill Name Description }} 50 | 51 | ```yaml 52 | Type: String 53 | Parameter Sets: (All) 54 | Aliases: 55 | 56 | Required: False 57 | Position: 0 58 | Default value: None 59 | Accept pipeline input: True (ByPropertyName) 60 | Accept wildcard characters: False 61 | ``` 62 | 63 | ### -ProgressAction 64 | {{ Fill ProgressAction Description }} 65 | 66 | ```yaml 67 | Type: ActionPreference 68 | Parameter Sets: (All) 69 | Aliases: proga 70 | 71 | Required: False 72 | Position: Named 73 | Default value: None 74 | Accept pipeline input: False 75 | Accept wildcard characters: False 76 | ``` 77 | 78 | ### CommonParameters 79 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 80 | 81 | ## INPUTS 82 | 83 | ### System.String 84 | 85 | ## OUTPUTS 86 | 87 | ### System.Object 88 | ## NOTES 89 | 90 | ## RELATED LINKS 91 | -------------------------------------------------------------------------------- /docs/Start-OSDCloudWorkflow.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: OSDCloud-help.xml 3 | Module Name: OSDCloud 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Start-OSDCloudWorkflow 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Start-OSDCloudWorkflow [[-Name] ] [-CLI] [-ProgressAction ] [] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | {{ Fill in the Description }} 21 | 22 | ## EXAMPLES 23 | 24 | ### Example 1 25 | ``` 26 | PS C:\> {{ Add example code here }} 27 | ``` 28 | 29 | {{ Add example description here }} 30 | 31 | ## PARAMETERS 32 | 33 | ### -CLI 34 | {{ Fill CLI Description }} 35 | 36 | ```yaml 37 | Type: SwitchParameter 38 | Parameter Sets: (All) 39 | Aliases: 40 | 41 | Required: False 42 | Position: Named 43 | Default value: False 44 | Accept pipeline input: False 45 | Accept wildcard characters: False 46 | ``` 47 | 48 | ### -Name 49 | {{ Fill Name Description }} 50 | 51 | ```yaml 52 | Type: String 53 | Parameter Sets: (All) 54 | Aliases: 55 | 56 | Required: False 57 | Position: 0 58 | Default value: None 59 | Accept pipeline input: True (ByPropertyName) 60 | Accept wildcard characters: False 61 | ``` 62 | 63 | ### -ProgressAction 64 | {{ Fill ProgressAction Description }} 65 | 66 | ```yaml 67 | Type: ActionPreference 68 | Parameter Sets: (All) 69 | Aliases: proga 70 | 71 | Required: False 72 | Position: Named 73 | Default value: None 74 | Accept pipeline input: False 75 | Accept wildcard characters: False 76 | ``` 77 | 78 | ### CommonParameters 79 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 80 | 81 | ## INPUTS 82 | 83 | ### System.String 84 | ## OUTPUTS 85 | 86 | ### System.Object 87 | ## NOTES 88 | 89 | ## RELATED LINKS 90 | -------------------------------------------------------------------------------- /docs/Invoke-OSDCloudPEStartup.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: OSDCloud-help.xml 3 | Module Name: OSDCloud 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Invoke-OSDCloudPEStartup 9 | 10 | ## SYNOPSIS 11 | {{ Fill in the Synopsis }} 12 | 13 | ## SYNTAX 14 | 15 | ``` 16 | Invoke-OSDCloudPEStartup [-Id] [[-Value] ] [-ProgressAction ] 17 | [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | {{ Fill in the Description }} 22 | 23 | ## EXAMPLES 24 | 25 | ### Example 1 26 | ``` 27 | PS C:\> {{ Add example code here }} 28 | ``` 29 | 30 | {{ Add example description here }} 31 | 32 | ## PARAMETERS 33 | 34 | ### -Id 35 | {{ Fill Id Description }} 36 | 37 | ```yaml 38 | Type: String 39 | Parameter Sets: (All) 40 | Aliases: 41 | Accepted values: OSK, DeviceHardware, Info, IPConfig, UpdateModule, WiFi 42 | 43 | Required: True 44 | Position: 0 45 | Default value: None 46 | Accept pipeline input: False 47 | Accept wildcard characters: False 48 | ``` 49 | 50 | ### -Value 51 | {{ Fill Value Description }} 52 | 53 | ```yaml 54 | Type: String 55 | Parameter Sets: (All) 56 | Aliases: 57 | 58 | Required: False 59 | Position: 1 60 | Default value: None 61 | Accept pipeline input: False 62 | Accept wildcard characters: False 63 | ``` 64 | 65 | ### -ProgressAction 66 | {{ Fill ProgressAction Description }} 67 | 68 | ```yaml 69 | Type: ActionPreference 70 | Parameter Sets: (All) 71 | Aliases: proga 72 | 73 | Required: False 74 | Position: Named 75 | Default value: None 76 | Accept pipeline input: False 77 | Accept wildcard characters: False 78 | ``` 79 | 80 | ### CommonParameters 81 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 82 | 83 | ## INPUTS 84 | 85 | ### None 86 | ## OUTPUTS 87 | 88 | ### System.Object 89 | ## NOTES 90 | 91 | ## RELATED LINKS 92 | -------------------------------------------------------------------------------- /private/main/Initialize-OSDCloudModule.ps1: -------------------------------------------------------------------------------- 1 | function Initialize-OSDCloudModule { 2 | [CmdletBinding()] 3 | param ( 4 | # Specifies a path to one or more locations. 5 | [Parameter(Mandatory = $false, 6 | Position = 0, 7 | ValueFromPipeline = $true, 8 | ValueFromPipelineByPropertyName = $true)] 9 | [ValidateNotNullOrEmpty()] 10 | [string[]] 11 | $Path = "$($MyInvocation.MyCommand.Module.ModuleBase)\module.json", 12 | 13 | [System.Management.Automation.SwitchParameter] 14 | $AsJson 15 | ) 16 | #================================================= 17 | $Error.Clear() 18 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 19 | $ModuleName = $($MyInvocation.MyCommand.Module.Name) 20 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] ModuleName: $ModuleName" 21 | $ModuleBase = $($MyInvocation.MyCommand.Module.ModuleBase) 22 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] ModuleBase: $ModuleBase" 23 | $ModuleVersion = $($MyInvocation.MyCommand.Module.Version) 24 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] ModuleVersion: $ModuleVersion" 25 | #================================================= 26 | # Import the RAW content of the JSON file 27 | $rawJsonContent = Get-Content -Path $Path -Raw 28 | 29 | if ($AsJson) { 30 | return $rawJsonContent 31 | } 32 | 33 | # https://stackoverflow.com/questions/51066978/convert-to-json-with-comments-from-powershell 34 | $JsonContent = $rawJsonContent -replace '(?m)(?<=^([^"]|"[^"]*")*)//.*' -replace '(?ms)/\*.*?\*/' 35 | 36 | $hashtable = [ordered]@{} 37 | (ConvertFrom-Json $JsonContent).psobject.properties | ForEach-Object { $hashtable[$_.Name] = $_.Value } 38 | 39 | $global:OSDCloudModule = $hashtable 40 | #================================================= 41 | # End the function 42 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 43 | Write-Verbose -Message $Message; Write-Debug -Message $Message 44 | #================================================= 45 | } -------------------------------------------------------------------------------- /workflow/default/os-amd64.json: -------------------------------------------------------------------------------- 1 | { 2 | "OSActivation.default": "Retail", 3 | "OSActivation.values": [ 4 | "Retail", 5 | "Volume" 6 | ], 7 | "OSEdition.default": "Pro", 8 | "OSEditionId.default": "Professional", 9 | "OSEdition.values": [ 10 | { 11 | "Edition": "Home", 12 | "EditionId": "Core" 13 | }, 14 | { 15 | "Edition": "Home N", 16 | "EditionId": "CoreN" 17 | }, 18 | { 19 | "Edition": "Education", 20 | "EditionId": "Education" 21 | }, 22 | { 23 | "Edition": "Education N", 24 | "EditionId": "EducationN" 25 | }, 26 | { 27 | "Edition": "Pro", 28 | "EditionId": "Professional" 29 | }, 30 | { 31 | "Edition": "Pro N", 32 | "EditionId": "ProfessionalN" 33 | }, 34 | { 35 | "Edition": "Enterprise", 36 | "EditionId": "Enterprise" 37 | }, 38 | { 39 | "Edition": "Enterprise N", 40 | "EditionId": "EnterpriseN" 41 | } 42 | ], 43 | "OSLanguageCode.default": "en-us", 44 | "OSLanguageCode.values": [ 45 | "ar-sa", 46 | "bg-bg", 47 | "cs-cz", 48 | "da-dk", 49 | "de-de", 50 | "el-gr", 51 | "en-gb", 52 | "en-us", 53 | "es-es", 54 | "es-mx", 55 | "et-ee", 56 | "fi-fi", 57 | "fr-ca", 58 | "fr-fr", 59 | "he-il", 60 | "hr-hr", 61 | "hu-hu", 62 | "it-it", 63 | "ja-jp", 64 | "ko-kr", 65 | "lt-lt", 66 | "lv-lv", 67 | "nb-no", 68 | "nl-nl", 69 | "pl-pl", 70 | "pt-br", 71 | "pt-pt", 72 | "ro-ro", 73 | "ru-ru", 74 | "sk-sk", 75 | "sl-si", 76 | "sr-latn-rs", 77 | "sv-se", 78 | "th-th", 79 | "tr-tr", 80 | "uk-ua", 81 | "zh-cn", 82 | "zh-tw" 83 | ], 84 | "OSName.default": "Win11-25H2-amd64", 85 | "OSName.values": [ 86 | "Win11-25H2-amd64", 87 | "Win11-24H2-amd64", 88 | "Win11-23H2-amd64" 89 | ] 90 | } -------------------------------------------------------------------------------- /workflow/demo/os-amd64.json: -------------------------------------------------------------------------------- 1 | { 2 | "OSActivation.default": "Retail", 3 | "OSActivation.values": [ 4 | "Retail", 5 | "Volume" 6 | ], 7 | "OSEdition.default": "Pro", 8 | "OSEditionId.default": "Professional", 9 | "OSEdition.values": [ 10 | { 11 | "Edition": "Home", 12 | "EditionId": "Core" 13 | }, 14 | { 15 | "Edition": "Home N", 16 | "EditionId": "CoreN" 17 | }, 18 | { 19 | "Edition": "Education", 20 | "EditionId": "Education" 21 | }, 22 | { 23 | "Edition": "Education N", 24 | "EditionId": "EducationN" 25 | }, 26 | { 27 | "Edition": "Pro", 28 | "EditionId": "Professional" 29 | }, 30 | { 31 | "Edition": "Pro N", 32 | "EditionId": "ProfessionalN" 33 | }, 34 | { 35 | "Edition": "Enterprise", 36 | "EditionId": "Enterprise" 37 | }, 38 | { 39 | "Edition": "Enterprise N", 40 | "EditionId": "EnterpriseN" 41 | } 42 | ], 43 | "OSLanguageCode.default": "en-us", 44 | "OSLanguageCode.values": [ 45 | "ar-sa", 46 | "bg-bg", 47 | "cs-cz", 48 | "da-dk", 49 | "de-de", 50 | "el-gr", 51 | "en-gb", 52 | "en-us", 53 | "es-es", 54 | "es-mx", 55 | "et-ee", 56 | "fi-fi", 57 | "fr-ca", 58 | "fr-fr", 59 | "he-il", 60 | "hr-hr", 61 | "hu-hu", 62 | "it-it", 63 | "ja-jp", 64 | "ko-kr", 65 | "lt-lt", 66 | "lv-lv", 67 | "nb-no", 68 | "nl-nl", 69 | "pl-pl", 70 | "pt-br", 71 | "pt-pt", 72 | "ro-ro", 73 | "ru-ru", 74 | "sk-sk", 75 | "sl-si", 76 | "sr-latn-rs", 77 | "sv-se", 78 | "th-th", 79 | "tr-tr", 80 | "uk-ua", 81 | "zh-cn", 82 | "zh-tw" 83 | ], 84 | "OSName.default": "Win11-25H2-amd64", 85 | "OSName.values": [ 86 | "Win11-25H2-amd64", 87 | "Win11-24H2-amd64", 88 | "Win11-23H2-amd64" 89 | ] 90 | } -------------------------------------------------------------------------------- /private/steps/5-drivers/step-drivers-recast-winre.ps1: -------------------------------------------------------------------------------- 1 | function step-drivers-recast-winre { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | $LogPath = "C:\Windows\Temp\osdcloud-logs" 13 | 14 | $DriverPath = "C:\Windows\Temp\osdcloud-drivers-recast" 15 | 16 | $WinrePath = "C:\Windows\System32\Recovery\winre.wim" 17 | $WinreMountPath = "C:\Windows\Temp\mount-winre" 18 | 19 | if ((Test-Path -Path $DriverPath) -and (Test-Path -Path $WinrePath)) { 20 | if (-not (Test-Path -Path $LogPath)) { 21 | New-Item -ItemType Directory -Path $LogPath -Force | Out-Null 22 | } 23 | if (-not (Test-Path -Path $WinreMountPath)) { 24 | New-Item -ItemType Directory -Path $WinreMountPath -Force | Out-Null 25 | } 26 | 27 | $Params = @{ 28 | Path = $WinreMountPath 29 | ImagePath = $WinrePath 30 | Index = 1 31 | LogPath = "$LogPath\mount-winre.log" 32 | } 33 | $MountWinRE = Mount-WindowsImage @Params | Out-Null 34 | 35 | if ($MountWinRE) { 36 | Add-WindowsDriver -Path $WinreMountPath -Driver "$DriverPath" -Recurse -ForceUnsigned -LogPath "$LogPath\drivers-recast-winre.log" -ErrorAction SilentlyContinue 37 | } 38 | 39 | Dismount-WindowsImage -Path $WinreMountPath -Save -LogPath "$LogPath\dismount-winre.log" -ErrorAction SilentlyContinue 40 | 41 | if (Test-Path -Path $WinreMountPath) { 42 | Remove-Item -Path $WinreMountPath -Recurse -Force -ErrorAction SilentlyContinue 43 | } 44 | } 45 | #================================================= 46 | # End the function 47 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 48 | Write-Verbose -Message $Message; Write-Debug -Message $Message 49 | #================================================= 50 | } -------------------------------------------------------------------------------- /workflow/archive/tasks/task-disk-wipe-and-partition.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "d9a3ee71-7b9c-456e-a12c-f424afb8327d", 3 | "name": "Disk Wipe and Partition", 4 | "description": "OSDCloud", 5 | "author": "OSDeploy", 6 | "version": "2025.9.23.1", 7 | "amd64": true, 8 | "arm64": true, 9 | "steps": [ 10 | { 11 | "name": "Validate Local Disk", 12 | "description": "Tests the local disk for readiness", 13 | "command": "step-validate-isdiskready", 14 | "args": [], 15 | "parameters": {}, 16 | "rules": { 17 | "runinfullos": false, 18 | "skip": false 19 | } 20 | }, 21 | { 22 | "name": "Remove usbdriveletter", 23 | "description": "Removes drive letters assigned to USB devices", 24 | "command": "step-preinstall-removeusbdriveletter", 25 | "args": [], 26 | "parameters": {}, 27 | "rules": { 28 | "runinfullos": false, 29 | "skip": false 30 | } 31 | }, 32 | { 33 | "name": "Clear-Disk", 34 | "description": "Clears the disk for a fresh start", 35 | "command": "step-preinstall-cleardisk", 36 | "args": [], 37 | "parameters": {}, 38 | "rules": { 39 | "runinfullos": false, 40 | "skip": false 41 | } 42 | }, 43 | { 44 | "name": "PartitionDisk", 45 | "description": "Partitions the disk for installation", 46 | "command": "step-preinstall-partitiondisk", 47 | "args": [], 48 | "parameters": {}, 49 | "rules": { 50 | "runinfullos": false, 51 | "skip": false 52 | } 53 | }, 54 | { 55 | "name": "Addusbdriveletter", 56 | "description": "Assigns drive letters to USB devices", 57 | "command": "step-preinstall-restoreusbdriveletter", 58 | "args": [], 59 | "parameters": {}, 60 | "rules": { 61 | "runinfullos": false, 62 | "skip": false 63 | } 64 | } 65 | ] 66 | } -------------------------------------------------------------------------------- /public/Deploy-OSDCloud.ps1: -------------------------------------------------------------------------------- 1 | function Deploy-OSDCloud { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $false, 5 | Position = 0, 6 | ValueFromPipelineByPropertyName = $true)] 7 | [System.String] 8 | $Name = 'default', 9 | 10 | [System.Management.Automation.SwitchParameter] 11 | $CLI 12 | ) 13 | #================================================= 14 | # Initialize OSDCloudWorkflow 15 | Initialize-OSDCloudWorkflow -Name $Name 16 | #================================================= 17 | if ($CLI.IsPresent) { 18 | #================================================= 19 | # Initialize OSDCloudWorkflow 20 | Initialize-OSDCloudWorkflow -Name $Name 21 | #================================================= 22 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Invoke-OSDCloudWorkflow" 23 | $global:OSDCloudWorkflowInit.TimeStart = Get-Date 24 | $OSDCloudWorkflowInit | Out-Host 25 | Invoke-OSDCloudWorkflow 26 | #================================================= 27 | } 28 | else { 29 | # Prevents the workflow from starting unless the Start button is clicked in the Ux 30 | $global:OSDCloudWorkflowInit.TimeStart = $null 31 | #================================================= 32 | # OSDCloudWorkflowUx 33 | Invoke-OSDCloudWorkflowUx -Name $Name 34 | #================================================= 35 | # Ensure workflow frontend is triggered before invoking workflow 36 | if ($null -ne $global:OSDCloudWorkflowInit.TimeStart) { 37 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Invoke-OSDCloudWorkflow $Name" 38 | $OSDCloudWorkflowInit | Out-Host 39 | try { 40 | Invoke-OSDCloudWorkflow 41 | } 42 | catch { 43 | Write-Warning "Failed to invoke OSDCloud Workflow $Name $_" 44 | break 45 | } 46 | } else { 47 | Write-Host -ForegroundColor DarkCyan "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] OSDCloud Workflow $Name was not started." 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /public/Deploy-OSDCloudDR.ps1: -------------------------------------------------------------------------------- 1 | function Deploy-OSDCloudDR { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $false, 5 | Position = 0, 6 | ValueFromPipelineByPropertyName = $true)] 7 | [System.String] 8 | $Name = 'osdcloud-dr', 9 | 10 | [System.Management.Automation.SwitchParameter] 11 | $CLI 12 | ) 13 | #================================================= 14 | # Initialize OSDCloudWorkflow 15 | Initialize-OSDCloudWorkflow -Name $Name 16 | #================================================= 17 | if ($CLI.IsPresent) { 18 | #================================================= 19 | # Initialize OSDCloudWorkflow 20 | Initialize-OSDCloudWorkflow -Name $Name 21 | #================================================= 22 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Invoke-OSDCloudWorkflow" 23 | $global:OSDCloudWorkflowInit.TimeStart = Get-Date 24 | $OSDCloudWorkflowInit | Out-Host 25 | Invoke-OSDCloudWorkflow 26 | #================================================= 27 | } 28 | else { 29 | # Prevents the workflow from starting unless the Start button is clicked in the Ux 30 | $global:OSDCloudWorkflowInit.TimeStart = $null 31 | #================================================= 32 | # OSDCloudWorkflowUx 33 | Invoke-OSDCloudWorkflowUx -Name $Name 34 | #================================================= 35 | # Ensure workflow frontend is triggered before invoking workflow 36 | if ($null -ne $global:OSDCloudWorkflowInit.TimeStart) { 37 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Invoke-OSDCloudWorkflow $Name" 38 | $OSDCloudWorkflowInit | Out-Host 39 | try { 40 | Invoke-OSDCloudWorkflow 41 | } 42 | catch { 43 | Write-Warning "Failed to invoke OSDCloud Workflow $Name $_" 44 | break 45 | } 46 | } else { 47 | Write-Host -ForegroundColor DarkCyan "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] OSDCloud Workflow $Name was not started." 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /public/Start-OSDCloudWorkflow.ps1: -------------------------------------------------------------------------------- 1 | function Start-OSDCloudWorkflow { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $false, 5 | Position = 0, 6 | ValueFromPipelineByPropertyName = $true)] 7 | [System.String] 8 | $Name = 'default', 9 | 10 | [System.Management.Automation.SwitchParameter] 11 | $CLI 12 | ) 13 | #================================================= 14 | # Initialize OSDCloudWorkflow 15 | Initialize-OSDCloudWorkflow -Name $Name 16 | #================================================= 17 | if ($CLI.IsPresent) { 18 | #================================================= 19 | # Initialize OSDCloudWorkflow 20 | Initialize-OSDCloudWorkflow -Name $Name 21 | #================================================= 22 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Invoke-OSDCloudWorkflow" 23 | $global:OSDCloudWorkflowInit.TimeStart = Get-Date 24 | $OSDCloudWorkflowInit | Out-Host 25 | Invoke-OSDCloudWorkflow 26 | #================================================= 27 | } 28 | else { 29 | # Prevents the workflow from starting unless the Start button is clicked in the Ux 30 | $global:OSDCloudWorkflowInit.TimeStart = $null 31 | #================================================= 32 | # OSDCloudWorkflowUx 33 | Invoke-OSDCloudWorkflowUx -Name $Name 34 | #================================================= 35 | # Ensure workflow frontend is triggered before invoking workflow 36 | if ($null -ne $global:OSDCloudWorkflowInit.TimeStart) { 37 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Invoke-OSDCloudWorkflow $Name" 38 | $OSDCloudWorkflowInit | Out-Host 39 | try { 40 | Invoke-OSDCloudWorkflow 41 | } 42 | catch { 43 | Write-Warning "Failed to invoke OSDCloud Workflow $Name $_" 44 | break 45 | } 46 | } else { 47 | Write-Host -ForegroundColor DarkCyan "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] OSDCloud Workflow $Name was not started." 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /workflow/archive/os-amd64.json: -------------------------------------------------------------------------------- 1 | { 2 | "OSActivation.default": "Retail", 3 | "OSActivation.values": [ 4 | "Retail", 5 | "Volume" 6 | ], 7 | "OSEdition.default": "Pro", 8 | "OSEditionId.default": "Professional", 9 | "OSEdition.values": [ 10 | { 11 | "Edition": "Home", 12 | "EditionId": "Core" 13 | }, 14 | { 15 | "Edition": "Home N", 16 | "EditionId": "CoreN" 17 | }, 18 | { 19 | "Edition": "Education", 20 | "EditionId": "Education" 21 | }, 22 | { 23 | "Edition": "Education N", 24 | "EditionId": "EducationN" 25 | }, 26 | { 27 | "Edition": "Pro", 28 | "EditionId": "Professional" 29 | }, 30 | { 31 | "Edition": "Pro N", 32 | "EditionId": "ProfessionalN" 33 | }, 34 | { 35 | "Edition": "Enterprise", 36 | "EditionId": "Enterprise" 37 | }, 38 | { 39 | "Edition": "Enterprise N", 40 | "EditionId": "EnterpriseN" 41 | } 42 | ], 43 | "OSLanguageCode.default": "en-us", 44 | "OSLanguageCode.values": [ 45 | "ar-sa", 46 | "bg-bg", 47 | "cs-cz", 48 | "da-dk", 49 | "de-de", 50 | "el-gr", 51 | "en-gb", 52 | "en-us", 53 | "es-es", 54 | "es-mx", 55 | "et-ee", 56 | "fi-fi", 57 | "fr-ca", 58 | "fr-fr", 59 | "he-il", 60 | "hr-hr", 61 | "hu-hu", 62 | "it-it", 63 | "ja-jp", 64 | "ko-kr", 65 | "lt-lt", 66 | "lv-lv", 67 | "nb-no", 68 | "nl-nl", 69 | "pl-pl", 70 | "pt-br", 71 | "pt-pt", 72 | "ro-ro", 73 | "ru-ru", 74 | "sk-sk", 75 | "sl-si", 76 | "sr-latn-rs", 77 | "sv-se", 78 | "th-th", 79 | "tr-tr", 80 | "uk-ua", 81 | "zh-cn", 82 | "zh-tw" 83 | ], 84 | "OSName.default": "Win11-25H2-amd64", 85 | "OSName.values": [ 86 | "Win11-25H2-amd64", 87 | "Win11-24H2-amd64", 88 | "Win11-23H2-amd64", 89 | "Win11-22H2-amd64", 90 | "Win11-21H2-amd64", 91 | "Win10-22H2-amd64" 92 | ] 93 | } -------------------------------------------------------------------------------- /private/steps/6-powershell/step-powershell-updatemodule.ps1: -------------------------------------------------------------------------------- 1 | function step-powershell-updatemodule { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | $PowerShellSavePath = 'C:\Program Files\WindowsPowerShell' 14 | 15 | if (-not (Test-Path "$PowerShellSavePath\Configuration")) { 16 | New-Item -Path "$PowerShellSavePath\Configuration" -ItemType Directory -Force | Out-Null 17 | } 18 | if (-not (Test-Path "$PowerShellSavePath\Modules")) { 19 | New-Item -Path "$PowerShellSavePath\Modules" -ItemType Directory -Force | Out-Null 20 | } 21 | if (-not (Test-Path "$PowerShellSavePath\Scripts")) { 22 | New-Item -Path "$PowerShellSavePath\Scripts" -ItemType Directory -Force | Out-Null 23 | } 24 | 25 | $ExistingModules = Get-ChildItem -Path "$PowerShellSavePath\Modules" -ErrorAction SilentlyContinue | Where-Object { $_.PSIsContainer -eq $true } | Select-Object -ExpandProperty Name 26 | 27 | foreach ($Name in $ExistingModules) { 28 | $FindModule = Find-Module -Name $Name -ErrorAction SilentlyContinue 29 | if ($null -eq $FindModule) { 30 | # Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Unable to update $Name" 31 | continue 32 | } 33 | 34 | try { 35 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Save-Module -Name $Name -Path `"$PowerShellSavePath\Modules`" -Force" 36 | Save-Module -Name $Name -Path "$PowerShellSavePath\Modules" -Force -ErrorAction Stop 37 | } 38 | catch { 39 | Write-Warning "[$(Get-Date -format G)] Save-Module failed: $Name" 40 | } 41 | } 42 | #================================================= 43 | # End the function 44 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 45 | Write-Verbose -Message $Message; Write-Debug -Message $Message 46 | #================================================= 47 | } -------------------------------------------------------------------------------- /workflow/default/user-arm64.json: -------------------------------------------------------------------------------- 1 | { 2 | "StartWorkflow": { 3 | "Debug": false, 4 | "Skip": false, 5 | "Verbose": false 6 | }, 7 | "InitializeLogs": { 8 | "Debug": false, 9 | "Skip": false, 10 | "Verbose": false 11 | }, 12 | "TestWindowsImage": { 13 | "Debug": false, 14 | "Skip": false, 15 | "Verbose": false 16 | }, 17 | "TestDriverPack": { 18 | "Debug": false, 19 | "Skip": false, 20 | "Verbose": false 21 | }, 22 | "ClearDisk": { 23 | "Confirm": true, 24 | "Debug": true, 25 | "Skip": false, 26 | "ToolTip": "Skip clearing the Local Disk. Skip this step will also skip Clear-Disk. This will also skip the New-OSDisk step.", 27 | "Verbose": false 28 | }, 29 | "PartitionDisk": { 30 | "Confirm": false, 31 | "Debug": false, 32 | "Skip": false, 33 | "ToolTip": "Skip initializing and creating GPT partitions on the Local Disk. This will also skip the Clear-Disk step.", 34 | "UseDiskPart": false, 35 | "Verbose": false 36 | }, 37 | "MSUpdateDriver": { 38 | "Debug": false, 39 | "Skip": false, 40 | "Verbose": false 41 | }, 42 | "MSUpdateFirmware": { 43 | "Debug": false, 44 | "Skip": true, 45 | "Verbose": false 46 | }, 47 | "IsTpmReady": { 48 | "Error": "Device is not fully TPM 2.0 compatible. Autopilot will not work.", 49 | "Success": "TPM is 2.0 an working as expected.\n Autopilot will work.", 50 | "Warning": "Device is not fully TPM 2.0 compatible." 51 | }, 52 | "PSInstallModuleOSD": false, 53 | "PSInstallModuleWindowsAutopilotIntune": false, 54 | "PSUpdateModulePackageManagement": false, 55 | "PSUpdateModulePowershellGet": false, 56 | "RecoveryPartition": { 57 | "Force": false, 58 | "Skip": false, 59 | "ToolTip": "Recovery Partition is created by default, except when deploying to a Virtual Machine. Force will always create the Recovery Partition. Skip will never create the Recovery Partition." 60 | }, 61 | "SkipRecoveryPartition": false, 62 | "UpdateDiskDrivers": true, 63 | "UpdateNetworkDrivers": true, 64 | "UpdateScsiDrivers": true, 65 | "UpdateSystemFirmware": false, 66 | "WinpeRestart": false, 67 | "WinpeShutdown": false 68 | } -------------------------------------------------------------------------------- /workflow/default/ux/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("OSDCloud")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("HP Inc.")] 14 | [assembly: AssemblyProduct("OSDCloud")] 15 | [assembly: AssemblyCopyright("Copyright © HP Inc. 2025")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | [assembly: AssemblyVersion("1.0.0.0")] 52 | [assembly: AssemblyFileVersion("1.0.0.0")] 53 | -------------------------------------------------------------------------------- /workflow/osdcloud-dr/ux/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("OSDCloud")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("HP Inc.")] 14 | [assembly: AssemblyProduct("OSDCloud")] 15 | [assembly: AssemblyCopyright("Copyright © HP Inc. 2025")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | [assembly: AssemblyVersion("1.0.0.0")] 52 | [assembly: AssemblyFileVersion("1.0.0.0")] 53 | -------------------------------------------------------------------------------- /core/vs-projects/OSDCloud/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("OSDCloud")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("HP Inc.")] 14 | [assembly: AssemblyProduct("OSDCloud")] 15 | [assembly: AssemblyCopyright("Copyright © HP Inc. 2025")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | [assembly: AssemblyVersion("1.0.0.0")] 52 | [assembly: AssemblyFileVersion("1.0.0.0")] 53 | -------------------------------------------------------------------------------- /public-winpe/Invoke-OSDCloudPEStartup.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-OSDCloudPEStartup { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $true, Position = 0)] 5 | [ValidateSet( 6 | 'OSK', 7 | 'DeviceHardware', 8 | 'Info', 9 | 'IPConfig', 10 | 'UpdateModule', 11 | 'WiFi' 12 | )] 13 | [System.String] 14 | $Id, 15 | 16 | [Parameter(Position = 1)] 17 | [System.String] 18 | $Value 19 | ) 20 | Start-Transcript -Path "$($env:Temp)\OSDCloudPEStartup.log" -Append -Force -ErrorAction SilentlyContinue 21 | Write-Host "Processing $Id with value $Value" 22 | 23 | switch ($Id) { 24 | 'OSK' { 25 | # Make sure osk.exe is available 26 | if (Get-Command -Name 'osk.exe' -ErrorAction SilentlyContinue) { 27 | # Invoke-OSDCloudPEStartupCommand Use-PEStartupOSK -WindowStyle Hidden 28 | Start-Process -FilePath 'osk.exe' -WindowStyle Minimized 29 | } 30 | } 31 | 'DeviceHardware' { 32 | Invoke-OSDCloudPEStartupCommand Use-PEStartupHardware -WindowStyle Minimized -NoExit 33 | Invoke-OSDCloudPEStartupCommand Use-PEStartupHardwareErrors -WindowStyle Maximized -NoExit -Wait 34 | } 35 | 'WiFi' { 36 | # If we can reach the PowerShell Gallery, we can assume we have a network connection 37 | try { 38 | $WebRequest = Invoke-WebRequest -Uri "https://www.powershellgallery.com" -UseBasicParsing -Method Head 39 | } 40 | catch { 41 | Invoke-OSDCloudPEStartupCommand Use-PEStartupWiFi -Wait 42 | } 43 | } 44 | 'IPConfig' { 45 | Invoke-OSDCloudPEStartupCommand Use-PEStartupIpconfig -Run Asynchronous -WindowStyle Minimized -NoExit 46 | } 47 | 'UpdateModule' { 48 | # Value must be specified for this function to work 49 | if ($Value) { 50 | # Make sure we are online and can reach the PowerShell Gallery 51 | try { 52 | $WebRequest = Invoke-WebRequest -Uri "https://www.powershellgallery.com/packages/$Value" -UseBasicParsing -Method Head 53 | } 54 | catch { 55 | Write-Host "UpdateModule: Unable to reach the PowerShell Gallery. Please check your network connection." 56 | return 57 | } 58 | Invoke-OSDCloudPEStartupUpdateModule -Name $Value -Wait 59 | } 60 | } 61 | 'Info' { 62 | Invoke-OSDCloudPEStartupCommand Use-PEStartupDeviceInfo -NoExit -Wait 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /public-winpe/Use-PEStartupWiFi.ps1: -------------------------------------------------------------------------------- 1 | function Use-PEStartupWiFi { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 6 | $Error.Clear() 7 | $host.ui.RawUI.WindowTitle = '[OSDCloud] Wireless Connectivity' 8 | #================================================= 9 | if (Test-Path "$env:SystemRoot\System32\dmcmnutils.dll") { 10 | if ($WirelessConnect) { 11 | #TODO - Enable functionality for WirelessConnect.exe 12 | Write-Host -ForegroundColor DarkCyan "[$(Get-Date -format G)] Starting WirelessConnect.exe" 13 | Start-Process PowerShell -ArgumentList 'Start-WinREWiFi -WirelessConnect' -Wait 14 | } 15 | elseif ($WifiProfile) { 16 | #TODO - Enable functionality for WifiProfile 17 | Write-Host -ForegroundColor DarkCyan "[$(Get-Date -format G)] Starting WiFi Profile" 18 | $Global:WifiProfile = Get-PSDrive -PSProvider FileSystem | Where-Object { $_.Name -ne 'C' } | ForEach-Object { 19 | Get-ChildItem "$($_.Root)OSDCloud\Config\Scripts" -Include "WiFiProfile.xml" -File -Recurse -Force -ErrorAction Ignore 20 | } 21 | Start-Process PowerShell -ArgumentList "Start-WinREWiFi -WifiProfile `"$Global:WifiProfile`"" -Wait 22 | } 23 | else { 24 | Write-Host -ForegroundColor DarkCyan "[$(Get-Date -format G)] Starting Wi-Fi" 25 | Start-Process PowerShell Start-WinREWiFi -Wait 26 | } 27 | } 28 | 29 | Write-Host -ForegroundColor DarkCyan "[$(Get-Date -format G)] Initialize Network Connections" 30 | $timeout = 0 31 | while ($timeout -lt 20) { 32 | Start-Sleep -Seconds $timeout 33 | $timeout = $timeout + 5 34 | 35 | $IP = Test-Connection -ComputerName $(HOSTNAME) -Count 1 | Select-Object -ExpandProperty IPV4Address 36 | if ($null -eq $IP) { 37 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Network adapter error. This should not happen!" 38 | } 39 | elseif ($IP.IPAddressToString.StartsWith('169.254') -or $IP.IPAddressToString.Equals('127.0.0.1')) { 40 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] IP address not yet assigned by DHCP. Trying to get a new DHCP lease." 41 | ipconfig /release | Out-Null 42 | ipconfig /renew | Out-Null 43 | } 44 | else { 45 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Network configuration renewed with IP: $($IP.IPAddressToString)" 46 | break 47 | } 48 | } 49 | #================================================= 50 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Done" 51 | #================================================= 52 | } -------------------------------------------------------------------------------- /public/Get-OSDCloudInfo.ps1: -------------------------------------------------------------------------------- 1 | function Get-OSDCloudInfo { 2 | [CmdletBinding()] 3 | param () 4 | 5 | # Clear previous errors 6 | $Error.Clear() 7 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand)] Start" 8 | 9 | # Retrieve module details 10 | $ModuleName = $($MyInvocation.MyCommand.Module.Name) 11 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] ModuleName: $ModuleName" 12 | $ModuleBase = $($MyInvocation.MyCommand.Module.ModuleBase) 13 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] ModuleBase: $ModuleBase" 14 | $ModuleVersion = $($MyInvocation.MyCommand.Module.Version) 15 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] ModuleVersion: $ModuleVersion" 16 | 17 | # Validate global variable dependencies 18 | if (-not $OSDCloudModule -or -not $OSDCloudModule.links) { 19 | Write-Warning "The global variable '$OSDCloudModule' or its 'links' property is not defined. Please ensure it is initialized before running this function." 20 | return 21 | } 22 | 23 | # Display OSDCloud Module Collaboration 24 | Write-Host -ForegroundColor DarkCyan 'OSDCloud Module Collaboration' 25 | Write-Host -ForegroundColor DarkGray "David Segura $($OSDCloudModule.links.david)" 26 | Write-Host -ForegroundColor DarkGray "Michael Escamilla $($OSDCloudModule.links.michael)" 27 | Write-Host 28 | 29 | # Display upcoming events 30 | Write-Host -ForegroundColor DarkCyan 'MMSMOA: OSDCloud and OSDWorkspace' 31 | Write-Host -ForegroundColor DarkGray "May 5-8 2025 $($OSDCloudModule.links.mmsmoa)" 32 | Write-Host 33 | Write-Host -ForegroundColor DarkCyan 'WPNinjasUK: OSDCloud and OSDWorkspace' 34 | Write-Host -ForegroundColor DarkGray "June 16-17 2025 $($OSDCloudModule.links.wpninjasuk)" 35 | Write-Host 36 | Write-Host -ForegroundColor DarkCyan 'WPNinjas: OSDCloud and OSDWorkspace' 37 | Write-Host -ForegroundColor DarkGray "September 22-25, 2025 | $($OSDCloudModule.links.wpninjasch)" 38 | Write-Host 39 | 40 | # Display additional resources 41 | Write-Host -ForegroundColor DarkCyan 'GitHub: OSDCloud' 42 | Write-Host -ForegroundColor DarkGray $($OSDCloudModule.module.project) 43 | Write-Host 44 | Write-Host -ForegroundColor DarkCyan 'PowerShell Gallery: OSDCloud' 45 | Write-Host -ForegroundColor DarkGray $($OSDCloudModule.module.powershellgallery) 46 | Write-Host 47 | Write-Host -ForegroundColor DarkCyan 'Discord: WinAdmins os-deployment' 48 | Write-Host -ForegroundColor DarkGray $($OSDCloudModule.links.discord) 49 | #================================================= 50 | # End the function 51 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 52 | Write-Verbose -Message $Message; Write-Debug -Message $Message 53 | #================================================= 54 | } -------------------------------------------------------------------------------- /private/steps/5-drivers/step-drivers-firmware.ps1: -------------------------------------------------------------------------------- 1 | function step-drivers-firmware { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | if ($PSVersionTable.PSVersion.Major -ne 5) { 13 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] PowerShell 5.1 is required to run this step. Skip." 14 | return 15 | } 16 | if ($IsVM -eq $true) { 17 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Microsoft Update Firmware is not enabled for Virtual Machines. Skip." 18 | return 19 | } 20 | if ($IsOnBattery -eq $true) { 21 | # Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Microsoft Update Firmware is not enabled for devices on battery power" 22 | # return 23 | } 24 | #================================================= 25 | # Is it reachable online? 26 | $Url = 'https://catalog.update.microsoft.com/Home.aspx' 27 | try { 28 | $WebRequest = Invoke-WebRequest -Uri $Url -UseBasicParsing -Method Head 29 | if ($WebRequest.StatusCode -eq 200) { 30 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Microsoft Update Catalog URL returned a 200 status code. OK." 31 | } 32 | } 33 | catch { 34 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Microsoft Update Catalog URL is not reachable. Skip." 35 | return 36 | } 37 | 38 | $FirmwarePath = "C:\Windows\Temp\osdcloud-drivers-firmware" 39 | 40 | $Params = @{ 41 | Path = $FirmwarePath 42 | ItemType = 'Directory' 43 | Force = $true 44 | ErrorAction = 'SilentlyContinue' 45 | } 46 | 47 | if (-not (Test-Path $Params.Path)) { 48 | New-Item @Params | Out-Null 49 | } 50 | 51 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Firmware Updates will be downloaded from Microsoft Update Catalog to $FirmwarePath" 52 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Not all systems support a driver Firmware Update" 53 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] BIOS or Firmware Settings may need to be enabled for Firmware Updates" 54 | Save-SystemFirmwareUpdate -DestinationDirectory $FirmwarePath 55 | #================================================= 56 | # End the function 57 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 58 | Write-Verbose -Message $Message; Write-Debug -Message $Message 59 | #================================================= 60 | } -------------------------------------------------------------------------------- /workflow/default/ux/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace OSDCloud.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OSDCloud.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /core/vs-projects/OSDCloud/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace OSDCloud.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OSDCloud.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /workflow/osdcloud-dr/ux/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace OSDCloud.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OSDCloud.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /private/steps/3-preinstall/step-preinstall-partitiondisk.ps1: -------------------------------------------------------------------------------- 1 | function step-preinstall-partitiondisk { 2 | [CmdletBinding()] 3 | param ( 4 | [System.String] 5 | $RecoveryPartitionForce = $global:OSDCloudWorkflowInvoke.RecoveryPartition.Force, 6 | 7 | [System.String] 8 | $RecoveryPartitionSkip = $global:OSDCloudWorkflowInvoke.RecoveryPartition.Skip, 9 | 10 | [Int32] 11 | $DiskNumber = $global:OSDCloudWorkflowInvoke.DiskPartition.DiskNumber 12 | ) 13 | #================================================= 14 | # Start the step 15 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 16 | Write-Debug -Message $Message; Write-Verbose -Message $Message 17 | 18 | # Get the configuration of the step 19 | $Step = $global:OSDCloudWorkflowCurrentStep 20 | #================================================= 21 | #region Main 22 | # Mental Math 23 | $RecoveryPartition = $true 24 | if ($IsVM -eq $true) { $RecoveryPartition = $false } 25 | if ($RecoveryPartitionSkip) { $RecoveryPartition = $false } 26 | if ($RecoveryPartitionForce) { $RecoveryPartition = $true } 27 | 28 | if ($RecoveryPartition -eq $false) { 29 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Recovery Partition will not be created. OK." 30 | New-OSDisk -PartitionStyle GPT -NoRecoveryPartition -Force -ErrorAction Stop 31 | Write-Host "=========================================================================" -ForegroundColor Cyan 32 | Write-Host "| SYSTEM | MSR | WINDOWS |" -ForegroundColor Cyan 33 | Write-Host "=========================================================================" -ForegroundColor Cyan 34 | } 35 | else { 36 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] 2GB Recovery Partition will be created. OK." 37 | if ($DiskNumber) { 38 | New-OSDisk -PartitionStyle GPT -DiskNumber $DiskNumber -SizeRecovery 2000MB -Force -ErrorAction Stop 39 | } 40 | else { 41 | New-OSDisk -PartitionStyle GPT -SizeRecovery 2000MB -Force -ErrorAction Stop 42 | } 43 | Write-Host "=========================================================================" -ForegroundColor Cyan 44 | Write-Host "| SYSTEM | MSR | WINDOWS | RECOVERY |" -ForegroundColor Cyan 45 | Write-Host "=========================================================================" -ForegroundColor Cyan 46 | } 47 | Start-Sleep -Seconds 5 48 | 49 | # Make sure that there is a PSDrive 50 | if (!(Get-PSDrive -Name 'C')) { 51 | Write-Warning "[$(Get-Date -format G)] Failed to create a PSDrive FileSystem at C:\." 52 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Press Ctrl+C to exit OSDCloud" 53 | Start-Sleep -Seconds 86400 54 | exit 55 | } 56 | #endregion 57 | #================================================= 58 | # End the function 59 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 60 | Write-Verbose -Message $Message; Write-Debug -Message $Message 61 | #================================================= 62 | } -------------------------------------------------------------------------------- /private/Invoke-OSDCloudPEStartupCommand.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-OSDCloudPEStartupCommand { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $true, Position = 0)] 5 | [System.String] 6 | $Command, 7 | 8 | [Parameter(Mandatory = $false)] 9 | [ValidateSet('Normal', 'Minimized', 'Maximized', 'Hidden')] 10 | [System.String] 11 | $WindowStyle = 'Normal', 12 | 13 | [Parameter(Mandatory = $false)] 14 | [ValidateSet('Asynchronous', 'Synchronous')] 15 | [System.String] 16 | $Run = 'Synchronous', 17 | 18 | [switch] 19 | $NoExit, 20 | 21 | [switch] 22 | $Wait 23 | ) 24 | #================================================= 25 | $Error.Clear() 26 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 27 | #================================================= 28 | # https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-setup-runasynchronous 29 | # https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-setup-runsynchronous 30 | 31 | if ($NoExit) { 32 | $PSNoExit = '-NoExit ' 33 | } else { 34 | $PSNoExit = $null 35 | } 36 | 37 | $Unattend = @" 38 | 39 | 40 | 41 | 45 | 46 | 47 | 1 48 | $Command 49 | powershell.exe -NoLogo -NoProfile -WindowStyle $WindowStyle $PSNoExit-Command $Command 50 | 51 | 52 | 53 | 57 | 58 | 59 | 1 60 | $Command 61 | powershell.exe -NoLogo -NoProfile -WindowStyle $WindowStyle $PSNoExit-Command $Command 62 | 63 | 64 | 65 | 66 | 67 | "@ 68 | 69 | $Unattend | Out-File -FilePath "$env:Temp\$Command.xml" -Encoding utf8 -Force 70 | 71 | if ($Wait -and $NoExit) { 72 | Write-Host -ForegroundColor Yellow "[$(Get-Date -format G)] This window may need to be closed to continue the WinPE startup process" 73 | } 74 | 75 | if ($Wait) { 76 | Start-Process -FilePath wpeinit -Wait -ArgumentList "-unattend:$env:Temp\$Command.xml" 77 | } else { 78 | Start-Process -FilePath wpeinit -ArgumentList "-unattend:$env:Temp\$Command.xml" 79 | } 80 | #================================================= 81 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Done" 82 | #================================================= 83 | } -------------------------------------------------------------------------------- /private/steps/4-install/step-install-expandwindowsimage.ps1: -------------------------------------------------------------------------------- 1 | function step-install-expandwindowsimage { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] C:\" 14 | #================================================= 15 | # Create ScratchDirectory 16 | $Params = @{ 17 | ErrorAction = 'SilentlyContinue' 18 | Force = $true 19 | ItemType = 'Directory' 20 | Path = 'C:\OSDCloud\Temp' 21 | } 22 | if (-not (Test-Path $Params.Path -ErrorAction SilentlyContinue)) { 23 | New-Item @Params | Out-Null 24 | } 25 | #================================================= 26 | # Build the Params 27 | if ($global:OSDCloudWorkflowInit.LocalImageFileDestination.FullName -match '.swm') { 28 | #TODO - Add support for multiple SWM files 29 | $Params = @{ 30 | ApplyPath = 'C:\' 31 | ErrorAction = 'Stop' 32 | ImagePath = $global:OSDCloudWorkflowInit.LocalImageFileDestination.FullName 33 | Name = (Get-WindowsImage -ImagePath $global:OSDCloudWorkflowInit.LocalImageFileDestination.FullName).ImageName 34 | ScratchDirectory = 'C:\OSDCloud\Temp' 35 | SplitImageFilePattern = ($global:OSDCloudWorkflowInit.LocalImageFileDestination.FullName).replace('install.swm', 'install*.swm') 36 | } 37 | } 38 | else { 39 | $Params = @{ 40 | ApplyPath = 'C:\' 41 | ErrorAction = 'Stop' 42 | ImagePath = $global:OSDCloudWorkflowInvoke.WindowsImagePath 43 | Index = $global:OSDCloudWorkflowInvoke.WindowsImageIndex 44 | ScratchDirectory = 'C:\OSDCloud\Temp' 45 | } 46 | } 47 | 48 | $global:OSDCloudWorkflowInvoke.ParamsExpandWindowsImage = $Params 49 | #================================================= 50 | # Expand WindowsImage 51 | if ($IsWinPE -eq $true) { 52 | try { 53 | Expand-WindowsImage @Params 54 | } 55 | catch { 56 | Write-Warning "[$(Get-Date -format G)] Expand-WindowsImage failed." 57 | Write-Warning "[$(Get-Date -format G)] $_" 58 | Write-Warning 'Press Ctrl+C to cancel OSDCloud' 59 | Start-Sleep -Seconds 86400 60 | exit 61 | } 62 | } 63 | #================================================= 64 | # Remove OS after expanding the image 65 | $Params = @{ 66 | ErrorAction = 'SilentlyContinue' 67 | Force = $true 68 | Path = 'C:\OSDCloud\Temp' 69 | } 70 | if (Test-Path $Params.Path -ErrorAction SilentlyContinue) { 71 | Remove-Item @Params | Out-Null 72 | } 73 | #================================================= 74 | # End the function 75 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 76 | Write-Verbose -Message $Message; Write-Debug -Message $Message 77 | #================================================= 78 | } -------------------------------------------------------------------------------- /private/steps/5-drivers/step-drivers-msupdate.ps1: -------------------------------------------------------------------------------- 1 | function step-drivers-msupdate { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | # Gather Variables 13 | $ComputerManufacturer = $global:OSDCloudWorkflowInit.ComputerManufacturer 14 | #================================================= 15 | # Step Variables 16 | $DriverPackName = $global:OSDCloudWorkflowInit.DriverPackName 17 | #================================================= 18 | # Exclusions 19 | if ($PSVersionTable.PSVersion.Major -ne 5) { 20 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] PowerShell 5.1 is required to run this step. Skip." 21 | return 22 | } 23 | if (($IsVM -eq $true) -and ($ComputerManufacturer -match 'Microsoft')) { 24 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Microsoft Update Drivers is not enabled for Microsoft Hyper-V. Skip." 25 | return 26 | } 27 | if ($DriverPackName -eq 'None') { 28 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Microsoft Update Drivers is not enabled. Skip." 29 | return 30 | } 31 | #================================================= 32 | # Is it reachable online? 33 | $Url = 'https://catalog.update.microsoft.com/Home.aspx' 34 | try { 35 | $WebRequest = Invoke-WebRequest -Uri $Url -UseBasicParsing -Method Head 36 | if ($WebRequest.StatusCode -eq 200) { 37 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Microsoft Update Catalog URL returned a 200 status code. OK." 38 | } 39 | } 40 | catch { 41 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Microsoft Update Catalog URL is not reachable. Skip." 42 | return 43 | } 44 | #================================================= 45 | # Microsoft Update Catalog 46 | if ($DriverPackName -eq 'Microsoft Update Catalog') { 47 | $DestinationDirectory = "C:\Windows\Temp\osdcloud-drivers-msupdate" 48 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Microsoft Update Drivers is enabled for all devices. OK." 49 | Save-MsUpCatDriver -DestinationDirectory $DestinationDirectory 50 | return 51 | } 52 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Microsoft Update Drivers is enabled for critical devices. OK." 53 | 54 | $DestinationDirectory = "C:\Windows\Temp\osdcloud-drivers-disk" 55 | Save-MsUpCatDriver -DestinationDirectory $DestinationDirectory -PNPClass 'DiskDrive' 56 | 57 | $DestinationDirectory = "C:\Windows\Temp\osdcloud-drivers-net" 58 | Save-MsUpCatDriver -DestinationDirectory $DestinationDirectory -PNPClass 'Net' 59 | 60 | $DestinationDirectory = "C:\Windows\Temp\osdcloud-drivers-scsi" 61 | Save-MsUpCatDriver -DestinationDirectory $DestinationDirectory -PNPClass 'SCSIAdapter' 62 | #================================================= 63 | # End the function 64 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 65 | Write-Verbose -Message $Message; Write-Debug -Message $Message 66 | #================================================= 67 | } -------------------------------------------------------------------------------- /private/steps/5-drivers/step-drivers-recast-winpe.ps1: -------------------------------------------------------------------------------- 1 | function step-drivers-recast-winpe { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | # Output Path 13 | $OutputPath = "C:\Windows\Temp\osdcloud-drivers-recast" 14 | if (-not (Test-Path -Path $OutputPath)) { 15 | New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null 16 | } 17 | $LogPath = "C:\Windows\Temp\osdcloud-logs" 18 | if (-not (Test-Path -Path $LogPath)) { 19 | New-Item -ItemType Directory -Path $LogPath -Force | Out-Null 20 | } 21 | #================================================= 22 | # Gather In-Use Drivers 23 | $PnputilXml = & pnputil.exe /enum-devices /format xml 24 | $PnputilXmlObject = [xml]$PnputilXml 25 | $PnputilDevices = $PnputilXmlObject.PnpUtil.Device | ` 26 | Where-Object { $_.DriverName -like "oem*.inf" } | ` 27 | Sort-Object DriverName -Unique | ` 28 | Select-Object -Property DriverName, Status, ClassGuid, ClassName, DeviceDescription, ManufacturerName, InstanceId 29 | 30 | if ($PnputilDevices) { 31 | $PnputilDevices | Export-Clixml -Path "$LogPath\drivers-recast-winpe.xml" -Force 32 | # Export Drivers to Disk 33 | Write-Verbose "[$(Get-Date -format G)] Exporting drivers to: $OutputPath" 34 | foreach ($Device in $PnputilDevices) { 35 | # Check that the Device has a DriverName 36 | if ($Device.Drivername) { 37 | $FolderName = $Device.DriverName -replace '.inf', '' 38 | $destinationPath = $OutputPath + "\$($Device.ClassName)\" + $FolderName 39 | # Ensure the output directory exists 40 | if (-not (Test-Path -Path $destinationPath)) { 41 | New-Item -ItemType Directory -Path $destinationPath -Force | Out-Null 42 | } 43 | 44 | # Export the driver using pnputil 45 | Write-Verbose "[$(Get-Date -format G)] Exporting $($Device.DriverName) to: $destinationPath" 46 | $null = & pnputil.exe /export-driver $Device.DriverName $destinationPath 47 | } 48 | } 49 | } 50 | #================================================= 51 | #================================================= 52 | # Registry OOBEInProgressDriverUpdatesPostponed 53 | <# 54 | $Content = @" 55 | :: ======================================================== 56 | :: OOBEInProgressDriverUpdatesPostponed 57 | :: ======================================================== 58 | reg add "HKEY_LOCAL_MACHINE\SYSTEM\Setup" /v OOBEInProgressDriverUpdatesPostponed /t REG_DWORD /d 0 /f 59 | :: ======================================================== 60 | "@ 61 | $ScriptsPath = "C:\Windows\Setup\Scripts" 62 | $SetupCompleteCmd = "$ScriptsPath\SetupComplete.cmd" 63 | if (-not (Test-Path $ScriptsPath)) { 64 | New-Item -Path $ScriptsPath -ItemType Directory -Force -ErrorAction Ignore | Out-Null 65 | } 66 | $Content | Out-File -FilePath $SetupCompleteCmd -Append -Encoding ascii -Width 2000 -Force 67 | #> 68 | #================================================= 69 | # End the function 70 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 71 | Write-Verbose -Message $Message; Write-Debug -Message $Message 72 | #================================================= 73 | } -------------------------------------------------------------------------------- /private/steps/do-not-use/Step-UpdatePSModule.ps1: -------------------------------------------------------------------------------- 1 | function Step-UpdatePSModule { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | Write-Host -ForegroundColor DarkGray "Saving PowerShell Modules and Scripts" 14 | if ($IsWinPE -eq $true) { 15 | $PowerShellSavePath = 'C:\Program Files\WindowsPowerShell' 16 | 17 | if (-not (Test-Path "$PowerShellSavePath\Configuration")) { 18 | New-Item -Path "$PowerShellSavePath\Configuration" -ItemType Directory -Force | Out-Null 19 | } 20 | if (-not (Test-Path "$PowerShellSavePath\Modules")) { 21 | New-Item -Path "$PowerShellSavePath\Modules" -ItemType Directory -Force | Out-Null 22 | } 23 | if (-not (Test-Path "$PowerShellSavePath\Scripts")) { 24 | New-Item -Path "$PowerShellSavePath\Scripts" -ItemType Directory -Force | Out-Null 25 | } 26 | 27 | if (Test-WebConnection -Uri "https://www.powershellgallery.com") { 28 | Copy-PSModuleToFolder -Name OSD -Destination "$PowerShellSavePath\Modules" 29 | try { 30 | Save-Script -Name Get-WindowsAutopilotInfo -Path "$PowerShellSavePath\Scripts" -ErrorAction Stop 31 | } 32 | catch { 33 | Write-Warning "[$(Get-Date -format G)] Unable to Save-Script Get-WindowsAutopilotInfo to $PowerShellSavePath\Scripts" 34 | } 35 | if ($HPFeaturesEnabled) { 36 | try { 37 | Save-Module -Name HPCMSL -AcceptLicense -Path "$PowerShellSavePath\Modules" -Force -ErrorAction Stop 38 | } 39 | catch { 40 | Write-Warning "[$(Get-Date -format G)] Unable to Save-Module HPCMSL to $PowerShellSavePath\Modules" 41 | } 42 | } 43 | } 44 | else { 45 | Write-Verbose -Verbose "Copy-PSModuleToFolder -Name OSD to $PowerShellSavePath\Modules" 46 | Copy-PSModuleToFolder -Name OSD -Destination "$PowerShellSavePath\Modules" 47 | Copy-PSModuleToFolder -Name PackageManagement -Destination "$PowerShellSavePath\Modules" 48 | Copy-PSModuleToFolder -Name PowerShellGet -Destination "$PowerShellSavePath\Modules" 49 | Copy-PSModuleToFolder -Name WindowsAutopilotIntune -Destination "$PowerShellSavePath\Modules" 50 | if ($HPFeaturesEnabled) { 51 | Write-Verbose -Verbose "Copy-PSModuleToFolder -Name HPCMSL to $PowerShellSavePath\Modules" 52 | Copy-PSModuleToFolder -Name HPCMSL -Destination "$PowerShellSavePath\Modules" 53 | } 54 | $StepOfflinePath = Find-OSDCloudOfflinePath 55 | 56 | foreach ($Item in $StepOfflinePath) { 57 | if (Test-Path "$($Item.FullName)\PowerShell\Required") { 58 | Write-Host -ForegroundColor Cyan "Applying PowerShell Modules and Scripts in $($Item.FullName)\PowerShell\Required" 59 | robocopy "$($Item.FullName)\PowerShell\Required" "$PowerShellSavePath" *.* /s /ndl /njh /njs 60 | } 61 | } 62 | } 63 | } 64 | #================================================= 65 | # End the function 66 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 67 | Write-Verbose -Message $Message; Write-Debug -Message $Message 68 | #================================================= 69 | } -------------------------------------------------------------------------------- /private/steps/8-finalize/step-finalize-exportofflineosinfo.ps1: -------------------------------------------------------------------------------- 1 | function step-finalize-exportofflineosinfo { 2 | [CmdletBinding()] 3 | param () 4 | #================================================= 5 | # Start the step 6 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 7 | Write-Debug -Message $Message; Write-Verbose -Message $Message 8 | 9 | # Get the configuration of the step 10 | $Step = $global:OSDCloudWorkflowCurrentStep 11 | #================================================= 12 | #region Main 13 | $StepLogPath = "C:\Windows\Temp\osdcloud-logs" 14 | 15 | #Grab Build from WinPE, as 24H2 has issues with some of these commands: 16 | $CurrentOSInfo = Get-Item -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' 17 | $CurrentOSBuild = $($CurrentOSInfo.GetValue('CurrentBuild')) 18 | 19 | #================================================= 20 | #Get-AppxProvisionedPackage 21 | $StepLogFile = (Join-Path $StepLogPath 'Get-AppxProvisionedPackage.txt') 22 | try { 23 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] $StepLogFile" 24 | $Report = Get-AppxProvisionedPackage -Path C:\ -ErrorAction Stop 25 | if ($Report) { 26 | $Report | Select-Object * | Sort-Object DisplayName | Out-File -FilePath $StepLogFile -Force -Encoding ascii 27 | } 28 | } 29 | catch { 30 | Write-Warning "[$(Get-Date -format G)] Unable to export $StepLogFile" 31 | } 32 | 33 | #================================================= 34 | #Get-WindowsCapability 35 | $StepLogFile = (Join-Path $StepLogPath 'Get-WindowsCapability.txt') 36 | try { 37 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] $StepLogFile" 38 | $Report = Get-WindowsCapability -Path C:\ -ErrorAction Stop 39 | if ($Report) { 40 | $Report | Sort-Object Name | Select-Object Name, State | Out-File -FilePath $StepLogFile -Force -Encoding ascii 41 | } 42 | } 43 | catch { 44 | Write-Warning "[$(Get-Date -format G)] Unable to export $StepLogFile" 45 | } 46 | 47 | #================================================= 48 | #Get-WindowsEdition 49 | $StepLogFile = (Join-Path $StepLogPath 'Get-WindowsEdition.txt') 50 | try { 51 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] $StepLogFile" 52 | $Report = Get-WindowsEdition -Path C:\ -ErrorAction Stop 53 | if ($Report) { 54 | $Report | Select-Object Edition | Out-File -FilePath $StepLogFile -Force -Encoding ascii 55 | } 56 | } 57 | catch { 58 | Write-Warning "[$(Get-Date -format G)] Unable to export $StepLogFile" 59 | } 60 | 61 | #================================================= 62 | #Get-WindowsOptionalFeature 63 | $StepLogFile = (Join-Path $StepLogPath 'Get-WindowsOptionalFeature.txt') 64 | try { 65 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] $StepLogFile" 66 | $Report = Get-WindowsOptionalFeature -Path C:\ -ErrorAction Stop 67 | if ($Report) { 68 | $Report | Sort-Object FeatureName | Select-Object FeatureName, State | Out-File -FilePath $StepLogFile -Force -Encoding ascii 69 | } 70 | } 71 | catch { 72 | Write-Warning "[$(Get-Date -format G)] Unable to export $StepLogFile" 73 | } 74 | 75 | #================================================= 76 | #Get-WindowsPackage 77 | $StepLogFile = (Join-Path $StepLogPath 'Get-WindowsPackage.txt') 78 | try { 79 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] $StepLogFile" 80 | $Report = Get-WindowsPackage -Path C:\ -ErrorAction Stop 81 | if ($Report) { 82 | $Report | Sort-Object PackageName | Select-Object PackageName, PackageState, ReleaseType | Out-File -FilePath $StepLogFile -Force -Encoding ascii 83 | } 84 | } 85 | catch { 86 | Write-Warning "[$(Get-Date -format G)] Unable to export $StepLogFile" 87 | } 88 | 89 | #endregion 90 | #================================================= 91 | # End the function 92 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 93 | Write-Verbose -Message $Message; Write-Debug -Message $Message 94 | #================================================= 95 | } -------------------------------------------------------------------------------- /private/steps/2-validation/step-validate-iswindowsimageready.ps1: -------------------------------------------------------------------------------- 1 | function step-validate-iswindowsimageready { 2 | [CmdletBinding()] 3 | param ( 4 | [System.String] 5 | $LaunchMethod = $global:OSDCloudWorkflowInvoke.LaunchMethod 6 | ) 7 | #================================================= 8 | # Start the step 9 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 10 | Write-Debug -Message $Message; Write-Verbose -Message $Message 11 | 12 | # Get the configuration of the step 13 | $Step = $global:OSDCloudWorkflowCurrentStep 14 | #================================================= 15 | # Is there an Opeating System ImageFile URL? 16 | if (-not ($global:OSDCloudWorkflowInvoke.OperatingSystemObject.Url)) { 17 | Write-Warning "[$(Get-Date -format G)] OperatingSystemObject does not have a Url to validate." 18 | Write-Warning 'Press Ctrl+C to cancel OSDCloud' 19 | Start-Sleep -Seconds 86400 20 | exit 21 | } 22 | #================================================= 23 | # Is it reachable online? 24 | try { 25 | $WebRequest = Invoke-WebRequest -Uri $global:OSDCloudWorkflowInvoke.OperatingSystemObject.Url -UseBasicParsing -Method Head 26 | if ($WebRequest.StatusCode -eq 200) { 27 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] OperatingSystem URL returned a 200 status code. OK." 28 | return 29 | } 30 | } 31 | catch { 32 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] OperatingSystem URL is not reachable." 33 | } 34 | #================================================= 35 | # Does the file exist on a Drive? 36 | $FileName = Split-Path $global:OSDCloudWorkflowInvoke.OperatingSystemObject.Url -Leaf 37 | $MatchingFiles = @() 38 | $MatchingFiles = Get-PSDrive -PSProvider FileSystem | ForEach-Object { 39 | Get-ChildItem "$($_.Name):\OSDCloud\OS\" -Include "$FileName" -File -Recurse -Force -ErrorAction Ignore 40 | } 41 | 42 | if ($MatchingFiles) { 43 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] OperatingSystem is available offline. OK." 44 | return 45 | } 46 | else { 47 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] OperatingSystem is not available offline." 48 | } 49 | #================================================= 50 | # Can't access the file so need to bail 51 | Write-Warning "[$(Get-Date -format G)] Unable to validate if the OperatingSystem is reachable online or offline." 52 | Write-Warning "Press Ctrl+C to cancel OSDCloud" 53 | Start-Sleep -Seconds 86400 54 | Exit 55 | #================================================= 56 | # End the function 57 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 58 | Write-Verbose -Message $Message; Write-Debug -Message $Message 59 | #================================================= 60 | } 61 | 62 | <# 63 | if ($LaunchMethod) { 64 | #TODO This is not working for Core 65 | #$null = Install-Module -Name $global:OSDCloudWorkflowInvoke.LaunchMethod -Force -ErrorAction Ignore -WarningAction Ignore 66 | } 67 | 68 | if ($global:OSDCloudWorkflowInit.LocalImageFileInfo) { 69 | # Test if the file is on USB (example: check if path starts with a removable drive letter) 70 | if (!(Test-Path $global:OSDCloudWorkflowInit.LocalImageFileInfo)) { 71 | Write-Warning "[$(Get-Date -format G)] OSDCloud failed to find the Operating System Local ImageFile Item" 72 | Write-Warning $($global:OSDCloudWorkflowInit.LocalImageFileInfo) 73 | Write-Warning "Press Ctrl+C to cancel OSDCloud" 74 | Start-Sleep -Seconds 86400 75 | Exit 76 | } 77 | } 78 | 79 | if ($global:OSDCloudWorkflowInvoke.LocalImageFileDestination) { 80 | if (!(Test-Path $global:OSDCloudWorkflowInvoke.LocalImageFileDestination)) { 81 | Write-Warning "[$(Get-Date -format G)] OSDCloud failed to find the Operating System Local ImageFile Destination" 82 | Write-Warning $($global:OSDCloudWorkflowInvoke.LocalImageFileDestination) 83 | Write-Warning 'Press Ctrl+C to cancel OSDCloud' 84 | Start-Sleep -Seconds 86400 85 | Exit 86 | } 87 | } 88 | #> -------------------------------------------------------------------------------- /private/Initialize-OSDCloudWorkflowSettingsOS.ps1: -------------------------------------------------------------------------------- 1 | function Initialize-OSDCloudWorkflowSettingsOS { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $false, 5 | Position = 0, 6 | ValueFromPipeline = $true, 7 | ValueFromPipelineByPropertyName = $true)] 8 | [ValidateNotNullOrEmpty()] 9 | [System.String] 10 | $Name = 'default', 11 | 12 | [System.Management.Automation.SwitchParameter] 13 | $AsJson, 14 | 15 | [System.String] 16 | $Architecture = $Env:PROCESSOR_ARCHITECTURE, 17 | 18 | $Path = "$($MyInvocation.MyCommand.Module.ModuleBase)\workflow" 19 | ) 20 | #================================================= 21 | $Error.Clear() 22 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 23 | $ModuleName = $($MyInvocation.MyCommand.Module.Name) 24 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] ModuleName: $ModuleName" 25 | $ModuleBase = $($MyInvocation.MyCommand.Module.ModuleBase) 26 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] ModuleBase: $ModuleBase" 27 | $ModuleVersion = $($MyInvocation.MyCommand.Module.Version) 28 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] ModuleVersion: $ModuleVersion" 29 | #================================================= 30 | # Workflow Path must exist, there is no fallback 31 | if (-not (Test-Path $Path)) { 32 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] The specified Path does not exist" 33 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] $Path" 34 | break 35 | } 36 | 37 | $WorkflowSettingsOSPath = Join-Path $Path $Name 38 | $WorkflowSettingsOSDefaultPath = Join-Path $Path 'default' 39 | 40 | $PathAmd64 = "$WorkflowSettingsOSPath\os-amd64.json" 41 | $PathArm64 = "$WorkflowSettingsOSPath\os-arm64.json" 42 | 43 | if (-not ($WorkflowSettingsOSPath -eq $WorkflowSettingsOSDefaultPath)) { 44 | if (-not (Test-Path $PathAmd64)) { 45 | $PathAmd64 = "$WorkflowSettingsOSDefaultPath\os-amd64.json" 46 | } 47 | if (-not (Test-Path $PathArm64)) { 48 | $PathArm64 = "$WorkflowSettingsOSDefaultPath\os-arm64.json" 49 | } 50 | } 51 | 52 | if (-not (Test-Path $PathAmd64)) { 53 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Unable to find $PathAmd64" 54 | break 55 | } 56 | else { 57 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] $PathAmd64" 58 | } 59 | if (-not (Test-Path $PathArm64)) { 60 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Unable to find $PathArm64" 61 | break 62 | } 63 | else { 64 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] $PathArm64" 65 | } 66 | 67 | # Import the RAW content of the JSON file 68 | if ($Architecture -eq 'AMD64') { 69 | $SettingsOSPath = $PathAmd64 70 | } elseif ($Architecture -eq 'ARM64') { 71 | $SettingsOSPath = $PathArm64 72 | } else { 73 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Invalid Architecture: $Architecture" 74 | break 75 | } 76 | $rawJsonContent = Get-Content -Path $SettingsOSPath -Raw 77 | 78 | if ($AsJson) { 79 | return $rawJsonContent 80 | } 81 | 82 | # https://stackoverflow.com/questions/51066978/convert-to-json-with-comments-from-powershell 83 | $JsonContent = $rawJsonContent -replace '(?m)(?<=^([^"]|"[^"]*")*)//.*' -replace '(?ms)/\*.*?\*/' 84 | 85 | $hashtable = [ordered]@{} 86 | (ConvertFrom-Json $JsonContent).psobject.properties | ForEach-Object { $hashtable[$_.Name] = $_.Value } 87 | 88 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Initialized OSDCloudWorkflowSettingsOS: $SettingsOSPath" 89 | $global:OSDCloudWorkflowSettingsOS = $hashtable 90 | #================================================= 91 | # End the function 92 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 93 | Write-Verbose -Message $Message; Write-Debug -Message $Message 94 | #================================================= 95 | } -------------------------------------------------------------------------------- /private/Initialize-OSDCloudWorkflowSettingsUser.ps1: -------------------------------------------------------------------------------- 1 | function Initialize-OSDCloudWorkflowSettingsUser { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $false, 5 | Position = 0, 6 | ValueFromPipeline = $true, 7 | ValueFromPipelineByPropertyName = $true)] 8 | [ValidateNotNullOrEmpty()] 9 | [System.String] 10 | $Name = 'default', 11 | 12 | [System.Management.Automation.SwitchParameter] 13 | $AsJson, 14 | 15 | [System.String] 16 | $Architecture = $Env:PROCESSOR_ARCHITECTURE, 17 | 18 | $Path = "$($MyInvocation.MyCommand.Module.ModuleBase)\workflow" 19 | ) 20 | #================================================= 21 | $Error.Clear() 22 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 23 | $ModuleName = $($MyInvocation.MyCommand.Module.Name) 24 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] ModuleName: $ModuleName" 25 | $ModuleBase = $($MyInvocation.MyCommand.Module.ModuleBase) 26 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] ModuleBase: $ModuleBase" 27 | $ModuleVersion = $($MyInvocation.MyCommand.Module.Version) 28 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] ModuleVersion: $ModuleVersion" 29 | #================================================= 30 | # Workflow Path must exist, there is no fallback 31 | if (-not (Test-Path $Path)) { 32 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] The specified Path does not exist" 33 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] $Path" 34 | break 35 | } 36 | 37 | $WorkflowSettingsUserPath = Join-Path $Path $Name 38 | $WorkflowSettingsUserDefaultPath = Join-Path $Path 'default' 39 | 40 | $PathAmd64 = "$WorkflowSettingsUserPath\user-amd64.json" 41 | $PathArm64 = "$WorkflowSettingsUserPath\user-arm64.json" 42 | 43 | if (-not ($WorkflowSettingsUserPath -eq $WorkflowSettingsUserDefaultPath)) { 44 | if (-not (Test-Path $PathAmd64)) { 45 | $PathAmd64 = "$WorkflowSettingsUserDefaultPath\user-amd64.json" 46 | } 47 | if (-not (Test-Path $PathArm64)) { 48 | $PathArm64 = "$WorkflowSettingsUserDefaultPath\user-arm64.json" 49 | } 50 | } 51 | 52 | if (-not (Test-Path $PathAmd64)) { 53 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Unable to find $PathAmd64" 54 | break 55 | } 56 | else { 57 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] $PathAmd64" 58 | } 59 | if (-not (Test-Path $PathArm64)) { 60 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Unable to find $PathArm64" 61 | break 62 | } 63 | else { 64 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] $PathArm64" 65 | } 66 | 67 | # Import the RAW content of the JSON file 68 | if ($Architecture -eq 'AMD64') { 69 | $SettingsUserPath = $PathAmd64 70 | } elseif ($Architecture -eq 'ARM64') { 71 | $SettingsUserPath = $PathArm64 72 | } else { 73 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Invalid Architecture: $Architecture" 74 | break 75 | } 76 | $rawJsonContent = Get-Content -Path $SettingsUserPath -Raw 77 | 78 | if ($AsJson) { 79 | return $rawJsonContent 80 | } 81 | 82 | # https://stackoverflow.com/questions/51066978/convert-to-json-with-comments-from-powershell 83 | $JsonContent = $rawJsonContent -replace '(?m)(?<=^([^"]|"[^"]*")*)//.*' -replace '(?ms)/\*.*?\*/' 84 | 85 | $hashtable = [ordered]@{} 86 | (ConvertFrom-Json $JsonContent).psobject.properties | ForEach-Object { $hashtable[$_.Name] = $_.Value } 87 | 88 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Initialized OSDCloudWorkflowSettingsUser: $SettingsUserPath" 89 | $global:OSDCloudWorkflowSettingsUser = $hashtable 90 | #================================================= 91 | # End the function 92 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 93 | Write-Verbose -Message $Message; Write-Debug -Message $Message 94 | #================================================= 95 | } -------------------------------------------------------------------------------- /workflow/default/ux/OSDCloud.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {78491010-EC60-4726-843B-16627447BD36} 8 | WinExe 9 | OSDCloud 10 | OSDCloud 11 | v4.8 12 | 512 13 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 4 15 | true 16 | true 17 | 18 | 19 | AnyCPU 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 4.0 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | MSBuild:Compile 56 | Designer 57 | 58 | 59 | MSBuild:Compile 60 | Designer 61 | 62 | 63 | App.xaml 64 | Code 65 | 66 | 67 | MainWindow.xaml 68 | Code 69 | 70 | 71 | 72 | 73 | Code 74 | 75 | 76 | True 77 | True 78 | Resources.resx 79 | 80 | 81 | True 82 | Settings.settings 83 | True 84 | 85 | 86 | ResXFileCodeGenerator 87 | Resources.Designer.cs 88 | 89 | 90 | SettingsSingleFileGenerator 91 | Settings.Designer.cs 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /workflow/osdcloud-dr/ux/OSDCloud.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {78491010-EC60-4726-843B-16627447BD36} 8 | WinExe 9 | OSDCloud 10 | OSDCloud 11 | v4.8 12 | 512 13 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 4 15 | true 16 | true 17 | 18 | 19 | AnyCPU 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 4.0 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | MSBuild:Compile 56 | Designer 57 | 58 | 59 | MSBuild:Compile 60 | Designer 61 | 62 | 63 | App.xaml 64 | Code 65 | 66 | 67 | MainWindow.xaml 68 | Code 69 | 70 | 71 | 72 | 73 | Code 74 | 75 | 76 | True 77 | True 78 | Resources.resx 79 | 80 | 81 | True 82 | Settings.settings 83 | True 84 | 85 | 86 | ResXFileCodeGenerator 87 | Resources.Designer.cs 88 | 89 | 90 | SettingsSingleFileGenerator 91 | Settings.Designer.cs 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /core/vs-projects/OSDCloud/OSDCloud.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {78491010-EC60-4726-843B-16627447BD36} 8 | WinExe 9 | OSDCloud 10 | OSDCloud 11 | v4.8 12 | 512 13 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 4 15 | true 16 | true 17 | 18 | 19 | AnyCPU 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 4.0 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | MSBuild:Compile 56 | Designer 57 | 58 | 59 | MSBuild:Compile 60 | Designer 61 | 62 | 63 | App.xaml 64 | Code 65 | 66 | 67 | MainWindow.xaml 68 | Code 69 | 70 | 71 | 72 | 73 | Code 74 | 75 | 76 | True 77 | True 78 | Resources.resx 79 | 80 | 81 | True 82 | Settings.settings 83 | True 84 | 85 | 86 | ResXFileCodeGenerator 87 | Resources.Designer.cs 88 | 89 | 90 | SettingsSingleFileGenerator 91 | Settings.Designer.cs 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /private/Invoke-OSDCloudPEStartupUpdateModule.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-OSDCloudPEStartupUpdateModule { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $true, Position = 0)] 5 | [System.String] 6 | $Name, 7 | 8 | [Parameter(Mandatory = $false)] 9 | [ValidateSet('Normal', 'Minimized', 'Maximized', 'Hidden')] 10 | [System.String] 11 | $WindowStyle = 'Normal', 12 | 13 | [Parameter(Mandatory = $false)] 14 | [ValidateSet('Asynchronous', 'Synchronous')] 15 | [System.String] 16 | $Run = 'Synchronous', 17 | 18 | [switch] 19 | $NoExit, 20 | 21 | [switch] 22 | $Wait 23 | ) 24 | #================================================= 25 | $Error.Clear() 26 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 27 | #================================================= 28 | # Are we on the last version of the module? 29 | $InstalledModule = Get-Module -Name $Name -ListAvailable -ErrorAction Ignore | Sort-Object Version -Descending | Select-Object -First 1 30 | $GalleryPSModule = Find-Module -Name $Name -ErrorAction Ignore -WarningAction Ignore 31 | #================================================= 32 | # Install the OSD module if it is not installed or if the version is older than the gallery version 33 | if ($GalleryPSModule) { 34 | if (($GalleryPSModule.Version -as [version]) -le ($InstalledModule.Version -as [version])) { 35 | return 36 | } 37 | } 38 | #================================================= 39 | <# 40 | # Make sure we are online and can reach the PowerShell Gallery 41 | try { 42 | $WebRequest = Invoke-WebRequest -Uri "https://www.powershellgallery.com/packages/$Name" -UseBasicParsing -Method Head 43 | } 44 | catch { 45 | return 46 | } 47 | #> 48 | #================================================= 49 | # https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-setup-runasynchronous 50 | # https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-setup-runsynchronous 51 | 52 | if ($NoExit) { 53 | $PSNoExit = '-NoExit ' 54 | } else { 55 | $PSNoExit = $null 56 | } 57 | 58 | $Unattend = @" 59 | 60 | 61 | 62 | 66 | 67 | 68 | 1 69 | Update PowerShell Module $Name 70 | powershell.exe -NoLogo -NoProfile -WindowStyle $WindowStyle $PSNoExit-Command Use-PEStartupUpdateModule -Name $Name 71 | 72 | 73 | 74 | 78 | 79 | 80 | 1 81 | Update PowerShell Module $Name 82 | powershell.exe -NoLogo -NoProfile -WindowStyle $WindowStyle $PSNoExit-Command Use-PEStartupUpdateModule -Name $Name 83 | 84 | 85 | 86 | 87 | 88 | "@ 89 | 90 | $Unattend | Out-File -FilePath "$env:Temp\UpdatePSModule$Name.xml" -Encoding utf8 -Force 91 | 92 | if ($Wait -and $NoExit) { 93 | Write-Host -ForegroundColor Yellow "[$(Get-Date -format G)] This window may need to be closed to continue the WinPE startup process" 94 | } 95 | 96 | if ($Wait) { 97 | Start-Process -FilePath wpeinit -Wait -ArgumentList "-unattend:$env:Temp\UpdatePSModule$Name.xml" 98 | } 99 | else { 100 | Start-Process -FilePath wpeinit -ArgumentList "-unattend:$env:Temp\UpdatePSModule$Name.xml" 101 | } 102 | 103 | #================================================= 104 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Done" 105 | #================================================= 106 | } -------------------------------------------------------------------------------- /private/steps/2-validation/step-validate-isdriverpackready.ps1: -------------------------------------------------------------------------------- 1 | function step-validate-isdriverpackready { 2 | [CmdletBinding()] 3 | param ( 4 | [System.String] 5 | $DriverPackName = $global:OSDCloudWorkflowInvoke.DriverPackName, 6 | 7 | [System.String] 8 | $DriverPackGuid = $global:OSDCloudWorkflowInvoke.DriverPackObject.Guid, 9 | 10 | $DriverPackObject = $global:OSDCloudWorkflowInvoke.DriverPackObject 11 | ) 12 | #================================================= 13 | # Start the step 14 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 15 | Write-Debug -Message $Message; Write-Verbose -Message $Message 16 | 17 | # Get the configuration of the step 18 | $Step = $global:OSDCloudWorkflowCurrentStep 19 | #================================================= 20 | # Is DriverPackName set to None? 21 | if ($DriverPackName -eq 'None') { 22 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] DriverPackName is set to None. OK." 23 | return 24 | } 25 | #================================================= 26 | # Is DriverPackName set to Microsoft Update Catalog? 27 | if ($DriverPackName -eq 'Microsoft Update Catalog') { 28 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] DriverPackName is set to Microsoft Update Catalog. OK." 29 | return 30 | } 31 | #================================================= 32 | # Is there a DriverPack Object? 33 | if (-not ($DriverPackObject)) { 34 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] DriverPackObject is not set. OK." 35 | return 36 | } 37 | #================================================= 38 | # Is there a DriverPack Guid? 39 | if (-not ($DriverPackGuid)) { 40 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] DriverPackObject.GUID is not set. OK." 41 | return 42 | } 43 | #================================================= 44 | # Is there a URL? 45 | if (-not $($DriverPackObject.Url)) { 46 | Write-Warning "[$(Get-Date -format G)] DriverPackObject does not have a Url to validate." 47 | Write-Warning 'Press Ctrl+C to cancel OSDCloud' 48 | Start-Sleep -Seconds 86400 49 | exit 50 | } 51 | #================================================= 52 | # Is it reachable online? 53 | try { 54 | $WebRequest = Invoke-WebRequest -Uri $DriverPackObject.Url -UseBasicParsing -Method Head 55 | if ($WebRequest.StatusCode -eq 200) { 56 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] DriverPack URL returned a 200 status code. OK." 57 | return 58 | } 59 | } 60 | catch { 61 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] DriverPack URL is not reachable." 62 | } 63 | #================================================= 64 | # Does the file exist on a Drive? 65 | $FileName = Split-Path $DriverPackObject.Url -Leaf 66 | $MatchingFiles = @() 67 | $MatchingFiles = Get-PSDrive -PSProvider FileSystem | ForEach-Object { 68 | Get-ChildItem "$($_.Name):\OSDCloud\DriverPacks\" -Include "$FileName" -File -Recurse -Force -ErrorAction Ignore 69 | } 70 | 71 | if ($MatchingFiles) { 72 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] DriverPack is available offline. OK." 73 | return 74 | } 75 | else { 76 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] DriverPack is not available offline." 77 | } 78 | #================================================= 79 | # DriverPack does not exist 80 | Write-Warning "[$(Get-Date -format G)] Unable to validate if the OperatingSystem is reachable online or offline." 81 | Write-Warning "[$(Get-Date -format G)] OSDCloud will continue without a DriverPack. Clearing variables." 82 | $global:OSDCloudWorkflowInit.DriverPackObject 83 | $global:OSDCloudWorkflowInit.DriverPackObject = $null 84 | $global:OSDCloudWorkflowInit.DriverPackName = 'None' 85 | Write-Host -ForegroundColor DarkCyan "[$(Get-Date -format G)] Continue $WorkflowName in 5 seconds..." 86 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] Press CTRL+C to cancel" 87 | Start-Sleep -Seconds 5 88 | #endregion 89 | #================================================= 90 | # End the function 91 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 92 | Write-Verbose -Message $Message; Write-Debug -Message $Message 93 | #================================================= 94 | } -------------------------------------------------------------------------------- /private/Initialize-OSDCloudWorkflowTasks.ps1: -------------------------------------------------------------------------------- 1 | function Initialize-OSDCloudWorkflowTasks { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $false, 5 | Position = 0, 6 | ValueFromPipeline = $true, 7 | ValueFromPipelineByPropertyName = $true)] 8 | [ValidateNotNullOrEmpty()] 9 | [System.String] 10 | $Name = 'default', 11 | 12 | [System.String] 13 | $Architecture = $Env:PROCESSOR_ARCHITECTURE, 14 | 15 | $Path = "$($MyInvocation.MyCommand.Module.ModuleBase)\workflow" 16 | ) 17 | #================================================= 18 | $Error.Clear() 19 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Start" 20 | $ModuleName = $($MyInvocation.MyCommand.Module.Name) 21 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] ModuleName: $ModuleName" 22 | $ModuleBase = $($MyInvocation.MyCommand.Module.ModuleBase) 23 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] ModuleBase: $ModuleBase" 24 | $ModuleVersion = $($MyInvocation.MyCommand.Module.Version) 25 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] ModuleVersion: $ModuleVersion" 26 | #================================================= 27 | # Workflow Path must exist, there is no fallback 28 | if (-not (Test-Path $Path)) { 29 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] The specified Path does not exist" 30 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] $Path" 31 | break 32 | } 33 | 34 | # Is the name not default? 35 | if ($Name -ne 'default') { 36 | $WorkflowTasksPath = Join-Path $Path (Join-Path $Name 'tasks') 37 | 38 | # Gather the Json files 39 | try { 40 | $WorkflowTasksFiles = Get-ChildItem -Path $WorkflowTasksPath -Filter '*.json' -Recurse -ErrorAction Stop 41 | } 42 | catch { 43 | $Name = 'default' 44 | } 45 | 46 | # Are there Json files that can be used? 47 | if (-not ($WorkflowTasksFiles)) { 48 | $Name = 'default' 49 | } 50 | } 51 | 52 | # Use the default path 53 | if ($Name -eq 'default') { 54 | $WorkflowTasksPath = Join-Path $Path (Join-Path $Name 'tasks') 55 | 56 | try { 57 | $WorkflowTasksFiles = Get-ChildItem -Path $WorkflowTasksPath -Filter '*.json' -Recurse -ErrorAction Stop 58 | } 59 | catch { 60 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] OSDCloud Workflows do not exist in the specified Path" 61 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] $WorkflowTasksPath" 62 | break 63 | } 64 | } 65 | 66 | if (-not ($WorkflowTasksFiles)) { 67 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] OSDCloud Workflows do not exist in the specified Path" 68 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] $WorkflowTasksPath" 69 | break 70 | } 71 | 72 | # Path that is going to be used 73 | Write-Host -ForegroundColor DarkGray "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] $WorkflowTasksPath" 74 | 75 | $OSDCloudWorkflowTasks = foreach ($item in $WorkflowTasksFiles) { 76 | Get-Content $item.FullName -Raw | ConvertFrom-Json 77 | } 78 | 79 | if ($Architecture -match 'amd64') { 80 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Filtering amd64 workflows" 81 | $OSDCloudWorkflowTasks = $OSDCloudWorkflowTasks | Where-Object { $_.amd64 -eq $true } 82 | } 83 | elseif ($Architecture -match 'arm64') { 84 | Write-Verbose "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] Filtering arm64 workflows" 85 | $OSDCloudWorkflowTasks = $OSDCloudWorkflowTasks | Where-Object { $_.arm64 -eq $true } 86 | } 87 | 88 | if ($OSDCloudWorkflowTasks.Count -eq 0) { 89 | Write-Warning "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] No workflows found for architecture: $Architecture" 90 | break 91 | } 92 | 93 | $global:OSDCloudWorkflowTasks = $OSDCloudWorkflowTasks | Sort-Object -Property @{Expression='default';Descending=$true}, @{Expression='name';Descending=$false} 94 | #================================================= 95 | # End the function 96 | $Message = "[$(Get-Date -format G)] [$($MyInvocation.MyCommand.Name)] End" 97 | Write-Verbose -Message $Message; Write-Debug -Message $Message 98 | #================================================= 99 | } -------------------------------------------------------------------------------- /OSDCloud.psd1: -------------------------------------------------------------------------------- 1 | # 2 | # Module manifest for module 'OSDCloud' 3 | # 4 | # Generated by: David Segura, Michael Escamilla 5 | # 6 | # Generated on: 5/1/2025 7 | # 8 | 9 | @{ 10 | 11 | # Script module or binary module file associated with this manifest. 12 | RootModule = 'OSDCloud.psm1' 13 | 14 | # Version number of this module. 15 | ModuleVersion = '25.9.30.3' 16 | 17 | # Supported PSEditions 18 | CompatiblePSEditions = 'Desktop' 19 | 20 | # ID used to uniquely identify this module 21 | GUID = '2fbd5c65-79c7-4561-9a2e-c4a4eebc89c7' 22 | 23 | # Author of this module 24 | Author = 'David Segura, Michael Escamilla' 25 | 26 | # Company or vendor of this module 27 | CompanyName = 'OSDeploy' 28 | 29 | # Copyright statement for this module 30 | Copyright = '(c) 2025 @ osdeploy.com. All rights reserved.' 31 | 32 | # Description of the functionality provided by this module 33 | Description = 'OSDCloud with Windows 11 25H2' 34 | 35 | # Minimum version of the PowerShell engine required by this module 36 | PowerShellVersion = '5.1' 37 | 38 | # Name of the PowerShell host required by this module 39 | # PowerShellHostName = '' 40 | 41 | # Minimum version of the PowerShell host required by this module 42 | # PowerShellHostVersion = '' 43 | 44 | # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 45 | # DotNetFrameworkVersion = '' 46 | 47 | # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 48 | # ClrVersion = '' 49 | 50 | # Processor architecture (None, X86, Amd64) required by this module 51 | # ProcessorArchitecture = '' 52 | 53 | # Modules that must be imported into the global environment prior to importing this module 54 | # RequiredModules = @() 55 | 56 | # Assemblies that must be loaded prior to importing this module 57 | # RequiredAssemblies = @() 58 | 59 | # Script files (.ps1) that are run in the caller's environment prior to importing this module. 60 | # ScriptsToProcess = @() 61 | 62 | # Type files (.ps1xml) to be loaded when importing this module 63 | # TypesToProcess = @() 64 | 65 | # Format files (.ps1xml) to be loaded when importing this module 66 | # FormatsToProcess = @() 67 | 68 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess 69 | # NestedModules = @() 70 | 71 | # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. 72 | FunctionsToExport = 73 | 'Deploy-OSDCloud', 74 | 'Deploy-OSDCloudCLI', 75 | 'Deploy-OSDCloudGUI', 76 | 'Get-OSDCloudInfo', 77 | 'Get-OSDCloudModulePath', 78 | 'Get-OSDCloudModuleVersion', 79 | 'Invoke-OSDCloudPEStartup', 80 | 'Start-OSDCloudWorkflow', 81 | 'Use-PEStartupDeviceInfo', 82 | 'Use-PEStartupHardware', 83 | 'Use-PEStartupHardwareErrors', 84 | 'Use-PEStartupIpconfig', 85 | 'Use-PEStartupUpdateModule', 86 | 'Use-PEStartupWiFi' 87 | 88 | 89 | # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. 90 | CmdletsToExport = @() 91 | 92 | # Variables to export from this module 93 | # VariablesToExport = @() 94 | 95 | # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. 96 | AliasesToExport = @() 97 | 98 | # DSC resources to export from this module 99 | # DscResourcesToExport = @() 100 | 101 | # List of all modules packaged with this module 102 | # ModuleList = @() 103 | 104 | # List of all files packaged with this module 105 | # FileList = @() 106 | 107 | # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. 108 | PrivateData = @{ 109 | 110 | PSData = @{ 111 | 112 | # Tags applied to this module. These help with module discovery in online galleries. 113 | Tags = 'OSDeploy','OSD','OSDWorkspace','OSDCloud' 114 | 115 | # A URL to the license for this module. 116 | LicenseUri = 'https://github.com/OSDeploy/OSDCloud/blob/main/LICENSE' 117 | 118 | # A URL to the main website for this project. 119 | ProjectUri = 'https://github.com/OSDeploy/OSDCloud' 120 | 121 | # A URL to an icon representing this module. 122 | # IconUri = '' 123 | 124 | # ReleaseNotes of this module 125 | # ReleaseNotes = '' 126 | 127 | # Prerelease string of this module 128 | # Prerelease = '' 129 | 130 | # Flag to indicate whether the module requires explicit user acceptance for install/update/save 131 | # RequireLicenseAcceptance = $false 132 | 133 | # External dependent modules of this module 134 | # ExternalModuleDependencies = @() 135 | 136 | } # End of PSData hashtable 137 | 138 | } # End of PrivateData hashtable 139 | 140 | # HelpInfo URI of this module 141 | # HelpInfoURI = '' 142 | 143 | # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. 144 | # DefaultCommandPrefix = '' 145 | 146 | } 147 | 148 | --------------------------------------------------------------------------------