attempted to add self heal if get-psrepository is missing
This commit is contained in:
@@ -1,3 +1,117 @@
|
|||||||
|
function Repair-PowerShellGetStack {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Repairs (self-heals) the local PowerShellGet/PackageManagement installation so PowerShellGet v2 cmdlets (e.g. Get-PSRepository) are available.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
Normalizes common broken module layouts for PowerShellGet and PackageManagement that prevent Import-Module PowerShellGet from working.
|
||||||
|
This can happen when the modules are installed/unpacked into non-standard folder names such as:
|
||||||
|
- PowerShellGet\PowerShellGet.2.2.5\
|
||||||
|
- PowerShellGet\<GUID>\
|
||||||
|
- PackageManagement\PackageManagement.1.4.8.1\
|
||||||
|
- PowerShellGet\PackageManagement.1.4.8.1\ (wrong root)
|
||||||
|
|
||||||
|
The function:
|
||||||
|
1) Ensures the Program Files module path is present in $env:PSModulePath
|
||||||
|
2) Moves PackageManagement out of the wrong root if found under the PowerShellGet folder
|
||||||
|
3) Renames/moves module folders into the standard versioned layout:
|
||||||
|
...\Modules\PackageManagement\<version>\
|
||||||
|
...\Modules\PowerShellGet\<version>\
|
||||||
|
4) Imports the requested versions and verifies Get-PSRepository is available
|
||||||
|
|
||||||
|
Safe to run multiple times. It does not download anything from the internet; it only rearranges/loads locally present modules.
|
||||||
|
|
||||||
|
.PARAMETER PowerShellGetVersion
|
||||||
|
The PowerShellGet version to normalize and import (default: 2.2.5).
|
||||||
|
|
||||||
|
.PARAMETER PackageManagementVersion
|
||||||
|
The PackageManagement version to normalize and import (default: 1.4.8.1).
|
||||||
|
#>
|
||||||
|
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[Version]$PowerShellGetVersion = [Version]'2.2.5',
|
||||||
|
[Version]$PackageManagementVersion= [Version]'1.4.8.1'
|
||||||
|
)
|
||||||
|
|
||||||
|
function _EnsurePSModulePath {
|
||||||
|
$all = Join-Path $env:ProgramFiles 'WindowsPowerShell\Modules'
|
||||||
|
if (($env:PSModulePath -split ';') -notcontains $all) {
|
||||||
|
$env:PSModulePath = "$env:PSModulePath;$all"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _NormalizeModuleFolder {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory)][string]$ModuleName,
|
||||||
|
[Parameter(Mandatory)][Version]$Version
|
||||||
|
)
|
||||||
|
|
||||||
|
$base = Join-Path (Join-Path $env:ProgramFiles 'WindowsPowerShell\Modules') $ModuleName
|
||||||
|
New-Item -ItemType Directory -Path $base -Force | Out-Null
|
||||||
|
|
||||||
|
$wanted = Join-Path $base $Version.ToString()
|
||||||
|
|
||||||
|
# common wrong names:
|
||||||
|
$candidates = @(
|
||||||
|
Join-Path $base ("{0}.{1}" -f $ModuleName, $Version.ToString()),
|
||||||
|
Join-Path $base ("{0}.{1}" -f $ModuleName, $Version.ToString()),
|
||||||
|
Join-Path $base ("{0}.{1}" -f $ModuleName, $Version.ToString(3))
|
||||||
|
) | Select-Object -Unique
|
||||||
|
|
||||||
|
$manifestName = "{0}.psd1" -f $ModuleName
|
||||||
|
$foundManifests = Get-ChildItem -Path $base -Recurse -Filter $manifestName -ErrorAction SilentlyContinue
|
||||||
|
foreach ($m in $foundManifests) {
|
||||||
|
$candidates += (Split-Path $m.FullName -Parent)
|
||||||
|
}
|
||||||
|
$candidates = $candidates | Select-Object -Unique
|
||||||
|
|
||||||
|
if (Test-Path $wanted) { return }
|
||||||
|
|
||||||
|
foreach ($src in $candidates) {
|
||||||
|
if (-not (Test-Path $src)) { continue }
|
||||||
|
if (-not (Test-Path (Join-Path $src $manifestName))) { continue }
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($src -eq $wanted) { return }
|
||||||
|
if (Test-Path $wanted) { Remove-Item -Recurse -Force $wanted }
|
||||||
|
Move-Item -Path $src -Destination $wanted -Force
|
||||||
|
return
|
||||||
|
} catch {
|
||||||
|
try {
|
||||||
|
if (Test-Path $wanted) { Remove-Item -Recurse -Force $wanted }
|
||||||
|
Copy-Item -Path $src -Destination $wanted -Recurse -Force
|
||||||
|
return
|
||||||
|
} catch { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_EnsurePSModulePath
|
||||||
|
|
||||||
|
$pmWrong = Join-Path (Join-Path (Join-Path $env:ProgramFiles 'WindowsPowerShell\Modules') 'PowerShellGet') ("PackageManagement.{0}" -f $PackageManagementVersion.ToString())
|
||||||
|
if (Test-Path $pmWrong) {
|
||||||
|
$pmRightBase = Join-Path (Join-Path $env:ProgramFiles 'WindowsPowerShell\Modules') 'PackageManagement'
|
||||||
|
New-Item -ItemType Directory -Path $pmRightBase -Force | Out-Null
|
||||||
|
$pmRight = Join-Path $pmRightBase $PackageManagementVersion.ToString()
|
||||||
|
if (Test-Path $pmRight) { Remove-Item -Recurse -Force $pmRight }
|
||||||
|
try { Move-Item -Path $pmWrong -Destination $pmRight -Force } catch { Copy-Item -Path $pmWrong -Destination $pmRight -Recurse -Force }
|
||||||
|
}
|
||||||
|
|
||||||
|
_NormalizeModuleFolder -ModuleName 'PackageManagement' -Version $PackageManagementVersion
|
||||||
|
_NormalizeModuleFolder -ModuleName 'PowerShellGet' -Version $PowerShellGetVersion
|
||||||
|
|
||||||
|
Remove-Module PackageManagement,PowerShellGet -Force -ErrorAction SilentlyContinue
|
||||||
|
Import-Module PackageManagement -RequiredVersion $PackageManagementVersion -Force -ErrorAction Stop
|
||||||
|
Import-Module PowerShellGet -RequiredVersion $PowerShellGetVersion -Force -ErrorAction Stop
|
||||||
|
|
||||||
|
if (-not (Get-Command Get-PSRepository -ErrorAction SilentlyContinue)) {
|
||||||
|
throw "PowerShellGet loaded but Get-PSRepository still missing."
|
||||||
|
}
|
||||||
|
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
|
||||||
function Install-SVSMSP {
|
function Install-SVSMSP {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
param (
|
param (
|
||||||
@@ -165,6 +279,15 @@ function Install-SVSMSP {
|
|||||||
function Start-Cleanup {
|
function Start-Cleanup {
|
||||||
Write-LogHybrid "Cleanup mode enabled. Starting cleanup..." "Info" "SVSModule"
|
Write-LogHybrid "Cleanup mode enabled. Starting cleanup..." "Info" "SVSModule"
|
||||||
|
|
||||||
|
# Self-heal PowerShellGet only on systems missing PSGet v2 cmdlets
|
||||||
|
if (-not (Get-Command Get-PSRepository -ErrorAction SilentlyContinue)) {
|
||||||
|
try {
|
||||||
|
Repair-PowerShellGetStack | Out-Null
|
||||||
|
} catch {
|
||||||
|
Write-LogHybrid "PowerShellGet self-heal failed: $($_.Exception.Message). Skipping PSGet v2 repo operations." "Warning" "SVSModule" -LogToEvent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Uninstall module using whichever tooling exists
|
# Uninstall module using whichever tooling exists
|
||||||
try {
|
try {
|
||||||
if (Get-Command Uninstall-PSResource -ErrorAction SilentlyContinue) {
|
if (Get-Command Uninstall-PSResource -ErrorAction SilentlyContinue) {
|
||||||
@@ -180,6 +303,8 @@ function Install-SVSMSP {
|
|||||||
Uninstall-Package -Name $NewModuleName -ProviderName NuGet -AllVersions -Force -ErrorAction SilentlyContinue | Out-Null
|
Uninstall-Package -Name $NewModuleName -ProviderName NuGet -AllVersions -Force -ErrorAction SilentlyContinue | Out-Null
|
||||||
} catch { }
|
} catch { }
|
||||||
|
|
||||||
|
# PSGet v2 repo cleanup (guarded)
|
||||||
|
if (Get-Command Get-PSRepository -ErrorAction SilentlyContinue) {
|
||||||
if (Get-PSRepository -Name $NewRepositoryName -ErrorAction SilentlyContinue) {
|
if (Get-PSRepository -Name $NewRepositoryName -ErrorAction SilentlyContinue) {
|
||||||
try {
|
try {
|
||||||
Unregister-PSRepository -Name $NewRepositoryName -ErrorAction Stop
|
Unregister-PSRepository -Name $NewRepositoryName -ErrorAction Stop
|
||||||
@@ -188,7 +313,11 @@ function Install-SVSMSP {
|
|||||||
Write-LogHybrid "Failed to unregister PSRepository ${NewRepositoryName}: $($_.Exception.Message)" "Error" "SVSModule" -LogToEvent
|
Write-LogHybrid "Failed to unregister PSRepository ${NewRepositoryName}: $($_.Exception.Message)" "Error" "SVSModule" -LogToEvent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Write-LogHybrid "Skipping PSGet v2 repo cleanup: Get-PSRepository not available on this system." "Info" "SVSModule" -LogToEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
# PSResourceGet repo cleanup (already guarded)
|
||||||
if (Get-Command Get-PSResourceRepository -ErrorAction SilentlyContinue) {
|
if (Get-Command Get-PSResourceRepository -ErrorAction SilentlyContinue) {
|
||||||
if (Get-PSResourceRepository -Name $NewRepositoryName -ErrorAction SilentlyContinue) {
|
if (Get-PSResourceRepository -Name $NewRepositoryName -ErrorAction SilentlyContinue) {
|
||||||
try {
|
try {
|
||||||
@@ -200,6 +329,7 @@ function Install-SVSMSP {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# NuGet provider source cleanup (guarded by Get-PackageSource existence)
|
||||||
if (Get-PackageSource -Name $NewRepositoryName -ErrorAction SilentlyContinue) {
|
if (Get-PackageSource -Name $NewRepositoryName -ErrorAction SilentlyContinue) {
|
||||||
try {
|
try {
|
||||||
Unregister-PackageSource -Name $NewRepositoryName -ErrorAction SilentlyContinue | Out-Null
|
Unregister-PackageSource -Name $NewRepositoryName -ErrorAction SilentlyContinue | Out-Null
|
||||||
@@ -225,7 +355,7 @@ function Install-SVSMSP {
|
|||||||
Write-LogHybrid "Failed to delete '$cscePath': $($_.Exception.Message)" "Warning" "SVSModule" -LogToEvent
|
Write-LogHybrid "Failed to delete '$cscePath': $($_.Exception.Message)" "Warning" "SVSModule" -LogToEvent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Remove-SVSDeploymentRegKey {
|
function Remove-SVSDeploymentRegKey {
|
||||||
$regKey = 'HKLM:\Software\SVS'
|
$regKey = 'HKLM:\Software\SVS'
|
||||||
@@ -325,159 +455,3 @@ function Install-SVSMSP {
|
|||||||
Start-ToolkitInstallation
|
Start-ToolkitInstallation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<# Function as is before we attempted to have it attempt to use
|
|
||||||
|
|
||||||
Prefer PSResourceGet when it exists (and your ProGet v3 index works).
|
|
||||||
Fallback to PowerShellGet v2 (Register-PSRepository / Install-Module) if PSResourceGet isn't available.
|
|
||||||
Last-resort fallback to your proven NuGet provider path (Register-PackageSource / Install-Package + optional “promote”) for the cursed endpoints where PSGet v2 explodes.
|
|
||||||
|
|
||||||
function Install-SVSMSP {
|
|
||||||
param (
|
|
||||||
[switch] $Cleanup,
|
|
||||||
[switch] $InstallToolkit,
|
|
||||||
[Parameter(Mandatory = $false)][array] $AllModules = @(@{ ModuleName = "SVS_Toolkit" }, @{ ModuleName = "SVSMSP" }),
|
|
||||||
[Parameter(Mandatory = $false)][array] $AllRepositories = @(@{ RepoName = "SVS_Repo" }, @{ RepoName = "SVS_Toolkit" }),
|
|
||||||
[Parameter(Mandatory = $false)][string] $NewModuleName = "SVSMSP",
|
|
||||||
[Parameter(Mandatory = $false)][string] $NewRepositoryName= "SVS_Repo",
|
|
||||||
[Parameter(Mandatory = $false)][string] $NewRepositoryURL = "https://proget.svstools.ca/nuget/SVS_Repo/"
|
|
||||||
)
|
|
||||||
|
|
||||||
function Start-Cleanup {
|
|
||||||
Write-LogHybrid "Cleanup mode enabled. Starting cleanup..." "Info" "SVSModule"
|
|
||||||
|
|
||||||
try {
|
|
||||||
Uninstall-Module -Name SVSMSP -AllVersions -Force -ErrorAction Stop
|
|
||||||
Write-LogHybrid "SVSMSP module uninstalled from system." "Success" "SVSModule" -LogToEvent
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
if ($_.Exception.Message -match 'No match was found') {
|
|
||||||
Write-LogHybrid "No existing SVSMSP module found to uninstall." "Warning" "SVSModule" -LogToEvent
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Write-LogHybrid "Failed to uninstall SVSMSP: $($_.Exception.Message)" "Error" "SVSModule" -LogToEvent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Get-PSRepository -Name SVS_Repo -ErrorAction SilentlyContinue) {
|
|
||||||
try {
|
|
||||||
Unregister-PSRepository -Name SVS_Repo -ErrorAction Stop
|
|
||||||
Write-LogHybrid "SVS_Repo repository unregistered." "Success" "SVSModule" -LogToEvent
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
Write-LogHybrid "Failed to unregister SVS_Repo: $($_.Exception.Message)" "Error" "SVSModule" -LogToEvent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Get-Module -Name SVSMSP) {
|
|
||||||
try {
|
|
||||||
Remove-Module SVSMSP -Force -ErrorAction Stop
|
|
||||||
Write-LogHybrid "SVSMSP module removed from current session." "Success" "SVSModule" -LogToEvent
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
Write-LogHybrid "Failed to remove SVSMSP from session: $($_.Exception.Message)" "Error" "SVSModule" -LogToEvent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$cscePath = 'C:\CSCE'
|
|
||||||
if (Test-Path $cscePath) {
|
|
||||||
try {
|
|
||||||
Remove-Item -Path $cscePath -Recurse -Force
|
|
||||||
Write-LogHybrid "Deleted '$cscePath' contents." "Success" "SVSModule" -LogToEvent
|
|
||||||
} catch {
|
|
||||||
Write-LogHybrid "Failed to delete '$cscePath': $($_.Exception.Message)" "Warning" "SVSModule" -LogToEvent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Remove-SVSDeploymentRegKey {
|
|
||||||
$regKey = 'HKLM:\Software\SVS'
|
|
||||||
try {
|
|
||||||
if (Test-Path $regKey) {
|
|
||||||
Remove-Item -Path $regKey -Recurse -Force
|
|
||||||
Write-LogHybrid "Registry key '$regKey' deleted successfully." "Success" "SVSModule" -LogToEvent
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Write-LogHybrid "Registry key '$regKey' not found; nothing to delete." "Info" "SVSModule" -LogToEvent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
Write-LogHybrid "Failed to delete registry key '$regKey': $($_.Exception.Message)" "Error" "SVSModule" -LogToEvent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Repair-SVSMspEventLogBinding {
|
|
||||||
param(
|
|
||||||
[string]$EventSource = "SVSMSP_Module",
|
|
||||||
[string]$TargetLog = "SVSMSP Events"
|
|
||||||
)
|
|
||||||
|
|
||||||
Write-LogHybrid "Checking Event Log binding for source '$EventSource'..." Info SVSModule -LogToEvent
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (-not [System.Diagnostics.EventLog]::SourceExists($EventSource)) {
|
|
||||||
Write-LogHybrid "Event source '$EventSource' not found. Nothing to repair." Info SVSModule -LogToEvent
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
$currentLog = [System.Diagnostics.EventLog]::LogNameFromSourceName($EventSource, '.')
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
Write-LogHybrid "Failed to query Event Log binding for '$EventSource': $($_.Exception.Message)" Warning SVSModule -LogToEvent
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (-not $currentLog) {
|
|
||||||
Write-LogHybrid "Could not determine current log for event source '$EventSource'. Skipping repair." Warning SVSModule -LogToEvent
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($currentLog -eq $TargetLog) {
|
|
||||||
Write-LogHybrid "Event source '$EventSource' already bound to '$TargetLog'." Info SVSModule -LogToEvent
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-LogHybrid "Rebinding event source '$EventSource' from '$currentLog' to '$TargetLog'..." Warning SVSModule -LogToEvent
|
|
||||||
|
|
||||||
try {
|
|
||||||
[System.Diagnostics.EventLog]::DeleteEventSource($EventSource)
|
|
||||||
New-EventLog -LogName $TargetLog -Source $EventSource -ErrorAction Stop
|
|
||||||
Write-LogHybrid "Event source '$EventSource' rebound to '$TargetLog'." Success SVSModule -LogToEvent
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
Write-LogHybrid "Failed to rebind event source '$EventSource' to log '$TargetLog': $($_.Exception.Message)" Error SVSModule -LogToEvent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Start-ToolkitInstallation {
|
|
||||||
Initialize-NuGetProvider
|
|
||||||
Start-Cleanup
|
|
||||||
|
|
||||||
Write-LogHybrid "Registering repo $NewRepositoryName…" "Info" "SVSModule" -LogToEvent
|
|
||||||
if (-not (Get-PSRepository -Name $NewRepositoryName -ErrorAction SilentlyContinue)) {
|
|
||||||
Register-PSRepository -Name $NewRepositoryName -SourceLocation $NewRepositoryURL -InstallationPolicy Trusted
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-LogHybrid "Installing module $NewModuleName…" "Info" "SVSModule" -LogToEvent
|
|
||||||
Install-Module -Name $NewModuleName -Repository $NewRepositoryName -Scope AllUsers -Force
|
|
||||||
|
|
||||||
Repair-SVSMspEventLogBinding -EventSource "SVSMSP_Module" -TargetLog "SVSMSP Events"
|
|
||||||
|
|
||||||
Write-LogHybrid "Toolkit installation completed." "Success" "SVSModule" -LogToEvent
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-LogHybrid "Install-SVSMSP called" "Info" "SVSModule" -LogToEvent
|
|
||||||
|
|
||||||
if ($Cleanup) {
|
|
||||||
Start-Cleanup
|
|
||||||
Remove-SVSDeploymentRegKey
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($InstallToolkit) { Start-ToolkitInstallation; return }
|
|
||||||
|
|
||||||
Start-ToolkitInstallation
|
|
||||||
}
|
|
||||||
#>
|
|
||||||
Reference in New Issue
Block a user