PowerShell Password Generator
Generate cryptographically secure passwords from the command line using PowerShell's access to .NET's RandomNumberGenerator class.
The Secure Way
PowerShell has full access to the .NET class library, so the same RandomNumberGenerator used in C# is available directly in a script:
function New-SecurePassword {
param(
[int]$Length = 20,
[switch]$NoSymbols
)
$upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
$lower = 'abcdefghijklmnopqrstuvwxyz'
$digits = '0123456789'
$symbols = '!@#$%^&*()-_=+[]{}'
$pools = @($upper, $lower, $digits)
if (-not $NoSymbols) { $pools += $symbols }
$fullPool = -join $pools
function Get-SecureIndex([int]$Max) {
[System.Security.Cryptography.RandomNumberGenerator]::GetInt32($Max)
}
$chars = New-Object System.Collections.Generic.List[char]
foreach ($pool in $pools) {
$chars.Add($pool[(Get-SecureIndex $pool.Length)])
}
while ($chars.Count -lt $Length) {
$chars.Add($fullPool[(Get-SecureIndex $fullPool.Length)])
}
# Fisher-Yates shuffle using the same secure source
for ($i = $chars.Count - 1; $i -gt 0; $i--) {
$j = Get-SecureIndex ($i + 1)
$tmp = $chars[$i]; $chars[$i] = $chars[$j]; $chars[$j] = $tmp
}
-join $chars
}
New-SecurePassword -Length 20
# e.g. k7$Rt2Xz!mQ9wLp#4vNc
The Weaker Way
Get-Random for passwords. It is well-distributed and fine for general scripting, but it is not documented by Microsoft as cryptographically secure โ the underlying PRNG's suitability for security purposes is not guaranteed.
# NOT RECOMMENDED for passwords โ Get-Random is not documented as cryptographically secure
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
-join (1..16 | ForEach-Object { $chars[(Get-Random -Maximum $chars.Length)] })
Applying a Generated Password to a Windows Account
To use a generated password with account-management cmdlets, convert it to a SecureString first โ and avoid printing the plaintext value to the console afterward:
$plain = New-SecurePassword -Length 20
$secure = ConvertTo-SecureString -String $plain -AsPlainText -Force
Set-LocalUser -Name "ServiceAccount" -Password $secure
# Clear the plaintext variable when done
Remove-Variable plain
Common Mistakes
- Relying on
Get-Randomfor production credential generation โ fine for test data or non-security scripting, not for real passwords. - Leaving the plaintext password in
$Error, transcript logs, or PowerShell history (Get-History) โ disable transcription or clear history when scripting credential generation. - Writing the password to a plain text file "temporarily" for handoff โ use a secure channel (a password manager's share feature, or an encrypted vault) instead.
Frequently Asked Questions
Get-Random is well-distributed for general scripting but is not documented as cryptographically secure. For passwords, use .NET's RandomNumberGenerator class, accessible directly from any PowerShell session.
Yes โ it relies only on the cross-platform System.Security.Cryptography.RandomNumberGenerator class, so it runs identically on Windows PowerShell 5.1 and PowerShell 7+ on Windows, macOS, or Linux.
Convert the plaintext string to a SecureString with ConvertTo-SecureString -AsPlainText -Force, then pass it to Set-LocalUser -Password or the equivalent Active Directory cmdlet, as shown above.
Prefer not to write the script?
Generate a strong password instantly in your browser.
Use the Password Generator โ