Configuration Management of Non-Azure VM’s with Azure Automation – Part 3

We’ve now reached the final article in this three part series covering Configuration Management in Azure automation.  In Part 1, I discussed the Inventory tool and how to onboard an AWS EC2 virtual machine to Azure.  Part 2 covered Change tracking and how to monitor changes to various resources on the AWS instance.  In this article, Part 3, I will cover Azure State configuration (DSC) and how to register an AWS VM as a DSC node to apply a desired state.

An Overview of State configurtion (DSC) Components
Azure State configuration builds upon Powershell’s Desired State Configuration (DSC), which was introduced in version 4.0 of Powershell.  These are the main components of Azure DSC, along with a brief description of each:

  • Configuration files – Powershell scripts written in a declarative syntax that defines how a target should be configured.  These contain building blocks that define the nodes to be configured and the resources to be applied.
  • Resources – These are Powershell modules that contains the code that determines the state of a machine.
  • Local Configuration Manager (LCM) – This runs on the target nodes.  It serves as the engine that consumes and applies DSC configurations to the target machine.  It also has settings that determine how often a node checks for new configs from the Pull server in Azure automation and what action to take when a node drifts from a desired state.
  • DSC Metaconfigurations – These files define the settings for the Local Configuration Manager (LCM).
  • Pull Server – located in Azure automation.  It functions as a repository for the configuration files that are applied to DSC target nodes.

Why Azure State configuration (DSC)
By leveraging DSC as a service in Azure, this eliminates the need to deploy and maintain an On-Premises Pull server, and all of it’s necessary components such as SSL certificates.  Also, State configuration (DSC) data can be forwarded to Azure Monitor, which provides searching capabilities with Log Analytics and alerting on compliance failures.  Furthermore, if you’re doing the DevOps thing by implementing agile practices, State configuration fits in seamlessly with continuous deployments in Azure DevOps.

To complete the tasks in this example, the following will be needed:
1. An Azure automation account
2. An AWS EC2 VM
3. WMF 5.1 – on the AWS VM
4. WinRM – on the AWS VM

Steps to Onboard the AWS EC2 VM to Azure
Even though DSC is a part of Azure’s Configuration Management, any machine that it manages has to be onboarded separately from Inventory and Change Tracking.  There are a few ways to onboard an AWS instance to State configuration (DSC):

  1. The AWS DSC Toolkit created by the Powershell Team – this method includes installing the toolkit using PSGet, then running commands to login to your Azure subscription and register the AWS EC2 instance.  Go here to get more details.
  2. A Powershell DSC script – involves running a Powershell DSC configuration script locally on the AWS EC2 instance.  The script will generate a Metaconfig file that contains settings for the Local Configuration Manager (LCM). This Microsoft doc explains more.
  3. Azure Automation Cmdlets – a quick method to produce the DSC Metaconfig file using AzureRm cmdlets in Windows Powershell on the AWS VM.

