lithnet/ad-password-protection

Restrict scope to specific OU (recursively)

bezzoh opened this issue · 6 comments

Is there a way I can modify the audit powershell script to set the scope to a specific OU (or at least 'from' an OU, looking down recursively) rather than the entire AD subtree?

Its good that I can obviously filter by active/inactive accounts, but we retain years (therefore thousands) of inactive users and it therefore takes quite a while to audit.

Thanks in advance

@bezzoh

Just add a Search root value and specify your OU

$Searcher.SearchRoot = "OU=XXX,DC=XXX"

The full script would look like this

Import-Module LithnetPasswordProtection

$file = "get-pwned-users.csv";

"accountName,UPN,pwdLastSet,lastLogin,accountDisabled" | out-file $file

$Searcher = New-Object System.DirectoryServices.DirectorySearcher
$Searcher.PageSize = 200
$Searcher.SearchScope = "subtree"
$Searcher.SearchRoot = "OU=XXX,DC=XXX"

$Searcher.Filter = "(&(objectCategory=person)(objectClass=user))"
$Attributes = @("PwdLastSet","lastLogonTimeStamp", "userAccountControl", "userPrincipalName", "name")
ForEach($Attribute In $Attributes)
{
    $Searcher.PropertiesToLoad.Add($Attribute) > $Null
}

$Results = $null
$Total = 0
$NumChanged = 0

$Searcher.FindAll() | % {
    $user = $_.Properties["UserPrincipalName"][0]

    if ($user -eq $null)
    {
        write-warning "User $($_.Properties["Name"][0]) has a null UPN";
        return;
    }

    $result = Test-IsADUserPasswordCompromised -UPN $user -server localhost 
    
    $pwdLastSet = $null
    $lastLogin = $null
    $disabled = $false;

    if ($_.Properties["PwdLastSet"][0] -gt 0)
    {
        $pwdLastSet = [DateTime]::FromFileTimeUtc($_.Properties["pwdLastSet"][0]).ToLocalTime()
    }

    if ($_.Properties["lastLogonTimeStamp"][0] -gt 0)
    {
        $lastLogin = [DateTime]::FromFileTimeUtc($_.Properties["lastLogonTimeStamp"][0]).ToLocalTime()
    }

    if (($_.Properties["userAccountControl"][0] -band 2) -eq 2)
    {
        $disabled = $true;
    }

    if ($result -ne $true)
    {  
        return;
    }

    $message = "$($_.Properties["Name"][0]),$user,$pwdLastSet,$lastLogin,$disabled"
    Write-Output $message
    $message | out-file $file -Append
} 

Awesome. Thanks again for the assist!

Actually, I've given this a try.. Don't think I'm doing anything wrong, but I'm getting the following if trying to implement this;

Exception calling "FindAll" with "0" argument(s): "Unspecified error
"
At C:\support\Scripts\Get-Pwned-Staff.ps1:23 char:1

  • $Searcher.FindAll() | % {
  •   + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
      + FullyQualifiedErrorId : COMException
    

Are you using the full DN of the OU?

Oh you might need to prefix the DN with "LDAP://"

Thats done it, needed the prefix. Thanks once again for the quick support. Really helpful!