All good things must come to an end.  Sometimes, users become ex-users.  Here’s a quick-and-dirty way to check.

One notable line here is:

[bool](($_.UserAccountControl.ToString() -as [int]) -band 2);

With AD, the second bit from the right is the enable/disabled one.  -BAnd is short for ‘binary AND’.  It doesn’t matter what the other bits in the UserAccountControl property says, the second bit from the right is all we care about.  The –BAnd returns either 2 (the value of 0x010) or 0 (the value of 0x0).

 

 

function Get-AdUser
{
     param (
         [String[]]$Alias = @(),
         [string]$Domain = $env:UserDnsDomain.ToLower(),
         [String]$Comment = "Disabled $(Get-Date -Format 'yyyy-MM-dd')",
         [switch]$Force,
         [switch]$WhatIf
     );

     begin
     {
         if (!$Alias)
         {
             Write-Warning "-Alias required, not specified.";
             break __outOfScript;
         }
         $directorySearcher = New-Object DirectoryServices.DirectorySearcher([ADSI]"LDAP://$Domain");
     }

     process
     {
         foreach ($username in $Alias)
         {
             $filter = "(&(objectCategory=User)(sAMAccountName=$username))";
             Write-Progress (Get-Date) "Searching for '$filter'";
             $directorySearcher.Filter = $filter;
             $directorySearcher.FindAll() | % { $_.GetDirectoryEntry(); }
         }
     }
}

function Test-AdUserDisabled {

param (
         [String[]]$Alias = @(),
         [string]$Domain = $env:UserDnsDomain.ToLower()
     );

     begin
     {
         if (!$Alias)
         {
             Write-Warning "-Alias required, not specified.";
             break __outOfScript;
         }
         $directorySearcher = New-Object DirectoryServices.DirectorySearcher([ADSI]"LDAP://$Domain");

     }

     process
     {
         foreach ($username in $Alias)
         {
             $filter = "(&(objectCategory=User)(sAMAccountName=$username))";
             Write-Progress (Get-Date) "Searching for '$filter'";
             $directorySearcher.Filter = $filter;

             $found = $false;

             $directorySearcher.FindAll() | %{
                 $found = $true;
                 $_.GetDirectoryEntry() | Select-Object -Property @{
                     n = 'Username';
                     e = { $_.sAMAccountName.ToString(); }
                 }, @{
                     n = 'Name';
                     e = { $_.Name.ToString(); }
                 }, @{
                     n = 'Disabled';
                     e = { [bool](($_.UserAccountControl.ToString() -as [int]) -band 2); }
                 }

             }

             if (!$found) { Write-Warning "Unable to find -Alias '$username'"; }
         }
     }
}

function Disable-AdUser {
     param (
         [String[]]$Alias = @(),
         [string]$Domain = $env:UserDnsDomain.ToLower(),
         [String]$Comment = "Disabled $(Get-Date -Format 'yyyy-MM-dd')",
         [switch]$Force,
         [switch]$WhatIf
     );

     begin
     {

         if ($Alias)
         {
             if (!$Force)
             {
                 Write-Warning ("About to disable user account(s) for '{0}'" -f [string]::Join("', '", $Alias));
                 if ((Read-Host -Prompt "Type 'YES' to continue") -ne 'yes')
                 {
                     break__outOfScript;
                 }
             }
         } else
         {
             Write-Warning "-Alias required, not specified.";
             break __outOfScript;
         }

         $directorySearcher = New-Object DirectoryServices.DirectorySearcher([ADSI]"LDAP://$Domain");
     }

     process
     {

         foreach ($username in $Alias)
         {

             if ($username -match "[^a-zA-Z0-9_-]")
             {
                 Write-Warning "Illegal character in '$username', skipping.";
                 continue;
             }

             if ($username -match $env:USERNAME)
             {
                 Write-Warning "Trying to disable your own account, eh?  No!";
                 continue;
             }

             $filter = "(&(objectCategory=User)(sAMAccountName=$username))";
             Write-Progress (Get-Date) "Searching for '$filter'";
             $directorySearcher.Filter = $filter;

             [Object[]]$results = $directorySearcher.FindAll();

             if ($results.Count -eq 1)
             {
                 if ($directoryEntry = $results[0].GetDirectoryEntry())
                 {
                     Write-Progress (Get-Date) "Disabling account '$($directoryEntry.Name)'";
                     if ($WhatIf) {
                         Write-Host "WHATIF: Disable account '$($directoryEntry.sAMAccountName)' ($($directoryEntry.Name))";
                     } else
                     {
                         $userObject = [ADSI]"LDAP://$($directoryEntry.DistinguishedName)";
                         $userObject.PsBase.InvokeSet("AccountDisabled", $true);
                         $userObject.Description = "Disabled $(Get-Date -Format 'yyyy-MM-dd')";
                         $userObject.SetInfo();
                     }
                 } else
                 {
                     Write-Warning "Unable to find -Alias '$username'";
                     continue;
                 }
             } elseif ($results.Count -gt 1)
             {
                 Write-Warning ("Searching for user account '$username' returns {0} accounts: {1}" -f $results.Count, [string]::Join(', ', ($results | % { $_.Properties.Name; })));
             } else
             {
                 Write-Warning "Unable to find any user accounts matching '$username'";
             }
         }
     }
}