Functions/Authentication/New-StrongPassword.ps1

Function New-StrongPassword
    {
    [CmdletBinding()]
    Param
        (
        # Length of Password to Create
        [Parameter(Mandatory=$false)]
        [ValidateRange(1,128)]
        [Int]
        $Length = 64,

        # Number of NonAlphaNumeric Characters
        [Parameter(Mandatory=$false)]
        [int]
        $NonAlpha,

        # Specific Characters to Omit
        [String[]]
        $RejectChars
        )

    Process
        {
        # Add Assembly
        Add-Type -AssemblyName System.Web
        
        # Define count of Non Alpha Characters
        if (!$NonAlpha){$NonAlpha = [Math]::Floor($Length/3)}

        # Generate Pass
        $PWCheck = $false
        while (!$PWCheck)
            {
            $PW = [System.Web.Security.Membership]::GeneratePassword($Length,$NonAlpha)

            # Remove Bad Punctuation Characters
            $PreRejectChars = '(',')','{','}','[',']','>','<','_','/','.',';',':','|','.','^','-'
            foreach ($PreRejectChar in $PreRejectChars)
                {
                Switch -Wildcard ($PreRejectChar)
                    {
                    {$_ -eq '['}
                        {
                        $Search = "``["
                        $Replace = "\["
                        }
                    {$_ -in '(',')','{','}','.','|','^','-'}
                        {
                        $Search = $PreRejectChar
                        $Replace = [regex]::Escape($PreRejectChar)
                        }
                    Default
                        {
                        $Search = [regex]::Escape($PreRejectChar)
                        $Replace = [regex]::Escape($PreRejectChar)
                        }
                    }

                while ($PW -clike "*$Search*")
                        {
                        $NewCharClear = $false
                        while (!$NewCharClear)
                            {
                            $NewChar = (65..90) + (97..122) | Get-Random -Count 1 | % {[char]$_}
                            if ($NewChar -cnotin $PreRejectChars){$NewCharClear = $true}
                            #else {write-host "$newchar was in PreRejected Character Set" -ForegroundColor Cyan}
                            }
                        $PW = $PW -creplace $Replace,$NewChar
                        #write-host "Adjusted $PreRejectChar to $NewChar" -ForegroundColor Magenta
                        }
                }

            # Remove Other Manually Selected Values
            $Check = $true
            foreach($RejectChar in $RejectChars)
                {
                if ($Check)
                    {
                    while ($PW -clike "*$RejectChar*")
                        {
                        $NewCharClear = $false
                        while (!$NewCharClear)
                            {
                            $NewChar = (65..90) + (97..122) | Get-Random -Count 1 | % {[char]$_}
                            if ($NewChar -cnotin $RejectChars){$NewCharClear = $true}
                            else {write-host "$newchar was in Rejected Character Set" -ForegroundColor Cyan}
                            }
                        
                        $PW = $PW -replace $RejectChar,$NewChar
                        #write-host "Adjusted $RejectChar to $NewChar" -ForegroundColor Yellow
                        }
                    }
                }
            if ($Check)
                {
                $PWCheck = $true
                #write-host "PW `" $PW `" is clear of Reject Chars" -ForegroundColor Green
                }
            }
        
        # Output Pass
        $PW
        }
    }