Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Measure-ScriptCode calculates some metrics about the PowerShell script files and modules it is fed, like number of comments and lines-of-code.
# Measure-ScriptCode.ps1
# Return metrics about the script and module files
# This is the PowerShell 2 version; AST is NOT used (PowerShell 3 is required for AST)
# Jan 2014
# If this works, Victor Vogelpoel <victor@victorvogelpoel.nl> wrote this.
# If it doesn't, I don't know who wrote this.
#
# Disclaimer
# This script is provided AS IS without warranty of any kind. I disclaim all implied warranties including, without limitation,
# any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or
# performance of the sample scripts and documentation remains with you. In no event shall I be liable for any damages whatsoever
# (including, without limitation, damages for loss of business profits, business interruption, loss of business information,
# or other pecuniary loss) arising out of the use of or inability to use the script or documentation.
#requires -version 2
Set-PSDebug -Strict
Set-StrictMode -Version Latest
function Measure-ScriptCode
{
[CmdletBinding()]
param
(
[Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, HelpMessage="One or more PS1 or PSM1 files to calculate code metrics for")]
[Alias('PSPath', 'Path')]
[string[]]$ScriptFile
)
begin
{
$files = 0
$modules = 0
$manifests = 0
$lines = 0
$words = 0
$characters = 0
$codeLines = 0
$comments = 0
}
process
{
foreach ($file in $ScriptFile)
{
if ($file -like "*.ps1") { $files++ }
if ($file -like "*.psm1") { $modules++ }
if ($file -like "*.psd1") { $manifests++ }
$fileContentsArray = Get-Content -Path $file
if ($fileContentsArray)
{
# First, measure basic metrics
$measurement = $fileContentsArray | Measure-Object -Character -IgnoreWhiteSpace -Word -Line
$lines += $measurement.Lines
$words += $measurement.Words
$characters += $measurement.Characters
# Next, use AST to extract more complex metrics
$tokenAst = [System.Management.Automation.PSParser]::Tokenize($fileContentsArray, [ref]$null)
# Get the number of comment lines and comments on the end of a code line
$comments += @($tokenAst | where { $_.Type -eq "Comment" } ).Length
# Calculate the lines of code: remove comment tokens from the the tokenAst, remove all double newlines and count all the newlines (minus 1)
$prevTokenIsNewline = $false
$codeLines += @($tokenAst | select -ExpandProperty Type | where { $_ -ne "comment" } | where {
if ($_ -ne "NewLine" -or (!$prevTokenIsNewline))
{
$_
}
$prevTokenIsNewline = ($_ -eq "NewLine")
} | where { $_ -eq "NewLine" }).Length-1
}
}
}
end
{
return [PSCustomObject]@{
Files = $files
Modules = $modules
Manifests = $manifests
CodeLines = $codeLines
Comments = $comments
Characters = $characters
Lines = $lines
Words = $words
}
}
}
Measure-ScriptCode -ScriptFile (Join-Path (Split-Path $MyInvocation.MyCommand.Path) "Write-HelloWorld.ps1")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.