Public/Install-OriAzBopPrerequisiteForce.ps1

<#
.SYNOPSIS
    Install modules required from PSGallery when force is needed
.DESCRIPTION
    Install modules required from PSGallery when force is needed
 
.PARAMETER Name
    Specifies the exact names of modules to install from the online gallery. The module name must match the module name in the repository.
     
.PARAMETER RequiredVersion
    Specifies the exact version of a single module to install.
.EXAMPLE
    Install-OriAzBopPrerequisiteForce
#>

function Install-OriAzBopPrerequisiteForce {
  [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingInvokeExpression', '', Justification = "There's required use the recomanded code.")]
  [CmdLetBinding()]
  param ()
  $ErrorActionPreference = 'Stop'
  Write-Verbose -Message ("[ START: {0}:{1} (v.{2}) ]" -f $Local:MyInvocation.MyCommand.Source, $Local:MyInvocation.MyCommand.Name, $Local:MyInvocation.MyCommand.Version)
  foreach ($arg in $PSBoundParameters.GetEnumerator()) {
    if ([string]::IsNullOrEmpty($arg.Value)) {
      Write-Debug -Message ("[null] {0}: {1}" -f $arg.Key, $arg.Value) -ErrorAction SilentlyContinue 
    }
    else {
      Write-Debug -Message ("[{2}] {0}: {1}" -f $arg.Key, $arg.Value, $arg.Value.GetType().Name) -ErrorAction SilentlyContinue 
    }
  }

  # Fix credential provider
  Invoke-WebRequest -Uri "https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.ps1" -UseBasicParsing | Invoke-Expression | Out-Null


  $InstalledPackageManagement = Get-Module -Name PackageManagement -ListAvailable | Sort-Object -Property Version -Descending | Select-Object -First 1
  $InstalledPowershellGet = Get-Module -Name PowershellGet -ListAvailable | Sort-Object -Property Version -Descending | Select-Object -First 1
    
  if ([string]::IsNullOrEmpty($InstalledPackageManagement) -or [string]::IsNullOrEmpty($InstalledPowershellGet)) {
    Write-Error "Some version of Powershell module PackageManagement and PowershellGet is required. In this case please copy these modules manually."
  }
    
  if ($InstalledPackageManagement.Version -lt [Version]::new(1, 4, 6) -or $InstalledPowershellGet.Version -lt [Version]::new(2, 2, 3)) {
    Write-Debug "Upgrade of PackageManagement and PowershellGet is required"  
      
    # New-TemporaryDirectory
    $parent = [System.IO.Path]::GetTempPath()
    [string] $name = [System.Guid]::NewGuid()
    $tempDir = (Join-Path $parent $name)
    Write-Debug "Temp path $tempDir "
    New-Item -ItemType Directory -Path $tempDir | Out-null
      
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
      
    # Some kind of PowershellGet should be installed for import.
    Import-Module -Name PowerShellGet -RequiredVersion $InstalledPowershellGet.Version 
      
    # The trick in case of issues is in the download modules as packages in new directory
    Save-Package -Name PackageManagement -RequiredVersion 1.4.6 -Path $tempDir -ProviderName PowerShellGet
    Save-Package -Name PowershellGet -RequiredVersion 2.2.3 -Path $tempDir -ProviderName PowerShellGet
      
    # Extract path to current PackageManagemet
    if (![string]::IsNullOrEmpty($InstalledPackageManagement) -and ![string]::IsNullOrEmpty($InstalledPackageManagement.Version) -and ![string]::IsNullOrEmpty($InstalledPackageManagement.Path)) {
      $VersionDir = Split-Path -Path $InstalledPackageManagement.Path -Parent
      $ModuleDir = Split-Path -Path $VersionDir -Parent
      Move-Item -Path "$tempDir\PackageManagement\*" -Destination $ModuleDir
    }
      
    if (![string]::IsNullOrEmpty($InstalledPowershellGet) -and ![string]::IsNullOrEmpty($InstalledPowershellGet.Version) -and ![string]::IsNullOrEmpty($InstalledPowershellGet.Path)) {
      $VersionDir = Split-Path -Path $InstalledPowershellGet.Path -Parent
      $ModuleDir = Split-Path -Path $VersionDir -Parent
      Move-Item -Path "$tempDir\PowershellGet\*" -Destination $ModuleDir
    }
      
  }  

  Write-Verbose -Message ("[ END: {0} ]" -f $Local:MyInvocation.MyCommand.Name)
}