Activate Hyper-V Feature on Windows 10 using PowerShell DSC

Recently I got a new laptop and I am planning to configure the laptops OS the best way possible.

As I’m a big fan of PowerShell DSC I want to use PowerShell DSC for this configuration. I did use PowerShell DSC in many customer engagements with Windows Server OS. Sadly the switch to Windows 10 was not as smooth as expected.

PowerShell Execution Policy

The very first and major blocking error was the PowerShell Execution Policy. Per default the PowerShell Execution Policy on Windows 10 is set to RemoteSigned. Not every DSC Module is remote-signed. A possible solution is not pretty: Setting the execution policy to a lower level of security.

BTW: This ExecutionPolicy blocks also the Domain Join of a Windows 10 VM in Azure (see: Error: “Resource”.psm1 is not digitally signed)

WindowsFeature Resource

As part of my configuration I did want to setup Hyper-V. Windows Features can be configured by using the WindowsFeature Resource. There is just one limitation that will error during runtime: The WindowsFeature Resource does require functions, that are only available in Windows Server OS. During runtime of the configuration there will be the following error message:

“Installing roles and features using PowerShell Desired State Configuration is supported only on Server SKU’s. It is not supported on Client SKU.”

To get around this issue I created the following Script Resource:

Script Hyper-V
{
GetScript = {
Write-Verbose "Get current status for Microsoft-Hyper-V Feature"
$hyperVFeatureState = Get-WindowsOptionalFeature -FeatureName Microsoft-Hyper-V -Online -ErrorAction SilentlyContinue
return @{
Result = $hyperVFeatureState
}
}
SetScript = {
Write-Verbose "Activating Microsoft-Hyper-V Feature"
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
}
TestScript = {
Write-Verbose "Test the current status for Microsoft-Hyper-V Feature"
$hyperVFeatureState = & ([ScriptBlock]::Create($GetScript))
Write-Verbose "Current status is: $($hyperVFeatureState.Result.State)"
return $hyperVFeatureState.Result.State -eq 'Enabled'
}
}

chocolatey

If you never heard of chocolatey head over to their website: The package manager for Windows. Chocolatey is a package manager for windows and allow you to install software from their repository very easy. The even provide a DSC Resource to automate this process even further.

Implementing the cChocoInstaller comes with a small hurdle: Make sure you have the InstallDir created before using the cChocoInstaller resource. I use a File Resource in dependency with chocolatey to avoid this glitch.

 

 

Advertisement

Using Desired State Configuration (DSC) for SaaS – Office365DSC thoughts

PowerShell Desired State Configuration (DSC) enhances your setup experience of new environments like no other technique before. There are around 270 different DSC resources available that provide methods used to configure windows server components and software like:

  • SharePoint Server
  • SQL Server
  • Active Directory
  • IIS

I’m using DSC very frequently. It gives me great advantages over my previous PowerShell scripts. I can use DSC in combination with Azure DSC to configure my systems and track their status. Configuration drifts can only happen for parts that are not part of my configuration.

The part that is missing: PowerShell DSC is a per node technology. Every server, that I want to configure must have a local configuration manager (LCM), that is responsible for applying my configuration. The LCM is responsible for applying the configuration either as local system account or as a configurable account.

Fast forward: Currently more and more people switch to Software as a Service (SaaS) offerings like Office 365. Office 365 offers many configuration options, but there is no LCM available, that would handle the configuration.

Let’s speak about a possible Office 365 DSC resource.

This resource should be responsible for administering Office 365 in a DSC way. I see the following options on how to apply a configuration to Office 365:

  1. Create a configuration and apply this configuration on node “localhost”. This means we are using the current computer and the LCM to apply a configuration to a SaaS.
    This looks like an “ok” solution. The configuration depends on the local system and nothing of the configuration gets apply to the local system. This feels odd.
  2. Azure Runbooks offer a way to run a PowerShell script, reuse PowerShell Modules and schedule the script.
    Compared to a local PowerShell and LCM Azure Runbooks could be the way to go. A SaaS to configure another SaaS – this feels kind of perfect – but won’t work as many cmdlets are dependant on .NET components, that can’t be loaded into Azure Runbooks and this is very not DSC.

Maybe there are other options available, that I can’t think of. If you have a suggestion, feel free to leave a comment.

Currently the most resources focus on products and functions that life on a Windows Server System – the configuration is specific to a Node.

Thoughts about an Office365DSC Resource

Now many customers start using Office365. In Germany customers are very aware of their data and sometimes spend a good amount of time to define a governance for Office365.

With an option to configure Office365 with DSC, they could gain a lot of comfort and overview of what is configured and how. Working with test tenants would be very easy, as you could replicate your production settings to your test tenant easily – despite there is no Office365 DSC Resource available yet.

What are the current options to script your Office365 administration?

Why not to script everything and use DSC instead?

DSC is about configuration management. If I want to update any setting in the Office 365 admin centre, a DSC configuration seems to be the best option.

The scripting guy would load the PowerShell Module, the CLI or open the admin portal to change a setting with a function call like:

IWantToSetThis-Function -Something This

With DSC there would happen something else:

Something {
    State = "This"
}

DSC would try to get the current setting for “Something”, compare the parameter “State” to “This” and only if they differ, call the function above.

Is DSC only a better approach to script?

