Zoho Banner September 2011

Archive for June, 2015

Like that hipster beard you grew last summer, all good things must eventually come to an end. You will likely be aware that the end of extended support for Windows Server 2003 finishes on July 14th 2015. If you don’t know whether you still have 2003 boxes lurking in the dark recesses of your AD domain, you could try running the handy script below to flush them out.

The script looks for Window Server 2003 machine accounts that have logged on to the domain some time within the past 60 days – a good indicator that they are still active. It produces a CSV output for your perusal.

#########################################################
#
# Name: Find-W2K3StillActive.ps1
# Author: Tony Murray
# Version: 1.0
# Date: 25/06/2015
# Comment: PowerShell 2.0 script to find active
# Windows Server 2003 computer accounts
#
#########################################################

## Define global variables
# Export file for storing results
$expfile = "c:\w2k3_still_active.csv"
# Define the header row for the CSV (we will create our own)
$header = "`"name`",`"os`",`"sp`",`"lastlogondate`""
# Consider any account logged on in the last x days to be active
$days = 60
$Today = Get-date
$SubtractDays = New-Object System.TimeSpan $days, 0, 0, 0, 0
$StartDate = $Today.Subtract($SubtractDays)
$startdate = $startdate.ToFiletime()
# LDAP filter settings
$filter = "(&(lastlogontimestamp>=$startDate)(operatingsystem=Windows Server 2003*))"

## Functions
Function Format-ShortDate ($fdate)
{
        if ($fdate) {
            $day = $fdate.day
            $month = $fdate.month
            $year = $fdate.year
            "$day/$month/$year"
        } # end if

} # end function

## Start doing things
# Import the AD module
ipmo ActiveDirectory
# Tidy up any previous copies of the export file 
if (test-path $expfile) {Remove-Item $expfile}
# Add the header row to the export file
Add-Content -Value $header -Path $expfile
# Create an array of computer objects
$active = Get-ADComputer -LDAPFilter $filter -pr *
# loop through the array
foreach ($w2k3 in $active) {
    # Grab the attribute values we need from the AD object
    $nm = $w2k3.name
    $os = $w2k3.operatingsystem
    $sp = $w2k3.operatingsystemservicepack
    $lt = Format-ShortDate $($w2k3.lastlogondate)
    $row = "`"$nm`",`"$os`",`"$sp`",`"$lt`""
    # Commit the row to the export file
    Add-Content -Value $row -Path $expfile
} # end foreach

## End script

Enjoy!

Unfortunately Active Directory doesn’t yet provide dynamic security groups in the way that, for example, Exchange provides dynamic distribution groups.  Sometimes it is useful to maintain a group’s membership based on a specific attribute, or set of attributes.  Here’s a quick Powershell example that shows how to maintain the membership based on the presence of a single attribute value.

You can download the script here: AttributeBasedGroupMembership

 

#########################################################
#
# Name: AttributeBasedGroupMembership.ps1
# Author: Tony Murray
# Version: 1.0
# Date: 18/06/2015
# Comment: PowerShell 2.0 script to manage group 
# membership based on attribute values
#
#########################################################

# Import the AD module
ipmo ActiveDirectory

# Define arrays to be used for matching
$arratt = @()
$arrgp = @()

# Domain controller to be used
$dc = (Get-ADRootDSE).dnshostname
write-host "Using DC $dc for all AD reads/writes"

# Specify the OU where the accounts are located
$OUdn = "OU=Corp Users,DC=Contoso,DC=com"

# Find all the objects that have the specified attribute value
$AttUsrs = Get-ADUser -LDAPFilter "(extensionattribute1=Sales)" -SearchBase $oudn -Server $dc

# Specify the GUID of the group to use
# You could also use name of group (but this can be changed)
$grp = "7bbf64bc-46c7-4a90-9d58-7cb5eca35fce" # i.e. "Sales Team"

# Find all the group members
$grpusers = Get-ADGroupMember -Identity $grp -Server $dc

# Build arrays using the DN attribute value
$AttUsrs | % {$arratt += $_.distinguishedname}
$grpusers | % {$arrgp += $_.distinguishedname}


# Add to group membership (newly assigned attribute value)
foreach ($usr in $arratt) {
    if ($arrgp -contains $usr) {
        write-host "User $usr is a member of the group"
    }
    else {
        write-host "User $usr is not a member of the group - adding..."
        Add-ADGroupMember -Identity $grp -Members $usr -Server $dc
    } # end else
    Remove-Variable -ErrorAction SilentlyContinue -Name usr    
} # end foreach

write-host "`n"

# Remove from group (no longer has attribute value or has been manually added to group)
# Assumption here is that the attribute value is authoritative for the group's membership
foreach ($mem in $arrgp) {
    if ($arratt -contains $mem) {
        write-host "User $mem still has the attribute value.  Nothing to do"
    } # end if
    else {
        write-host "User $mem does not have the attribute value.  Removing from membership..."
        Remove-ADGroupMember -Identity $grp -Members $mem -Server $dc -Confirm:$false
    } # end else
    Remove-Variable -ErrorAction SilentlyContinue -Name mem
} # end foreach

 

To ensure the script is run regularly, you would likely want to call it from a scheduled task.