My suggestions:
The script (rewritten almost completely):
<#
SYNOPSIS: Calculates simple size metrics about code projects.
Combination of `Get-ChildItem`, `Get-Content` and `Measure-Object`
Parameter Meaning (see native cmdlet)
--------- ---------------------------
-Path obvious (Convert-Path, Get-ChildItem, Get-Item, Push-Location)
-LiteralPath obvious (Convert-Path, Get-ChildItem, Get-Item, Push-Location)
-Filter obvious (Get-ChildItem)
-IgnoreWhiteSpace obvious (Measure-Object)
-Detailed returns size metrics about individual files severally
-PushLocation side effect: `Push-Location`
RETURNS: Custom combination of GenericMeasureInfo and TextMeasureInfo:
Name Type Meaning
---- ---- -------
Count [int] number of files of given pattern in given (literal)path
Lines [int] number of lines
Words [int] number of words
Characters [int] number of characters
Property [string] tested path
#>
Set-StrictMode -Version latest
Function Measure-Project
{
[CmdletBinding(DefaultParameterSetName='Items')]
Param(
[Alias('projectPath')]
[Parameter(Mandatory=$false,
Position=0,
ParameterSetName='Items')]
[string]$Path='.\',
[Parameter(Mandatory=$false,
Position=0,
ParameterSetName='LiteralItems')]
[string]$LiteralPath='.\',
[Alias('fileFilter')]
[Parameter(Mandatory=$false,
Position=1)]
[string]$Filter='*.ps1',
[Alias('IgnoreWS')]
[switch]$IgnoreWhiteSpace,
[Alias('PushD')]
[switch]$PushLocation,
[switch]$Detailed
)
Function out ($Cnt, $Prm, $Obj) {
$auxCounter = $Obj | Measure-Object -Character -Word -Line @auxParMO
$auxCounter | Add-Member -NotePropertyName Count -NotePropertyValue $Cnt
$auxCounter.Property = $Prm
return $auxCounter
}
if ( $PSCmdlet.ParameterSetName -eq 'LiteralItems') {
$auxParTP = @{ LiteralPath = $LiteralPath }
} else {
$auxParTP = @{ Path = $Path }
}
if ( Test-Path @auxParTP ) {
$auxPath = Convert-Path @auxParTP
if ( (Get-Item @auxParTP) -is [System.IO.DirectoryInfo]) {
$auxFiles = Get-ChildItem @auxParTP -Filter $Filter -Recurse -File
$auxParMO = @{ IgnoreWhiteSpace = $IgnoreWhiteSpace.IsPresent }
# $PSBoundParameters.ContainsKey('IgnoreWhiteSpace')
if ($Detailed.IsPresent -and $auxFiles) {
$auxFiles | ForEach-Object {
out -Cnt 1 -Prm $_.FullName -Obj ($_ | Get-Content)
}
} else {
$auxPar = Join-Path -Path $auxPath -ChildPath $Filter
if ( $auxFiles ) {
if ( $auxFiles -is [array] ) {
$auxCnt = $auxFiles.Count
} else {
$auxCnt = 1
}
out -Cnt $auxCnt -Prm $auxPar -Obj ($auxFiles | Get-Content)
} else {
Write-Warning "No '$Filter' inside '$Path'"
out -Cnt 0 -Prm $auxPar -Obj ''
}
}
if ( $PushLocation.IsPresent ) {Push-Location @auxParTP}
} else {
$auxMsg = "'$($auxParTP.Values.GetEnumerator())' is not a directory"
Write-Error -Message $auxMsg -Category InvalidArgument
}
}
else
{
$auxMsg = "Cannot find path '$($auxParTP.Values.GetEnumerator())'"
Write-Error -Message $auxMsg -Category ObjectNotFound
}
}
Sample output demonstrates necessity of -Encoding
parameter as both files contain nearly the same text so the utility should show the same count of characters. Of course, I'd expect the same encoding of source files in a particular project so sorry for the following simplified example:
PS D:\PSh> Measure-Project -LiteralPath 'D:\bat\[source]\XX\' -filter * -Detailed | ft
Count Lines Words Characters Property
----- ----- ----- ---------- --------
1 1 5 118 D:\bat\[source]\XX\[sourcefile].log
1 1 5 59 D:\bat\[source]\XX\[sourcefile].txt
PS D:\PSh> type -LiteralPath 'D:\bat\[source]\XX\[sourcefile].txt'
Toto je obsah souboru `D:\bat\[source]\XX\[sourcefile].txt`
PS D:\PSh> type -LiteralPath 'D:\bat\[source]\XX\[sourcefile].log' -Encoding Unicode
Toto je obsah souboru `D:\bat\[source]\XX\[sourcefile].log`