28 December, 2020

Powershell - Password generators, a different take.

 A different take on generating random passwords - Let me explain...
I found myself, or the person I was on the phone with...
Struggling to locate, on their keyboards, most of the special characters used by password generators.
I've also had many an eyeroll, talking to someone who got a temporary password emailed to them, but they could not tell the difference between: O and 0, or l, I, and 1... (see comments in the script), and ended up locking their account, thus having to call me, to tell me the password I sent does not work - (queue 'eyeroll')

The below script, just gets rid of those problematic characters.
Making it ~ MUCH EASIER TO COMMUNICATE ~ a random password
I use THIS to create passwords, now.

 And it tests for AD password complexity too... (see comments in the script)

  • Tell it how long the password should be (15 is the max length, but you can add to the 'PWDgen' function... Though, that'd be kinda' mean.)
  • Tell it how many passwords to generate...

= 8 # How many characters long (max is 15).
$HowMany = 6 # So you can pick from an assortment.

   ############## password generator - Some characters removed:
   # '1' (number one), 'I' (letter 'eye' upper case), and 'l' (letter 'el' lower case) - look to similar
   # '0' (number zero), and 'O' (letter 'oh', uppercase) - look to similar
   # Special characters that are ambiguous, less common, difficult to explain on the phone, or harder to locate on the keyboard.

# AD standard password complexity:
   #  One character from at least three, of these four categories: Upper Alpha, Lower alpha, Number, Special character.

SpecChar {("!@#$%&".tochararray()) | Get-Random}
Function UpperAlpha {("ABCDEFGHJKLMNPQRSTUVWXYZ".tochararray()) | Get-Random}
Function LowerAlpha {("abcdefghijkmnopqrstuvwxyz".tochararray()) | Get-Random}
Function Number {("23456789".tochararray()) | Get-Random}
Function WildCard {("!@#$%&23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".tochararray()) | Get-Random}

Function PWDgen {
$Password = ((
Number)+(Number)+(Number) +`
WildCard)+(WildCard)+(WildCard)).tochararray() | sort {Get-Random})[0..($Length - 1)] -join ''
Return $Password

Write-Host "Here's a bunch of random, $Length character passwords:" -ForegroundColor Cyan
$Counter = 1
..$HowMany | % {
Write-Host "$($Counter): "
    Do {$Password00 = PWDgen # Force AD password complexity compliance - At least three out of four
    $Rule = 0
    If (($Password00 -cmatch "[A-Z]")) {$Rule++}
If (($Password00 -cmatch "[a-z]")) {$Rule++}
If (($Password00 -match ".*\d+.*")) {$Rule++}
If (($Password00 -match '[^a-zA-Z.*\d+.*]')) {$Rule++}
Until ($Rule -ge 3)
Write-Host $($Password00) -ForegroundColor Yellow

Powershell: 'Manager can update membership list'

 I ran into a post on a Powershell Facebook group, where someone was asking how to use Powershell to interact with an Active Directory groups 'Managed by', and (more specifically) the 'Manager can update membership list' values...

This 'Manager can update membership list' value is not available from the Get/Set-ADGroup command...
It is an ACL, and it is obscure. (that GIUD tho!!!)

I ran into all kinds of complicated scripts / functions that woked on this... But its not that complicated... If you know the GUID value, that is...
Anyway - Here it is:

= "Some Group" # Group display Name
$ManagerName = "BossMan" # AD Username

$mgr = (Get-ADUser $ManagerName)
$grp = [ADSI]"LDAP://$((Get-ADGRoup $GroupName).DistinguishedName)"

[System.DirectoryServices.DirectoryEntryConfiguration]$Options = $grp.get_Options()
$Options.SecurityMasks = [System.DirectoryServices.SecurityMasks]'Dacl'

$Rule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($(New-Object System.Security.Principal.SecurityIdentifier (($mgr).SID.Value)),`
[System.DirectoryServices.ActiveDirectoryRights]::WriteProperty, [System.Security.AccessControl.AccessControlType]::Allow, [Guid]"bf9679c0-0de6-11d0-a285-00aa003049e2")

.InvokeSet("managedBy", @("$($mgr.DistinguishedName)")) # Sets the Managed By

.get_ObjectSecurity().AddAccessRule($Rule) # Yep, it is an ACL, this sets it.