PSelect.psm1
<#
.Synopsis Short description .DESCRIPTION Long description .EXAMPLE PSelect { Field company Field raisedAmt -as AvgRaisedAmt -Average -Unit Currency Field raisedAmt -as TotalRaisedAmt -Sum -Unit Currency Field raisedAmt -as MaxRaisedAmt -Maximum -Unit Currency Field raisedAmt -as Rounds -Count GroupBy company FromCsv "TechCrunchcontinentalUSA.csv" } #> function PSelect { [CmdletBinding()] Param ( # Param1 help description [Parameter(Mandatory=$true,Position=0)] [Scriptblock] $ScriptBlock, # Parameter help description [Parameter(ValueFromPipeline=$true)] [Object[]] $InputObject ) Begin { $PSelectParams = @{} } Process { if ($PSBoundParameters.ContainsKey('InputObject')) { FromPipeline -Object $InputObject } } End { & $ScriptBlock If (-not $PSelectParams.ContainsKey("GroupBy")) { Throw "GroupBy is required." } $groups = $PSelectParams.Data | Group-Object $PSelectParams.GroupBy If ($PSelectParams.ContainsKey("Sort")) { $groups = $groups | Sort-Object Name -Descending:$PSelectParams["Sort"] } foreach ($group in $groups) { $output = New-Object PSObject foreach ($field in $PSelectParams.Fields) { $propertyName = $field["Name"] $value = $group.Name if ($field.ContainsKey("As")) { $propertyName = $field["As"] } if ($field.ContainsKey("Aggregate")) { #$aggregates = $group.Group | # Measure-Object -Property $field["Name"] -Sum -Average -Maximum -Minimum switch ($field["Aggregate"]) { 'Average' { $value = ($group.Group | Measure-Object -Property $field["Name"] -Average).Average } 'Sum' { $value = ($group.Group | Measure-Object -Property $field["Name"] -Sum).Sum } 'Minimum' { $value = ($group.Group | Measure-Object -Property $field["Name"] -Minimum).Minimum } 'Maximum' { $value = ($group.Group | Measure-Object -Property $field["Name"] -Maximum).Maximum } 'StdDev' { $value = Get-StandardDeviation ($group.Group | Select-Object -ExpandProperty $field["Name"]) } Default { $value = $group.Count } } } # if ($field.ContainsKey("Unit")) { switch ($field["Unit"]) { 'Currency' {$value = $value.ToString("C")} #'Currency' { # $value = "{0,18:C}" -f $value #"{0,10:C}" -f 100 #} 'Percentage' {$value = $value.ToString("P")} } } if ($field.ContainsKey("Format")) { $value = $field["Format"] -f $value } $output | Add-Member -NotePropertyName $propertyName -NotePropertyValue $value } $output.PSObject.TypeNames.Insert(0, "PSelectRecord") $output } } } <# .Synopsis Short description .DESCRIPTION Long description .EXAMPLE Example of how to use this cmdlet .EXAMPLE Another example of how to use this cmdlet #> function Field { [CmdletBinding(DefaultParameterSetName="Default")] Param ( # Param1 help description [Parameter(Mandatory,Position=0)] [String] $Name, # Param2 help description [Parameter(Position=1)] [String] $As, [Parameter(Position=2,ParameterSetName="Unit")] [ValidateSet("Currency","Percentage","Seconds","Minutes","Hours","Days","Weeks","Months","Years")] [String] $Unit, [Parameter(Position=2,ParameterSetName="Format")] [String] $Format, [Switch] $Average, [Switch] $Sum, [Switch] $Minimum, [Switch] $Maximum, [Switch] $Count, [Switch] $StdDev ) Begin { If (-not $PSelectParams.ContainsKey("Fields")) { $PSelectParams.Add("Fields", (New-Object System.Collections.ArrayList)) } } End { $field = @{Name=$Name} if ($PSBoundParameters.ContainsKey("As")) { $field.Add("As", $As) } if ($PSBoundParameters.ContainsKey("Unit")) { $field.Add("Unit", $Unit) } if ($PSBoundParameters.ContainsKey("Format")) { $field.Add("Format", $Format) } if ($Average) { $field.Add("Aggregate", "Average") } elseif ($Sum) { $field.Add("Aggregate", "Sum") } elseif ($Minimum) { $field.Add("Aggregate", "Minimum") } elseif ($Maximum) { $field.Add("Aggregate", "Maximum") } elseif ($Count) { $field.Add("Aggregate", "Count") } elseif ($StdDev) { $field.Add("Aggregate", "StdDev") } $PSelectParams.Fields.Add($field) | Out-Null } } <# .Synopsis Short description .DESCRIPTION Long description .EXAMPLE Example of how to use this cmdlet .EXAMPLE Another example of how to use this cmdlet #> function GroupBy { [CmdletBinding()] Param ( # Param1 help description [Parameter(Mandatory=$true, Position=0)] [string[]] $Name ) If (-not $PSelectParams.ContainsKey("GroupBy")) { $PSelectParams.Add("GroupBy", ($Name)) } else { Throw "Only one source is supported." } } <# .Synopsis Short description .DESCRIPTION Long description .EXAMPLE Example of how to use this cmdlet .EXAMPLE Another example of how to use this cmdlet #> function FromCsv { [CmdletBinding(DefaultParameterSetName="csv")] Param ( # Param1 help description [Parameter(Mandatory=$true, Position=0, ParameterSetName="csv")] [string] $Path ) If (-not $PSelectParams.ContainsKey("Data")) { $PSelectParams.Add("Data", (Get-Content -Path $Path | ConvertFrom-Csv)) } else { Throw "Only one From statement is supported." } } <# .Synopsis Short description .DESCRIPTION Long description .EXAMPLE Example of how to use this cmdlet .EXAMPLE Another example of how to use this cmdlet #> function FromPipeline { [CmdletBinding()] Param ( # Param1 help description [Parameter(Mandatory=$true, Position=0, ParameterSetName="csv")] [Object[]] $Object ) If (-not $PSelectParams.ContainsKey("Data")) { $PSelectParams.Add("Data", (New-object Collections.ArrayList)) } $Object | Foreach-Object { $null = $PSelectParams["Data"].Add($PSItem) } } function SortData { [CmdletBinding(DefaultParameterSetName="Ascending")] param ( [Parameter(ParameterSetName="Ascending")] [Switch]$Ascending, [Parameter(ParameterSetName="Descending")] [Switch]$Descending ) If (-not $PSelectParams.ContainsKey("Sort")) { $dirDesc=$false if($Descending) { $dirDesc=$true } $PSelectParams.Add("Sort", $dirDesc) } else { Throw "Only one SortData statement is supported." } } function Get-StandardDeviation ([double[]]$numbers ) { $avg = $numbers | Measure-Object -Average | Select-Object Count, Average $popdev = 0 foreach ($number in $numbers){ $popdev += [math]::pow(($number - $avg.Average), 2) } $sd = [math]::sqrt($popdev / ($avg.Count-1)) return $sd } |