Options 1 and 3 will allow you to register the node in Azure without having to write a Powershell DSC configuration script to generate the Metaconfiguration.  This is fine as long as you’re comfortable with the default LCM settings. In this case, I will use Option 3 since it’s simple and this is only for demonstration purposes.  Here are the steps to be executed on the AWS VM:

  1. In a Powershell console, install the AzureRm module from the Powershell Gallery using  install-module AzureRM
  2. Login to Azure using login-azurermaccount
  3. Download the Powershell DSC Metaconrigurations from Azure automation with the following Powershell command :
    $Params = @{
    ResourceGroupName = 'myautogroup'; 
    AutomationAccountName = 'myautoacct1'; 
    ComputerName = @('IP address or computer name'); #this will be the Private IP not Public 
    OutputFolder = "$env:UserProfile\Desktop\";
    Get-AzureRmAutomationDscOnboardingMetaconfig @Params
  4. Run Set-DscLocalConfigurationManager -path “$env:UserProfile\Desktop\”

To verify that the AWS VM has been successfully onboarded, in the Azure portal, go to the Automation account.  Under Configuration Management, click on State configuration (DSC) to go to the main where it shows the EC2 instance and it’s configuration status.

The next step is to assign a configuration to the node.

Add and Assign State Configurations
Now that the AWS VM is registered as a DSC node in Azure, configuration files can be assigned to it.   This can be done by composing your own configuration files and uploading them to Azure; or using the ones available in the Gallery.

If you select “Configurations“, there’s an option to upload a configuration file or compose one in the Portal.  I will click “Add” and upload a previously created config file called “WindowsFeatureSet.ps1 that will ensure the IIS and Web server features are enabled.

Next browse to the location of configuration script file and hit “Ok” to import it.

I’m not going to walk through the steps of writing a DSC script, but only provide an overview of assigning it to a node.  Once the import is complete, the config file is now available under “Configurations“.

Before it’s assigned to a node, the uploaded file will then need to be compiled into a MOF document by the LCM on the Pull server.  To begin this process, select the imported config file and click on the “Compile” button.

Once complete, the file will show as compiled and will be in the format of filename.nodename.  At this point, the configuration can be assigned to the node.

To assign the configuration, select the DSC node from the Nodes screen and click on the “Assign node configuration” button.

Confirm the assignment by clicking “Ok

The following figure shows that the configuration file has been assigned to the DSC node.

Here I remoted into the AWS VM and verified that IIS has been installed.

Powershell commands to manage State configuration (DSC)
The following Powershell script and commands can be used to complete some of the above tasks that were done in the Portal.

Script to upload config file and compile it:

-ResourceGroupName myautogroup –AutomationAccountName myautoacct1
-SourcePath $env:userprofile\Desktop\AzureAutomationDsc\WindowsFeaturSet.ps1
-Published –Force

$jobData = Start-AzureRmAutomationDscCompilationJob
-ResourceGroupName myautogroup –AutomationAccountName myautoacct1
-ConfigurationName Featureset

$compilationJobId = $jobData.Id

-ResourceGroupName myautogroup –AutomationAccountName myautoacct1
-Id $compilationJobId

Command to view DSC Nodes

Command to view the status of a DSC compilation job

Command to view the a DSC configuration

Troubleshooting – Notes from the Field
During the process of onboarding the AWS VM to Azure, I ran into a couple of errors when running the Set-DscLocalConfigurationManager command.

Problem 1 – Here’s a screenshot of the first error:

Fix 1 – I had to log into the AWS console and re-configure the Security group that manages traffic to the virtual machine.  The inbound traffic rule needed an allowance for WinRm-HTTPS (Powershell remoting) on Port 5986.

Problem 2 – when I ran the Set-DscLocalConfigurationManager command again after allowing Powershell remoting in the EC2 Security group, I got this error:

Fix 2 – I had to open the Local Group Policy editor on the AWS VM, enable trusted hosts for the WinRM client and add the source as a Trusted host.  Open gpedit.msc and go to Computer Configuration > Administrative Templates > Windows Components > Windows Remote Management (WinRM) > WinRM Client.  From there, enable Trusted Hosts and add the source server.

This concludes the third article in the series on Configuration management of a non-Azure VM.  Azure State configuration is a service  that can be used to manage Azure, On-premises and other non-Azure VMs to configure and maintain a desired state.







C# Intro for Powershellers

Let me begin by stating that I am not a programmer or C# expert.  I am a System engineer by trade, who has become proficient in Powershell scripting.  When I first began working in IT, about 13 years ago, the first programming language that I tried to learn was Perl.  At the beginning of that process, I immediately discovered programming is not for me and this relationship will not work.  So I dumped Perl after a few “dates” and never looked back. However, that was then.  Now, after having worked with Powershell to create scripts to automate tasks, I have developed a renewed interest in coding.  According to Jeffrey Snover, the inventor of Powershell, the intent behind Powershell was for it to be a glide path to C#.  I guess you can say, mission accomplished.

In this article, I’m going to create a basic C# application in Visual Studio while using Powershell as reference to explain some of the concepts in C#.  As the saying goes, use what you already know to learn new things.  However, let’s review a few basics first.

Before we dive into C# coding, it’s necessary that we briefly cover the essential elements related to the .Net Framework architecture. There are two main components of .Net Framework – Common Language Runtime (CLR) and Class Library. In a nutshell, the CLR is responsible for converting the compiled code of C# into the native code of the underlying machine.  C# code is initially compiled into a format called Intermediate Language code (IL). This IL code is consumed by the CLR and converted into a format which is comprehensible to the underlying machine. This process flow is depicted in Figure 1.

The second component which makes up the .Net framework architecture, the Class Library, is a set of namespaces, classes, interfaces and types that are used by the application to access the systems functionality.  Here’s a small subset of the .Net Class Library in Figure 2.

Figure 2

Due to the number of classes, they need to be organized in a manner that is based on their function.  This is the purpose of a Namespace – a container of related classes. In Figure 3 below, we see illustrated the structure of a .Net Framework namespace called “System”.  The System namespace consists of multiple classes such as Console, DateTime, Math and many more not presented in the diagram. Powershell commands and C# code use namespaces to produce and manipulate instantiated instances (objects) of these classes, which contains various methods and properties.

As mentioned, within each namespace are classes  A class (Figure 4) is a container that consists of various methods and types.  Methods allow you to perform certain actions against an object referenced by a class and a type describes its properties.  In essence, a class can be seen as the blueprint used to build objects. For Instance, if you have a class called “Car”, it may have the following type categories:  make, model, color, year, etc. Also, it will have methods which determine the actions that can be performed against a “Car” object such as: start(), drive(), stop() and so on.  The types and methods of a class are known as the class members.

To build a fully functional C# application, we must assemble all of the necessary components that work in conjunction to produce a desired result.  For instance, you may have an application that may need to output to the screen or work with a collection of data. These tasks will require you to make the System and System.Collections namespaces accessible to your application, along with the relevant classes.  As the number of namespaces that your application uses increase, they will need to be organized into a unit called an “Assembly”. This is basically a DLL or EXE file (Figure 5).

Figure 5  C# Assembly (DLL or EXE)

Now that we have completed our review of the .Net Framework architecture and components, let’s proceed to doing some basic C# coding.


For this article, I will create a C# application that will retrieve the current date/time and output the results to the console screen.


As you already know, in Powershell this is simply done by executing the “Get-Datecommand shown in Figure 6.

Figure 6

Another important point of significance is to know how Powershell reaches into .Net Framework to produce this output.  If we pipe this command to “Get-Member”, we will see the TypeName or namespace and class the Get-Date command is referencing.  In Figure 5, we see it’s using the DateTime class which is a member of the “System” namespace. Therefore, our C# code must also use the System.DateTime class to achieve the same result.  For non-seasoned Powershellers, I omitted additional output produced by Get-Member in the Figure 7 screenshot. The Get-Member command also displays the methods and properties of objectified output that is passed to it via the pipeline.

Figure 7


For this example, I will create a C# application that will retrieve the current date/time and output the results to the console screen.  I will be using Visual Studio Community 2017 to accomplish this task.

First, open Visual Studio and go to File > New > Project (CTRL + Shift + N) as shown below in Figure 8.

Figure 8

In the window that appears (Figure 9), expand Visual C#, select > .Net Core and then choose Console App (.Net Core).

Figure 9

Notice you are given several settings to configure:

  • Name:  Give your Project a name.  I will call mine DateApp1.
  • Location:  Choose a location to store your project (or use the default location).
  • Solution:  You can create a new solution or use and existing one.  A solution contains the project and build information. Also, it can have multiple projects.
  • Solution Name:  By default, this will be the same name you give the Project.  You can give it a different name but I will leave the default.
  • Create new Git repository:  Check this box to create a Git repository.  I will leave it unchecked.

Once all the settings are configured, hit “OK”.  You will now see below in Figure 10, a window with a basic structure of your C# program.

Figure 10

Let me explain the above:  By default, certain namespaces are automatically added to a new program, each of which is preceded by the “using” keyword.  But remember, for our project we will only need to use the “System” namespace. It contains the class (DateTime) that our application requires.  Also, notice that a namespace is created that matches the name of the project, as well as a class called “Program”. Both can be changed to a different name.  The final piece added is a static method that can accept multiple string parameters. It has a “void” keyword, meaning it doesn’t return a value. A static method is one that can be called without creating an instance of the class it’s a member of.  Look to the following Powershell examples to provide further explanation:

Figure 11  Powershell static method of the
DateTime class to add 5 days to the current date

Figure 12 Powershell instance method of the
DateTime class variable ($date) to add 5 days
to the current date

Figure 13 shows the structure of our DateTime app after removing the unused .Net namespaces, changing the Class name and adding the code to produce the current date on the screen.  To achieve this, create a variable called “Now” and assign it to the DateTime.Now property. In C#, a variable is created by preceding the variable name with the name of the .Net class it’s using. And finally, add the Console.Writeline method with a “Now” argument. Also, notice the “System” namespace is now highlighted, which indicates it’s being used.

Figure 13

To compile and execute the above code, press CTRL + F5.  If the build is successful, you will get a pop-up Command window showing the current date and time(Figure 14).  By default, it’s displayed in a long date and time format.

Figure 14

Visual Studio will also show output detailing the Build results.  It displays the location of the application executable file and if the Build succeeded or failed.

Figure 15

In summary, in this article I explained the fundamentals of .Net Framework and created a basic C# application that outputs the current date and time to the console.


Powershell Function to Get Messages

If you are an Exchange server administrator, you more than likely spend a fair amount of time searching the Message Tracking logs.  The data provided by these logs can be helpful in finding all messages with a particular subject or sent by a certain user during a specific time frame.  Of course, there are two ways to search the Message logs:  the Exchange Admin Center (EAC) or Exchange Management Shell.  Using the GUI is perfectly fine, if that is your preference.  However, if you are having to perform searches on a regular basis, the EMS is the more efficient option.

To help make your job and mine alot easier, I wrote this Powershell function that can be used to find messages based on various criteria.  Check it out on Github, and let me know what you think.