Extend xSharePointAdministration Desired State Configuration (DSC) with custom resources

I’ve got a lot of positive feedback about the DSC module xSharePointAdministration – but there was not a lot of activity in git hub. The reason might be, that developers do not use PowerShell or DSC very often – and scripting guys and administrators do not use git hub. Also the learning curve for writing custom DSC resources is pretty hard. So I decided to give you a little jump start here.

Write normal PowerShell scripts first

Do not try to directly write your DSC resource. The debugging experience is not as good as it should be. Start by building and debugging three scripts: New-XXX, Remove-XXX and Test-XXX. If you have the If you have the corresponding CmdLets you can skip this part – just inspect the parameters for the CmdLets and you’re good (See this post). If you have working scripts or CmdLets you can start creating your DSC resources.

Fork and clone your repository

Go to xSharePointAdministration and start by creating a fork of the repository (see https://help.github.com/articles/fork-a-repo). Then clone the fork to a local repository. You can do this from the command line with the following command:

git clone https://github.com/<your account>/xSharePointAdministration 

You can also use the Team Explorer in Visual Studio to clone the repository if you don’t feel confortable using the command line.

image

If you have cloned the repo open the PowerShell ISE as an administrator and change directory to the repo.

Define your resource and create the module

Open the script New-xSharePointAdministration.ps1 in PowerShell. If you have not yet installed the xDSCResourceDesigner yet, download it now and unzip the content to C:\program files\PowerShell\Modules. The script is pretty easy.

Add your resource to the bottom before the get and test section. For each parameter create a property with New-xDscResourceProperty.

# Create User Profile Property Resource
$Name               = New-xDscResourceProperty -Name Name           -Type String -Attribute Key -Description "The internal name of the profile proprty."
$Ensure             = New-xDscResourceProperty -Name Ensure         -Type String -Attribute Write -ValidateSet @("Present", "Absent") -Description "Set this to 'Present' to ensure that the profile property exists. Set it to 'Absent' to ensure that it is deleted. Default is 'Present'."
$ConnectionName     = New-xDscResourceProperty -Name ConnectionName -Type String -Attribute Write -Description "The name of the ad synch connection"
$AttributeName      = New-xDscResourceProperty -Name AttributeName  -Type String -Attribute Write -Description "The name of the mapped attribute in active directory."
$DisplayName        = New-xDscResourceProperty -Name DisplayName    -Type String -Attribute Write
$PropertyType       = New-xDscResourceProperty -Name PropertyType   -Type String -Attribute Write -ValidateSet @("Binary", "Boolean", "Currency", "DateTime", "Double", "Integer", "LongBinary", "LongString", "Short", "Single", "String", "Variant")
$Privacy            = New-xDscResourceProperty -Name Privacy        -Type String -Attribute Write -ValidateSet @("Public", "Contacts", "Organization", "Manager", "Private", "NotSet")
$PrivacyPolicy      = New-xDscResourceProperty -Name PrivacyPolicy  -Type String -Attribute Write -ValidateSet @("mandatory", "optin", "optout", "disabled")
$PropertyLength     = New-xDscResourceProperty -Name PropertyLength -Type Sint32 -Attribute Write
$IsUserEditable     = New-xDscResourceProperty -Name IsUserEditable      -Type Boolean -Attribute Write
$IsVisibleOnEditor  = New-xDscResourceProperty -Name IsVisibleOnEditor   -Type Boolean -Attribute Write
$IsVisibleOnViewer  = New-xDscResourceProperty -Name IsVisibleOnViewer   -Type Boolean -Attribute Write
$IsEventLog         = New-xDscResourceProperty -Name IsEventLog          -Type Boolean -Attribute Write
$UserOverridePrivacy= New-xDscResourceProperty -Name UserOverridePrivacy -Type Boolean -Attribute Write
$DisplayOrder       = New-xDscResourceProperty -Name DisplayOrder        -Type Sint32 -Attribute Write
$Section            = New-xDscResourceProperty -Name Section             -Type String -Attribute Write

A side note to the properties: use only one key that identifies the resource for get and delete operations. If you have a lot of keys your resource will get very messy. Add a ensure property with possible values “Present” and “Absent” for consistency with existing resources. Avoid required parameters and prefer the use of default values.

If you have set up your properties you can define your resource. Pass the properties as an array to the New-xDscResource command.

$properties = @($Name, $Ensure, $ConnectionName, $AttributeName, $DisplayName, $PropertyType, $Privacy, $PrivacyPolicy, $PropertyLength, $IsUserEditable, $IsVisibleOnEditor, $IsVisibleOnViewer, $IsEventLog, $UserOverridePrivacy, $DisplayOrder, $Section)
New-xDscResource -Name ALIS_xUserProfileProperty -FriendlyName xUserProfileProperty -ModuleName xSharePointAdministration -Property $properties  -Path $modulePath 

Now you can run the script and create the entire module along with your new resource.

Edit and test your resource

Open the psm1 file that was created for you from the module (i.e. ALIS_xUserProfileProperty.psm1 from “C:\Program Files\WindowsPowerShell\Modules\xSharePointAdministration\DSCResources\ALIS_xUserProfileProperty”) in PowerShell ISE. The file already contains the skeleton for the resource with the Get-TargetResource, Set-TargetResource and Test-TargetResource functions and the correct parameters. Don’t forget to add the default values to your parameters. Now add the code the resources. For the handling of  the SharePoint PSSnapIn you can check the existing psm1 files in your repo.

To unit test your functions and step thru the code you can import your module and directly call a function.

Import-Module -Name "C:\Program Files\WindowsPowerShell\Modules\xSharePointAdministration\DSCResources\ALIS_xUserProfileProperty\ALIS_xUserProfileProperty.psm1" 

Get-TargetResource -Name CostCenter 

You have to restart your PowerShell ISE if you make changes to your resource and want to repeat testing!.

It is really nice to step thru your functions like this. But it is very important that you also test your resource using DSC Configuration. The code then runs under the system account what really can make a difference. In my case I had to add the system account to the administrators of the user profile service application.

image

To test your resource you can use the test script from the repository and modify it. Make sure to restart the winmgmt service if you make changes to your resource.

Configuration MyTestConfig
{
    Import-DscResource -ModuleName xSharePointAdministration -Name ALIS_xUserProfileProperty
    
    Node localhost
    {
        xUserProfileProperty TestProperty
        {
            Name = "TestProperty"
            Ensure = "Present"
            DisplayName = "Test Property 2"
            Privacy = "Private"
        }
    }
}

MyTestConfig -verbose

Restart-Service Winmgmt -force

Start-DscConfiguration -Path .\MyTestConfig -Wait -Force -Verbose 

Add your resource to the module and create pull request

If your’re done creating your resource copy the psm1 file to the DSCResource folder in your repository and add a line to the New-xSharePointAdministration.ps1 script right under your resource to copy the file after the resource was created.

Copy-Item .\DSCResources\ALIS_xUserProfileProperty.psm1 "$modulePath\xSharePointAdministration\DSCResources\ALIS_xUserProfileProperty\ALIS_xUserProfileProperty.psm1" 

Also add a line to the test section of script to validate your resource after creation.

Test-xDscResource -Name xUserProfileProperty -Verbose 

Now rerun the script and run your test config again. Everything should work as expected.

If you have finished your module then please check in your changes to your branch and initiate the pull request (https://help.github.com/articles/using-pull-requests/) to share your resource with the community.

Conclusion

I think its really easy to add your own resources to the module. I hope we’ll get a lot of contributions soon. If you have any problems please leave a comment or file an issue on git hub. I will try to help.

One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s