diff --git a/samy.functions.ps1 b/samy.functions.ps1 index 6a47794..8492797 100644 --- a/samy.functions.ps1 +++ b/samy.functions.ps1 @@ -1,81 +1,86 @@ - function Initialize-NuGetProvider { - [CmdletBinding()] - param() +function Initialize-NuGetProvider { + [CmdletBinding()] + param() - #region — guarantee NuGet provider is present without prompting + # Silent defaults + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + $ProgressPreference = 'SilentlyContinue' + $ConfirmPreference = 'None' - # ─── Silent defaults ─── - [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - $ProgressPreference = 'SilentlyContinue' - $ConfirmPreference = 'None' + # Extra guardrails for "ShouldContinue" style prompts + $PSDefaultParameterValues['*:Confirm'] = $false - # ─── Pre-create folder if running as SYSTEM (avoids NuGet install bug) ─── - $provPath = "$env:ProgramData\PackageManagement\ProviderAssemblies" - if (-not (Test-Path $provPath)) { - try { - New-Item -Path $provPath -ItemType Directory -Force -ErrorAction Stop | Out-Null - Write-LogHybrid "Created missing provider folder: $provPath" Info Bootstrap -LogToEvent - } catch { - Write-LogHybrid "Failed to create provider folder: $($_.Exception.Message)" Warning Bootstrap -LogToEvent - } + # Ensure provider folders exist (CurrentUser and AllUsers locations) + $userProvPath = Join-Path $env:LOCALAPPDATA 'PackageManagement\ProviderAssemblies' + $allProvPath = Join-Path ${env:ProgramFiles} 'PackageManagement\ProviderAssemblies' + + foreach ($p in @($userProvPath, $allProvPath)) { + try { + if ($p -and -not (Test-Path $p)) { + New-Item -Path $p -ItemType Directory -Force -ErrorAction Stop | Out-Null + Write-LogHybrid "Ensured provider folder exists: $p" Info Bootstrap -LogToEvent } + } catch { + # AllUsers path can fail without admin. That's OK. + Write-LogHybrid "Could not create provider folder: $p ($($_.Exception.Message))" Warning Bootstrap -LogToEvent + } + } - # ─── Ensure PowerShellGet is available ─── - if (-not (Get-Command Install-PackageProvider -ErrorAction SilentlyContinue)) { - try { - Install-Module PowerShellGet -Force -AllowClobber -Confirm:$false -ErrorAction Stop - Write-LogHybrid "Installed PowerShellGet module" Info Bootstrap -LogToEvent - } catch { - Write-LogHybrid "PowerShellGet install failed: $($_.Exception.Message)" Error Bootstrap -LogToEvent - } - } + # 1) Install NuGet provider FIRST, silently, so Install-Module never prompts + try { + $existing = Get-PackageProvider -Name NuGet -ListAvailable -ErrorAction SilentlyContinue | + Sort-Object Version -Descending | Select-Object -First 1 - # ─── Ensure PackageManagement is up-to-date ─── - $pkgMgmtVersion = (Get-Module PackageManagement -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Version - if ($pkgMgmtVersion -lt [Version]"1.3.1") { - try { - Install-Module PackageManagement -Force -AllowClobber -Confirm:$false -ErrorAction Stop - Write-LogHybrid "Updated PackageManagement to latest version" Info Bootstrap -LogToEvent - } catch { - Write-LogHybrid "PackageManagement update failed: $($_.Exception.Message)" Warning Bootstrap -LogToEvent - } - } + if (-not $existing -or $existing.Version -lt [Version]'2.8.5.201') { - # ─── Import modules silently ─── - Import-Module PackageManagement -Force -ErrorAction SilentlyContinue | Out-Null - Import-Module PowerShellGet -Force -ErrorAction SilentlyContinue | Out-Null + Write-LogHybrid "Installing NuGet provider (min 2.8.5.201)..." Info Bootstrap -LogToEvent - # ─── Trust PSGallery if not already ─── - $gallery = Get-PSRepository -Name PSGallery -ErrorAction SilentlyContinue - if ($gallery -and $gallery.InstallationPolicy -ne 'Trusted') { - try { - Set-PSRepository -Name PSGallery -InstallationPolicy Trusted -ErrorAction Stop - Write-LogHybrid "PSGallery marked as Trusted" Info Bootstrap -LogToEvent - } catch { - Write-LogHybrid "Failed to trust PSGallery: $($_.Exception.Message)" Warning Bootstrap -LogToEvent - } - } + # ForceBootstrap helps avoid interactive bootstrap prompts + Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 ` + -Force -ForceBootstrap -Confirm:$false ` + -Scope CurrentUser -ErrorAction Stop | Out-Null - # ─── Ensure NuGet is installed silently ─── - $nuget = Get-PackageProvider -Name NuGet -ListAvailable -ErrorAction SilentlyContinue - if (-not $nuget) { - try { - Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Confirm:$false -ErrorAction Stop - $nuget = Get-PackageProvider -Name NuGet -ListAvailable -ErrorAction SilentlyContinue - Write-LogHybrid "Installed NuGet provider v$($nuget.Version)" Info Bootstrap -LogToEvent - } catch { - Write-LogHybrid "NuGet install failed: $($_.Exception.Message)" Error Bootstrap -LogToEvent - } - } else { - Write-LogHybrid "NuGet provider already present (v$($nuget.Version))" Info Bootstrap -LogToEvent - } + $existing = Get-PackageProvider -Name NuGet -ListAvailable -ErrorAction SilentlyContinue | + Sort-Object Version -Descending | Select-Object -First 1 + } - # ─── Final import check ─── - try { - Import-PackageProvider -Name NuGet -Force -ErrorAction Stop | Out-Null - } catch { - Write-LogHybrid "NuGet provider import failed: $($_.Exception.Message)" Error Bootstrap -LogToEvent - } + if ($existing) { + Import-PackageProvider -Name NuGet -Force -ErrorAction Stop | Out-Null + Write-LogHybrid "NuGet provider ready (v$($existing.Version))" Success Bootstrap -LogToEvent + } else { + throw "NuGet provider still not available after install attempt." + } + } + catch { + Write-LogHybrid "NuGet provider install/import failed: $($_.Exception.Message)" Error Bootstrap -LogToEvent + throw + } - #endregion — guarantee NuGet provider is present without prompting - } \ No newline at end of file + # 2) Now it is safe to update / install modules without NuGet prompts + try { + Import-Module PackageManagement -Force -ErrorAction SilentlyContinue | Out-Null + Import-Module PowerShellGet -Force -ErrorAction SilentlyContinue | Out-Null + + $pkgMgmtVersion = (Get-Module PackageManagement -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1).Version + if ($pkgMgmtVersion -and $pkgMgmtVersion -lt [Version]'1.3.1') { + Install-Module PackageManagement -Force -AllowClobber -Confirm:$false -ErrorAction Stop + Write-LogHybrid "Updated PackageManagement to latest version" Info Bootstrap -LogToEvent + } + + if (-not (Get-Module PowerShellGet -ListAvailable)) { + Install-Module PowerShellGet -Force -AllowClobber -Confirm:$false -ErrorAction Stop + Write-LogHybrid "Installed PowerShellGet module" Info Bootstrap -LogToEvent + } + + # Trust PSGallery (optional, but common) + $gallery = Get-PSRepository -Name PSGallery -ErrorAction SilentlyContinue + if ($gallery -and $gallery.InstallationPolicy -ne 'Trusted') { + Set-PSRepository -Name PSGallery -InstallationPolicy Trusted -ErrorAction Stop + Write-LogHybrid "PSGallery marked as Trusted" Info Bootstrap -LogToEvent + } + } + catch { + Write-LogHybrid "PackageManagement/PowerShellGet setup failed: $($_.Exception.Message)" Warning Bootstrap -LogToEvent + # You can choose to throw here if you want hard-fail behavior + } +}