mqsft.powershell.psm1
|
# ============================================================================== # mqsft.powershell.psm1 - AUTO-GENERATED by Create_Module_0_0_5.ps1 v0.0.5 # ------------------------------------------------------------------------------ # Module Version : 1.0.5 # Script Version : 0.0.5 # Built : 2026-02-24 17:13:23 # Source : C:\Modules\functions\mqsft.powershell # # DO NOT EDIT THIS FILE DIRECTLY. # Edit source files in C:\Modules\functions\mqsft.powershell and re-run Create_Module_0_0_5.ps1. # ============================================================================== Set-StrictMode -Version Latest # --- Source: Install-PowerShellVersion.ps1 ------------------------------- function Install-PowerShellVersion { <# .SYNOPSIS GUI-based PowerShell version installer with multiple installation methods .DESCRIPTION Displays a GUI to select and install different PowerShell versions. Shows currently installed versions and tries multiple installation methods. .EXAMPLE Install-PowerShellVersion #> [CmdletBinding()] param() Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing # Available PowerShell versions $AvailableVersions = @{ "PowerShell 7.4 (Latest)" = @{ Version = "7.4.6" MSIUrl = "https://github.com/PowerShell/PowerShell/releases/download/v7.4.6/PowerShell-7.4.6-win-x64.msi" WingetId = "Microsoft.PowerShell" ChocoId = "powershell-core" } "PowerShell 7.3" = @{ Version = "7.3.12" MSIUrl = "https://github.com/PowerShell/PowerShell/releases/download/v7.3.12/PowerShell-7.3.12-win-x64.msi" WingetId = "Microsoft.PowerShell" ChocoId = "powershell-core" } "PowerShell 7.2 (LTS)" = @{ Version = "7.2.23" MSIUrl = "https://github.com/PowerShell/PowerShell/releases/download/v7.2.23/PowerShell-7.2.23-win-x64.msi" WingetId = "Microsoft.PowerShell" ChocoId = "powershell-core" } "PowerShell 6.2" = @{ Version = "6.2.7" MSIUrl = "https://github.com/PowerShell/PowerShell/releases/download/v6.2.7/PowerShell-6.2.7-win-x64.msi" WingetId = "Microsoft.PowerShell" ChocoId = "powershell-core" } } # Function to get installed PowerShell versions function Get-InstalledPowerShellVersions { $installed = @() # Check for pwsh.exe in common locations $pwshPaths = @( "$env:ProgramFiles\PowerShell\7\pwsh.exe", "$env:ProgramFiles\PowerShell\6\pwsh.exe", "${env:ProgramFiles(x86)}\PowerShell\7\pwsh.exe", "${env:ProgramFiles(x86)}\PowerShell\6\pwsh.exe" ) foreach ($path in $pwshPaths) { if (Test-Path $path) { try { $versionInfo = & $path --version 2>$null if ($versionInfo) { $installed += $versionInfo.Trim() } } catch { # Ignore errors } } } # Also check Windows PowerShell $installed += "Windows PowerShell $($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor)" return $installed } # Function to check if a tool is available function Test-CommandAvailable { param([string]$Command) $null -ne (Get-Command $Command -ErrorAction SilentlyContinue) } # Function to install via MSI function Install-ViaMSI { param( [string]$Url, [string]$Version, [System.Windows.Forms.ProgressBar]$ProgressBar, [System.Windows.Forms.Label]$StatusLabel ) try { $StatusLabel.Text = "Method 1/3: Downloading MSI installer..." $ProgressBar.Value = 10 $msiPath = "$env:TEMP\PowerShell-$Version-win-x64.msi" # Download MSI $webClient = New-Object System.Net.WebClient $webClient.DownloadFile($Url, $msiPath) $StatusLabel.Text = "Installing PowerShell $Version via MSI..." $ProgressBar.Value = 40 # Install MSI silently $arguments = "/i `"$msiPath`" /qn /norestart ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL=1 ENABLE_PSREMOTING=1 REGISTER_MANIFEST=1" $process = Start-Process msiexec.exe -ArgumentList $arguments -Wait -PassThru $ProgressBar.Value = 70 # Clean up Remove-Item $msiPath -Force -ErrorAction SilentlyContinue if ($process.ExitCode -eq 0) { $StatusLabel.Text = "Successfully installed via MSI!" return $true } else { $StatusLabel.Text = "MSI installation failed (Exit code: $($process.ExitCode))" return $false } } catch { $StatusLabel.Text = "MSI method failed: $($_.Exception.Message)" return $false } } # Function to install via winget function Install-ViaWinget { param( [string]$WingetId, [string]$Version, [System.Windows.Forms.ProgressBar]$ProgressBar, [System.Windows.Forms.Label]$StatusLabel ) try { if (-not (Test-CommandAvailable "winget")) { $StatusLabel.Text = "Winget not available, skipping..." return $false } $StatusLabel.Text = "Method 2/3: Installing via winget..." $ProgressBar.Value = 40 $process = Start-Process winget -ArgumentList "install --id $WingetId --version $Version --silent --accept-package-agreements --accept-source-agreements" -Wait -PassThru -NoNewWindow $ProgressBar.Value = 70 if ($process.ExitCode -eq 0) { $StatusLabel.Text = "Successfully installed via winget!" return $true } else { $StatusLabel.Text = "Winget installation failed" return $false } } catch { $StatusLabel.Text = "Winget method failed: $($_.Exception.Message)" return $false } } # Function to install via Chocolatey function Install-ViaChocolatey { param( [string]$ChocoId, [string]$Version, [System.Windows.Forms.ProgressBar]$ProgressBar, [System.Windows.Forms.Label]$StatusLabel ) try { if (-not (Test-CommandAvailable "choco")) { $StatusLabel.Text = "Chocolatey not available, skipping..." return $false } $StatusLabel.Text = "Method 3/3: Installing via Chocolatey..." $ProgressBar.Value = 40 $process = Start-Process choco -ArgumentList "install $ChocoId --version=$Version -y --force" -Wait -PassThru -NoNewWindow $ProgressBar.Value = 70 if ($process.ExitCode -eq 0) { $StatusLabel.Text = "Successfully installed via Chocolatey!" return $true } else { $StatusLabel.Text = "Chocolatey installation failed" return $false } } catch { $StatusLabel.Text = "Chocolatey method failed: $($_.Exception.Message)" return $false } } # Create the form $form = New-Object System.Windows.Forms.Form $form.Text = "PowerShell Version Installer" $form.Size = New-Object System.Drawing.Size(500, 450) $form.StartPosition = "CenterScreen" $form.FormBorderStyle = "FixedDialog" $form.MaximizeBox = $false # Currently Installed Label $installedLabel = New-Object System.Windows.Forms.Label $installedLabel.Location = New-Object System.Drawing.Point(10, 10) $installedLabel.Size = New-Object System.Drawing.Size(470, 20) $installedLabel.Text = "Currently Installed Versions:" $installedLabel.Font = New-Object System.Drawing.Font("Segoe UI", 10, [System.Drawing.FontStyle]::Bold) $form.Controls.Add($installedLabel) # Installed Versions ListBox $installedListBox = New-Object System.Windows.Forms.ListBox $installedListBox.Location = New-Object System.Drawing.Point(10, 35) $installedListBox.Size = New-Object System.Drawing.Size(470, 80) $installedListBox.Font = New-Object System.Drawing.Font("Consolas", 9) $installedVersions = Get-InstalledPowerShellVersions foreach ($version in $installedVersions) { [void]$installedListBox.Items.Add($version) } $form.Controls.Add($installedListBox) # Version Selection Label $selectLabel = New-Object System.Windows.Forms.Label $selectLabel.Location = New-Object System.Drawing.Point(10, 130) $selectLabel.Size = New-Object System.Drawing.Size(470, 20) $selectLabel.Text = "Select Version to Install:" $selectLabel.Font = New-Object System.Drawing.Font("Segoe UI", 10, [System.Drawing.FontStyle]::Bold) $form.Controls.Add($selectLabel) # Version Dropdown $versionComboBox = New-Object System.Windows.Forms.ComboBox $versionComboBox.Location = New-Object System.Drawing.Point(10, 155) $versionComboBox.Size = New-Object System.Drawing.Size(470, 25) $versionComboBox.DropDownStyle = "DropDownList" foreach ($version in $AvailableVersions.Keys) { [void]$versionComboBox.Items.Add($version) } $versionComboBox.SelectedIndex = 0 $form.Controls.Add($versionComboBox) # Progress Bar $progressBar = New-Object System.Windows.Forms.ProgressBar $progressBar.Location = New-Object System.Drawing.Point(10, 200) $progressBar.Size = New-Object System.Drawing.Size(470, 30) $progressBar.Style = "Continuous" $form.Controls.Add($progressBar) # Status Label $statusLabel = New-Object System.Windows.Forms.Label $statusLabel.Location = New-Object System.Drawing.Point(10, 240) $statusLabel.Size = New-Object System.Drawing.Size(470, 60) $statusLabel.Text = "Ready to install. Click 'Install' to begin." $statusLabel.Font = New-Object System.Drawing.Font("Segoe UI", 9) $form.Controls.Add($statusLabel) # Install Button $installButton = New-Object System.Windows.Forms.Button $installButton.Location = New-Object System.Drawing.Point(10, 320) $installButton.Size = New-Object System.Drawing.Size(230, 40) $installButton.Text = "Install Selected Version" $installButton.Font = New-Object System.Drawing.Font("Segoe UI", 10, [System.Drawing.FontStyle]::Bold) $installButton.BackColor = [System.Drawing.Color]::FromArgb(0, 120, 215) $installButton.ForeColor = [System.Drawing.Color]::White $installButton.Add_Click({ $selectedVersion = $versionComboBox.SelectedItem if (-not $selectedVersion) { [System.Windows.Forms.MessageBox]::Show("Please select a version to install.", "No Selection", "OK", "Warning") return } $versionInfo = $AvailableVersions[$selectedVersion] $installButton.Enabled = $false $refreshButton.Enabled = $false $progressBar.Value = 0 $statusLabel.Text = "Starting installation of $selectedVersion..." # Try installation methods in order $installed = $false # Method 1: MSI Installer if (-not $installed) { $progressBar.Value = 5 $installed = Install-ViaMSI -Url $versionInfo.MSIUrl -Version $versionInfo.Version -ProgressBar $progressBar -StatusLabel $statusLabel } # Method 2: Winget if (-not $installed) { $progressBar.Value = 35 $installed = Install-ViaWinget -WingetId $versionInfo.WingetId -Version $versionInfo.Version -ProgressBar $progressBar -StatusLabel $statusLabel } # Method 3: Chocolatey if (-not $installed) { $progressBar.Value = 65 $installed = Install-ViaChocolatey -ChocoId $versionInfo.ChocoId -Version $versionInfo.Version -ProgressBar $progressBar -StatusLabel $statusLabel } if ($installed) { $progressBar.Value = 100 $statusLabel.Text = "Installation complete! Refreshing installed versions..." # Refresh installed versions Start-Sleep -Seconds 2 $installedListBox.Items.Clear() $newVersions = Get-InstalledPowerShellVersions foreach ($version in $newVersions) { [void]$installedListBox.Items.Add($version) } [System.Windows.Forms.MessageBox]::Show("PowerShell $($versionInfo.Version) installed successfully!`n`nYou may need to restart your terminal to use the new version.", "Installation Complete", "OK", "Information") } else { $progressBar.Value = 0 $statusLabel.Text = "All installation methods failed. Please check your internet connection or try manual installation." [System.Windows.Forms.MessageBox]::Show("Failed to install PowerShell. All methods failed.`n`nPlease check the status message for details.", "Installation Failed", "OK", "Error") } $installButton.Enabled = $true $refreshButton.Enabled = $true }) $form.Controls.Add($installButton) # Refresh Button $refreshButton = New-Object System.Windows.Forms.Button $refreshButton.Location = New-Object System.Drawing.Point(250, 320) $refreshButton.Size = New-Object System.Drawing.Size(230, 40) $refreshButton.Text = "Refresh Installed Versions" $refreshButton.Font = New-Object System.Drawing.Font("Segoe UI", 10) $refreshButton.Add_Click({ $installedListBox.Items.Clear() $versions = Get-InstalledPowerShellVersions foreach ($version in $versions) { [void]$installedListBox.Items.Add($version) } $statusLabel.Text = "Refreshed installed versions list." }) $form.Controls.Add($refreshButton) # Close Button $closeButton = New-Object System.Windows.Forms.Button $closeButton.Location = New-Object System.Drawing.Point(10, 370) $closeButton.Size = New-Object System.Drawing.Size(470, 30) $closeButton.Text = "Close" $closeButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel $form.Controls.Add($closeButton) $form.CancelButton = $closeButton # Show the form [void]$form.ShowDialog() } # Export the function # Export-ModuleMember -Function Install-PowerShellVersion Install-PowerShellVersion # --- Source: Load-Powershell_7.ps1 --------------------------------------- Function Load-Powershell_7{ function New-OutOfProcRunspace { param($ProcessId) $connectionInfo = New-Object -TypeName System.Management.Automation.Runspaces.NamedPipeConnectionInfo -ArgumentList @($ProcessId) $TypeTable = [System.Management.Automation.Runspaces.TypeTable]::LoadDefaultTypeFiles() #$Runspace = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateOutOfProcessRunspace($connectionInfo,$Host,$TypeTable) $Runspace = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace($connectionInfo,$Host,$TypeTable) $Runspace.Open() $Runspace } $Process = Start-Process PWSH -ArgumentList @("-NoExit") -PassThru -WindowStyle Hidden $Runspace = New-OutOfProcRunspace -ProcessId $Process.Id $Host.PushRunspace($Runspace) } Load-Powershell_7 |