Unexpected new lines in output during do..until loop

I found a snippet of code on the internet that creates a random string (passwords in my case). Thanks to Scripting Guy (or Dr. Scripto).

So I started with this:
-join ((33..33) + (35..38) + (40..47) + (58..64) + (48..57) + (65..90) + (97..122) + (97..122) | Get-Random -Count $length | ForEach-Object {[char]$_})

Then modified the character set to avoid single and double quotes and wrapped it in a do … until loop to require at least two digits. Like so:
Do { $c = 0; -join ((33..33) + (35..38) + (40..47) + (58..64) + (48..57) + (65..90) + (97..122) + (97..122) | Get-Random -Count 16 | ForEach-Object { [char]$_ ; if ([char]$_ -match "\d") { $c++ } }) } until ( $c -gt 1 )

Which works fine but then I tried to hide the invalid entries like this:
Do { $c = 0; $pw = ""; -join ((33..33) + (35..38) + (40..47) + (58..64) + (48..57) + (65..90) + (97..122) + (97..122) | Get-Random -Count 16 | ForEach-Object { $pw += [char]$_ ; if ([char]$_ -match "\d") { $c++ } }) } until ( $c -gt 1 ) $pw

Which is functional but outputs a blank line for each suppressed entry. This question is mostly about learning but I would like to know where the extra lines are coming from and get your suggestions of different possible solutions.

Jay,
Welcome to the forum. :wave:t4:

I think you’re overcompicating this. You may start with something like this:

$length = 12
-join (
(0..9),
('a'..'z'),
('A'..'Z'),
('+','-','!','?','@') | 
    Get-Random -Count $length 
)

I think that’s way easier to read and to understand. You simply join all numbers and letters you want to have in your pool and then you pick a number of them randomly.

Of course you can go way more fancy with it if you want. :wink:

I appreciate your response but I also need to require at least two digits, avoid single and double quotes and I’m currently trying to “hide” words without two digits. My post was to try and understand the extra line feeds in my current code.

Thanks from:
Jay

The code I posted is just a suggestion. You are allowed to use it as an inspiration for you own needs. :wink:

The usual password complexity rules include at least 3 of 4 character classes which are letters, capitals, numbers and special characters. But of course you can adjust it to whatever rules you apply. If you require two digits you use:

0..9 | Get-Random -Count 2

and add the result to the rest of the characters you collected. In the end you could use Get-Random -Shuffle to mix up the order.

BTW: most of the security specialists agree nowadays that the length of a password is much more importatnt than its complexity. :point_up_2:t4:

If that’s your phone number at the end of your post you should remove it. :wink:

I did re: remove the phone number thanks.

I don’t think you’re understanding what I’m trying to do re: two digits. I need to generate password that have at least two digits and don’t use single or double quotes. The code I have at the end works find for that but my question is why does the output have extra blank lines in it equal to the number of discarded passwords randomly generated.

I don’t think you understood what I was trying to show - there are other ways to achieve what you want.

If the condition “at least 2 digits” is the only condition you care about the following snippet would be enough:

Do { 
    $pw = 
        -join (
            ('a'..'z'), ('A'..'Z'), (0..9), '+','-','!','?','@','#','$','%' |
                Get-Random -Count 16
        )
}
until ( $pw -match '\d\D*\d' ) $pw

You don’t need to hide invalid entries when you don’t create some in the first place.

1 Like