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:

powershell
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

Avoid 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.
powershell โ€” avoid for passwords
# 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:

powershell
$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

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 โ†’

Related