Getting ever more ambitious with PowerShell scripts - some
over 1000 lines, and growing all the time - I thought it would be useful to
have an index/contents page of functions at the start of the script (my
PowerShell editor of choice is NotePad++.)
The below script can be run as:
.\Index-Functions.ps1
filename.ps1
And it puts the index at the start of the PowerShell
script/updates the index. It uses a couple of useful additional functions that
are included below.
The Script -
Index-Functions.ps1
Apologies for the
formatting, I really should use something else for posting PS Scripts!
# START OF SCRIPT #
## Function Pad-Right ##
## ================== ##
Function
Pad-Right{
Param([String]$in, [Int]$padR = 30,
[String]$pad = " ")
$in.PadRight($padR,$pad).SubString(0,$padR)
}
## Function Prompt-Menu ##
## ==================== ##
Function
Prompt-Menu{
# DESCRIPTION:
Prompts for valid answers to a menu.
# PARAMETER
$args[0]: The question
# PARAMETER
$args[1]/$args[1..X]: An array with answers in / the answers
$question = $args[0]
# Check if $args[1]
is an array (i.e. has more than 1 element)
If(($args[1].count) -ne 1){
$answers = $args[1] # Possible answers is array $args[1]
} else {
$answers = $args[1..(($args.count)-1)] # Possible answers are args 1 to ...
}
# Checks if
the answer ($readIn) is valid
do {
$readIn = Read-Host
"$question"
$readIn = $readIn.ToUpper()
foreach($answer in $answers){
if($readIn -eq
$answer.ToUpper()){return $readIn}
}
} while($true) #
An infinite loop!
}
## Function Index-Functions ##
## ======================== ##
Function
Index-Functions {
#
DESCRIPTION: Injects/Updates an Index of Functions at the start of the script.
# PARAMETER
filename: Name of the PS script file to be indexed.
Param([String]$filename)
If(!$filename){return} # If
no filename paramater - return
If(!(Test-Path $filename)){return} # If test-path fails - return
$contents = Get-Content $filename # Get contents of
the file
If(!$contents){return} # If no
contents (empty file) - return
#
$indexDisplay starts with a basic header
$indexDisplay =
"<#","Line
Function","~~~~
~~~~~~~~"
# Check for an
existing index ($hasIndex = true/false) #
#
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
If($contents[1] -eq "Line Function"){
$hasIndex = $true # We
have an index
$endOfIndex = $false # Not
found the end of the existing index
$contentRows = $contents.Count # Count the number of rows in $contents
$i=3 #
Check from 4th line since header is 3 lines (arrays start at 0)
do {
#
We're looking for the #> at the end of the index
If($contents[$i].contains("#>")){
$endOfIndex = $true # Found the end of the index
# Remove the index from the $contents
# ($i+2 because
have a blank line after the index)
$contents =
$contents[($i+2)..$contentRows]
}
$i++ # Accumlate $i for the next row
} while (!$endOfIndex) # Stops when found end of index
}else{$hasIndex = $false} # Othewise there is no index
# Search $contents
for functions and create the index #
#
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
$i = 1 # Start on
line 1 of the script
$index = @() #
Initialize the index array
foreach ($content in $contents){
$capitalize = $content.ToUpper() # Capitalized version of the row
# For
a Function we expect FUNCTION at the start of the line
If($capitalize.StartsWith("FUNCTION")){
$split =
$content.Split("{") # Split row at "{" to get [0] "Function
Name"
$split =
$split[0].Split(" ") # Split at "
" to get [1] "Name"
$index += $i #
Add line number to index array
$index += $split[1] # Add
Function name to array
}
$i ++ #
Accumlate $i for the next row
}
# Construct the
index #
#
~~~~~~~~~~~~~~~~~~~ #
$i = 0
$linesInIndex = ($index.count / 2) # $linesInIndex has 'line number', 'function name'...
do {
# Take
line number from $index, add number of lines in the index to it,
# +5 for index
header and footer
$lineNumber
= ($index[2*$i] + $linesInIndex + 5).ToString()
# Add
to IndexDisplay line number with a ')', and
# pad it right
with " " for 6 columns; then add the function name
$indexDisplay += (Pad-Right
($lineNumber + ")") 6) + ($index[2*$i+1])
$i++ # Accumulate $i for the next
row
} while ($i -lt $linesInIndex)
$indexDisplay +=
"#>","" # Adds a footer to
the index
# Displays the
index, prompt (Y/N), inject new/updated index into script file #
#
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
""
$indexDisplay #
Display the Index
# Change
screen output depending on whether the file had an index before
If ($hasIndex){$bleep = "replace the
index at"}else{$bleep = "be added to"}
"The above Index will $bleep the
start of $filename."
"The last saved version will be
saved with the .backup extension.";""
# Uses
Prompt-Menu function with Y/N as the only possible answers
$answer = Prompt-Menu "Do you want
to continue (Y/N)?" "Y" "N"
If($answer -eq "Y"){
$backupFile = $filename +
".backup"
If(Test-Path
$backupFile){Remove-Item $backupFile}
Rename-Item $filename $backupFile
[Void](New-Item $filename -type
file -force)
$indexDisplay += $contents # Contents is added to index (at start of file)
$indexDisplay | Out-File $filename
}
""
}
Index-Functions
$args[0]
# END OF SCRIPT #
Comments
Post a Comment