The goal is to implement an advanced function Get-ObjectAge.
It should be a generic function to used with any group of objects as input. The output should show the object’s creation time, when it was last modified, and its age from creation. Additionally it has to indicate if the age is above or below, the average of all processed objects.
Reference: https://ironscripter.us/a-powershell-object-age-challenge/
- datetime
- timespan
- numbers (ticks)
- creation date (the lower, the older)
- modification date
- last logon
- dayssince, secondes since epoch (...)
- elapsed time (the higher the older)
- file
- directory
- AD
- Name of a property to be checked
- InputObject parameter
- via pipeline
- there are a lot of flavours of property names
- allow some common one by alias
- go with a pipeline design This would make it easy to handle objects of any kind in a really powershelly way.
- assume the properties to be tracked can be converted into
datetime
- keep the property names of the create/modify date attributes on output
The framework consists of a "08/15" design of a function accepting an array of (untyped) objects by parameter as well as by pipeline
function Get-ObjectAge {
[CmdletBinding()]
param (
# Any Input object to get an anti-aging check
[Parameter(Position=0, ValueFromPipeline, ValueFromPipelineByPropertyName, Mandatory=$true)]
[System.Object[]] $InputObject
# ...
)
begin {
...
}
process {
foreach ($item in $InputObject) {
...
}
}
end {
...
}
}
To be able to calculate the average of all objects (and still be pipeline ready) the container for the necessary data has to be instanciated in the begin block and evaluated in the end block. I decided to use a queue to easyly keep the order of the input objects in place and because the number of items to be stored is unknown.
begin {
$queue = [System.Collections.Queue]::new()
}
The main loop just creates a custom object storing the dates and a properties for age and the indicator above yes or no.
foreach ($item in $InputObject) {
$objHash = [ordered] @{
AboveAvg = $false
Age = ...
CreateDateProperty = [datetime] $item.$CreateTimeProperty
ModifyDateProperty = [datetime] $item.$ModifyTimeProperty
}
$obj = [PSCustomObject] $objHash
$queue.Enqueue( $obj )
}
In the end, the average is calculated and the indicator adjusted. Measure-Object cannot handle datetime directly so ticks are used instead.
$avgCreatedate = $queue.$CreateTimeProperty.Ticks | Measure-Object -Average
foreach ($item in $queue) {
if ( $item.$CreateTimeProperty.Ticks -gt $avgCreatedate.Average ) { $item.AboveAvg = $true }
$item
}
The final version handles some cases when properties do not exists or return non datetime
results.
And it adds support for displaying additional object properties as well as some default property names when using verious objects via pipeline.