Entrinsec.Powershell.SETUP.psm1

#Requires -Version 7.0

$SetupVersion = '1.4.9'

# Function to install NuGet.exe
function Install-Nuget {

    # Check if nuget.exe can be launched and hide the output
    try {
        $null = nuget.exe help  # This command will run nuget.exe help and discard the output
        Write-Output "nuget.exe is accessible and can be launched."
    } catch {
        Write-Output "nuget.exe cannot be launched. Please check your PATH and the existence of nuget.exe."
    }

    # Set the installation directory
    $installDir = "C:\Program Files\Nuget"
    $nugetExePath = Join-Path -Path $installDir -ChildPath "nuget.exe"

    # Check if nuget.exe already exists in the installation directory
    if (Test-Path -Path $nugetExePath) {
        Write-Host "nuGet.exe exists at $nugetExePath"
        return  # Exit the function
    }

    # Create the installation directory if it doesn't exist
    if (!(Test-Path -Path $installDir)) {
        New-Item -ItemType Directory -Path $installDir -Force
    }

    # Downloading Nuget from the official website
    Write-Host "Installing NuGet from the official source..." -ForegroundColor Green

    # Download nuget.exe from the official website
    $nugetUrl = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
    Invoke-WebRequest -Uri $nugetUrl -OutFile $nugetExePath

    # Add the installation directory to the system PATH if it's not already present
    $pathEnv = [Environment]::GetEnvironmentVariable("PATH", "Machine")
    if (-not ($pathEnv -like "*$installDir*")) {
        $newPathEnv = $installDir + ";" + $pathEnv
        [Environment]::SetEnvironmentVariable("PATH", $newPathEnv, "Machine")
    }

    Write-Host "NuGet.exe installed successfully at $nugetExePath"
}
function Clear-NuGetCache {
    # Clears the NuGet cache.
  
    # Use the dotnet CLI to clear the cache.
    dotnet nuget locals all --clear
  
    # Write a message to the console indicating that the cache has been cleared.
    Write-Host "NuGet cache cleared."
}
function Add-EntrinsecNugetSource {

    # Set the module path (you might want to make this configurable)
    $modulePath = "C:\Program Files\PowerShell\Modules" 
    Set-Location -Path "$modulePath"

    # Source name and URL
    $sourceName = "Entrinsec"
    $sourceUrl = "https://nuget.entrinsec.com/v3/index.json"

    # Check if the source already exists and remove it
    $existingSource = nuget sources list | Select-String -Pattern $sourceName
    if ($existingSource) {
        nuget sources remove -Name $sourceName
    }

    # Add the Entrinsec NuGet source
    nuget sources add -Name $sourceName -Source $sourceUrl

    # List all NuGet sources
    nuget sources list
}

function Install-EntrinsecCORE {

    # $command = "nuget locals all -clear"
    # Write-Host "Clearing all NuGet caches..." -ForegroundColor Yellow
    # Invoke-Expression $command
    # Write-Host "NuGet caches cleared." -ForegroundColor Green

    Write-Host ""

    # Set the output directory for the modules
    $outputDir = "C:\Program Files\PowerShell\Modules"

    $modules = @(
    "Entrinsec.Powershell.Alerting",
    "Entrinsec.Powershell.Common",
    "Entrinsec.Powershell.Identity",
    "Entrinsec.Powershell.Logging"
    )
    
    # Define the output directory
    $outputDir = "C:\Program Files\PowerShell\Modules"

    # Install and import each module
    foreach ($module in $modules) {
        Write-Host ""
        Write-Host "Installing module $module..." -ForegroundColor Cyan
        & "C:\Program Files\Nuget\nuget.exe" install $module -Source "Entrinsec" -OutputDirectory $outputDir -ExcludeVersion
        Write-Host "Importing module $module..." -ForegroundColor White
        Import-Module "$outputDir\$module" -Force
        Write-Host ""
    }

    try {
        Write-Host ""
        Write-Host "Installing Entrinsec.Powershell.SETUP module from PSGallery..." -ForegroundColor Green
        Install-Module -Name Entrinsec.Powershell.SETUP -Repository PSGallery -AllowClobber -Force -ErrorAction SilentlyContinue -Scope AllUsers *>$null
        Import-Module Entrinsec.Powershell.SETUP -Force -ErrorAction SilentlyContinue *>$null
        Write-Host ""
    }
    catch {
    }
    
    # Enumerate the modules folder and import any module starting with Entrinsec.Powershell
    Get-ChildItem -Path $outputDir -Directory | ForEach-Object {
        if ($_.Name -like "Entrinsec.Powershell*") {
            Import-Module $_.FullName
        }
    }

    # Run a test with Show-ToastNotification
    # Show-ToastNotification -Title "Entrinsec Powershell" -Information "You have successfully installed the Core Entrinsec Powershell modules!"
}

