PoshCode Logo PowerShell Code Repository

Get-ScriptCoverage.ps1 by Lee Holmes 3 years ago
embed code: <script type="text/javascript" src="http://PoshCode.org/embed/2164"></script>download | new post

From Windows PowerShell Cookbook (O’Reilly) by Lee Holmes

  1. #############################################################################
  2. ##
  3. ## Get-ScriptCoverage
  4. ##
  5. ## From Windows PowerShell Cookbook (O'Reilly)
  6. ## by Lee Holmes (http://www.leeholmes.com/guide)
  7. ##
  8. ##############################################################################
  9.  
  10. <#
  11.  
  12. .SYNOPSIS
  13.  
  14. Uses conditional breakpoints to obtain information about what regions of
  15. a script are executed when run.
  16.  
  17. .EXAMPLE
  18.  
  19. PS >Get-Content c:\temp\looper.ps1
  20.  
  21. param($userInput)
  22.  
  23. for($count = 0; $count -lt 10; $count++)
  24. {
  25.     "Count is: $count"
  26. }
  27.  
  28. if($userInput -eq "One")
  29. {
  30.     "Got 'One'"
  31. }
  32.  
  33. if($userInput -eq "Two")
  34. {
  35.     "Got 'Two'"
  36. }
  37.  
  38. PS >$action = { c:\temp\looper.ps1 -UserInput 'One' }
  39. PS >$coverage = Get-ScriptCoverage c:\temp\looper.ps1 -Action $action
  40. PS >$coverage | Select Content,StartLine,StartColumn | Format-Table -Auto
  41.  
  42. Content   StartLine StartColumn
  43. -------   --------- -----------
  44. param             1           1
  45. (                 1           6
  46. userInput         1           7
  47. )                 1          17
  48. Got 'Two'        15           5
  49. }                16           1
  50.  
  51. This example exercises a 'looper.ps1' script, and supplies it with some
  52. user input. The output demonstrates that we didn't exercise the
  53. "Got 'Two'" statement.
  54.  
  55. #>
  56.  
  57. param(
  58.     ## The path of the script to monitor
  59.     $Path,
  60.  
  61.     ## The command to exercise the script
  62.     [ScriptBlock] $Action = { & $path }
  63. )
  64.  
  65. Set-StrictMode -Version Latest
  66.  
  67. ## Determine all of the tokens in the script
  68. $scriptContent = Get-Content $path
  69. $ignoreTokens = "Comment","NewLine"
  70. $tokens = [System.Management.Automation.PsParser]::Tokenize(
  71.     $scriptContent, [ref] $null) |
  72.     Where-Object { $ignoreTokens -notcontains $_.Type }
  73. $tokens = $tokens | Sort-Object StartLine,StartColumn
  74.  
  75. ## Create a variable to hold the tokens that PowerShell actually hits
  76. $visited = New-Object System.Collections.ArrayList
  77.  
  78. ## Go through all of the tokens
  79. $breakpoints = foreach($token in $tokens)
  80. {
  81.     ## Create a new action. This action logs the token that we
  82.     ## hit. We call GetNewClosure() so that the $token variable
  83.     ## gets the _current_ value of the $token variable, as opposed
  84.     ## to the value it has when the breakpoints gets hit.
  85.     $breakAction = { $null = $visited.Add($token) }.GetNewClosure()
  86.  
  87.     ## Set a breakpoint on the line and column of the current token.
  88.     ## We use the action from above, which simply logs that we've hit
  89.     ## that token.
  90.     Set-PsBreakpoint $path -Line `
  91.         $token.StartLine -Column $token.StartColumn -Action $breakAction
  92. }
  93.  
  94. ## Invoke the action that exercises the script
  95. $null = . $action
  96.  
  97. ## Remove the temporary breakpoints we set
  98. $breakpoints | Remove-PsBreakpoint
  99.  
  100. ## Sort the tokens that we hit, and compare them with all of the tokens
  101. ## in the script. Output the result of that comparison.
  102. $visited = $visited | Sort-Object -Unique StartLine,StartColumn
  103. Compare-Object $tokens $visited -Property StartLine,StartColumn -PassThru
  104.  
  105. ## Clean up our temporary variable
  106. Remove-Item variable:\visited

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me