Password Complexity Validation with PowerShell

Sometimes you need to verify if a password meets some minimal requirements such as length, upper- and lowercase characters and special chars.

This simple script validates if a string / password matches at least these minimum requirements:

  • At least one uppercase character
  • At least one lowercase character
  • At least one digit
  • At least one special char
  • At least 10 characters in length
1
2
3
4
5
6
7
8
9
10
11
12
13
$password = 'mySecure!P@ssword$'
 
$counter = 0
@('[A-Z]', '[a-z]', '\d', '[\41-\57\100\133-\140]', '.{10,}') | foreach {
    if(($str -creplace $_, '') -ne $str) { $counter++ }
}
 
if($counter -ge 5){
    Write-Host "Strong password"
}
else {
    Write-Host "Weak password"
}

How to loop through the Properties of a PowerShell Object

If you have want to iterate through a hashtable to make use of the key/value pairs, you can do that using the GetEnumerator() function and foreach.

1
2
3
4
5
6
7
8
9
10
11
12
# Preparing the hastable
$myHastable = @{
    "AnimalType" = "Dog"
    "Name" = "Bella"
    "Owner" = "Mr. Smith"
}
 
# Looping through the hashtable
$myHastable.GetEnumerator() | foreach { 
    $_.Name
    $_.Value
}

To access the values of a PowerShell object you have to know the name of the object property to access it, which looks like this: $myObject.PropertyName

I had to make use of all the properties of a PowerShell object without knowing its property names beforehand. Since GetEnumerator() does not work on objects I had to come up with another solution, which is to access the properties using the PSMemberSet of my custom object.

1
2
3
4
5
6
7
8
9
10
11
12
# Preparing the object
$myObject = New-ObjectType PSObject
$myObject | Add-MemberType NoteProperty –Name "AnimalType" –Value "Dog"
$myObject | Add-MemberType NoteProperty –Name "Name" –Value "Bella"
$myObject | Add-MemberType NoteProperty –Name "Owner" –Value "Mr. Smith"
 
 
# Looping through the object
$myObject.PSObject.Properties | foreach { 
    $_.Name
    $_.Value
}

Works as easy as if it were a hastable.

PowerShell Datatype Declaration

PowerShell is a scripting and not a programming language, that much I know. Sometimes I am still missing a strict(er) datatype declaration to prevent a lot of mistakes caused by none or (automatically) false declared variables.

Have a look at the examples below and let me know what you think of it 🙂

1
2
3
4
2+"5" # => 7 
"2"+5 # => 25
[int]"2"+5 # => 7
[string]2+"5" # => 25

In my opinion all of the above examples should throw an error while the following ones should not:

1
2
3
4
2+5 # => 7
"2"+"5" # => 25
[int]2+5 # => 7
[string]"2"+"5" # => 25

Meltdown and Spectre Remote Vulnerability Check on Windows Systems

Given PowerShell remoting is activited on the Windows Computers in your environemnt, there is an easy solution to check if those systems are vulnerable or not (any more).
The script as follwos retrieves all computer objects from Active Directory

Make sure the computer on which you run this script has the Active Directory PowerShell module as well as the SpeculationControl PowerShell module installed and your currently logged in user has the appropriate permissions granted.

1
2
3
4
Import-Module -Name SpeculationControl
Get-ADComputer -Filter * | foreach {
    Invoke-Command -ComputerName $_.DNSHostName ${function:Get-SpeculationControlSettings}
}

How to use certutil output as Objects within PowerShell

Working with Certification Authorities (CA), native PowerShell commands are not too well established yet to fit all my needs, so I had to think about a solution how I could use the well-known certutil tool and use its output within PowerShell.

That is what I came up with (thanks to Shane’s blogpost):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
function certutilToObjectList($certutilOutput){
 
    $certutilObjectList = @()
    $currentKey = $null
    $currentValue = $null
    $certutilOutput -split [environment]::NewLine | foreach {
 
        switch -regex ($_){
 
            '[Entry|Row] \d+:(.*)' {
                # New Object found
                $currentObject = New-Object psobject
                $currentValue = $null
                continue
            }
 
            '(\s{2})(?[\w\s]+):\s*(?.*)' {
                # Add key / value pair to Object
                if($currentObject){ 
                    if( -not $matches.value){
                        $currentKey = $matches.key.Trim()
                        $currentValue = $null
                    }
                    else {
                        $currentObject | Add-Member -MemberType NoteProperty -Name $($matches.key.Trim()) -Value $($matches.value.trim(@("'",'"','`'))) -Force 
                    }
                }
            }
 
            '^$' {
                # Add Object to ObjectList if Object exists
                if($currentObject){ 
                    if($currentKey -and $currentValue){
                        $currentObject | Add-Member -MemberType NoteProperty -Name $($currentKey) -Value $($currentValue) -Force 
                    }
                    $certutilObjectList += $currentObject 
                    $currentObject = $null
                    $currentKey = $null
                    $currentValue = $null
                }
            }
 
            default {
                # Save Values of Multiline Parameters if a current Key exists
                if($currentObject -and $currentKey){ 
                    $currentValue += $_+"`n"
                }
            }
        }
    }
 
    # Add last Object to ObjectList if necessary
    if($currentKey -and $currentValue){
        $currentObject | Add-Member -MemberType NoteProperty -Name $($currentKey) -Value $($currentValue) -Force 
    }
    $certutilObjectList += $currentObject
 
    return $certutilObjectList
}
 
 
$certutil = "$($env:SystemRoot)\system32\certutil.exe"
$certutilOutput = Invoke-Expression "$certutil -view -restrict disposition==20 -out 'serialnumber,requestid,Issued Common Name,Certificate Expiration Date'"
$certutilObjectList = certutilToObjectList $certutilOutput

This function splits the certutil output into single rows and processes them one by one using regular expressions to figure out what to do with each row. It further creates a list (array) of PowerShell objects to make the output easily usable with PowerShell.

Read More