Private/Install-ModuleForWindows.ps1

function Install-ModuleForwindows {
    param (
        [string]$Name,
        [string]$Version,
        [string]$Scope,
        [string]$BucketName,
        [string]$BucketRegion,
        [string]$ObjectKey
    )

    # The command is ran inside another PowerShell core process to avoid issues with the current process
    # More specifically the AWS PowerShell module needed to install the module might not be compatible
    # with the requirements of the module we are trying to install.
    pwsh -Command {
        try {
            $WarningPreference = "SilentlyContinue"
            $ProgressPreference = "SilentlyContinue"

            # Access the passed in arguments
            $receivedBucketName = $args[0]
            $receivedBucketRegion = $args[1]
            $receivedObjectKey = $args[2]
            $receivedModuleName = $args[3]
            $receivedModuleVersion = $args[4]
            $receivedScope = $args[5]

            # Check if the module is already installed
            if (Get-Module -Name $receivedModuleName -ListAvailable) {
                # Check if the candidate version is already installed
                if (Get-Module -Name $receivedModuleName -ListAvailable | Where-Object { $_.Version -eq $receivedModuleVersion }) {
                    # If the module version is already installed, skip the installation
                    Write-Host "Module $($receivedModuleName) version $($receivedModuleVersion) is already installed."
                    Write-Host "No action required."
                    exit 0
                }
            }

            Write-Host "Installing $($receivedModuleName) version $($receivedModuleVersion)..."

            # Download the module from S3
            Write-Host "Downloading $($receivedModuleName) version $($receivedModuleVersion) from S3 object $($receivedObjectKey) in bucket $($receivedBucketName)."
            $tempFile = Read-S3Object -BucketName $receivedBucketName -Region $receivedBucketRegion -Key $receivedObjectKey -File ([System.IO.Path]::GetTempFileName())

            if (-not (Test-Path -Path $tempFile.FullName)) {
                throw "Failed to download $($Name) version $($Version) from S3 object $($ObjectKey) in bucket $($BucketName)."
            }
            
            $tempPath = [System.IO.Path]::GetTempPath()
            Expand-Archive -Path $tempFile.FullName -DestinationPath $tempPath -Force

            # Get the path to the module version
            $tempModuleVersionPath = Join-Path -Path $tempPath -ChildPath $receivedModuleName
            $newTempModuleVersionPath = Join-Path -Path $tempPath -ChildPath $receivedModuleVersion

            # Rename the folder to the module version so dtx.cloud.management > 0.6.1
            if (Test-Path -Path $newTempModuleVersionPath) {
                Remove-Item -Path $newTempModuleVersionPath -Recurse -Force
            }
            Rename-Item -Path $tempModuleVersionPath -NewName $newTempModuleVersionPath -Force
            
            switch ($receivedScope) {
                "CurrentUser" { $modulePath = Join-Path -Path $HOME -ChildPath "Documents" -AdditionalChildPath "PowerShell", "Modules", $receivedModuleName }
                "AllUsers" { $modulePath = Join-Path -Path $env:ProgramFiles -ChildPath "PowerShell" -AdditionalChildPath "Modules", $receivedModuleName }
            }

            $modulePathInclVersion = Join-Path -Path $modulePath -ChildPath $receivedModuleVersion

            # Check if the module exist
            if (Test-Path -Path $modulePath) {
                # Check if the module version is already installed
                Write-Host "Checking if $($modulePathInclVersion) exists..."
                if (Test-Path -Path $modulePathInclVersion) {
                    # If we reached this point, we do not expect the version dir for this module to exist.
                    # We need to remove it before proceeding
                    Remove-Item -Path $modulePathInclVersion -Recurse -Force
                }
            }
            else {
                # If the module doesn't exist, create its path
                Write-Host "Creating $($modulePath)..."
                [void]$(New-Item -ItemType Directory -Path $modulePath -Force)
            }

            # Move the module to the modules folder
            Write-Host "Installing $receivedModuleName version $receivedModuleVersion to $modulePath"
            
            Move-Item -Path $newTempModuleVersionPath -Destination $modulePath -Force

            Write-Host "Module installed successfully."
        }
        catch {
            Write-Error $_.Exception.Message
            exit 1 
        }
    } -Args $BucketName, $BucketRegion, $ObjectKey, $Name, $Version, $Scope

    if ($LASTEXITCODE -ne 0) {
        Write-Error $_.Exception.Message
        throw "Failed to install module."
    }
}