VMware Cloud Community
virtualhobbit
Enthusiast
Enthusiast
Jump to solution

Struggling with random string

I'm struggling to create some users in PowerShell for a VMware Horizon environment.

The user accounts aren't the problem, rather the random string for passwords. I'm currently using this:

# Create the array

$accounts = @()

# Create the users

1..10 | Foreach-Object {

  # Calculate random character string for the password

  $randomStr = -join ((38..47) + (48..57) + (65..90) + (97..122) | Get-Random -Count 8 | % {[char]$_})

  # Create the account with password

  New-ADUser -Name "user$_" -AccountPassword (ConvertTo-SecureString $randomStr -AsPlaintext -Force) -Enabled:$true

  # Add to the array

  $accounts += "user$_",$randomStr

}

However the script often fails as it sometimes doesn't choose a non-alphanumic character from the (38..47) range.

Anyone any ideas why it's not always selecting a character from each selection?

Many thanks,

-Mark

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

I f*#$d up when adapting the function.

This should do a better job.

Function New-Password {

    param(

        [int]$Size = 8,

        [char[]]$CharSets = "ULNS",

        [char[]]$Exclude

    )


    $Chars = @()


    $TokenSets = @{

            U = 97..122 | %{[char]$_}                                          #Lower case

            L = 65..90 | %{[char]$_}                                           #Upper case

            N = 48..57 | %{[char]$_}                                           #Numerals

            S = 38..47 | %{[char]$_}                                           #Symbols

    }


    $CharSets | ForEach-Object -Process {

        $Tokens = $TokenSets."$_" | ForEach-Object -Process {

            If ($Exclude -cNotContains $_) {$_}

        }

        If ($Tokens) {

            $TokensSet += $Tokens

            If ($_ -cle [Char]"Z") {$Chars += $Tokens | Get-Random}             #Character sets defined in upper case are mandatory

        }

    }

    While ($Chars.Count -lt $Size) {

        $Chars += $TokensSet | Get-Random

    }

    ($Chars | Sort-Object {Get-Random}) -Join ''                                #Mix the (mandatory) characters and output string

}

1..10 | %{

    New-Password -Size 8 -CharSets Suln

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
4 Replies
LucD
Leadership
Leadership
Jump to solution

You are presenting an array of chars to the Get-Random cmdlet and ask the cmdlet to pick 'randomly' 8 characters.

Since the selection is random, it can randomly pick none of the non-alphanumeric ones.

The following function, which is not mine but comes from StackOverflow by user iRon, has a solution for that issue.

Somewhat adapted, it looks like this.
In the call example, it uses the uppercase S, which will guarantee at least 1 character from the Symbols.

Function New-Password {

    param(

        [int]$Size = 8,

        [char[]]$CharSets = "ULNS",

        [char[]]$Exclude

    )


    $Chars = @()

    $TokenSet = @()


    If (!$TokenSets) {

        $Global:TokenSets = @{

            U = [char]97..[char]122                                            #Upper case

            L = [char]65..[char]90                                               #Lower case

            N = [char]48..[char]57                                              #Numerals

            S = [char]38..[char]47                                              #Symbols

        }

    }


    $CharSets | ForEach-Object -Process {

        $Tokens = $TokenSets."$_" | ForEach-Object -Process {

            If ($Exclude -cNotContains $_) {$_}

        }

        If ($Tokens) {

            $TokensSet += $Tokens

            If ($_ -cle [Char]"Z") {$Chars += $Tokens | Get-Random}             #Character sets defined in upper case are mandatory

        }

    }

    While ($Chars.Count -lt $Size) {

        $Chars += $TokensSet | Get-Random

    }

    ($Chars | Sort-Object {Get-Random}) -Join ''                                #Mix the (mandatory) characters and output string

}


1..10 | %{

    New-Password -Size 8 -CharSets Suln

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

virtualhobbit
Enthusiast
Enthusiast
Jump to solution

Thanks Luc.

Um, I must be doing something seriously wrong. When I run it, I get a tring of eighteen numbers back:

Screenshot 2020-05-20 at 14.48.14.png

(sorry for the screenshot - the code is running in a secure environment and gettign code back out isn't possible).

What am I messing up?

-Mark

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I f*#$d up when adapting the function.

This should do a better job.

Function New-Password {

    param(

        [int]$Size = 8,

        [char[]]$CharSets = "ULNS",

        [char[]]$Exclude

    )


    $Chars = @()


    $TokenSets = @{

            U = 97..122 | %{[char]$_}                                          #Lower case

            L = 65..90 | %{[char]$_}                                           #Upper case

            N = 48..57 | %{[char]$_}                                           #Numerals

            S = 38..47 | %{[char]$_}                                           #Symbols

    }


    $CharSets | ForEach-Object -Process {

        $Tokens = $TokenSets."$_" | ForEach-Object -Process {

            If ($Exclude -cNotContains $_) {$_}

        }

        If ($Tokens) {

            $TokensSet += $Tokens

            If ($_ -cle [Char]"Z") {$Chars += $Tokens | Get-Random}             #Character sets defined in upper case are mandatory

        }

    }

    While ($Chars.Count -lt $Size) {

        $Chars += $TokensSet | Get-Random

    }

    ($Chars | Sort-Object {Get-Random}) -Join ''                                #Mix the (mandatory) characters and output string

}

1..10 | %{

    New-Password -Size 8 -CharSets Suln

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
virtualhobbit
Enthusiast
Enthusiast
Jump to solution

Works like a charm!

Thanks Luc!

0 Kudos