Functions/New-RandomPassword.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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<#
  .SYNOPSIS
  Create a random password
  
  .DESCRIPTION
  The function creates a random password using a given set of available characters.
  The password is generated with fixed or random length.
  
  .PARAMETER MinPasswordLength
  Minimum password length when generating a random length password
  
  .PARAMETER MaxPasswordLength
  Maximum password length when generating a random length password
  
  .PARAMETER PasswordLength
  Fixed password length
  
  .PARAMETER InputStrings
  String array containing sets of available password characters
  
  .PARAMETER FirstChar
  Specifies a string containing a character group from which the first character in the password will be generated
  
  .PARAMETER Count
  Number of passwords to generate, default = 1
  
  .EXAMPLE
  New-RandomPassword -MinPasswordLength 6 -MaxPasswordLength 12
  Generates a random password fo minimum length 6 andmaximum length 12 characters
  
  .EXAMPLE
  New-RandomPassword -PasswordLength 20
  Generates a password of 20 characters
  
  .EXAMPLE
  New-RandomPassword -InputStrings Value -FirstChar Value -Count Value
  Describe what this call does
  
  .NOTES
  Author of function: Thomas Stensitzki
  Stolen from: https://github.com/Apoc70/GlobalFunctions/blob/master/GlobalFunctions/GlobalFunctions.psm1
  Based on Simon Wahlin's script published here: https://gallery.technet.microsoft.com/scriptcenter/Generate-a-random-and-5c879ed5
  Story behind: http://blog.simonw.se/powershell-generating-random-password-for-active-directory/
 
#>

function New-RandomPassword {
    [CmdletBinding(DefaultParameterSetName='FixedLength')]
    [OutputType([String])] 
    param(
      [Parameter(ParameterSetName='RandomLength')]
      [ValidateScript({$_ -gt 0})]
      [Alias('Min')] 
      [int]$MinPasswordLength = 8,
            
      [Parameter(ParameterSetName='RandomLength')]
      [ValidateScript({
              if($_ -ge $MinPasswordLength){$true}
              else{Throw 'Max value cannot be lesser than min value.'}})]
      [Alias('Max')]
      [int]$MaxPasswordLength = 12,
    
      [Parameter(ParameterSetName='FixedLength')]
      [ValidateRange(1,2147483647)]
      [int]$PasswordLength = 8,
            
      [String[]]$InputStrings = @('abcdefghjkmnpqrstuvwxyz', 'ABCEFGHJKLMNPQRSTUVWXYZ', '23456789', '=+_?!"*@#%&'),
    
      [String] $FirstChar,
            
      # Specifies number of passwords to generate.
      [ValidateRange(1,2147483647)]
      [int]$Count = 1
    )
    
      Function Get-Seed{
                # Generate a seed for randomization
                $RandomBytes = New-Object -TypeName 'System.Byte[]' 4
                $Random = New-Object -TypeName 'System.Security.Cryptography.RNGCryptoServiceProvider'
                $Random.GetBytes($RandomBytes)
                [BitConverter]::ToUInt32($RandomBytes, 0)
            }
    
      For($iteration = 1;$iteration -le $Count; $iteration++){
        $Password = @{}
        # Create char arrays containing groups of possible chars
        [char[][]]$CharGroups = $InputStrings
    
        # Create char array containing all chars
        $AllChars = $CharGroups | ForEach-Object {[Char[]]$_}
    
        # Set password length
        if($PSCmdlet.ParameterSetName -eq 'RandomLength')
        {
            if($MinPasswordLength -eq $MaxPasswordLength) {
                # If password length is set, use set length
                $PasswordLength = $MinPasswordLength
            }
            else {
                # Otherwise randomize password length
                $PasswordLength = ((Get-Seed) % ($MaxPasswordLength + 1 - $MinPasswordLength)) + $MinPasswordLength
            }
        }
    
        # If FirstChar is defined, randomize first char in password from that string.
        if($PSBoundParameters.ContainsKey('FirstChar')){
            $Password.Add(0,$FirstChar[((Get-Seed) % $FirstChar.Length)])
        }
        # Randomize one char from each group
        Foreach($Group in $CharGroups) {
            if($Password.Count -lt $PasswordLength) {
                $Index = Get-Seed
                While ($Password.ContainsKey($Index)){
                    $Index = Get-Seed                        
                }
                $Password.Add($Index,$Group[((Get-Seed) % $Group.Count)])
            }
        }
    
        # Fill out with chars from $AllChars
        for($i=$Password.Count;$i -lt $PasswordLength;$i++) {
            $Index = Get-Seed
            While ($Password.ContainsKey($Index)){
                $Index = Get-Seed                        
            }
            $Password.Add($Index,$AllChars[((Get-Seed) % $AllChars.Count)])
        }
      }
    
      return $(-join ($Password.GetEnumerator() | Sort-Object -Property Name | Select-Object -ExpandProperty Value))
    
    }