PoshCode Archive  Artifact [c06dfc24cb]

Artifact c06dfc24cb4d512b997df8afbb83135ba26b0324c70349709a67ccb7c620fe7c:

  • File Export-CustomProperty.ps1 — part of check-in [bf25145342] at 2018-06-10 13:07:59 on branch trunk — An example of making “custom objects” with strongly-typed properties, custom enumeration/validation and error messages. (user: unknown size: 4033)

# encoding: ascii
# api: powershell
# title: Export-CustomProperty
# description: An example of making “custom objects” with strongly-typed properties, custom enumeration/validation and error messages.
# version: 0.1
# type: function
# license: CC0
# function: Export-CustomProperty
# x-poshcode-id: 2269
# x-archived: 2010-10-04T16:23:07
#
#
## An example of how to make a custom object with strongly-typed properties, custom enumeration values, and custom validators, etc.

function Export-CustomProperty {
param(
   [Parameter(ValueFromPipeline=$true)]
   [PSCustomObject]$Object
)
process {
   foreach($property in Get-Member Get_*,Set_* -Input $Object -Type Methods | Group-Object { $_.Name.Split("_",2)[1] }) {
      $GetAccessor = $SetAccessor = {}
      foreach($accessor in $property.Group) {
         switch($accessor.Name.Split("_")[0]) {
            "Get" {
               $GetAccessor = [ScriptBlock]::Create('$this.' + $accessor.Name + '()')
            }
            "Set" {
               $SetAccessor = [ScriptBlock]::Create('try { $this.' + $accessor.Name + '( $args ) } catch { throw $_.Exception.Message.Split(":",2)[1].trim('' "'') }')
            }
         }
      }
         
      Add-Member -Input $Object -Type ScriptProperty -Name $Property.Name -Value $GetAccessor $SetAccessor
   }
   Write-Output $Object
}
}


## USAGE:

$customThing = New-Module -AsCustomObject {

   ## The FooBar property: a variable, two accessor methods and later, a ScriptProperty.
   [string]$FooBar = 'foo'
   [string[]]$FooBarValues = 'foo','bar'
   
   function Get_FooBar { $FooBar }
   
   function Set_FooBar { 
      param([string]$value)
      if($FooBarValues -notcontains $Value) {
         throw "You can't set FooBar to '$value', valid values are $($FooBarValues -join ', ').";
      }
      $script:FooBar = $value
   }
   
   ## The Enabled property: just a strongly-typed variable
   [bool]$Enabled = $False
   
  
   ## The UserName property: a variable, two accessor methods (and a validation method) and later, a ScriptProperty.
   [String]$UserName = $Env:UserName

   function Test-ADUser {
      [CmdletBinding()]
      param([string]$UserName)
      $ads = New-Object System.DirectoryServices.DirectorySearcher([ADSI]'')
      $ads.filter = "(&(objectClass=Person)(samAccountName=$UserName))"
      return [bool]$ads.FindOne()
   }

   function Get_UserName { $UserName }

   function Set_UserName { 
      param([string]$value)
      if(!(Test-ADUser $Value)) {
         throw "You can't set UserName to '$value', that user doesn't exist.";
      }
      $script:UserName = $value
   }

   Export-ModuleMember -Function Get_*,Set_* -Variable Enabled

} | Export-CustomProperty


#### Sample Validation Output:
##############################################################################
#  C:\PS> $customThing.UserName = 'Nobody'
#  
#  Exception setting "UserName": "You can't set UserName to 'Nobody', that user doesn't exist."
#  At line:1 char:6
#  + $customThing. <<<< UserName = 'Nobody'
#      + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
#      + FullyQualifiedErrorId : PropertyAssignmentException
#   
#  
#  C:\PS> $customThing.FooBar = 'foobar'
#  
#  Exception setting "FooBar": "You can't set FooBar to 'foobar', valid values are foo, bar."
#  At line:1 char:6
#  + $customThing. <<<< FooBar = 'foobar'
#      + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
#      + FullyQualifiedErrorId : PropertyAssignmentException
#  
#  
#  C:\PS> $customThing.Enabled = "what"
#  
#  Cannot convert value "System.String" to type "System.Boolean", parameters of this type only accept booleans or numbers, use $true, $false, 1 or 0 instead.
#  At line:1 char:6
#  + $customThing. <<<< Enabled = "what"
#      + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
#   + FullyQualifiedErrorId : PropertyAssignmentException