Disabling Inactive Domain User and Computer Accounts in Active Directory with Ansible

In my last article I wrote about having Ansible run several audit requests including: “We need a list of all inactive user accounts” as well as “We need a list of inactive computer accounts”. Now that we have those listed, we can let Ansible clean those up. I preferred to create a new playbook for these tasks. First it will list the Users and Computers it will be handling first, next it will disable the account, followed by moving it to either the Inactive_Users or Inactive_Computers OU. I never delete the accounts as we prefer to disable, then move them.

Below is my ansible playbook “fix_AD_Inactive-Users-AND-Computers-90days.yml”

---
- hosts: pdc
  gather_facts: no
  tasks:
     - name: copy file to windows
       win_copy:
          src: files/fix_inactive_usr.ps1
          dest: c:\it\fix_inactive_usr.ps1

     - name: copy file to windows
       win_copy:
          src: files/fix_inactive_pc.ps1
          dest: c:\it\fix_inactive_pc.ps1

     - name: Fix inactive users - 90 days
       win_shell: c:\it\fix_inactive_usr.ps1
       register: inactive_usr

     - debug: var=inactive_usr.stdout_lines

     - name: Fix inactive computers - 90 days
       win_shell: c:\it\fix_inactive_pc.ps1
       register: inactive_computer

     - debug: var=inactive_computer.stdout_lines

Below is the code for “fix_inactive_usr.ps1”

$date = (get-date).AddDays(-90)

$USR = (Get-ADUser -Filter {LastLogonDate -lt $date} -Property Enabled | Where-Object {$_.Enabled -like "true"} | Select DistinguishedName).DistinguishedName
echo $USR
ForEach ($Item in $USR){
   Disable-ADAccount $Item
   Move-ADObject -Identity $Item -TargetPath "OU=Disabled_Accounts,DC=contoso,DC=com"
   }

Please note in the PowerShell scripts above and below, you will need to change “DC=contoso,DC=com” to reflect your actual domain

Below is the code for “fix_inactive_pc.ps1”

# Specify inactivity range value below
$DaysInactive = 90
# $time variable converts $DaysInactive to LastLogonTimeStamp property format for the -Filter switch to work

$time = (Get-Date).Adddays(-($DaysInactive))

# Identify inactive computer accounts

$PC = (Get-ADComputer -Filter {LastLogonTimeStamp -lt $time} -Property Enabled | Where-Object {$_.Enabled -like "true"} | Select DistinguishedName).DistinguishedName
echo $PC
ForEach ($Item in $PC){
   Disable-ADAccount $Item
   Move-ADObject -Identity $Item -TargetPath "OU=Disabled_Computers,DC=contoso,DC=com"
   }

Audit Active Directory with Ansible

Everyone loves an audit right? We have to deal with audits quite a bit and that requires remedial tasks like “We need a list of AD user accounts that have been locked out”, “We need a list of all inactive user accounts”, “We need a list of inactive computer accounts”, “We need a list of all members of Domain Admins group” as well as “We need a list of all AD accounts”. All of these requirements can easily be scripted with PowerShell. Since I love to automate things and I would rather not run these commands separately, I figured I would just create an Ansible script to run all request at the same time. that way I could logon once, select my Ansible playbook and let it run and I don’t even need to logon to the DC to run theses tasks. I can sit back and let Ansible deal with this.

This simple Ansible playbook uses 3 PowerShell commands and 2 PowerShell scripts that I’m sure most Windows Administrators are familiar with.

---
- hosts: pdc
  gather_facts: no
  tasks:
     - name: copy audit_AD_inactive_users.ps1 to Windows
       win_copy:
          src: files/audit_AD_inactive_users.ps1
          dest: c:\cit\audit_AD_inactive_users.ps1

     - name: copy audit_AD_inactive_computers.ps1 to Windows
       win_copy:
          src: files/audit_AD_inactive_computers.ps1
          dest: c:\cit\audit_AD_inactive_computers.ps1

     - name: Run Audit for Locked-Out Accounts
       win_shell: Search-AdAccount -LockedOut | select Name, LockedOut,LastLogonDate,distinguishedName
       register: lockedoutaccounts

     - debug: var=lockedoutaccounts.stdout_lines

     - name: Run Audit of inactive users - 90 days
       win_shell: c:\cit\audit_AD_inactive_users.ps1
       register: inactive_users

     - debug: var=inactive_users.stdout_lines

     - name: Run Audit of inactive computers - 90 days
       win_shell: c:\cit\audit_AD_inactive_computers.ps1
       register: inactive_computers

     - debug: var=inactive_computers.stdout_lines

     - name: Run Audit for members of Domain Admins group
       win_shell: Get-ADGroupMember -Identity 'Domain Admins' | Select-Object name, objectClass,distinguishedName
       register: dom_admin_users

     - debug: var=dom_admin_users.stdout_lines

     - name: Run Audit for all domain users
       win_shell: Get-ADUser -Filter * -SearchBase "dc=contoso,dc=com" | select Name, objectClass,distinguishedName
       register: all_dom_users

     - debug: var=all_dom_users.stdout_lines

Not bad right? Ansible Rocks! The only complaint I may see is I’m not outputting the results to a CSV file, but if you run this script often, you shouldn’t need the fancy format.

