Common/Utils-Module.psm1

Import-Module "$PSScriptRoot\WebAdministration-Module.psm1" -Force
$ErrorActionPreference = "Stop"

function RestartPowerShell {
    Write-Warning "SAF did a change which requires a PowerShell restart. Restarting after 5 seconds..."
    Start-Sleep -s 5
    Clear-Host
    & "$env:WINDIR\system32\windowspowershell\v1.0\powershell.exe" -NonInteractive -NoProfile -NoExit -File "$PSScriptRoot\RestartPowerShell.ps1" -SAFCommand $global:RunningCommand
}

function RefreshEnvironment {
    $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User") 
    refreshenv
}

function DownloadAndUnzip {
    [CmdletBinding()]
    Param(
        [string]$ToolName,
        [string]$DownloadFullPath,
        [string]$DownloadURL,
        [string]$TargetDir
    )

    if (Test-Path -Path $TargetDir) {
        if (Test-Path -Path $DownloadFullPath) {
            Remove-Item $DownloadFullPath -Recurse -Force | Out-Null
        }

        Write-Output "Downloading $ToolName..."
        Start-BitsTransfer -Source $DownloadURL -Destination $DownloadFullPath
    
        Write-Output "Extracting $ToolName to $TargetDir..."
        Expand-Archive $DownloadFullPath -DestinationPath $TargetDir -Force
    }
    else {
        Write-Error "'$TargetDir' does not exist..."
    }
}

function DeleteServices {
    [CmdletBinding()]
    Param
    (
        [string[]]$Services
    )

    Write-Output "Deleting existing services..."

    try {
        taskkill /F /IM mmc.exe
    }
    catch {}

    foreach ($service in $Services) {
        if (Get-Service $service -ErrorAction SilentlyContinue) {
            Write-Output "Stopping '$service' service..."
            nssm stop $service
            Write-Output "Deleting '$service' service..."
            nssm remove $service confirm
        }
        else {
            Write-Warning "Service '$service' not found..."
        }
    }

    Write-Output "Deleting existing services done."
}

function RemoveOldPSModuleVersions {
    [CmdletBinding()]
    Param
    (
        [string]$Name
    )

    $latestModule = Get-InstalledModule $Name -ErrorAction SilentlyContinue
    $allModuleVersions = Get-InstalledModule $Name -AllVersions -ErrorAction SilentlyContinue
    foreach ($module in $allModuleVersions) {
        if ($module.version -ne $latestModule.version) {
            $module | Uninstall-Module -Force
            Write-Output "$($module.Name) $($module.Version) has been removed because a newer version is already installed."
        }
    }
}

function LoadLatestPSModule {
    [CmdletBinding()]
    Param
    (
        [string]$Name
    )

    if (Get-Module $Name -ListAvailable) {
        Write-Output "$Name module is installed. Checking for updates..."
        $currentModule = Import-Module $Name -PassThru
        $onlineModule = Find-Module $Name
        if ($onlineModule.version -gt $currentModule.version) {
            Write-Output "Update is available. Updating from $($currentModule.version) to $($onlineModule.version)..."
            if (!(Test-Path -Path "$($currentModule.ModuleBase)\PSGetModuleInfo.xml")) {
                Install-Module $Name -AllowClobber -Force
                RemoveOldPSModuleVersions -Name $Name
                RestartPowerShell
            }
            else {
                Update-Module $Name
                RemoveOldPSModuleVersions -Name $Name
            }
        }
        else {
            Write-Output "No updates found..."
        }
    }
    else {
        Write-Output "$Name module is not installed. Installing..."
        Install-Module $Name -AllowClobber -Force
    }

    Get-Module $Name | Remove-Module -Force
    Import-Module $Name
}

Export-ModuleMember -Function "DeleteServices"
Export-ModuleMember -Function "DownloadAndUnzip"
Export-ModuleMember -Function "RefreshEnvironment"
Export-ModuleMember -Function "LoadLatestPSModule"
Export-ModuleMember -Function "RestartPowerShell"