PowerShell - Filter a list Computers by LastLogon Date
2012, Jan 29
I needed a script to filter a list of computers by the number of days since the computer was last logged onto. This is my solution to that. When supplied a list of computers, this will return the ones that have been Active (Logged On) within the Last X amount of days. Where X is supplied as $DaysSinceLastLogon. I’ve populated the PowerShell Comment Doc, so check out the Examples supplied in there for usage.
<# .SYNOPSIS Filter a list Computers by LastLogon Date. .DESCRIPTION When supplied a list of computers, this will return the ones that have been Active (Logged On) within the Last X amount of days. Where X is supplied as $DaysSinceLastLogon. .PARAMETER ComputerNames Object supplied via piped in result from a Get-ADComputer query, or similar. Alias: Name .PARAMETER DaysSinceLastLogon Default: 180. Number of days since Last Logon. Used to justify an Active Computer. .INPUTS System.Object ComputerNames System.Int32 DaysSinceLastLogon .OUTPUTS List of Computer Names. .EXAMPLE Get-ADComputer Computer0123A | Get-CompByUser Active Computers: 1 Total Computers: 1 The Active Computers are: Hostname LastLogon OperatingSystem -------- --------- --------------- Computer0123A 1/26/2012 8:55:20 PM Windows 7 Enterprise .NOTES .LINK go.vertigion.com/PowerShell-Get-CompByActivity function Get-CompByActivity { param( [Alias("Name")] [parameter( Position = 0, Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "Enter the Name of a computer account." )] $ComputerNames , [parameter(Mandatory = $false)] [int] $DaysSinceLastLogon = 180 ) Begin { $OutputList = @() $Domain = $(Get-ADDomain).DNSRoot $DCs = Get-ADDomainController $TotalComputers = 0 function Measure-Latest { BEGIN { $latest = $null } PROCESS {if (($_ -ne $null) -and (($latest -eq $null) -or ($_ -gt $latest))) {$latest = $_}} END { $latest } } } Process { Write-Debug "ComputerNames: $ComputerNames" $TotalComputers += ($ComputerNames | Measure-Object).Count Write-Debug "ComputerNames Type: $(($ComputerNames.GetType()).Name)" switch -regex ($(($ComputerNames.GetType()).Name)) { "PSCustomObject|ADComputer" { foreach ($Computer in $ComputerNames) { Write-Debug "Computer: $Computer" $LastLogon = [datetime]::FromFileTime($($(foreach ($DC in $DCs) { (Get-ADComputer $Computer.Name -Server $DC.Name -Properties LastLogon).LastLogon }) | Measure-Latest)) if (($(Get-Date)-$LastLogon).Days -lt $DaysSinceLastLogon) { $NewObject = New-Object PSObject Add-Member -InputObject $NewObject NoteProperty 'Hostname' $Computer.Name.ToUpper() Add-Member -InputObject $NewObject NoteProperty 'LastLogon' $LastLogon Add-Member -InputObject $NewObject NoteProperty 'OperatingSystem' (Get-ADComputer ($Computer.Name) -Properties OperatingSystem).OperatingSystem $OutputList += $NewObject } } } default { Throw("Unable to handle that Type: $(($ComputerNames.GetType()).Name)") } } } End { Write-Debug "ComputerNames Type: $(($ComputerNames.GetType()).Name)" Write-Output "Active Computers: $($OutputList.Count)`nTotal Computers: $TotalComputers`nThe Active Computers are:" Write-Output $OutputList | sort @{expression="LastLogon";Ascending=$true},@{expression="Hostname";Ascending=$true} | ft -auto } }
Hope it helps others out there. Just add the function to your PowerShell Profile or as a Functions in a script to make it available!