Class in PowerShell 5 that run custom code when you "set" property

Hi,

It took me some time to find a way how to use classes in something else then DSC resource…

I would like to build class (and advanced function that returns this class) that has a few properties that by default have data from specified registry values. Object from this class may look like for example like this:

$mySpecial = [MySpecial]::new()
$mySpecial | gm


   TypeName: MySpecial

Name        MemberType Definition                    
----        ---------- ----------                    
...             
Prop0       Property   string Prop0 {get;set;}       
Prop1       Property   string Prop1 {get;set;}       
Prop2       Property   string Prop2 {get;set;}  

When I create an object from this class then I will be able to run for example:
$mySpecial.Prop0
and I will get data from specified registry value.

But the main reason why I want to use classes is to be able to run
$mySpecial.Prop0 = ‘Something else’
and modify data in registry. But I have no idea how to implement class with custom code when I “set” property. Please can you give me some examples?

Other option is to implement SetProp0() method but I believe that this is not the right way how to do it.

Thank you for any help,
Bor

Hi Bor,
Here is a very simplified example reading a text file for input and writing back to the text file when setting the property. Of course this is a public property so left just like this, the underlying code would be exposed to everyone. This should, however, give you somewhere to start.

Class AppDB {
    AppDB(){
        $prop = new-object management.automation.PsScriptProperty 'connectionstring',{Get-Content c:\temp\out.txt},{param($newvalue) $newvalue | Out-File c:\temp\out.txt}
        $this.psobject.properties.add($prop)
    }
}

If you have an hour or two, try taking a look at June Blenders “A Class of Wine” talk (from Virtual PowerShell User Group):

Gives a pretty good understanding of how to work with classes.

Basically what you need is to use get and set accessors. I have just tried it like I would do it in C# but it doesn’t work. Looks like PowerShell doesn’t accept script block for [int] property.

class MyDate {
    hidden [int] $_month = 3
    
    [int] $Month {
        get {
            return $_month
        }
        set {
            if ($value -gt 0 -and $value -lt 13) {
                $this._month = $value
            } else {
                Write-Warning -Message 'wrong number'
            }
        }
    }
    
    [void] DoSomething() {
        Write-Warning -Message 'Hello World'
    }
    hidden [void] doNotShowThisMethod() {
        Write-Warning -Message 'Hello World'
    }
}

$myDate = [MyDate]::new()
$myDate | Get-Member

@Curtis: Thank you. Do you know about different ways? I would prefer not using PsScriptProperty since I would prefer using more native way…

@Rudolf: Thank you. Unfortunately as you mentioned, this way works only in C#.

@Christian: I saw the video from User Group, thank you. If I understand correctly It might be possible to edit set_NameOfProperty() / get_NameOfProperty() methods that are autogenerated by PowerShell. This is probably the only way how to accomplish my goal without using PsScriptProperty.