by Klaus Graefensteiner
29. April 2010 13:16
Introduction
I was working on a SkyTap REST API client implementation in PowerShell and spent quite some time understanding the HTTPWebRequest object of the .Net Framework. The HTTPWebRequest object has a generic way to modify the HTTP Request headers and also some convenient properties to directly access the most common header values like for example the request method (GET, POST, PUT, DELETE etc.).
In my PowerShell scripts I wanted to use an convenient property, if it is available and if it isn’t modify the Headers collection instead. In order to do this I needed to check whether a property exists or not. This blog post is about my version of the Test-Member cmdlet.
Figure 1: The missing cmdlet
Features
This short cmdlet demonstrates some valuable advanced functions features:
- Advanced parameter binding
- Parameter sets
- Parameter validation
- PSUnit unit tests
Test-Member
Here is the script:
function Test-Member()
{
<#
.Synopsis
Verifies whether a specific property or method member exists for a given .NET object
.Description
Verifies whether a specific property or method member exists for a given .NET object
.Example
Test-Member -PropertyName "Context" -InputObject (new-object System.Collections.ArrayList)
.Example
new-object "System.Collections.ArrayList" | Test-Member -PropertyName "ToArray"
.Parameter PropertyName
Name of a Property to test for
.Parameter MethodName
Name of a Method to test for
.ReturnValue
$True or $False
.Link
about_functions_advanced
about_functions_advanced_methods
about_functions_advanced_parameters
.Notes
NAME: Test-Member
AUTHOR: Klaus Graefensteiner
LASTEDIT: 04/20/2010 12:12:42
#Requires -Version 2.0
#>
[CmdletBinding(DefaultParameterSetName="Properties")]
PARAM(
[ValidateNotNull()]
[Parameter(Position=0, Mandatory=$True, ValueFromPipeline=$True)]
$InputObject,
[ValidateNotNullOrEmpty()]
[Parameter(Position=1, Mandatory=$True, ValueFromPipeline=$False, ParameterSetName="Properties")]
[string] $PropertyName,
[ValidateNotNullOrEmpty()]
[Parameter(Position=1, Mandatory=$True, ValueFromPipeline=$False, ParameterSetName="Methods")]
[string] $MethodName
)
Process{
switch ($PsCmdlet.ParameterSetName)
{
"Properties"
{
$Members = Get-Member -InputObject $InputObject;
if ($Members -ne $null -and $Members.count -gt 0)
{
foreach($Member in $Members)
{
if(($Member.MemberType -eq "Property" ) -and ($Member.Name -eq $PropertyName))
{
return $true
}
}
return $false
}
else
{
return $false;
}
}
"Methods"
{
$Members = Get-Member -InputObject $InputObject;
if ($Members -ne $null -and $Members.count -gt 0)
{
foreach($Member in $Members)
{
if(($Member.MemberType -eq "Method" ) -and ($Member.Name -eq $MethodName))
{
return $true
}
}
return $false
}
else
{
return $false;
}
}
}
}# End Process
}
function Parse-XML([string] $XMLString, [String] $XPath, [int] $Status )
{
$XMLResult = [XML] $XMLString;
if($XMLResult -ne $null)
{
if($Status -eq 200)
{
$XPathSingle = $XPath.substring(0, $XPath.Length -1)
return $XMLResult.$XPath.$XPathSingle;
}
else
{
return $XMLResult.Error;
}
}
}
Unit Tests
Here are the unit tests:
. PSUnit.ps1
function Test.InputObjectFromPipelineReturnsTrueWhenLookingForToArrayMethodInArrayList()
{
#Arrange
#Act
$Result = new-object "System.Collections.ArrayList" | Test-Member -MethodName "ToArray"
#Assert
Assert-That -ActualValue $Result -Constraint {$ActualValue -eq $True}
}
function Test.InputObjectFromPipelineReturnsFalseWhenLookingForToArrayPropertyInArrayList()
{
#Arrange
#Act
$Result = new-object "System.Collections.ArrayList" | Test-Member -PropertyName "ToArray"
#Assert
Assert-That -ActualValue $Result -Constraint {$ActualValue -eq $False}
}
function Test.InputObjectFromPipelineReturnsTrueWhenLookingForCountPropertyInArrayList()
{
#Arrange
#Act
$Result = new-object "System.Collections.ArrayList" | Test-Member -PropertyName "Count"
#Assert
Assert-That -ActualValue $Result -Constraint {$ActualValue -eq $True}
}
function Test.InputObjectFromPipelineReturnsFalseWhenLookingForCountMethodInArrayList()
{
#Arrange
#Act
$Result = new-object "System.Collections.ArrayList" | Test-Member -MethodName "Count"
#Assert
Assert-That -ActualValue $Result -Constraint {$ActualValue -eq $False}
}
Download
The Cmdlet can be downloaded here: Test-Member.zip
Ausblick
That’s it.