ScriptVersion.psm1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<#
.SYNOPSIS
PowerShell commandlet returning script version information.
 
.LINK
https://github.com/alekdavis/ScriptVersion
#>


#Requires -Version 4.0

<#
.SYNOPSIS
Returns a hash table with name-value pairs of the properties defined in the
NOTES section of the script's comment-based help header.
 
.DESCRIPTION
Use this function to get script's notes, such as version, copyright information,
and so on. The name-value pairs in the NOTES section must be single-line and
separated by colons (':'), such as:
 
  version : 1.2.0
  copyright : (c) My Company 2019
 
MAKE SURE THAT THE COMMENT HEADER IS AT THE TOP OF THE SCRIPT AND IS PRECEDED
AND FOLLOWED BY AT LEAST ONE BLANK LINE; OTHERWISE, GET-HELP AND GETVERSION
COMMANDS WILL NOT WORK.
 
.PARAMETER ScriptPath
Optional path to the script. If not specified, the calling script will be used.
 
.EXAMPLE
$notes = Get-ScriptVersion
Returns the contents of the NOTES section of the calling script.
 
.EXAMPLE
$notes = Get-ScriptVersion -ScriptPath "C:\Scripts\MyScript.ps1"
Returns the contents of the NOTES section of the specified script.
 
.EXAMPLE
$version = (Get-ScriptVersion)["version"]
Returns the value of the 'version' element of the NOTES section of the calling script.
#>


function Get-ScriptVersion {
    [CmdletBinding()]
    param (
        [string]
        $ScriptPath = $null,

        [string]
        $KeyValueSeparator = ':',

        [string]
        $CommentIndicator = '#'
    )

    # Allow module to inherit '-Verbose' flag.
    if (($PSCmdlet) -and (-not $PSBoundParameters.ContainsKey('Verbose'))) {
        $VerbosePreference = $PSCmdlet.GetVariableValue('VerbosePreference')
    }

    # Allow module to inherit '-Debug' flag.
    if (($PSCmdlet) -and (-not $PSBoundParameters.ContainsKey('Debug'))) {
        $DebugPreference = $PSCmdlet.GetVariableValue('DebugPreference')
    }
    
    $notes = $null
    $notes = @{}

    # If script path is missing, use the running script.
    if (!$ScriptPath) {
        # If the invoking script is a module, check the caller.
        if ($PSCmdlet) {
            $ScriptPath = $MyInvocation.PSCommandPath
        }
        else {
            $ScriptPath = $PSCommandPath
        }
    }

    # Get the .NOTES section from the script header comment.
    $notesText = (Get-Help -Full $ScriptPath).alertSet.alert.Text

    if (!$notesText) {
        return $notes
    }

    # Split the .NOTES section by lines.
    $lines = ($notesText -split '\r?\n').Trim()

    # Iterate through every line.
    foreach ($line in $lines) {
        if (!$line) {
            continue
        }

        $name  = $null
        $value = $null

        # Split line by the first colon (:) character.
        if ($line.Contains($KeyValueSeparator)) {
            $nameValue = $null
            $nameValue = @()

            $nameValue = ($line -split $KeyValueSeparator,2).Trim()

            $name = $nameValue[0]

            if ($name) {
                $name = $name.Trim()
                
                # If name starts with hash, it's a comment, so ignore.
                if ($CommentIndicator -and ($name -match "^$CommentIndicator")) {
                    continue
                }

                $value = $nameValue[1]

                if ($value) {
                    $value = $value.Trim()
                }

                if (!($notes.ContainsKey($name))) {
                    $notes.Add($name, $value)
                }
            }
        }
    }

    return $notes
}

#------------------------------------------------------------------------------
Export-ModuleMember -Function *