Auditing File Share access

Say you’ve been tasked with cleaning up an old and poorly-maintained file server and need to figure out which network shares see lots of use and which ones little to none. While Windows provides totally adequate facilities for creating logs, actually parsing said logs without paying for an expensive 3rd-party solution can be frustrating.

Here’s a quick Powershell snippet that should give you the information you most likely want:

$FilterHashTable = @{
    LogName   = 'Security'
    ID        = 5140
    StartTime = (Get-Date).AddHours(-24)
}

Get-WinEvent -FilterHashtable $FilterHashTable |
    Select-Object -Property @{Name='Time';Expression={$_.TimeCreated}}, `
                            @{Name='Share';Expression={$_.Properties[7].Value}}, `
                            @{Name='SourceIP';Expression={$_.Properties[5].Value}}, `
                            @{Name='User';Expression={$_.Properties[1].Value}} |
Format-Table -AutoSize

If nothing shows up in the results:
* Do you have the permissions required to read the Security log of the server being audited?
* Does the Security log contain 5140 events? (You still need to actually enable auditing for them to show up)

Figuring out the last time a user logged into an AD domain

When tasked with figuring out the last time a user logged on into an Active Directory domain, some people might be awfully tempted to just look at lastLogonTimestamp attribute of a user’s AD account and then call it a day. This approach has a multitude of gotchas:

  • lastLogonTimestamp does get synced across DCs, but only if the entry is more than 14 days old
  • It can get updated even when the user has NOT logged on (Kerberos S4U)
  • It can fail to get updated even when the user HAS logged in (seen with some VPN solutions)
  • Probably something else I haven’t yet run into

So the appropriate solution that is less prone to error is to look at the lastLogon value for the account and you have to look it up on all DCs active in the domain. Since individually querying each and every one can and does get tedious, here’s a Powershell one-liner:

[datetime]::FromFileTime((Get-ADDomainController -Filter * | foreach {Get-ADUser USERNAME -Properties LastLogon -Server $_.Name | select LastLogon} | Measure-Object -Property LastLogon -Maximum).Maximum)

The basics of dynamic AD security group management

Consider a situation where you’re tasked with maintaining dynamic Active Directory group membership based on the user account Office-attribute:

$users = Get-ADUser -Filter {Office -like "New York"}
foreach($user in $users)
{
Add-ADGroupMember -Identity GroupName -Members $user.samaccountname -ErrorAction SilentlyContinue
}

$members = Get-ADGroupMember -Identity GroupName
foreach($member in $members)
{
if ((Get-ADUser -identity $member -properties Office|Select-Object Office).office -notlike "New York")
{
Remove-ADGroupMember -Identity GroupName -Member $member.samaccountname -Confirm:$false
}
}

Now set this to run once per day via Task Scheduler and you’re set. Make sure to check the service account used to run the scheduled task has permissions to modify the group and user objects involved.