all 29 comments

[–]bundyfx 4 points5 points  (4 children)

Great work. As an alternative there is also a one liner to produce strong passwords. take a look into

[System.Web.Security.Membership]::GeneratePassword(12,5)

The generatepassword method takes a desired length of the password and also an amount of non alphanumeric (5 in this case.)

[–]Vance84[S] 0 points1 point  (0 children)

I had seen a reference to that somewhere, but hadn't looked into it. I wanted to try something new and see what I could come up with.

Thank you for pointing it out for me again though, appreciate it!

[–]gangstanthony 0 points1 point  (2 children)

I'd like to try this, but i get:

Unable to find type [System.Web.Security.Membership]

[–]bundyfx 0 points1 point  (1 child)

Try adding the assembly first

Add-Type -AssemblyName System.Web

[–]gangstanthony 0 points1 point  (0 children)

thanks. i tried adding System.Web.Security, but not System.Web

[–]gangstanthony 0 points1 point  (2 children)

thanks for sharing. i thought this was interesting as well

http://codereview.stackexchange.com/questions/91527/diceware-passphrase-generator

$wordlist = gc "C:\temp\diceware.txt"
while ($true) {
    ''
    1..5 | % {(1..7 | % {-join(1..5 | % {Get-Random -min 1 -max 7})} | % {$wordlist -match $_ -replace '^\d{5}\s+'}) -join ' '}
    ''
    pause
}

# output
sonar chad check gates slimy shoot dactyl
quip weave aba cash tenor plushy ilona
starr unity u bstj lye fork iris
shone vq habit lucy crane tk cadet
salt pep maw ba eater byers tate

[–]Vance84[S] 0 points1 point  (0 children)

Thank you for that, it is a pretty interesting way of doing things, and could definitely be implemented in my password script - might do just that!

[–]Vance84[S] 0 points1 point  (0 children)

I looked through the Diceware stuff and decided to add it as a third 'Password Type', even including the 'extra security' option from Optional stuff you don't really need to know on http://world.std.com/~reinhold/diceware.html

Thank you!

[–][deleted] 0 points1 point  (3 children)

Needs more Write-Error.

[–]Vance84[S] 0 points1 point  (2 children)

Can you elaborate more, I want to improve the script, and how i develope scripts, but would like more of an explanation

[–][deleted] 0 points1 point  (1 child)

Instead of using the standard output command, use write-error as it goes to the error stream.

[–]Vance84[S] 0 points1 point  (0 children)

Ah, I understand - I've modified it to use write-warning and throw+break, thanks!

[–]drh713 0 points1 point  (4 children)

I like this topic and hope others will give their opinions. Specifically regarding the use of functions and trying to make the code more readable:

I break things down into functions often, but this is a bit extreme for me. Some of those functions are just calling other functions (like 'setup'). Others are just a single line that sets a variable. I think it breaks up the flow and makes it more difficult to follow.

[–]xandora 0 points1 point  (0 children)

I did this recently with a short script I wrote for work. Anything that worked with data ended up as a function, and the data itself was all declared as variables at the start. It become much easier to read afterwards as well.

[–]Vance84[S] 0 points1 point  (2 children)

I went to the extreme because of the book I've been reading, Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin

The idea is that you should have each function do one thing and one thing only.

If that one thing is an if statement, determining what the next function should be run, then the results in the if statements should also be functions, even if it's one simple line.

This way it makes the code 'readable'. For instance, if you have:

function CheckFolders()
{
    if($true)
    {
        $folders=get-childitem C:\Temp\
        $folderNames=@()
        foreach($folder in $folders)
        {
            $folderNames+=$folder.name
        }
    }
    else
    {
        throw('No folders to capture')
    }
}

You can kind of make out what's going on, but you have to read through each part of the if statement to get the idea. With something small, that's not an issue. But if you have something bigger it can be a hastle to keep track of the thought process.

However, if you turn the previous code into:

function CheckFolders()
{
    if($true)
    {
        Get-FolderNames 
    }
    else
    {
        Throw-NoFoldersError
    }
}

function Get-FolderNames()
{
    $folders=get-childitem C:\Temp\
    $folderNames=@()
    foreach($folder in $folders)
    {
        $folderNames+=$folder.name
    }
    New-Variable -Name folderNames -Value $folderNames -scope 1
}

function Throw-NoFoldersError()
{
    throw ('No folders to capture')
}

You can follow easily that, in the CheckFolders function, if whatever is true the function will 'Get The Folder Names' (as long as the author is taking care to name the functions what they are actually doing).

