PublishPsGalleryModule.ps1

#requires -Modules PowerShellGet


$ReleaseNotes =@'

IPv6Regex
 
Chris Warwick, @cjwarwickps, October 2015
 
This PowerShell script tests a number of regular expressions that match text representations of IPv6 addresses.
The script also runs the sample test cases against the [System.Net.IpAddress]::TryParse() method to illustrate
some subtle considerations with address validation.
 
See the comments at the end of the script file for further detailed notes and references.
 
Script Structure
----------------
 
This script is split into four sections:
 
1. The first section defines an IPv6 regex to the tested against a set of sample addresses. A number of other
Regexs gathered from across the web are also defined here.
    
2. Following the regex definitions, an array of test script-blocks is defined. Each script block takes a test
IPv6 address as a parameter and tests this address against a specific regex or against the IpAddress.TryParse()
method. The script blocks return true if the address is considered valid by the test or false otherwise.
 
3. The next (largest) section of the script defines sample IPv6 addresses to be tested. There are a large number
of both valid and invalid address representations defined.
    
4. The final section of the script runs the tests. Each test script block is selected in turn and the test
addresses are matched against the script blocks. Each test returns a test result object containing details of the
individual test. The tests are timed to allow comparison of the performance of each test method (use the -Verbose
switch to view timings).
 
**NOTE**: The output of this script is most useful as a consolidated report. Consequently, the script 'breaks the
rules' somewhat by including output formatting. This behaviour can be changed by specifying the '-NoFormat'
switch parameter to instruct the script to pass test-result objects to the output pipeline (these can then be
formatted or collected as required).
 
 
Results
-------
 
Unsurprisingly, a number of regexs found on the web are invalid (only one is included here, others have been
omitted). Beware of using random regexs without testing them.
 
There are some subtleties with the operation of the IpAddress.TestParse() method:
 
1. The IpAddress.TryParse() methods allow leading zeroes in the IPv4 octets. This is actually explicitly invalid
in the definition in rfc3986 (apparently some systems(?) use a leading zero to denote an Octal number in the IPv4
Octet).
 
2. The IpAddress::TryParse method does not accept leading elided-zeroes syntax: ('::....') if there is only one
group (the first group) of the address mising - although this is valid according to the RFC. So, for example,
::2:3:4:5:6:7 is considered valid by IpAddress.TryParse(), but ::2:3:4:5:6:7:8 isn't
 
3. The IpAddress.TryParse() method by default accepts IPv4 addresses; these can be qualified by checking the
address against the [System.Net.Sockets.AddressFamily]::InterNetworkV6 type
 
Compiling regexs is an expensive operation, and even for the relatively large number of tests defined here it can
be seen from the timing information that the investment is not warranted in this case.
 
Although the IpAddress.TryParse() method has some idiosyncrasies it may be preferred to the regex matching methods
given the complexity of these regexs (IpAddress.TryParse() is probably equally as complex but the at least the
complexity is hidden :-)
 
Script Help
-----------
````

<#
.SYNOPSIS
   Tests IPv6 Regex patterns against a large number of sample test addresses.
.DESCRIPTION
   This function tests a number of IPv6 regexs against a selection of valid and invalid
   IPv6 addresses to verify that the regexs perform as expected. The function also tests
   the sample addresses using the [System.Net.IpAddress]::TryParse() method to illustrate
   the performance and conformance of this method.
.NOTES
   The script will time the relative performance of the various regexs; use the -Verbose
   switch to display the timimg information.
.PARAMETER TestName
   If specified, only run tests with names matching this.
.PARAMETER NoFormat
   Provide raw output objects for each test. The default is to select only failing test
   result objects and to format the resulting output. Use this parameter if you wish to
   use a different selection or formatting option to the default provided here.
.EXAMPLE
   IPv6Regex
   Run all tests and display those that fail.
.EXAMPLE
   IPv6Regex -Verbose
   Run all tests; additionally display relative performance timings.
.EXAMPLE
   IPv6Regex -TestName 'compiled'
   Only run tests where the test name includes the string 'compiled'.
.EXAMPLE
   IPv6Regex -NoFormat
   Run all tests and output a raw RegexMatchResult object for each test.
.INPUTS
   None
.OUTPUTS
   By default, outputs formated table of failing tests. Use -NoFormat to output raw objects.
.FUNCTIONALITY
   Test IPv6 Regexs against sample IPv6 Addresses.
.LINK
   http://github.com/ChrisWarwick/IPv6Regex
#>

 
````
 
 
Sample Output
-------------
**Note:** By default the script will only output results of failed tests (use the -NoFormat parameter to change
this behaviour). As illustrated below, use the -Verbose switch to display relative timing information.
 
````
 
