I admittedly took the code at face value and didn't scrutinize it too heavily. With an additional powershell window open, my code throws an error. Your recommendation resolves that. Thanks for the tip!.
On Mon, Feb 8, 2016 at 10:16 AM, Michael B. Smith <[email protected]> wrote: > Math is hard. > > > > But this is very cool! I like it a lot. > > > > Just one comment – your current PowerShell process id is always in $pid. > So: > > > > $PSWindow = ( Get-Process –pid $pid ) > > > > That allows you to have multiple PowerShell windows open at the same time > when using your script. > > > > *From:* [email protected] [mailto: > [email protected]] *On Behalf Of *Sean Martin > *Sent:* Monday, February 8, 2016 1:48 PM > > *To:* [email protected] > *Subject:* Re: [powershell] Random Password Generator > > > > FWIW, our Information Security Engineer requested the use of > RNGCryptoServiceProvider because Get-Random uses the system clock as the > default seed, so in his opinion, deriving the generated string would be > relatively trivial. In his explanation, the resulting Base64 string using > RNGCryptoServiceProvider is longer than 15 characters, but the entropy is > coming from the original 15 bytes, which should put cracking beyond > nation-state capabilities...possibly. In the end, we've opted for a > combination of both methods to ensure complexity requirements are met. > > > > ========== > > > > $randombytes = new-object byte[] 15 > (new-object > System.Security.Cryptography.RNGCryptoServiceProvider).GetBytes($randombytes) > $pass = [System.Convert]::ToBase64String($randombytes) > $a = ([char[]](get-random -input (33..47) -count 2)) -join "" > $b = ([char[]](get-random -input (48..57) -count 2)) -join "" > $password = $a + $pass + $b > > > > ========== > > > > As stated earlier, we use the above in an automated script that runs on a > routine basis to change passwords for disabled accounts. I used the same > technique to put together a quick random password generator for other use > cases. A handy little trick was incorporating an automatic copy to the > clipboard to make recording the password easier, and then emptying the > clipboard upon exit. Sticking with the "secure" theme, I wanted to prevent > the script from be stopped or exited prior to the clipboard being emptied, > so I incorporated the code from here: http://mymsworld.kahsky.com/?p=154 > to prevent the powershell window from being closed, and used Try/Finally > blocks to handle Ctrl+C input. > > > > ========== > > > > #Calling user32.dll methods for Windows and Menus > $MethodsCall = ' > [DllImport("user32.dll")] public static extern long GetSystemMenu(IntPtr > hWnd, bool bRevert); > [DllImport("user32.dll")] public static extern bool EnableMenuItem(long > hMenuItem, long wIDEnableItem, long wEnable); > [DllImport("user32.dll")] public static extern long SetWindowLongPtr(long > hWnd, long nIndex, long dwNewLong); > [DllImport("user32.dll")] public static extern bool EnableWindow(long > hWnd, int bEnable); > ' > > > > #Create a new namespace for the Methods to be able to call them > Add-Type -MemberDefinition $MethodsCall -name NativeMethods -namespace > Win32 > > > > #WM_SYSCOMMAND Message > $MF_GRAYED = 0x00000001L #Indicates that the menu item is disabled and > grayed so that it cannot be selected. > $MF_BYCOMMAND = 0x0 #Gives the identifier of the menu item. > If neither the MF_BYCOMMAND nor MF_BYPOSITION flag is specified, the > MF_BYCOMMAND flag is the default flag. > $MF_DISABLED = 0x00000002L #Indicates that the menu item is disabled, but > not grayed, so it cannot be selected. > $MF_ENABLED = 0x00000000L #Indicates that the menu item is enabled and > restored from a grayed state so that it can be selected. > #... > http://msdn.microsoft.com/en-us/library/windows/desktop/ms647636(v=vs.85).aspx > > > > $SC_CLOSE = 0xF060 > $SC_CONTEXTHELP = 0xF180 > $SC_MAXIMIZE = 0xF030 > $SC_MINIMIZE = 0xF020 > $SC_TASKLIST = 0xF130 > $SC_MOUSEMENU = 0xF090 > $SC_KEYMENU = 0xF100 > #... > http://msdn.microsoft.com/en-us/library/windows/desktop/ms646360(v=vs.85).aspx > > > > $GWL_EXSTYLE = -20 > $GWL_STYLE = -16 > #... > http://msdn.microsoft.com/en-us/library/windows/desktop/ms644898(v=vs.85).aspx > > > > #WM_SETICON Message - > http://msdn.microsoft.com/en-us/library/ms632643%28VS.85%29.aspx > $WM_SETICON = 0x0080; > $ICON_SMALL = 0; > $ICON_BIG = 1; > > > > #Extended Window Styles > $WS_EX_DLGMODALFRAME = 0x00000001L > $WS_EX_NOACTIVATE = 0x08000000L > $WS_EX_TOOLWINDOW = 0x00000080L > $WS_EX_STATICEDGE = 0x00020000L > $WS_EX_WINDOWEDGE = 0x00000100L > $WS_EX_TRANSPARENT = 0x00000020L > $WS_EX_CLIENTEDGE = 0x00000200L > $WS_EX_LAYERED = 0x00080000 > $WS_EX_TOPMOST = 0x00000008L > #... > http://msdn.microsoft.com/en-us/library/windows/desktop/ff700543(v=vs.85).aspx > > > > #Get window handle of Powershell process (Ensure there is only one > Powershell window opened) > $PSWindow = (Get-Process Powershell) | where {$_.MainWindowTitle -like > "*Powershell*"} > $hwnd = $PSWindow.MainWindowHandle > > > > #Get System menu of windows handled > $hMenu = [Win32.NativeMethods]::GetSystemMenu($hwnd, 0) > > > > #Window Style : TOOLWINDOW > [Win32.NativeMethods]::SetWindowLongPtr($hwnd, $GWL_EXSTYLE, > $WS_EX_TOOLWINDOW) | Out-Null > > > > #Disable X Button and window itself > [Win32.NativeMethods]::EnableMenuItem($hMenu, $SC_CLOSE, $MF_DISABLED) | > Out-Null > [Win32.NativeMethods]::EnableWindow($hwnd, 0) | Out-Null > > > > Try { > [Console]::TreatControlCAsInput = $True > > > > # Header Information > Write-Host "Random Password Generator" -ForeGroundColor Magenta > Write-Host "Created on: 2/3/2016" -ForeGroundColor Magenta > Write-Host "Author: Sean Martin" -ForeGroundColor Magenta > Write-Host "" > Write-Host "This script will generate a randomized 24 character > password that meets existing complexity requirements." -ForeGroundColor > Magenta > Write-Host > "---------------------------------------------------------------------------------------------------------" > -ForeGroundColor Yellow > > > > # Generate Random Password > $randombytes = new-object byte[] 15 > (new-object > System.Security.Cryptography.RNGCryptoServiceProvider).GetBytes($randombytes) > $pass = [System.Convert]::ToBase64String($randombytes) > $a = ([char[]](get-random -input (33..47) -count 2)) -join "" > $b = ([char[]](get-random -input (48..57) -count 2)) -join "" > $password = $a + $pass + $b > $password | clip > > > > # Display Password > Write-Host "" > Write-Host "Your password is: " -ForeGroundColor Cyan > Write-Host "" > Write-Host "$Password" -ForeGroundColor Yellow > Write-Host "" > Write-Host "The password has been automatically copied to the > clipboard for your convenience." > Write-Host "Please paste the password to a safe location as the > clipboard will be cleared upon exit." > Write-Host "" > Write-Host "The script exit automatically in 10 seconds" > -ForeGroundColor Cyan > Start-sleep 10 > > > > # Clear Clipboard > $null | clip > > > > } Finally { > [Console]::TreatControlCAsInput = $False > } > > > > #Enable X Button > [Win32.NativeMethods]::EnableMenuItem($hMenu, $SC_CLOSE, $MF_ENABLED) | > Out-Null > [Win32.NativeMethods]::EnableWindow($hwnd, 1) | Out-Null > > > > Exit > > > > ========== > > > > - Sean > > > > On Mon, Feb 8, 2016 at 7:25 AM, Sean Martin <[email protected]> > wrote: > > That is very cool. As much as I appreciate the mention, this is where I > came up with the concept: > > > > > https://gallery.technet.microsoft.com/scriptcenter/Simple-random-code-b2c9c9c9 > > > > - Sean > > > > On Fri, Feb 5, 2016 at 5:58 PM, Michael B. Smith <[email protected]> > wrote: > > Ok. Here is my final version, and I’ll probably blog about it. J Great > stuff. I love these kinds of conversations! > > > > -----start----- > > ## > > ## Create-Password > > ## > > ## February 5, 2016 > > ## michael at TheEssentialExchange dot com > > ## > > ## Based on an idea from Sean Martin > > ## seanmartin14 at gmail dot com > > ## > > > > Param( > > [int] $Length = 20, > > [bool] $AllPrintableAscii = $false > > ) > > > > function range > > { > > Param( > > [char] $start, > > [char] $finish > > ) > > > > [int]$start .. [int]$finish > > } > > > > ## ASCII table: > > ## > https://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters > > > > ## I intentionally exclude <space>, since if a space occurs > as the first > > ## or last character, most password input dialogs will trim > the <space>. > > > > $password = '' > > if( $AllPrintableAscii ) > > { > > $password = ( [char[]]( Get-Random > -InputObject ( 33..126 ) -Count 20 ) ) -Join '' > > } > > else > > { > > $validChars = ( range 'a' 'z' ) + > > ( range 'A' > 'Z' ) + > > ( range '0' > '9' ) + > > ( [char[]] > '!@#$%^&*()' ) > > > > $password = ( [char[]]( Get-Random > -InputObject $validChars -Count 20 ) ) -Join '' > > } > > > > $password > > -----end----- > > > > *From:* [email protected] [mailto: > [email protected]] *On Behalf Of *Michael B. Smith > *Sent:* Friday, February 5, 2016 9:31 PM > > > *To:* [email protected] > *Subject:* RE: [powershell] Random Password Generator > > > > Here is the medium easier-to-understand version: > > > > function range { param( [char]$start, [char]$finish ) [int]$start .. > [int]$finish } > > > > $validChars = ( range 'a' 'z' ) + ( range 'A' 'Z' ) + ( range '0' '9' ) + > ( [char[]] '!@#$%^&*()' ) > > > > ( [char[]]( Get-Random -InputObject $validChars -Count 20 ) ) -Join '' > > > > > > *From:* [email protected] [ > mailto:[email protected] <[email protected]>] *On > Behalf Of *Michael B. Smith > *Sent:* Friday, February 5, 2016 9:16 PM > *To:* [email protected] > *Subject:* RE: [powershell] Random Password Generator > > > > You can do that with this solution as well. > > > > Here is the long version: > > > > $upperCase = 65..90 > > $lowerCase = 97..122 > > $numbers = 48..57 > > $bang = , ( [char] '!' ) > > $splat = , ( [char] '@' ) > > $hash = , ( [char] '#' ) > > $dollar = , ( [char] '$' ) > > $percent = , ( [char] '%' ) > > $carat = , ( [char] '^' ) > > $amp = , ( [char] '&' ) > > $star = , ( [char] '*' ) > > $lparen = , ( [char] '(' ) > > $rparen = , ( [char] ')' ) > > > > $characters = $upperCase + $lowerCase + $numbers + $bang + $splat + $hash > + $dollar + $percent + $carat + $amp + $star + $lparen + $rparen > > > > ( [char[]]( Get-Random -InputObject $characters -Count 20 ) ) -Join '' > > > > Here is the short version: > > > > [char[]] $validChars = 65..90 + 97..122 + 48..57 + ( [char[]] '!@#$%^&*()' > ) > > ( [char[]]( Get-Random -InputObject $validChars -Count 20 ) ) -Join '' > > > > > > *From:* [email protected] [ > mailto:[email protected] <[email protected]>] *On > Behalf Of *Scott Crawford > *Sent:* Friday, February 5, 2016 8:31 PM > *To:* [email protected] > *Subject:* RE: [powershell] Random Password Generator > > > > That’s fantastic. > > > > This had been my solution and I do kinda like seeing the actual valid > characters cuz it makes it easy to edit out quotes or other possible > illegal values. But, it’s tough to beat the elegance of yours when valid > characters aren’t a concern. > > > > $Chars = > "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()" > > $Rand = New-Object System.Random > > For ($i = 1; $i -le 20; $i++) { > > $Password = $Password + $Chars.Substring($Rand.Next(0, > $Chars.Length), 1) > > } > > $Password > > > > *From:* [email protected] [ > mailto:[email protected] <[email protected]>] *On > Behalf Of *Michael B. Smith > *Sent:* Friday, February 5, 2016 7:07 PM > *To:* [email protected] > *Subject:* RE: [powershell] Random Password Generator > > > > Interestingly enough, you can take Get-Random and get an even better > random password. Take a look at this: > > > > ( [char[]]( Get-Random -Input ( 33..126 ) -Count 20 ) ) -Join '' > > > > Great solution using all of the printable ASCII characters (except for the > <space> character). > > > > *From:* [email protected] [ > mailto:[email protected] <[email protected]>] *On > Behalf Of *Michael B. Smith > *Sent:* Thursday, February 4, 2016 3:39 PM > *To:* [email protected] > *Subject:* RE: [powershell] Random Password Generator > > > > That’s very nice. I never would have thought of that application of > Get-Random. > > > > *From:* [email protected] [ > mailto:[email protected] <[email protected]>] *On > Behalf Of *Sean Martin > *Sent:* Thursday, February 4, 2016 10:44 AM > *To:* [email protected] > *Subject:* Re: [powershell] Random Password Generator > > > > You make a good point. How about this? > > > > $randombytes = new-object byte[] 15 > (new-object > System.Security.Cryptography.RNGCryptoServiceProvider).GetBytes($randombytes) > $pass = [System.Convert]::ToBase64String($randombytes) > $a = ([char[]](get-random -input (33..47 + 48..57) -count 4)) -join "" > $password = $a + $pass > > > > - Sean > > > > > > On Wed, Feb 3, 2016 at 6:36 PM, Michael B. Smith <[email protected]> > wrote: > > The maximum entropy you get from Base64 is 2.58 bits per character, kinda > by definition( ln2( 6 ) ). Given that your maximum length is 15 digits, > that limits you to ~38 bits of entropy. At a thousand guesses a second, > that’s about 8 years to brute force. Not bad. > > > > However, you’ve GIVEN UP over 10 bits of entropy because of four constant > characters, taking you to about 28 bits of entropy. Believe it or not, > having constants makes a password far far easier to crack. (This is why the > revelation of a non-random non-prime in netcat/socat is such a big deal – > it makes Diffie-Helman much much simpler to crack.) > > > > That’s about 3 days to brute force. > > > > That is completely believable for someone to spend the time/energy to > crack. (And remember, the 3 days assumes that your password is the last one > checked, out of the entire “password universe” – on average, assume half > that.) > > > > So, the lesson here is that 15 bytes of base64 is fine (if impossible to > remember). But don’t use constants. Evah. > > > > *From:* [email protected] [mailto: > [email protected]] *On Behalf Of *Sean Martin > *Sent:* Wednesday, February 3, 2016 3:24 PM > *To:* [email protected] > *Subject:* [powershell] Random Password Generator > > > > I don't get the opportunity to contribute all that often so I thought I > would throw this out there in case it helps anyone. > > > I got the method from this article: > https://www.scriptjunkie.us/2013/09/secure-random-password-generation/ > > > > I modify the resulting password by prepending/appending a couple of > special and numerical characters to ensure it meets complexity requirements > in my current environment. > > > > Easy way to generate a secure password whenever the need arises. Critiques > are always welcome. > > > > =================================================================== > > > > # Generate Random Password > > > $randombytes = new-object byte[] 15 > (new-object > System.Security.Cryptography.RNGCryptoServiceProvider).GetBytes($randombytes) > $pass = [System.Convert]::ToBase64String($randombytes) > $password = "&#" + $pass + "82" > > > Write-Host "" > Write-Host "Your password is: " -ForeGroundColor Cyan -NoNewLine > Write-Host "$Password" -ForeGroundColor Yellow > Write-Host "" > Write-Host "" > Write-Host "Press enter to exit script..." -ForeGroundColor Cyan > > > $Pause = Read-Host > > Exit > > > > ================================================================== > > > > - Sean > > > ================================================ > Did you know you can also post and find answers on PowerShell in the > forums? > http://www.myitforum.com/forums/default.asp?catApp=1 > > > ================================================ > Did you know you can also post and find answers on PowerShell in the > forums? > http://www.myitforum.com/forums/default.asp?catApp=1 > > > > > ================================================ > Did you know you can also post and find answers on PowerShell in the > forums? > http://www.myitforum.com/forums/default.asp?catApp=1 > > > ================================================ > Did you know you can also post and find answers on PowerShell in the > forums? > http://www.myitforum.com/forums/default.asp?catApp=1 > > > ================================================ > Did you know you can also post and find answers on PowerShell in the > forums? > http://www.myitforum.com/forums/default.asp?catApp=1 > > > ================================================ > Did you know you can also post and find answers on PowerShell in the > forums? > http://www.myitforum.com/forums/default.asp?catApp=1 > > > ================================================ > Did you know you can also post and find answers on PowerShell in the > forums? > http://www.myitforum.com/forums/default.asp?catApp=1 > > > ================================================ > Did you know you can also post and find answers on PowerShell in the > forums? > http://www.myitforum.com/forums/default.asp?catApp=1 > > > ================================================ > Did you know you can also post and find answers on PowerShell in the > forums? > http://www.myitforum.com/forums/default.asp?catApp=1 > > > > > ================================================ > Did you know you can also post and find answers on PowerShell in the > forums? > http://www.myitforum.com/forums/default.asp?catApp=1 > > > > > ================================================ > Did you know you can also post and find answers on PowerShell in the > forums? > http://www.myitforum.com/forums/default.asp?catApp=1 > > ================================================ > Did you know you can also post and find answers on PowerShell in the > forums? > http://www.myitforum.com/forums/default.asp?catApp=1 > ================================================ Did you know you can also post and find answers on PowerShell in the forums? http://www.myitforum.com/forums/default.asp?catApp=1
