Search code examples
powershellpowershell-2.0powershell-3.0powershell-4.0powershell-5.0

Enforce Password complexity on Windows using Powershell


How to Enable password complexity on Workgroup computers using Windows Powershell? I know how to do it on the Domain level. We have some computer which are located on remote locations and they don't have domain access, hence they are on Workgroup.


Solution

  • This is not a good solution for powershell. This would be ok for a Local Security Policy.

    1. Go to run and type in SecPol.msc
    2. Go to Account Policies > Password Policy > Password must meet complexity requirements
    3. Set to Enable.
    4. Set Minimum Password Length
    5. Set Maximum Password Age

    So i decided to write a few functions to take care of all this through Powershell for you.

    You can get and edit the Security Policy with this function Parse-SecPol. This will turn the entire config file into a PSobject so you can change properties and sort them or whatever you want to do.

    The Next is Set-SecPol which will allow you to resave the object back into Local Security Policy.

    The Parameter -CfgFile is the location you would like to save the config file.

    Here is full script with example (Must be run as a Administrator)

    Function Parse-SecPol($CfgFile){ 
        secedit /export /cfg "$CfgFile" | out-null
        $obj = New-Object psobject
        $index = 0
        $contents = Get-Content $CfgFile -raw
        [regex]::Matches($contents,"(?<=\[)(.*)(?=\])") | %{
            $title = $_
            [regex]::Matches($contents,"(?<=\]).*?((?=\[)|(\Z))", [System.Text.RegularExpressions.RegexOptions]::Singleline)[$index] | %{
                $section = new-object psobject
                $_.value -split "\r\n" | ?{$_.length -gt 0} | %{
                    $value = [regex]::Match($_,"(?<=\=).*").value
                    $name = [regex]::Match($_,".*(?=\=)").value
                    $section | add-member -MemberType NoteProperty -Name $name.tostring().trim() -Value $value.tostring().trim() -ErrorAction SilentlyContinue | out-null
                }
                $obj | Add-Member -MemberType NoteProperty -Name $title -Value $section
            }
            $index += 1
        }
        return $obj
    }
    
    Function Set-SecPol($Object, $CfgFile){
       $SecPool.psobject.Properties.GetEnumerator() | %{
            "[$($_.Name)]"
            $_.Value | %{
                $_.psobject.Properties.GetEnumerator() | %{
                    "$($_.Name)=$($_.Value)"
                }
            }
        } | out-file $CfgFile -ErrorAction Stop
        secedit /configure /db c:\windows\security\local.sdb /cfg "$CfgFile" /areas SECURITYPOLICY
    }
    
    
    $SecPool = Parse-SecPol -CfgFile C:\test\Test.cgf
    $SecPool.'System Access'.PasswordComplexity = 1
    $SecPool.'System Access'.MinimumPasswordLength = 8
    $SecPool.'System Access'.MaximumPasswordAge = 60
    
    Set-SecPol -Object $SecPool -CfgFile C:\Test\Test.cfg