My New-ComplexPassword PowerShell function allows you to generate complex passwords of custom length. Optionally, you can add one or several special characters to the passwords.
Latest posts by Graham Beer (see all)

I was working on a project recently that involved adding and moving users to Office 365. They wanted a way to generate and pass a list of random complex passwords for many new users to the admin team. They also required the ability to capture the user and password so they had a record in case the user required these details from first-line support. By using PowerShell, I came up with the New-ComplexPassword function.

I came across the .NET namespace System.Web.Security. Under this namespace is the Membership class. The MSDN documentation states this class "Validates user credentials and manages user settings." I used the GeneratePassword method in the function. This method takes two parameters to generate a random password, requiring the specified length and the number of special characters to use.

I'll describe the two parameters below (taken from MSDN):

length

Type: System.Int32

> The number of characters in the generated password. The length must be between 1 and 128 characters.

numberOfNonAlphanumericCharacters

Type: System.Int32

> The minimum number of non-alphanumeric characters (such as @, #, !, %, &, and so on) in the generated password.

Now that I know how I'm going generate the passwords, let's focus on how I built the function.

I created the function with two parameter sets. A parameter set gives a single cmdlet the ability to perform different actions for different scenarios. The two tasks I wanted to perform with this function were creating a single ad-hoc password and passing a list of usernames from the pipeline.

This is how I constructed the first part:

    [Cmdletbinding(DefaultParameterSetName='Single')]
        Param(
        [Parameter(ParameterSetName='Single')]
        [Parameter(ParameterSetName='Multiple')]
        [Int]
        $PasswordLength,
        
        [Parameter(ParameterSetName='Single')]
        [Parameter(ParameterSetName='Multiple')]
        [int]
        $SpecialCharCount,

        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='Multiple')]
        [String[]]
        $GenerateUserPW
        )

The main two parameters take an integer, and the last parameter, which is in the 'multiple' parameter set, takes an array of strings.

Using the Syntax switch and the Get-Command cmdlet on the function shows the two parameter sets:

Get-Command New-ComplexPassword -Syntax
New ComplexPassword syntax

New ComplexPassword syntax

The Begin block of the function loads the System.Web assembly so we can use the Membership class:

    Begin {   
        # The System.Web namespaces contain types that enable browser/server communication
        Add-Type -AssemblyName System.Web 
    }

The process block uses one of PowerShell's automatic variables, $PsCmdlet, in our switch statement. PowerShell's help system states this "Contains an object that represents the cmdlet or advanced function that is being run." We are using the ParameterSetName property, which gives us the name of the parameter set we're using. (To learn more about PowerShell automatic variables, read the help on about_Automatic_Variables.)

The switch gives us an either-or instance. This is where we'll use the System.Web.Security.Membership class. The static method described earlier takes two parameters. From the function, we pass our two parameters: password length and the special character count. This will generate our password.

Process {
        switch ($PsCmdlet.ParameterSetName) {
            'Single' {
                # GeneratePassword static method: Generates a random password of the specified length
                [System.Web.Security.Membership]::GeneratePassword($PasswordLength, $SpecialCharCount)
            }
            'Multiple' {
                $GenerateUserPW | Foreach {
                    # Custom Object to display results
                    New-Object -TypeName PSObject -Property @{
                        User = $_
                        Password = [System.Web.Security.Membership]::GeneratePassword($PasswordLength, $SpecialCharCount)
                   }
                }
            }
        } # End of Switch
    }

The multiple part of the switch uses a foreach loop to parse each object to a custom object that will output the name with an assigned password.

Let's work with our function and see how we can use it.

Here is the function at its most basic level:

PS D:\> New-ComplexPassword -PasswordLength 16 -SpecialCharCount 1 %f.=vu%:hbANT)l

We can pass some users through the pipeline to the function, providing a password length of 10 characters and containing 2 special characters:

'John','Paul','George','Ringo' | New-ComplexPassword -PasswordLength 10 ‑SpecialCharCount 2
Generate passwords with usernames

Generate passwords with usernames

By using the range operator, I can generate many passwords quickly:

1..12 | New-ComplexPassword -PasswordLength 16 -SpecialCharCount 5
Piping a number range to the function

Piping a number range to the function

Finally, to show the flexibility of the function, I can pass and generate a text file with a list of passwords by typing the following:

(1..5 | New-ComplexPassword -PasswordLength 10 -SpecialCharCount 1).Password | 
Out-File c:\demo\Passwords.csv -Encoding utf8 -Force

This is a great example of using .NET classes with PowerShell to generate passwords quickly and efficiently.

And this is the function in full:

Subscribe to 4sysops newsletter!

Function New-ComplexPassword {
    <#
    .SYNOPSIS
    Password Generator
    
    .DESCRIPTION
    Password Generator tool to obtain any length and numbers of passwords, 
    adding desired number of special characters, quickly. 
    
    .PARAMETER PasswordLength
    Add a integer value for desired password length
    
    .PARAMETER SpecialCharCount
     Add a integer value for desired number of special characters
    
    .PARAMETER GenerateUserPW
    Enter as many named string or integer values 
    
    .EXAMPLE
    'John','Paul','George','Ringo' | New-ComplexPassword -PasswordLength 10 -SpecialCharCount 2

    1..5 | New-ComplexPassword -PasswordLength 16 -SpecialCharCount 5
    
    .NOTES
    By Graham Beer
    #>
    
    [Cmdletbinding(DefaultParameterSetName='Single')]
        Param(
        [Parameter(ParameterSetName='Single')]
        [Parameter(ParameterSetName='Multiple')]
        [Int]
        $PasswordLength,
        
        [Parameter(ParameterSetName='Single')]
        [Parameter(ParameterSetName='Multiple')]
        [int]
        $SpecialCharCount,

        [Parameter(ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ParameterSetName='Multiple')]
        [String[]]
        $GenerateUserPW
        )
    Begin {   
        # The System.Web namespaces contain types that enable browser/server communication
        Add-Type -AssemblyName System.Web 
    }
Process {
        switch ($PsCmdlet.ParameterSetName) {
            'Single' {
                # GeneratePassword static method: Generates a random password of the specified length
                [System.Web.Security.Membership]::GeneratePassword($PasswordLength, $SpecialCharCount)
            }
            'Multiple' {
                $GenerateUserPW | Foreach {
                    # Custom Object to display results
                    New-Object -TypeName PSObject -Property @{
                        User = $_
                        Password = [System.Web.Security.Membership]::GeneratePassword($PasswordLength, $SpecialCharCount)
                   }
                }
            }
        } # End of Switch
    }
    End {}
} # End of Function
avataravatar
1 Comment
  1. Tom 4 years ago

    Hi Graham, thanks for this post which I found useful.  I wanted to create complex passwords for use with O365 and which would be within the set restrictions, but I also wanted the passwords to be easier for my users to type in.  If you’re interested, I wrote about it here.

Leave a reply

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account