Raona.SPPowerShell.psm1

#Requires -Version 7.0

<#
.SYNOPSIS
    SharePoint PowerShell Module.

.DESCRIPTION
    Provides reusable functions for SharePoint Online
    and Microsoft Entra ID administration.

.NOTES
    Requires PnP.PowerShell.
    Public functions are stored in the Public directory.
    Private functions are stored in the Private directory.
#>


Set-StrictMode -Version Latest

# --------------------------------------------------
# Validate dependencies
# --------------------------------------------------

$requiredModules = @(
    @{
        Name           = 'PnP.PowerShell'
        MinimumVersion = '3.2.0'
    }
)

foreach ($requiredModule in $requiredModules) {

    $installedModule = Get-Module `
        -ListAvailable `
        -Name $requiredModule.Name |
    Where-Object {
        $_.Version -ge [version]$requiredModule.MinimumVersion
    } |
    Sort-Object -Property Version -Descending |
    Select-Object -First 1

    if (-not $installedModule) {
        throw @"
The required PowerShell module '$($requiredModule.Name)' is not installed
or its installed version is lower than $($requiredModule.MinimumVersion).

Install it by running:

    Install-Module PnP.PowerShell -Scope CurrentUser

Then import this module again.
"@

    }

    Import-Module $installedModule.Path -ErrorAction Stop
}

# --------------------------------------------------
# Define module directories
# --------------------------------------------------

$publicPath = Join-Path -Path $PSScriptRoot -ChildPath 'Public'
$privatePath = Join-Path -Path $PSScriptRoot -ChildPath 'Private'

# --------------------------------------------------
# Load private functions
# --------------------------------------------------

if (Test-Path -Path $privatePath -PathType Container) {

    $privateFunctions = Get-ChildItem `
        -Path $privatePath `
        -Filter '*.ps1' `
        -File `
        -Recurse |
    Sort-Object -Property FullName

    foreach ($file in $privateFunctions) {
        try {
            . $file.FullName
        }
        catch {
            throw "Failed to load private function file '$($file.FullName)': $($_.Exception.Message)"
        }
    }
}

# --------------------------------------------------
# Load public functions
# --------------------------------------------------

if (-not (Test-Path -Path $publicPath -PathType Container)) {
    throw "The Public directory was not found: '$publicPath'."
}

$publicFunctions = Get-ChildItem `
    -Path $publicPath `
    -Filter '*.ps1' `
    -File `
    -Recurse |
Sort-Object -Property FullName

foreach ($file in $publicFunctions) {
    try {
        . $file.FullName
    }
    catch {
        throw "Failed to load public function file '$($file.FullName)': $($_.Exception.Message)"
    }
}

# --------------------------------------------------
# Export public functions
# --------------------------------------------------

$functionsToExport = @(
    $publicFunctions |
    ForEach-Object { $_.BaseName } |
    Sort-Object -Unique
)

Export-ModuleMember -Function $functionsToExport

# --------------------------------------------------
# Clean up temporary variables
# --------------------------------------------------

Remove-Variable -Name requiredModules -ErrorAction SilentlyContinue
Remove-Variable -Name requiredModule -ErrorAction SilentlyContinue
Remove-Variable -Name installedModule -ErrorAction SilentlyContinue
Remove-Variable -Name publicPath -ErrorAction SilentlyContinue
Remove-Variable -Name privatePath -ErrorAction SilentlyContinue
Remove-Variable -Name publicFunctions -ErrorAction SilentlyContinue
Remove-Variable -Name privateFunctions -ErrorAction SilentlyContinue
Remove-Variable -Name functionsToExport -ErrorAction SilentlyContinue