Today I was very happy to find a neat solution to handle configuration data for a DSC configuration. I was facing the following challenge:
In a SharePoint DSC Configuration I want to reuse several SQL Aliases that are created during run time of the DSC configuration based on the configuration data.
In recent DSC setups my configuration did look like this:
@{ | |
AllNodes = @( | |
@{ | |
NodeName = "*" | |
PSDscAllowPlainTextPassword = $true | |
PSDscAllowDomainUser = $true | |
ServerRole = "invalid" | |
}, | |
@{ | |
NodeName = "SharePointServer" | |
ServerRole = "SingleServerFarm" | |
CentralAdmin = $true | |
IsMasterNode = $true | |
ServiceInstances = @( | |
) | |
} | |
) | |
NonNodeData = @{ | |
SqlServerAlias = @( | |
@{ | |
ServerName = "SqlServer\Content" | |
Name = "SharePoint-Content" | |
Protocol = "TCP" | |
UseDynamicTcpPort = $true | |
TcpPort = $false | |
}, | |
@{ | |
ServerName = "SqlServer1\Config" | |
Name = "SharePoint-Config" | |
Protocol = "TCP" | |
UseDynamicTcpPort = $true | |
TcpPort = $false | |
} | |
) | |
} | |
} |
and I created the SQL Alias with the following lines of code:
$ConfigurationData.NonNodeData.SqlServerAlias | ForEach-Object -Process { | |
SqlAlias $_.Name | |
{ | |
Name = $_.Name | |
ServerName = $_.ServerName | |
Protocol = $_.Protocol | |
UseDynamicTcpPort = $_.UseDynamicTcpPort | |
TcpPort = $_.TcpPort | |
Ensure = 'Present' | |
PsDscRunAsCredential = $SpSetupAccount | |
} | |
} |
This far there was no struggle at all. Creating a SQL Alias with DSC is very straight forward, even if there is the need to create more than one.
The struggle got real the moment I had to reuse the Alias Name in SharePoint. How do I properly access the Alias? Do I iterate over all aliases again and filter or do I hard code the alias name or…? None of the before felt right.
My solutions is pretty simple: Why not change the array to another hash table – A hash table allows to access the data more easily. 🙂
@{ | |
AllNodes = @( | |
@{ | |
NodeName = "*" | |
PSDscAllowPlainTextPassword = $true | |
PSDscAllowDomainUser = $true | |
ServerRole = "invalid" | |
}, | |
@{ | |
NodeName = "SharePointServer" | |
ServerRole = "SingleServerFarm" | |
CentralAdmin = $true | |
IsMasterNode = $true | |
ServiceInstances = @( | |
) | |
} | |
) | |
NonNodeData = @{ | |
SqlServerAlias = @{ | |
Content = @{ | |
ServerName = "SqlServer\Content" | |
Name = "SharePoint-Content" | |
Protocol = "TCP" | |
UseDynamicTcpPort = $true | |
TcpPort = $false | |
} | |
Config = @{ | |
ServerName = "SqlServer1\Config" | |
Name = "SharePoint-Config" | |
Protocol = "TCP" | |
UseDynamicTcpPort = $true | |
TcpPort = $false | |
} | |
} | |
} | |
} |
Final challenge: How can I iterate over a hash table? A hash table object has two properties: keys and values:
$ConfigurationData.NonNodeData.SqlServerAlias.Keys | ForEach-Object -Process { | |
SqlAlias $ConfigurationData.NonNodeData.SqlServerAlias[$_].Name | |
{ | |
Name = $ConfigurationData.NonNodeData.SqlServerAlias[$_].Name | |
ServerName = $ConfigurationData.NonNodeData.SqlServerAlias[$_].ServerName | |
Protocol = $ConfigurationData.NonNodeData.SqlServerAlias[$_].Protocol | |
UseDynamicTcpPort = $ConfigurationData.NonNodeData.SqlServerAlias[$_].UseDynamicTcpPort | |
TcpPort = $ConfigurationData.NonNodeData.SqlServerAlias[$_].TcpPort | |
Ensure = 'Present' | |
PsDscRunAsCredential = $SpSetupAccount | |
} | |
} |
So what changed in my SharePointDsc configuration part? Now I can address my SQL Alias properly without having any troubles: