private/WinPEStartup/Initialize-WinPEStartupScript.ps1
|
#requires -Version 5.1 function Initialize-WinPEStartupScript { <# .SYNOPSIS Executes startup scripts found on attached drives .DESCRIPTION Scans every available drive letter for a scripts subfolder. When found, looks for files matching the FileName pattern with .cmd or .ps1 extensions. CMD scripts are executed synchronously with cmd.exe. PS1 scripts are executed in the current process by default. Use -NewProcess to launch them in a separate PowerShell window. This is the PowerShell equivalent of the main.cmd / main.ps1 / main-noexit.ps1 execution loops in startnet.cmd / ReStartnet.cmd. .PARAMETER SubfolderPath The relative subfolder path to search for on each drive. Defaults to 'WinPEStartup\Scripts'. .PARAMETER FileName The file name pattern to match. Defaults to 'startnet.cmd'. Only .cmd and .ps1 files are executed. .PARAMETER NoExit When specified, PowerShell scripts are started with -NoExit so the window remains open after the script completes. Only applies when -NewProcess is specified. .PARAMETER NewProcess When specified, PowerShell scripts are launched in a new PowerShell window using Start-Process instead of executing in the current process. .EXAMPLE Initialize-WinPEStartupScript Scans all drives for WinPEStartup\Scripts\startnet.cmd. .EXAMPLE Initialize-WinPEStartupScript -NoExit Same as above but PowerShell scripts keep the window open. .EXAMPLE Initialize-WinPEStartupScript -NewProcess Launches discovered PowerShell scripts in a new window. .EXAMPLE Initialize-WinPEStartupScript -FileName 'setup.*' -SubfolderPath 'MyScripts' Scans all drives for MyScripts\setup.cmd and setup.ps1. .NOTES Author: David Segura Module: OSDCloud #> [CmdletBinding()] [OutputType([void])] param ( [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$SubfolderPath = 'WinPEStartup\Scripts', [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$FileName = 'startnet.cmd', [Parameter(Mandatory = $false)] [switch]$NoExit, [Parameter(Mandatory = $false)] [switch]$NewProcess ) begin { $skipExecution = $false if ($env:SystemDrive -ne 'X:') { Write-Warning 'Initialize-WinPEStartupScript: Not running in WinPE (SystemDrive is not X:). Exiting.' $skipExecution = $true return } Write-Verbose 'Initialize-WinPEStartupScript: Starting script scan' } process { if ($skipExecution) { return } $driveLetters = [char[]](67..90) # C through Z foreach ($letter in $driveLetters) { $scriptFolder = '{0}:\{1}' -f $letter, $SubfolderPath if (-not (Test-Path -Path $scriptFolder -PathType Container)) { continue } Write-Verbose "Found script folder: $scriptFolder" $scriptFiles = Get-ChildItem -Path $scriptFolder -Filter $FileName -ErrorAction SilentlyContinue | Where-Object { -not $_.PSIsContainer -and ($_.Extension -eq '.cmd' -or $_.Extension -eq '.ps1') } if (-not $scriptFiles) { Write-Verbose "No matching script files found in $scriptFolder" continue } foreach ($scriptFile in $scriptFiles) { switch ($scriptFile.Extension) { '.cmd' { Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Script: $($scriptFile.FullName)" Write-Verbose "Executing CMD script: $($scriptFile.FullName)" Invoke-CmdScript -ScriptPath $scriptFile.FullName } '.ps1' { if ($NewProcess -and $NoExit) { $action = 'Start PowerShell script (NoExit)' } elseif ($NewProcess) { $action = 'Start PowerShell script' } else { $action = 'Execute PowerShell script in process' } Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Script: $($scriptFile.FullName)" Write-Verbose "Executing PowerShell script: $($scriptFile.FullName)" if ($NewProcess -and $NoExit) { Start-Process -FilePath 'powershell.exe' -ArgumentList '-NoExit', '-NoLogo', '-File', $scriptFile.FullName -Wait } elseif ($NewProcess) { Start-Process -FilePath 'powershell.exe' -ArgumentList '-NoLogo', '-File', $scriptFile.FullName -Wait } else { & $scriptFile.FullName } } } } } } end { if ($skipExecution) { return } Write-Verbose 'Initialize-WinPEStartupScript: Complete' } } |