#requires -version 2.0 <# ----------------------------------------------------------------------------- Script: Get-RankedObject.ps1 Version: 1.0 Author: Jeffery Hicks http://jdhitsolutions.com/blog http://twitter.com/JeffHicks http://www.ScriptingGeek.com Date: 12/23/2011 Keywords: Objects, Grouping, Math Comments: "Those who forget to script are doomed to repeat their work." **************************************************************** * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED * * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK. IF * * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, * * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING. * **************************************************************** ----------------------------------------------------------------------------- #> Function Get-RankedObject { <# .Synopsis Return objects ranked by a given property value .Description This function will take a collection of objects and return a ranking based on a property value. The ranking is a weighted value between 1 and 10, with higher numbers representing more significant items. For example, you might pipe a group of files to this function and want a ranking based on size. The largest files will have a high ranking. The ranking is determined by taking the object's property value and calculating a logarithm using the largest property value as the base. You can pipe any type of object to the function, as long as the property value is numeric. The function will write objects to the pipeline that have a rank equal to or greater than the -Rank parameter. The default value is 1 which should return all objects. All objects will have an additional property called Rank. .Parameter Property The name of the object property to base ranking. The default is Length. .Parameter Inputobject The collection of objects to analyze and rank. .Parameter Rank The minimum rank to display. The default is 1 which should return all objects. The maximum rank should be 10. .Example PS C:\Files> dir | where {! $_.PSIsContainer} | get-rankedobject -rank 9 .Example PS C:\Files> dir | where {! $_.PSIsContainer} | get-rankedobject | group Rank | Sort {$_.Name -as [int]} .Example PS C:\> dir c:\scripts | where {$_.PSIscontainer} | select FullName,@{Name="Size";Expression={(dir $_ -rec | measure length -sum).sum}} | Get-RankedObject size -rank 1 | group rank .Example PS C:\> dir c:\scripts | Select Name,Fullname,Length,*Time,@{Name="FileAge";Expression={((Get-Date)-$_.LastWriteTime).TotalDays}} | Get-RankedObject FileAge -rank 10 -verbose .Example PS C:\> get-process | Where {$_.ProcessName -notmatch "Idle|System"} | get-rankedobject ws -verb -ea silentlycontinue | select ProcessName,WS,Rank | sort rank -descending .Link http://jdhitsolutions.com/blog/2011/12/friday-fun-get-ranked-object/ .Inputs Objects .Outputs Objects with a RANK property added #> [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) { #add each input object to the $data array for processing in the END script block $data+=$item #find the largest property value to use as the base 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 rank to the item Write-Debug "Adding Rank property to item" $item | Add-Member -MemberType NoteProperty -Name Rank -Value $ItemRank #and write to pipeline if rank -ge $rank 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 #create an alias New-Alias -Name gro -Value Get-RankedObject