forked from brianary/scripts
-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathNew-Password.ps1
85 lines (75 loc) · 3.29 KB
/
New-Password.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<#
.SYNOPSIS
Generate a new password.
.OUTPUTS
System.String containing a generated password, or
System.Security.SecureString containing a generated password if requested.
.LINK
Invoke-RestMethod
.LINK
https://duckduckgo.com/api
.EXAMPLE
New-Password.ps1 64
-pTs[_?B0S6uqqBquWfB%f*FWPO)X6AEt|>}(V&|%%A-n^OSw!Z9#G/3s=LL;(Uq
.EXAMPLE
New-Password.ps1 32 -InvalidMatch '[ \\@]'
Y]Mo*>V0KUB$*V*j2J%YHsOvp:Ui^{L;
.EXAMPLE
New-Password 12 -HasNumber -HasUpper -HasLower -HasSpecial
ecRAgbdX^9)=
#>
#Requires -Version 3
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText','',
Justification='This is a bootstrap problem, since the string must be created first.')]
[CmdletBinding()][OutputType([string])][OutputType([SecureString])] Param(
# The length of the password in characters.
[Parameter(Position=0,Mandatory=$true)][int] $Length,
# Characters to avoid in the new password.
[string] $ExcludeCharacters,
# The maximum number of times a character may be repeated consecutively.
[int] $MaxRepeats,
# A regular expression the password must match.
[regex] $ValidMatch,
# A regular expression the password must not match.
[regex] $InvalidMatch,
# Converts the password to a secure string.
[Alias('SecureString')][switch] $AsSecureString,
# The most attempts that should be made to generate an acceptable password before failing.
[int] $TryMaxTimes = 100,
# Indicates the password must contain a numeric character.
[switch] $HasNumber,
# Indicates the password must contain an uppercase letter.
[switch] $HasUpper,
# Indicates the password must contain a lowercase letter.
[switch] $HasLower,
# Indicates the password must contain a special character (something that isn't a letter or number).
[switch] $HasSpecial
)
$i = 0
while($true)
{
$i++
if($i -gt $TryMaxTimes)
{ Stop-ThrowError.ps1 "Failed to meet requirements after $TryMaxTimes tries." -OperationContext $PSBoundParameters }
Add-Type -AssemblyName System.Web
$value =
try {[Web.Security.Membership]::GeneratePassword($Length,3)}
catch
{
$a = Invoke-RestMethod "https://api.duckduckgo.com/?q=pwgen+strong+$Length&format=json"
[Web.HttpUtility]::HtmlDecode($a.Answer) -replace ' \(random password\)\z',''
}
if($ExcludeCharacters -and $value.IndexOfAny($ExcludeCharacters) -gt -1)
{Write-Verbose "Password #$i has invalid characters.; continue"}
if($MaxRepeats -gt 1 -and $value -match "(.)$('\1' * $MaxRepeats)")
{Write-Verbose "Password #$i has too many duplicate characters"; continue}
if($ValidMatch -and $value -notmatch $ValidMatch) {Write-Verbose "Password #$i not valid: $value"; continue}
if($InvalidMatch -and $value -match $InvalidMatch) {Write-Verbose "Password #$i invalid: $value"; continue}
if($HasNumber -and $value -notmatch '\d') {Write-Verbose "Password #$i missing number: $value"; continue}
if($HasUpper -and $value -cnotmatch '\p{Lu}') {Write-Verbose "Password #$i missing uppercase: $value"; continue}
if($HasLower -and $value -cnotmatch '\p{Ll}') {Write-Verbose "Password #$i missing lowercase: $value"; continue}
if($HasSpecial -and $value -inotmatch '[^0-9A-Z]') {Write-Verbose "Password #$i missing lowercase: $value"; continue}
break
}
if($AsSecureString) {ConvertTo-SecureString $value -AsPlainText -Force}
else {$value}