function Install-EntrinsecEVERYTHING {

    # $command = "nuget locals all -clear"
    # Write-Host "Clearing all NuGet caches..." -ForegroundColor Yellow
    # Invoke-Expression $command
    # Write-Host "NuGet caches cleared." -ForegroundColor Green
    
    Write-Host ""

    # Set the output directory for the modules
    $outputDir = "C:\Program Files\PowerShell\Modules"

    # Define the list of modules
    $modules = @(
    "Entrinsec.Powershell.ADO",
    "Entrinsec.Powershell.Alerting",
    "Entrinsec.Powershell.Common",
    "Entrinsec.Powershell.Containers",
    "Entrinsec.Powershell.Dialogs",
    "Entrinsec.Powershell.Data",
    "Entrinsec.Powershell.Directories",
    "Entrinsec.Powershell.Email",
    "Entrinsec.Powershell.Endpoint.Diagnostics",
    "Entrinsec.Powershell.Endpoint.Management",
    "Entrinsec.Powershell.FileSystem",
    "Entrinsec.Powershell.Forensics",
    "Entrinsec.Powershell.Gaming",
    "Entrinsec.Powershell.Geography",
    "Entrinsec.Powershell.GIT",
    "Entrinsec.Powershell.Identity",
    "Entrinsec.Powershell.Logging",
    "Entrinsec.Powershell.Networking",
    "Entrinsec.Powershell.Registry",
    "Entrinsec.Powershell.SCCM",
    "Entrinsec.Powershell.Scheduling",
    "Entrinsec.Powershell.Software.Management",
    "Entrinsec.Powershell.SQL"
    )

    # Define the output directory
    $outputDir = "C:\Program Files\PowerShell\Modules"

    # Install and import each module
    foreach ($module in $modules) {
        Write-Host ""
        Write-Host "Installing module $module..." -ForegroundColor Cyan
        & "C:\Program Files\Nuget\nuget.exe" install $module -Source "Entrinsec" -OutputDirectory $outputDir -ExcludeVersion
        Write-Host "Importing module $module..." -ForegroundColor White
        Import-Module "$outputDir\$module" -Force
        Write-Host ""
    }

    try {
        Write-Host ""
        Write-Host "Installing Entrinsec.Powershell.SETUP module from PSGallery..." -ForegroundColor Green
        Install-Module -Name Entrinsec.Powershell.SETUP -Repository PSGallery -AllowClobber -Force -ErrorAction SilentlyContinue -Scope AllUsers *>$null
        Import-Module Entrinsec.Powershell.SETUP -Force -ErrorAction SilentlyContinue *>$null        
        Write-Host ""
    }
    catch {
    }

    # Enumerate the modules folder and import any module starting with Entrinsec.Powershell
    Get-ChildItem -Path $outputDir -Directory | ForEach-Object {
        if ($_.Name -like "Entrinsec.Powershell*") {
            Import-Module $_.FullName
        }
    }

    # Run a test with Show-ToastNotification
    # Show-ToastNotification -Title "Entrinsec Powershell" -Information "You have successfully installed all currently available Entrinsec Powershell modules!"
}

