Public/New-PstFunction.ps1

function New-PstFunction {
    <#
.SYNOPSIS
    Creates a new PowerShell function from a base template.
.DESCRIPTION
    This function takes an approved verb and noun, copies a function template, and renames the file and function block to the specified verb-noun combination.
.PARAMETER Verb
    (Required) The approved verb for the function name.
.PARAMETER Noun
    (Required) The noun for the function name.
.EXAMPLE
    New-FunctionFromTemplate -Verb Get -Noun Item
    This example creates a new function file named Get-Item.ps1 with the function name Get-Item.
.NOTES
    Ensure that the template file function.ps1 exists in the same directory as this script.
.LINK
    For more information on approved verbs, visit: https://docs.microsoft.com/en-us/powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands
#>

    [CmdletBinding(SupportsShouldProcess)]
    param (
        [Parameter(Mandatory = $true, Position = 0,
            HelpMessage = "The approved verb for the function name.")]
        [ValidateSet("Add", "Approve", "Assert", "Backup", "Block", "Checkpoint", "Clear", "Close", "Compare", "Complete", "Compress", "Confirm", "Connect", "Convert", "ConvertFrom", "ConvertTo", "Copy", "Debug", "Deny", "Disable", "Disconnect", "Dismount", "Edit", "Enable", "Enter", "Exit", "Expand", "Export", "Find", "Format", "Get", "Grant", "Group", "Hide", "Import", "Initialize", "Install", "Invoke", "Join", "Limit", "Lock", "Measure", "Merge", "Mount", "Move", "New", "Open", "Optimize", "Out", "Ping", "Pop", "Protect", "Publish", "Push", "Read", "Receive", "Redo", "Register", "Remove", "Rename", "Repair", "Request", "Reset", "Resize", "Resolve", "Restart", "Restore", "Resume", "Revoke", "Save", "Search", "Select", "Send", "Set", "Show", "Skip", "Split", "Start", "Step", "Stop", "Submit", "Suspend", "Switch", "Sync", "Test", "Trace", "Unblock", "Undo", "Uninstall", "Unlock", "Unprotect", "Unpublish", "Unregister", "Update", "Use", "Wait", "Watch", "Write")]
        [string]$Verb,
        [Parameter(Mandatory = $true, Position = 1,
            HelpMessage = "The noun for the function name.")]
        [ValidatePattern('^[A-Za-z][A-Za-z0-9]*$')]
        [string]$Noun,
        [Parameter(Mandatory = $false)]
        [switch]$Force
    )
    begin {
        Write-Debug -Message "Begin '$($MyInvocation.MyCommand.Name)' at '$(Get-Date)'"
        $templatePath = $Samples["Function.ps1"]
        $newFunctionName = "$Verb-$Noun"
        $newFilePath = "$newFunctionName.ps1"
        if (-not (Test-Path $templatePath)) {
            throw "Template file not found: $templatePath"
        } else {
            Write-Verbose "Template file found: $templatePath"
        }
    }
    process {
        try {
            # Check if we're in automation mode - inline check to avoid scope issues
            $isAutomationMode = $Force -or
            ($Global:PstAutomationMode -eq $true) -or
            ($env:CI -eq 'true') -or
            ($env:GITHUB_ACTIONS -eq 'true') -or
            ($Host.Name -eq 'ServerRemoteHost') -or
            (-not [Environment]::UserInteractive) -or
            ($global:ConfirmPreference -eq 'None')
            # Check if file already exists
            if ((Test-Path $newFilePath) -and -not $isAutomationMode) {
                if (-not $PSCmdlet.ShouldProcess($newFilePath, "Overwrite existing function file")) {
                    Write-Warning "Operation cancelled by user."
                    return
                }
            }
            elseif ((Test-Path $newFilePath) -and $isAutomationMode -and -not $Force) {
                Write-Warning "File '$newFilePath' already exists. Use -Force to overwrite in automation mode."
                return
            }
            # Proceed with file creation - skip ShouldProcess in automation mode
            if ($isAutomationMode -or $PSCmdlet.ShouldProcess($newFilePath, "Create new function file")) {
                Write-Verbose "Getting file content from '$($templatePath)'"
                $templateContent = Get-Content -Path $templatePath -Raw
                Write-Verbose "Replacing '""Function Verb-Noun"" with ""Function $($newFunctionName)""' "
                $newContent = $templateContent -replace "Function Verb-Noun", "Function $newFunctionName"
                Write-Verbose "Set-Content to path '$($newFilePath)'"
                $newContent | Set-Content -Path $newFilePath
                Write-Output "New function file created: $newFilePath"
            }
            else {
                Write-Verbose "Operation cancelled or skipped."
            }
        }
        catch {
            if ($_.Exception -and $_.Exception.Message) {
                Write-Error "An error occurred: $($_.Exception.Message)"
            } else {
                Write-Error "An error occurred, but no additional information is available."
            }
        }
    }
    end {
        if ($?) {
            Write-Debug -Message "End '$($MyInvocation.MyCommand.Name)' at '$(Get-Date)'"
        }
    }
}