Private/_New-RandomPassword.ps1

function _New-RandomPassword {
    <#
    .SYNOPSIS
        Generates a random complex password as a SecureString.
    #>

    [CmdletBinding()]
    [OutputType([securestring])]
    param(
        [int]$Length = 16
    )

    $uppercase  = 'ABCDEFGHJKLMNPQRSTUVWXYZ'
    $lowercase  = 'abcdefghjkmnpqrstuvwxyz'
    $digits     = '23456789'
    $special    = '!@#$%&*?'

    # Ensure at least one of each category
    $password  = $uppercase[(Get-Random -Maximum $uppercase.Length)]
    $password += $lowercase[(Get-Random -Maximum $lowercase.Length)]
    $password += $digits[(Get-Random -Maximum $digits.Length)]
    $password += $special[(Get-Random -Maximum $special.Length)]

    # Fill remaining length from all characters
    $allChars = $uppercase + $lowercase + $digits + $special
    for ($i = $password.Length; $i -lt $Length; $i++) {
        $password += $allChars[(Get-Random -Maximum $allChars.Length)]
    }

    # Shuffle
    $password = -join ($password.ToCharArray() | Get-Random -Count $password.Length)

    ConvertTo-SecureString -String $password -AsPlainText -Force
}