I’m a big fan of using the DSC approach. In the end it’s just PowerShell, but in a better structured manner. Having a predefined set of Get-, Set- and Test-Functions (and with Office365DSC Export-Function) allows to reuse the functionality provided.

Where can I find Office365DSC?

You can find the repository of Office365DSC at github: Microsoft/Office365DSC

The struggle with configuration data in DSC configurations – SQL Alias and reusability

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:

Previously:
SPFarm SharePointFarm
{
DatabaseServer = ¯\_(ツ)_/¯
IsSingleInstance = "Yes"
FarmConfigDatabaseName = "SP_Config"
AdminContentDatabaseName = "SP_AdminContent"
Passphrase = $Passphrase
FarmAccount = $FarmAccount
RunCentralAdmin = $true
PsDscRunAsCredential = $SpSetupAccount
}
Now:
SPFarm SharePointFarm
{
DatabaseServer = $ConfigurationData.NonNodeData.SqlServerAlias.Config.Name
IsSingleInstance = "Yes"
FarmConfigDatabaseName = "SP_Config"
AdminContentDatabaseName = "SP_AdminContent"
Passphrase = $Passphrase
FarmAccount = $FarmAccount
RunCentralAdmin = $true
PsDscRunAsCredential = $SpSetupAccount
}
view raw SharePoint.ps1 hosted with ❤ by GitHub

AutoSpInstaller XML to SharePointDsc Converter – Preview – Update 2018/04/19

Today the first preview of a web based AutoSpInstaller to SharePoint DSC converter got released.

There are still some limitations, as the mapping of the xml file to SharePointDsc is not complete jet. This is a preview to demonstrate the capabilities.

The converter targets the following use case:

As a user with an AutoSpInstaller XML available I want want to switch to SharePointDsc.

Currently the converter is able to create a multi node SharePoint DSC configuration based on the input of the contents of the AutoSPInstaller XML file. The configuration will contain the following elements:

  • one node block for each server name. If you are using localhost mixed with real server names, there will be an additional node for localhost.
    • On each node the following configuration is placed:
      • SQLAliases
      • SharePoint Prerequistes
      • SharePoint Binary Installation
      • Farm create or join
  • The following components are currently extracted from the AutoSPInstaller xml file:
    • Basic Farm setup
    • Managed Accounts
    • Web Applications
    • Site Collections
    • Managed Paths
    • Diagnostics Logging Service
    • State Service Application
    • Sandboxed Code Service
    • Claims to Windows Token Service
    • Outgoing Mail
    • Distributed Cache
    • Workflow Timer Setting
  • Update 2018/04/19 – There are the following additions:
    • Creation of Application Pools for Web Applications, Search, Serivces
    • User Profile Service Application
    • Search Service Application
    • Managed Metadata Service Application

Configuration of PHP and MySQL on Windows Server with IIS

Recently I challenged myself to see how far we can go with PowerShell DSC and non Microsoft Products. My goal in this challenge was to install and configure PHP and MySQL on a blank Windows Server 2012 R2 offline server.

Why would someone do this?

Because I wanted gain a better understanding on how far PowerShell DSC configurations are useful in challenging tasks with non Windows or Microsoft Products. Another outcome should be a fully functional PHP server to host PIWIK for a SharePoint Farm.

Read More »

The self-healing environment – PowerShell DSC for your SharePoint Ecosystem – Recap

During my preparations for Dublin I came across many topics in the Azure Automation world I wanted to automate as well. Currently the resources “on how to do this” are limited to the Microsoft Documentations available.

I planned to on-board a newly provisioned virutal machine in place and join this server into my automation account. A process I do on a day to day basis with development environments.

I tend to trash my virtual development machines on a regular basis. This process allows me to be assured that my systems are up to the customers requirement.
This means I upload the customer specific configuration and compile the DSC prior to joining the VM.
If you do already have a configuration in place and want to reuse this, you can go to step number 3.

What is the process of on-boarding a virtual machine to an Automation Account?

0. Login in to your Azure Account


Login-AzureRmAccount

1. Upload your latest DSC configuration to Azure Automation DSC

Uploading a configuration requires you to run the following PowerShell Script.

Import-AzureRmAutomationDscConfiguration -SourcePath "<Full Path to your Configuration>"`
-ResourceGroupName "<Your Resource Group Name>" `
-AutomationAccountName "<Your Automation Account Name>" `
-Published `
-Force `
-Verbose

2. Compile your configuration

After an successful upload you can start the compilation of your configuration. In case the configuration requires parameters, you can ass them into the cmdlet as hashtable:


$dscCompileParameters = @{ }

Start-AzureRmAutomationDscCompilationJob -AutomationAccountName "<Your Automation Account Name >"`
-ConfigurationName "<Name of your configuration>" `
-ResourceGroupName "< Your Resource Group Name>"`
-IncrementNodeConfigurationBuild `
-Parameters $dscCompileParameters `
-Verbose

3. Join a VM to your Azure Automation Account – using PowerShell

Register-AzureRmAutomationDscNode -AzureVMName "<Your VM Name>" `
-ResourceGroupName "< Your Resource Group Name>" `
-AutomationAccountName "<Your Automation Account Name >" `
-RebootNodeIfNeeded $true `
-NodeConfigurationName "<Your Node Configuration Name >" `
-ConfigurationMode "ApplyAndAutocorrect" `
-Verbose

Outcome

With these few lines of PowerShell you will be able to onboard a VM to Azure Automation and configure this machine to use a specific configuration.