Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Friday Fun – Get Ranked Object

Posted on December 23, 2011

Earlier this week on Google Plus, Hal Rottenberg posted a PowerShell idea he had. His goal was to identify a group of objects that would be statistically significant. For example, given a collection of files, group the files by size but ranked by size so that you might have a group for the largest files, then big files, then average files and finally small files. His idea was to calculate a rank using a logarithm of the file size. His code was quick and dirty so I took it, as I usually do, and ran with it. The result is a function that will analyse any group of objects and rank them based on a numeric property.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

The essence of the function is to take the property value and calculate its log using the largest property value as the base. If we use a file as an example, suppose the largest file size is 12500. Calculating the log of other file size with this as the base provides results like this:


PS S:\> [math]::log(12345,12500)
0.998677315654261
PS S:\> [math]::log(1244,12500)
0.755403553050584
PS S:\> [math]::log(123,12500)
0.510117406729404
PS S:\> [math]::log(90,12500)
0.47700401112898
PS S:\>

The larger the file, the higher the log which we can use as a rank. In my final code I multiply this value by 10.


[int32]$Itemrank=[math]::log($item.$property,$base)*10

I wanted the function to be able to handle any type of object, as long as it had a numeric property you could analyze. Since I assumed most people would use it on file objects, I set the default property to be Length.


Function Get-RankedObject {

[cmdletbinding()]

Param(
[Parameter(Position=0)]
[ValidateNotNullOrEmpty()]
[string]$Property="Length",
[Parameter(Position=1,Mandatory=$True,HelpMessage="You must specify an object",ValueFromPipeline=$True)]
[ValidateNotNullOrEmpty()]
[object[]]$InputObject,
[ValidateScript({$_ -gt 0 -AND $_ -le 10})]
[int32]$Rank=1
)

Begin {
Write-Verbose "Starting $($myinvocation.myCommand)"
Write-Verbose "Analyzing objects based on $property property"
Write-Verbose "Writing objects to the pipeline with a ranking of at least $Rank"
#define the log base
$base=1
#define an empty array to hold processed objects
$data=@()
Write-Debug "End of Begin script block"
} #Begin

Process {

foreach ($item in $Inputobject) {
$data+=$item

if ($item.$property -gt $base) {
$base=$item.$property
Write-Debug "base=$base"
}

} #foreach
Write-Debug "End of Process script block"
} #Process

End {
Write-Debug "Processing each item in data"
Write-Verbose "Base value is $Base"
Foreach ($item in $data) {
#calculate the rank if the property value is greater than 0
Write-Debug "Ranking value $($item.$property)"
if ($item.$property -le 0) {
$ItemRank=0
}
else {
[int32]$Itemrank=[math]::log($item.$property,$base)*10
}
Write-Debug "ItemRank will be $ItemRank"

#add it to the item and write to pipeline if rank -ge $rank
Write-Debug "Adding Rank property to item"
$item | Add-Member -MemberType NoteProperty -Name Rank -Value $ItemRank

if ($item.Rank -ge $Rank) {
Write-Output $item
}
} #foreach

Write-Verbose "Processed $($data.count) objects"
Write-Verbose "Exiting $($myinvocation.mycommand)"
Write-Debug "End of End script block"

} #end

} #end function

The assumption is that you will pipe objects into the function. If you want to rank objects on a different property, then use the -Property parameter. As each object is analyzed I add a custom property called Rank.


$item | Add-Member -MemberType NoteProperty -Name Rank -Value $ItemRank

By default the function will write all objects to the pipeline. But if you prefer, you can use the -Rank parameter to filter out objects with a low rank. For example, if you run a command using -rank 8, then only objects with a rank value of 8 and above will be written to the pipeline. Here some examples of this function in use.

Command help includes another of other examples as well. I'm sure there are a number of ways you could determine what is significant, but this approach seems to work for me and has been pretty consistent. But I hope you'll download it, try it out, and let me know. The download version will also create an alias, gro, for the function, so comment that out if you don't want to use it.

Download Get-RankedObject.


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d