function Initialize-EntrinsecNuget {
    
    <#
    .SYNOPSIS
        Sets up the Entrinsec PowerShell environment by installing NuGet,
        adding the Entrinsec NuGet source, and installing Entrinsec modules.
 
    .DESCRIPTION
        This function performs the following steps:
            1. Installs NuGet.exe if it's not already present.
            2. Adds the Entrinsec NuGet source.
            3. Installs core Entrinsec modules.
 
    .PARAMETER CORE
        Indicates whether to install core Entrinsec modules. Default is $true.
 
    .PARAMETER EVERYTHING
        Indicates whether to install all Entrinsec modules. Default is $false.
 
    .EXAMPLE
        PS> Initialize-EntrinsecNuget -CORE $true -EVERYTHING $false
 
    .NOTES
        Author: Entrinsec
        Date: 2024-11-19
        Version: 1.0
        Run as an administrator.
    #>


    param (
        [switch]$CORE = $false,
        [switch]$EVERYTHING = $false
    )

    # Check if the user is an administrator
    if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
        Write-Host "You need to run this script as an administrator." -ForegroundColor Red
        return
    }

    Clear-Host

    Write-Host "Setting up the Entrinsec PowerShell environment..." -ForegroundColor Cyan
    Write-Host "(Setup version : $SetupVersion)" -ForegroundColor Cyan
    Write-Host ""

    Install-Nuget

    Write-Host ""

    # Adding the Entrinsec NuGet source
    Write-Host "Adding the Entrinsec NuGet source..." -ForegroundColor Green
    Add-EntrinsecNugetSource

    Write-Host ""

    # Cleaning up previous Entrinsec modules
    Remove-EntrinsecModules

    # Installing core Entrinsec modules as an example and a starting point
    if ($CORE) {
        Write-Host ""
        Write-Host "Installing core Entrinsec modules..." -ForegroundColor Green
        Install-EntrinsecCORE
        Write-Host ""
    } elseif ($EVERYTHING) {
        Write-Host ""
        Write-Host "Installing all Entrinsec modules..." -ForegroundColor Green
        Install-EntrinsecEVERYTHING
        Write-Host ""
    } else {
        Write-Host ""
        Write-Host "Installing core Entrinsec modules..." -ForegroundColor Green
        Install-EntrinsecCORE
        Write-Host ""
    }

    Write-Host ""
    Write-Host "Entrinsec PowerShell environment setup completed." -ForegroundColor Green
    Write-Host "It is recommended that you close any existing Powershell sessions to apply changes." -ForegroundColor Green
    Write-Host ""
}

function Remove-EntrinsecModules {
    param (
        [switch]$Test
    )

    Write-Host "Cleanup of Entrinsec modules, folders, and references..." -ForegroundColor Green
    Write-Host "Removing all Entrinsec modules, folders, and references from the local machine..." -ForegroundColor Yellow

    # Get all installed modules
    $modules = Get-Module -ListAvailable | Where-Object { $_.Name -like "Entrinsec.Powershell.*" }

    # Uninstall each module or perform a WhatIf
    foreach ($module in $modules) {
        if ($Test) {
            Uninstall-Module -Name $module.Name -Force -AllVersions -WhatIf -ErrorAction SilentlyContinue
        } else {
            Write-Host "Uninstalling $($module.Name)..." -ForegroundColor Yellow
            Uninstall-Module -Name $module.Name -Force -AllVersions -ErrorAction SilentlyContinue
        }
    }

    # Remove cached and memory-resident modules
    $loadedModules = Get-Module | Where-Object { $_.Name -like "Entrinsec.Powershell.*" }
    foreach ($loadedModule in $loadedModules | Where-Object { $_.Name -ne "Entrinsec.Powershell.SETUP" }) {
        if ($Test) {
            Write-Host "Would remove loaded module $($loadedModule.Name)" -ForegroundColor Yellow
        } else {
            Write-Host "Removing loaded module $($loadedModule.Name)..." -ForegroundColor Yellow
            Remove-Module -Name $loadedModule.Name -Force -ErrorAction SilentlyContinue
        }
    }

    # Define paths to check
    $paths = @(
        "C:\Program Files\PowerShell\Modules",
        "C:\Program Files\PowerShell\Modules",
        "$env:USERPROFILE\Documents\WindowsPowerShell\Modules",
        "$env:ProgramFiles\WindowsPowerShell\Modules",
        "$env:ProgramFiles(x86)\WindowsPowerShell\Modules"
    )

    # Remove corresponding folders or perform a WhatIf
    foreach ($path in $paths) {
        if (Test-Path -Path $path) {
            if ($Test) {
                Get-ChildItem -Path $path -Directory |
                Where-Object { $_.Name -like "Entrinsec.Powershell.*" } |
                Remove-Item -Recurse -Force -WhatIf -ErrorAction SilentlyContinue
            } else {
                Write-Host "Removing all Entrinsec modules from folder $($path)..." -ForegroundColor Yellow
                Get-ChildItem -Path $path -Directory |
                Where-Object { $_.Name -like "Entrinsec.Powershell.*" } |
                Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
            }
        }
    }

    Write-Host "All Entrinsec.Powershell.* modules, folders, and references have been processed on the local machine." -ForegroundColor Yellow
}