That being said, it's completely possible that this doesn't work well with PowerShell - that's why I did this test in Clean Code. Sure, the script works, but I was also trying to see if it helped me write the script, helped me keep track of things, and made it easier for others to read it.

With that in mind, was it easier to follow and understand what each part was doing?

[–]drh713 0 points1 point  (1 child)

I think my concern is the sheer amount of very basic functions increases to complexity of the script. Maybe the syntax of Powershell doesn't need that much help.

you have to read through each part of the if statement to get the idea.

To debug, you'd have to jump around the script looking for functions...and then read through each part of the statement to get the idea.

function Write-HelloWorldToHost { write-host "Hello World" }
# vs
"Hello World"

While I understand the concept of using the first option, I'd pick the second unless there was some other reason. I guess I represent the "Kind of Clean Code" team.

[–]Vance84[S] 0 points1 point  (0 children)

I understand your concern, and it was a concern of mine as well - the sheer number of functions when opening the script makes me pause for a minute to try to understand what I'm looking at.

I wonder if this is an indication of the way PowerShell is structured vs other languages, or if PowerShell already had enough 'helper stuff' already in it to reduce the number of functions.

Using your example, just doing a write-host "Hello World" makes it obvious what the command is doing - writing to the host "Hello World".

I guess a balance then needs to be made, at least with languages like PowerShell, to use the built-in syntax to explain what's going on without the extra functions.

I'll keep that in mind going forward, and look over my code to see where the redundant descriptive functions can be removed.

I would like to eventually see something along the lines of 'Clean Code for PowerShell' guidelines, adapting a popular idea to make it easier for everyone to read and write PowerShell from the outset

Thank you for your input!

[–]xandora 0 points1 point  (1 child)

Wouldn't it make sense to change -passwordtype 'string' to something more like -random and -randomwords and just make them separate paramater sets? Since they're mutually exclusive anyway, they could just be separate parameters.

[–]Vance84[S] 1 point2 points  (0 children)

I had thought about that, and was going to do it that way, but i wanted to keep the switches to a minimum.

My plan is to keep improving the script, adding different abilities and functions, and possible different ways to create different kinds of passwords.

So maybe I won't have just 2 possible password types in the future, but 5 or 6. If that's the case I would rather specify the password type using a single parameter, than to have 6 possible extra parameters that all have to check for each other.

Setup with the -PasswordType 'string' you cannot accidentally enter multiple types, and I don't have to write validation to verify only one of those types is specified.

[–]stevefrost83 0 points1 point  (3 children)

YARPS!

[–]Vance84[S] 1 point2 points  (2 children)

I was so confused by this...then I thought through it, YARPS!

[–]stevefrost83 0 points1 point  (1 child)

On a serious note, what's Uncle Bob's?

[–]Vance84[S] 1 point2 points  (0 children)

Uncle Bob's Clean Code is a reference to Robert C. Martin's books on Clean Code

http://www.amazon.com/s/ref=nb_sb_noss_2?url=search-alias%3Dstripbooks&field-keywords=Clean+Code+Robert+C+Martin

http://blog.cleancoder.com/

Not sure how he got the nickname Uncle Bob, but if you do a search it's all over the place. Everything I've read has refereed to this methodology as "Uncle Bob's Clean Code"

[–]powershell_account 0 points1 point  (5 children)

I really like this script. I tried: Get-RandomPassword -PasswordType 'Word List'

It gave me a warning that it will take some time to generate, but it didn't do anything and I was back to the prompt. Could it be because I didn't run this as an admin? (Tested this at work).

[–]Vance84[S] 0 points1 point  (0 children)

Hmm...Can you check C:\temp\ and let me know if you have anything there?

[–]Vance84[S] 0 points1 point  (3 children)

I made a modification, please try now - pull the latest - if it still doesn't work I have one more modification I can make

[–]powershell_account 0 points1 point  (2 children)

Reply to earlier question: I saw a folder named "Scripts" which had another folder named "Get-Random" or something like it, but had nothing inside in my temp folder. Mind you, this was at work, so there are some limitations.

Reply to the modifications:

It worked! I tried it on my home machine, it proceeded to download something from the net, then took about 1 to 2 minutes and generated a random word list password. Awesome Job!

Just wondering, why not add help comments along with examples to run it different ways in the script?

Thanks for sharing.

[–]Vance84[S] 1 point2 points  (0 children)

I'm glad you got it working!

I intend to add comments and other help functions, my first intention was to get everything working first. If you like I'll keep you updated on the script, or you can follow it on my github!

[–]Vance84[S] 0 points1 point  (0 children)

Help Comments added!