Public/New-PstModule.ps1

function New-PstModule {
    <#
.SYNOPSIS
    Creates a new PowerShell module from a template zip file.
.DESCRIPTION
    This function unpacks a zip file containing a base module template, renames the `.psm1` and `.psd1` template files
    according to the module name (derived from the leaf of the Path parameter), and performs error handling.
.PARAMETER Path
    (Optional) The destination path where the new module will be created. Defaults to the current directory.
.EXAMPLE
    New-PstModule -Path "C:\Modules\MyNewModule"
    This example creates a new module named `MyNewModule` in the `C:\Modules` directory.
.NOTES
    This function is useful for quickly generating new PowerShell modules based on a standardized template.
.LINK
    No links available.
#>

    [CmdletBinding(SupportsShouldProcess)]
    param (
        [Parameter(Mandatory = $false, Position = 0, HelpMessage = "The destination path where the new module will be created.")]
        [string]$Path = (Get-Location)
    )
    begin {
        Write-Debug -Message "Begin '$($MyInvocation.MyCommand.Name)' at '$(Get-Date)'"
        Write-Verbose -Message "Path: '$($Path)'"
        # Check if Path is empty
        if (-not $Path) {
            throw "Path cannot be empty."
        }
        # Check if the Path is not empty (contains any files or folders)
        if (Test-Path -Path $Path) {
            $existingItems = Get-ChildItem -Path $Path
            if ($existingItems.Count -gt 0) {
                throw "The path '$Path' is not empty. Please choose an empty directory."
            }
        }
        # Get the leaf name of the Path, which will be the new module name
        $ModuleName = Split-Path -Path $Path -Leaf
        Write-Verbose -Message "ModuleName: '$($ModuleName)'"
        # Use the predefined file path from the $Samples hashtable
        if (-not $Samples.ContainsKey("Module.zip")) {
            throw "The file 'Module.zip' was not found in the Samples hashtable."
        }
        $ZipFilePath = $Samples["Module.zip"]
        Write-Verbose -Message "ZipFilePath: '$($ZipFilePath)'"
        $result = @{}
    }
    process {
        try {
            Write-Information -Message "Unpacking zip file to '$($Path)'"
            # Ensure the destination path exists
            if (-not (Test-Path -Path $Path)) {
                New-Item -Path $Path -ItemType Directory -Force | Out-Null
            }
            # Extract the contents of the zip file to the destination path
            Expand-Archive -Path $ZipFilePath -DestinationPath $Path -Force
            # Get the .psm1 file from the extracted contents
            $Psm1File = Get-ChildItem -Path $Path -Filter "*.psm1" | Select-Object -First 1
            if ($Psm1File) {
                # Rename the .psm1 file to match the module name
                $NewPsm1Name = "$Path\$ModuleName.psm1"
                Rename-Item -Path $Psm1File.FullName -NewName $NewPsm1Name -Force
                Write-Information -Message "Renamed .psm1 file to '$NewPsm1Name'"
            } else {
                throw "No .psm1 file found in the extracted template."
            }
            # Get the .psd1 file from the extracted contents
            $Psd1File = Get-ChildItem -Path $Path -Filter "*.psd1" | Select-Object -First 1
            if ($Psd1File) {
                # Rename the .psd1 file to match the module name
                $NewPsd1Name = "$Path\$ModuleName.psd1"
                Rename-Item -Path $Psd1File.FullName -NewName $NewPsd1Name -Force
                Write-Information -Message "Renamed .psd1 file to '$NewPsd1Name'"
            } else {
                Write-Warning -Message "No .psd1 file found in the extracted template."
            }
            Write-Output $result
        }
        catch {
            Write-Error -Message "An error occurred: $($_.Exception.Message)"
        }
    }
    end {
        if ($?) {
            Write-Debug -Message "End '$($MyInvocation.MyCommand.Name)' at '$(Get-Date)'"
            Write-Information -Message "Module '$ModuleName' created successfully at '$Path'."
        }
    }
}