Below is the first PowerShell script “audit_AD_inactive_users.ps1”

$date = (get-date).AddDays(-90)

Get-ADUser -Filter {LastLogonDate -lt $date} -Property Enabled | Where-Object {$_.Enabled -like “true”} | Select Name, SamAccountName, DistinguishedName

Below is the second PowerShell script “audit_AD_inactive_computers.ps1”

# Specify inactivity range value below
$DaysInactive = 90
# $time variable converts $DaysInactive to LastLogonTimeStamp property format for the -Filter switch to work

$time = (Get-Date).Adddays(-($DaysInactive))

# Identify inactive computer accounts

Get-ADComputer -Filter {LastLogonTimeStamp -lt $time} -ResultPageSize 2000 -resultSetSize $null -Properties Name, OperatingSystem, SamAccountName, DistinguishedName, LastLogonDate | Select DNSHostName, LastLogonDate, DistinguishedName

Creating an AD Realm on a Cisco ASA 5508-x running FTD (via FTM)

Creating an AD Realm on a Cisco ASA 5508-x running FTD (via FTM)

This was done on FTD vs 6.2.3-83. 

  1. In the Top Menu (Monitoring, Policies, Objects, Device), Select Objects
  2.  Under the Object types side menu, select Identity Realm
  3.  Enter a Realm name (I entered Client domain).
  4. For me, the Type: Active Directory was grayed out (it was my only choice anyway)
  5. For base DN, I entered: dc=example,dc=com
  6. for AD Primary domain, I entered our domain name
  7. Hostname, I entered the ip of the AD server and port I left at the default of 389
  8. I left encryption as None. I then tested satisfactory and saved the config.

Please check out my related article:

Setting up AnyConnect VPN’s on the Cisco ASA 5508x (FTD)

STOP 0x0000007B Resolved on P2V’d Windows SBS 2011

***The following was on a Hyper-V vm, but this also applies to VMware.***

****This should work on most versions of Windows (doesn’t have to be SBS)****

The other week we picked up a new client with an emergency issue. They had an SBS 2011 Server on failing hardware. The hardware was so bad that we didn’t think it would last until the replacement server would arrive. We had an older Server that had enough power to handle their server virtualized until their new hardware arrived. So I started the virtualization process. This is where the fun began. (There were several issues minor issues, but I’ll stick to the major problem here.)

After creating the vm without any disk drives, I attached the newly created drives and powered up the vm and was greeted by the BSOD: STOP 0x0000007B.

Luckily there is an easy fix for this and  you don’t need restart the p2v.

  • Boot the vm off any Windows CD/DVD (Windows 7 & up. Doesn’t have to be the same OS as vm. You could also mount the drive on the host or another vm. If you mount the drive, just run regedit)
  • After booting off OS cd, when you encounter the language selection, hit Shift-F10 for a command prompt
  • At the command prompt, run regedit
  •  In regedit, highlight Hkey_Local_Machine
  • With Hkey_Local_Machine highlighted, goto File, and Load Hive
  • In Load Hive, select the drive letter where Windows OS was installed (C: in this case), then go to: Windows\System32\config\system
  • Name the Hive whatever you want (IE: recovery)
  • Expand HKEY_LOCAL_MACHINE\recovery\ControlSet1\Services\intelide
  • Change the data for value “Start” from “3” to “0”
  • Now goto File and “Unload Hive” (If you run into issues make sure Hkey_Local_Machine is highlighted)
  • Exit regedit and reboot the machine and you’re good to go

If you still have issues after reboot, check the following keys and set them to:

Aliide = 3
Amdide =3
Atapi = 0
Cmdide = 3
iaStorV = 3
intelide = 0
msahci = 3
pciide = 3
viaide = 3

Unable to activate BitLocker after imaging Surface Pro or Surface Book

I ran into the following error after pushing an image to a Microsoft Surface Book and configuring the imaged device for a new user. I tried to Turn on BitLocker and immediately saw:

This device cannot use a Trusted Platform Module.  Your administrator must set the “Allow Bitlocker without a compatible TPM” option in the  “Required additional authentication at startup” policy for OS volumes

During the imaging process I had turned off TPM via BIOS, so I rebooted into BIOS ad made sure TPM was enabled. Next I saved and exited BIOS and restarted. WIth TPM enabled in BIOS I did the following:

  1. Entered Device manager: (Type device  Manager in Start Menu)
  2.  In Device Manager, look for “Security Devices” (If you don’t see “Security Devices”, click on “View” and “Show hidden devices”.
  3. Under Security Devices you should See “Trusted Platform Module 2.0” or similar
  4. Right Click on that and select Properties
  5. Mine showed the device was not detected
  6. I then clicked on cancel (In the TPM Properties screen)
  7. I then Right Clicked on TPM module and selected “Uninstall device”
  8. This required a reboot which I did.
  9. After reboot I checked the device manager and TPM was shown as working properly. I was then able to turn on and configure BitLocker

Force static IP clients to move to DHCP

The following will set the client to use DHCP:

netsh interface ip set address “Local Area Connection” dhcp

Unfortunately, you will need to do the same with DNS as well (otherwise it remains statically assigned)

netsh interface ip delete dns “Local Area Connection” all

Place that in GPO as a startup script after testing.