PS:\> Import-Module IPv6Regex
PS:\> IPv6Regex -Verbose
VERBOSE: 0 of 470 unique tests failed in 75ms for 'IPv6 Regex'
VERBOSE: 0 of 470 unique tests failed in 174ms for 'Compiled IPv6 Regex'
VERBOSE: 19 of 470 unique tests failed in 88ms for 'Php1'
VERBOSE: 0 of 470 unique tests failed in 98ms for 'RegexBuddy'
VERBOSE: 0 of 470 unique tests failed in 142ms for 'Compiled RegexBuddy'
VERBOSE: 11 of 470 unique tests failed in 120ms for 'Net IpAddress TryParse() Method'
VERBOSE: 8 of 470 unique tests failed in 180ms for 'Qualified Net IpAddress TryParse() Method'
VERBOSE: 0 of 470 unique tests failed in 202ms for 'Aeron Regex'
 
TestName TestAddress ExpectedResult ActualResult
-------- ----------- -------------- ------------
Php1 ::0:0:0:0:0:0:0 True False
Php1 ::0:a:b:c:d:e:f True False
Php1 ::2:3:4:5:6:7:8 True False
Php1 ::2222:3333:4444:5555:6666:123.123.123.123 True False
Php1 ::2222:3333:4444:5555:6666:7777:8888 True False
Php1 :1.2.3.4 False True
Php1 :10.0.0.1 False True
Php1 :2222:3333:4444:5555:6666:1.2.3.4 False True
Php1 :3333:4444:5555:6666:1.2.3.4 False True
Php1 :4444:5555:6666:1.2.3.4 False True
Php1 :5555:6666:1.2.3.4 False True
Php1 :6666:1.2.3.4 False True
Php1 0:0:0:0:0:0:0:: True False
Php1 0:a:b:c:d:e:f:: True False
Php1 1111:2222:3333:4444:5555:6666:00.00.00.00 False True
Php1 1111:2222:3333:4444:5555:6666:000.000.000.000 False True
Php1 1111:2222:3333:4444:5555:6666:7777:: True False
Php1 a:b:c:d:e:f:0:: True False
Php1 fe80:0000:0000:0000:0204:61ff:254.157.241.086 False True
Net IpAddress TryParse() Method ::0:0:0:0:0:0:0 True False
Net IpAddress TryParse() Method ::0:a:b:c:d:e:f True False
Net IpAddress TryParse() Method ::2:3:4:5:6:7:8 True False
Net IpAddress TryParse() Method ::2222:3333:4444:5555:6666:123.123.123.123 True False
Net IpAddress TryParse() Method ::2222:3333:4444:5555:6666:7777:8888 True False
Net IpAddress TryParse() Method 1.2.3.4 False True
Net IpAddress TryParse() Method 1111 False True
Net IpAddress TryParse() Method 1111:2222:3333:4444:5555:6666:00.00.00.00 False True
Net IpAddress TryParse() Method 1111:2222:3333:4444:5555:6666:000.000.000.000 False True
Net IpAddress TryParse() Method 123 False True
Net IpAddress TryParse() Method fe80:0000:0000:0000:0204:61ff:254.157.241.086 False True
Qualified Net IpAddress TryParse() Method ::0:0:0:0:0:0:0 True False
Qualified Net IpAddress TryParse() Method ::0:a:b:c:d:e:f True False
Qualified Net IpAddress TryParse() Method ::2:3:4:5:6:7:8 True False
Qualified Net IpAddress TryParse() Method ::2222:3333:4444:5555:6666:123.123.123.123 True False
Qualified Net IpAddress TryParse() Method ::2222:3333:4444:5555:6666:7777:8888 True False
Qualified Net IpAddress TryParse() Method 1111:2222:3333:4444:5555:6666:00.00.00.00 False True
Qualified Net IpAddress TryParse() Method 1111:2222:3333:4444:5555:6666:000.000.000.000 False True
Qualified Net IpAddress TryParse() Method fe80:0000:0000:0000:0204:61ff:254.157.241.086 False True



 Version History:

 V1.1 (This version)
  - Updated inline help and Readme

 V1.0
  - Initial release to the PowerShell Gallery and TechNet Script Center

 V0.1-0.9 Dev versions


'@


$Tags = @(
   'Regex'
   'PowerShell'
   'IPv6'
   'IpAddress'
   'Network'
   'Address'
   'rfc4291'
   'rfc5952'
   'rfc3986'
   'rfc4007'
)

$PublishParams = @{
    Name            = 'IPv6Regex'
    NuGetApiKey     = 'XXXXRedactedXXXX'
    ReleaseNotes    = $ReleaseNotes
    Tags            = $Tags
    ProjectUri      = 'https://github.com/ChrisWarwick/IPv6Regex'
}



Publish-Module @PublishParams


# ...later

# Find-Module IPv6Regex