# encoding: ascii
# api: powershell
# title: Test-IPMask
# description: The .NET framework has the System.Net.IPAddress class which can be used to validate a string as an IP address. I wanted to do the same with IP masks as well and came up with this script.
# version: 1.0.0
# type: script
# author: Rich Kusak 
# license: CC0
# x-poshcode-id: 2439
# x-archived: 2011-04-24T10:07:20
# x-published: 2011-01-04T22:53:00
#
#
<#
	.SYNOPSIS
		Tests for a valid IP mask.
	
	.DESCRIPTION
		The Test-IPMask script validates the input string against all CIDR subnet masks and returns a boolean value.
	
	.PARAMETER IPMask
		The IP mask to be evaluated.
	
	.EXAMPLE
		Test-IPMask 255.255.255.0
		Description
		-----------
		Tests if the IP mask "255.255.255.0" is a valid CIDR subnet mask.
	
	.INPUTS
		System.String
		
	.OUTPUTS
		System.String
		System.Boolean
	
	.NOTES
		Name: Test-IPMask.ps1
		Author: Rich Kusak (rkusak@cbcag.edu)
		Created: 2011-01-03
		LastEdit: 2011-01-05 00:49
		Version 1.0.0
		
		#Requires -Version 2.0

	.LINK
		http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing

	.LINK
		about_regular_expressions
	
#>

	[CmdletBinding()]
	param (
		[Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
		[string]$IPMask
	)

	begin {

		# Common subnet mask values
		$common = '0|128|192|224|240|248|252|254|255'
		
		# Build a regular expression to represent all possible mask strings
		$masks = @(
			"(^($common)\.0\.0\.0$)"
			"(^255\.($common)\.0\.0$)"
			"(^255\.255\.($common)\.0$)"
			"(^255\.255\.255\.($common)$)"
		)
		
		# Join all possible strings with the regex "or" operator
		$regex = [string]::Join('|', $masks)
	}

	process {

		# Evaluate the IPMask input and output the result
		[regex]::Match($IPMask, $regex) | Select @{name='IPMask' ; expression={$IPMask}},
			@{name='Valid' ; expression={$_.Success}}
	}
