<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Troy Ault's Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/troy_aults_blog/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/troy_aults_blog/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 03:25:51 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Desired State Configuration(DSC) for SQL Server ***Update 2</title>
      <link>https://docs.microsoft.com/archive/blogs/troy_aults_blog/desired-state-configurationdsc-for-sql-server-update-2</link>
      <pubDate>Fri, 20 Oct 2017 15:16:29 GMT</pubDate>
      <dc:creator><![CDATA[Troy Ault]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/troy_aults_blog/?p=696</guid>
      <description><![CDATA[Following up from my last post I have published the Failover Cluster Instance composite...]]></description>
      <content:encoded><![CDATA[<a href="https://msdnshared.blob.core.windows.net/media/2017/10/th.jpg"><img src="https://msdnshared.blob.core.windows.net/media/2017/10/th.jpg" alt="" width="192" height="176" class="alignnone size-full wp-image-705" /></a>

Following up from my last post I have published the Failover Cluster Instance composite configurations and updated the previous configurations.  Initially lets talk about the updates to the which were pushed.

Single Instance, Primary AlwaysOn,  and Secondary AlwaysOn  all had additional optional parameters added enabling all configurable items to be leveraged.  Each of these are defaulted so no breaking changes to the previous examples but additional flexibility added.

Lets move on to Failover Cluster Instance as this has been one I have gotten several questions on how to leverage.  Utilizing the SQLCompositeResources module there are three new resources which will be utilized to build a Failover Cluster Instance <a href="https://github.com/aultt/DSCSQLCompositeResources/tree/master/Modules/SQLCompositeResources/DSCResources/FailOverClusterDisk">FailOverClusterDisk</a>, <a href="https://github.com/aultt/DSCSQLCompositeResources/tree/master/Modules/SQLCompositeResources/DSCResources/FailOverClusterInstanceFirstNode">FailOverClusterInstance<span>FirstNode</span></a>, and <a href="https://github.com/aultt/DSCSQLCompositeResources/tree/master/Modules/SQLCompositeResources/DSCResources/FailOverClusterInstanceAdditionalNode">FailOverClusterInstanceAdditionalNode</a>.  To show how they can be leveraged we will walk through the example provided for <a href="https://github.com/aultt/DSCSQLCompositeResources/tree/master/Modules/SQLCompositeResources/DSCResources/FailOverClusterInstanceFirstNode">FailOverClusterInstance<span>FirstNode</span></a><span> and </span><a href="https://github.com/aultt/DSCSQLCompositeResources/tree/master/Modules/SQLCompositeResources/DSCResources/FailOverClusterInstanceAdditionalNode">FailOverClusterInstanceAdditionalNode</a>.
<h2>Failover Cluster Instance First Node</h2>
First resource we will cover this time is <a href="https://github.com/aultt/DSCSQLCompositeResources/blob/master/Modules/SQLCompositeResources/DSCResources/FailOverClusterInstanceFirstNode/Examples/FailOverClusterInstanceFirstNode_Example.ps1">FailOverClusterInstanceFirstNode_Example.ps1</a>. As in the previous post Credential Management and LCM Config are identical so I will not cover these again.
<h3>Metadata ($CofigData)</h3>
Here we need to provide a few more data elements than we did previously.  Unlike our previous builds we have to provide an installation path for our SQL Server database and logs files as these are required to reside on a shared disk.  Since at least one shared disk is required we need to provide the disk layout and how each drive should be labeled.  To simplify we do this by providing a key of DiskConfiguration and passing an array of hashtable values.  Each hashtable will provide the parameters FailOverClusterDisk requires. Finally we need to provide a name for our FCI and the IPaddress.
<h3>SQL Server Configuration</h3>
The main section is the SQL Configuration and its a simple call.  One call to  <a href="https://github.com/aultt/DSCSQLCompositeResources/tree/master/Modules/SQLCompositeResources/DSCResources/FailOverClusterInstanceFirstNode">FailOverClusterInstance<span>FirstNode</span></a><span> will ensure the following:</span>
<ol>
 	<li>Ensure Failover Cluster feature is installed on the machine</li>
 	<li>Ensures disks partitions are created, formatted and added to the cluster.  This is accomplished by calling<strong> </strong><a href="https://github.com/aultt/DSCSQLCompositeResources/tree/master/Modules/SQLCompositeResources/DSCResources/FailOverClusterDisk">FailOverClusterDisk</a></li>
 	<li>Ensure .Net framework is present</li>
 	<li>Installs Failover Cluster Instance of SQL Server</li>
 	<li>Configures SQL FCI</li>
</ol>
To complete the example Resources are moved and the configuration is generated and deployed.
<h2>Failover Cluster Instance Additional Node</h2>
Next we will look at <strong class="final-path"><a href="https://github.com/aultt/DSCSQLCompositeResources/blob/master/Modules/SQLCompositeResources/DSCResources/FailOverClusterInstanceAdditionalNode/Examples/FailOverClusterInstanceAdditionalNode_Example.ps1">FailOverClusterInstanceAdditionalNode_Example.ps1</a> </strong><a href="https://github.com/aultt/DSCSQLCompositeResources/blob/master/Modules/SQLCompositeResources/DSCResources/FailOverClusterInstanceAdditionalNode/Examples/FailOverClusterInstanceAdditionalNode_Example.ps1"></a>
<h3>Metadata ($CofigData)</h3>
Since we are adding to an existing cluster, we have a much smaller set required.  All required values are listed in <strong class="final-path"><a href="https://github.com/aultt/DSCSQLCompositeResources/blob/master/Modules/SQLCompositeResources/DSCResources/FailOverClusterInstanceAdditionalNode/Examples/FailOverClusterInstanceAdditionalNode_Example.ps1">FailOverClusterInstanceAdditionalNode_Example.ps1</a> .</strong>
<h3>SQL Server Configuration</h3>
The main section for SQL Configuration is again simple, a singe call to <span>FailOverClusterInstanceAdditionalNode.  Calling <a href="https://github.com/aultt/DSCSQLCompositeResources/tree/master/Modules/SQLCompositeResources/DSCResources/FailOverClusterInstanceAdditionalNode">FailOverClusterInstanceAdditionalNode</a> will do the following:</span>
<ol>
 	<li>Ensure Failover Cluster feature is installed on the machine</li>
 	<li>Wait for the cluster created from <a href="https://github.com/aultt/DSCSQLCompositeResources/blob/master/Modules/SQLCompositeResources/DSCResources/FailOverClusterInstanceFirstNode/Examples/FailOverClusterInstanceFirstNode_Example.ps1">Fail</a>OverClusterInstanceFirstNode to be found</li>
 	<li>Join the cluster</li>
 	<li>Ensure .Net framework is present</li>
 	<li>Add node to SQL FCI</li>
</ol>
<span>To complete the example Resources are moved and the configuration is generated and deployed.</span>

With the addition of these composite resources I hope building out new SQL configurations will be simpler and have less redundancy.  Please let me know if you have issues or recommendations for improvement.

&nbsp;

&nbsp;

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Desired State Configuration(DSC) for SQL Server ***Update</title>
      <link>https://docs.microsoft.com/archive/blogs/troy_aults_blog/desired-state-configurationdsc-for-sql-server-update</link>
      <pubDate>Mon, 09 Oct 2017 18:04:53 GMT</pubDate>
      <dc:creator><![CDATA[Troy Ault]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/troy_aults_blog/?p=675</guid>
      <description><![CDATA[Over the past few months several individuals/customers have asked me for updated examples of the...]]></description>
      <content:encoded><![CDATA[<img src="https://msdnshared.blob.core.windows.net/media/2017/09/SuperManPS.jpg" />

Over the past few months several individuals/customers have asked me for updated examples of the latest xSQLServer Resource.  As of this post, the current version is 8.2.0.0.  Throughout this post I will provide reference to configurations which are actually calling composite resources.  If you haven't heard of composite resources, then the following reference will explain what they are and how they can be leveraged --&gt;   <a href="https://blogs.msdn.com/b/powershell/archive/2014/02/25/reusing-existing-configuration-scripts-in-powershell-desired-state-configuration.aspx">Reusing existing configuration scripts in powershell desired state configuration</a>

Before getting started, we will need to pull down a module with the required composite resources.  On my GitHub repro (located <a href="https://github.com/aultt/DSCSQLCompositeResources">here</a>) you will find a module which has composite resources for stand alone SQL installation, AlwaysOn SQL Installation, and coming soon SQL Fail Over Cluster Instance (FCI).  Download the Zip, extract the contents and copy the SQLCompositeResources folder to C:\Program Files\WindowsPowerShell\Modules.  Aside from this module, you will also need xSQLServer, xComputerManagement, xFailoverCluster as the composite resources will utilize these resources.  All example configurations are demonstrated utilizing a push configuration and assume the machine you are pushing from has the above referenced modules located in the PowerShell modules folder referenced previously.

***Update ensure the folder you copy is SQLCompositeResources, once you copy you should have something which looks like the below.

<a href="https://msdnshared.blob.core.windows.net/media/2017/10/SQLCompositePath.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/10/SQLCompositePath.png" alt="" width="643" height="169" class="alignnone size-full wp-image-725" /></a>
<h2>Single Instance Install Example</h2>
<h4>Credential Management</h4>
We will first cover the simplest configuration <a href="https://github.com/aultt/DSCSQLCompositeResources/blob/master/Modules/SQLCompositeResources/DSCResources/SingleInstanceInstall/Examples/SingleInstanceInstall_Example.ps1">SingleInstanceInstall_Example.ps1</a>.  Let's look through what this configuration includes. First section of the script defines the credential objects we will pass to our configurations.  In the example referenced, the same password is leveraged for each of the three windows accounts and is stored clear text  in the script.  This is done for demonstration purposes only.  Please do not leverage this method in a production environment.  All examples referenced in this post were tested utilizing <a href="https://github.com/Microsoft/DSC-data-driven-deployment/tree/dev/utility/LabInaBox">LabInabox</a>.
<h4>Metadata ($CofigData)</h4>
These are the variables that must be changed in order for the configuration to function properly.  First three are our service accounts which are referenced above, provided we updated these we can move on to the next items.  MofPath is the location where our Mof files will be created in.  SetupSourcePath is the location of our SQL Server installation media.  For my purposes I mounted the ISO to the domain controller and shared the location for my other machines.  And finally we have SQLSysAdminAccounts, here I have utilized DSC\Administrator which is my domain admin account in my DSC Lab environment.  This is not needed just the account I was logging into the machine with at the time.  This could be a domain group such as your SQL administrator group.  The last parameter needed to complete our metadata is NodeName.  NodeName is the machine we are looking to push the configuration too, in my case it was DSC-SQL6.  We now have all the required parameters defined that are required.  I know many are reading and saying but wait there are so many more things required, and in one way you are correct, however, in this case many have been defaulted.  Taking a look at the module for SingleInstanceInstall.schema.psm1 we will see there are many parameters defined such as installation directory which are defaulted just as they are typically if we were to run through a GUI install.  Any parameter you see here can be defined in our configuration.  Since we do not define them here they will utilize the default values.
<h4>LCM Config</h4>
Local configuration manager is configured as part of the example to ensure it is only Applying the configuration and the LCM is set in a Push mode.  For your production workload this could vary and can be modified as needed.
<h4>SQL Server Configuration</h4>
Our SQL configuration looks very simplified here as there is not much required for input.  Under the covers there is a lot more going on than meets the eye.  As stated above, we are utilizing a composite resource here called SingleinstanceIntall.  We are provided only a handful of parameters which are required and relying on the default values for all other parameters.  As stated above, you can pass the additional parameters if needed/required.  Lets dig further into what the composite resource SingleInstanceInstall provides us.  If we look at he psm1 module referenced above we will see this composite resource makes a call to xSQLServerSetup which is a resource from the xSQLServer module and a call so<a href="https://github.com/aultt/DSCSQLCompositeResources/blob/master/Modules/SQLCompositeResources/DSCResources/SQLConfiguration/SQLConfiguration.schema.psm1"> SQLConfiguration</a> which is a resource from SQLCompositeResources.  Digging deeper into <a href="https://github.com/aultt/DSCSQLCompositeResources/blob/master/Modules/SQLCompositeResources/DSCResources/SQLConfiguration/SQLConfiguration.schema.psm1">SQLConfiguration</a> we see it does more than what it appears at first.  Looking through this resource we can see it does the following:
<ol>
 	<li>Sets PowerPlan to High Performance</li>
 	<li>Sets Virtualmemory initial and maximum size for windows</li>
 	<li>Sets SQL Server memory</li>
 	<li>Sets SQL Server MaxDop</li>
 	<li>Enables TCP for SQL Server listening on 1433 or the port passed</li>
 	<li>And finally sets 10 different SQL Server Configuration items based on the paramaters supplied.</li>
</ol>
To recap a single call to:

SingleInstanceInstall Standalone
{
Server = $Node.Nodename
SetupSourcePath = $Node.SetupSourcePath
SQLSysAdminAccounts = $Node.SQLSysAdminAccounts
SqlInstallCredential = $Node.SqlInstallCredential
SqlServiceCredential = $Node.SqlServiceCredential
SqlAgentServiceCredential = $Node.SqlAgentServiceCredential
}

will give us a completely configured stand along SQL server ready to go.
<h4>Move Resources</h4>
Since we are in a push mode, we need to ensure all of our modules exist on on client before we push our configuration.  In this section we are simply utilizing test-path to verify the if the module exists and if so remove before copying the module with copy-item.
<h4>Generate and Deploy</h4>
Finally we call the configuration to generate the mof file and start the configuration and wait for verbose output.

&nbsp;

Next we will talk about AlwaysOn, there are two configurations here PrimaryAlwaysOn and SecondaryAlwaysOn.  As the names imply PrimaryAlwaysOn is called for one and only one server and SecondaryAlwaysOn is called for all other servers participating in the cluster.  We will look at each of these configurations separately.
<h2>PrimaryAlwaysOn Example</h2>
Several parts of our configuration will be identical to our Single Instance Install referenced earlier so we won't go into those details again.  Taking a look at our example configuration <a href="https://github.com/aultt/DSCSQLCompositeResources/blob/master/Modules/SQLCompositeResources/DSCResources/PrimaryAlwaysOn/Examples/PrimaryAlwaysOn_Example.ps1">PrimaryAlwaysOn_Example.ps1</a>, we have the same layout as our first three sections.   Credential management, Parms, and LCM config hold the same information we discussed earlier.  The core difference in the example is in the SQL configuration, two resources are called PrimaryAlwaysOn and AvailabilityGroup.

Let's dig into each of these with PrimaryAlwaysOn first.  To understand what's going on behind the scenes we need to look at the module which is <a href="https://github.com/aultt/DSCSQLCompositeResources/blob/master/Modules/SQLCompositeResources/DSCResources/PrimaryAlwaysOn/PrimaryAlwaysOn.schema.psm1">PrimaryAlwaysOn.schema.psm1</a>.  Notice once again in our example we only pass the required parameters for the resource, there are many other parameters which can be passed if required.  Looking into the resources called we see we call four different resources SingleInstanceInstall, WindowsClusterInstall, xcluster, and EnableAlwaysOn.
<h3>PrimaryAlwaysOn</h3>
<h4>SingleInstanceInstall</h4>
SingleInstanceInstall should sound familiar as this is the exact resource we just finished dissecting above.
<h4>WindowsClusterInstall</h4>
The next resource is WindowsClusterInstall for which we can look at the its module definition <a href="https://github.com/aultt/DSCSQLCompositeResources/blob/master/Modules/SQLCompositeResources/DSCResources/WindowsClusterInstall/WindowsClusterInstall.schema.psm1">WindowsClusterInstall.schema.psm1</a>.  As we look at this resource we see it is simply ensuring the Windows Feature FailoverClustering is installed along with all the tools to manage it.
<h4>xCluster</h4>
xCluster is a resource provided with the xFailoverCluster resource which allows us to create a windows failover cluster.  We must pass the clustername the cluster ip and an account which has the appropriate permissions to create the cluster.
<h4>EnableAlwaysOn</h4>
EnableAlwaysOn is another composite resource provided with SQLServerCompositeResources.  Looking at the module <a href="https://github.com/aultt/DSCSQLCompositeResources/blob/master/Modules/SQLCompositeResources/DSCResources/EnableAlwaysOn/EnableAlwaysOn.schema.psm1">EnableAlwaysOn.schema.psm1</a> we see it makes reference to several resources in xSQLServer which are the following:
<ol>
 	<li>xSQLServerLogin -  used to add cluster service account and SQL Service account to the instance</li>
 	<li>xSQLServerPermission - used to grant clusterservice account permission to manage availability groups</li>
 	<li>xSQLServerEndpoint - used to create endpoints for availability groups</li>
 	<li>xSQLServerEndPointPermission - used to grant permissions to endpoints</li>
 	<li>xSQLServerAlwaysOnService - used to enable alwayson on SQL instance</li>
</ol>
<h3>AvailabilityGroup</h3>
AvailabilityGroup is a composite resource which takes a handful of parameters in which only three are required:
<ol>
 	<li>Server - Server to create availability group on</li>
 	<li>SQLInstallCredential - Credential with permissions to create availability group</li>
 	<li>Availability Group Name - availability group name or as an array of availability groups</li>
</ol>
Further exploring the AvailiabilityGroup module <a href="https://github.com/aultt/DSCSQLCompositeResources/blob/master/Modules/SQLCompositeResources/DSCResources/AvailabilityGroup/AvailabilityGroup.schema.psm1">AvailabilityGroup.schema.psm1</a>, we will find there are many additional parameters available if needed.  We will also see that ultimately this resource is only calling one resource <span>xSQLServerAlwaysOnAvailabilityGroup within it.  The difference in this resource is that we are looping through the array of availability group names passed and creating each of them.  One assumption made here is that all availability groups will have the same properties when they are created.  </span>

The remainder of the example is the same.  We copy resources to the server, generate the configuration mof files and push the configuration.
<h2>Secondary AlwaysOn Example</h2>
<a href="https://github.com/aultt/DSCSQLCompositeResources/blob/master/Modules/SQLCompositeResources/DSCResources/SecondaryAlwaysOn/Examples/SecondaryAlwaysOn_Example.ps1">SecondaryAlwaysOn_Example.ps1</a> will look very similar to PrimaryAlwaysOn_Example.ps1 with the difference being it passes all the secondary Nodes in the $ConfigData section as showed below, and calls SecondaryAlwyasOn and AvailabilityGroupJoin:
<table class="highlight tab-size js-file-line-container">
<tbody>
<tr>
<td id="LC10" class="blob-code blob-code-inner js-file-line"><span class="pl-k">$</span><span class="pl-smi">ConfigData</span> <span class="pl-k">=</span> @{</td>
</tr>
<tr>
<td id="L11" class="blob-num js-line-number"></td>
<td id="LC11" class="blob-code blob-code-inner js-file-line">AllNodes <span class="pl-k">=</span> <span class="pl-k">@(</span></td>
</tr>
<tr>
<td id="L12" class="blob-num js-line-number"></td>
<td id="LC12" class="blob-code blob-code-inner js-file-line">@{</td>
</tr>
<tr>
<td id="L13" class="blob-num js-line-number"></td>
<td id="LC13" class="blob-code blob-code-inner js-file-line">NodeName <span class="pl-k">=</span> <span class="pl-s">'*'</span></td>
</tr>
<tr>
<td id="L14" class="blob-num js-line-number"></td>
<td id="LC14" class="blob-code blob-code-inner js-file-line">SqlInstallCredential <span class="pl-k">=</span> <span class="pl-k">$</span><span class="pl-smi">SqlInstallCredential</span></td>
</tr>
<tr>
<td id="L15" class="blob-num js-line-number"></td>
<td id="LC15" class="blob-code blob-code-inner js-file-line">SqlServiceCredential <span class="pl-k">=</span> <span class="pl-k">$</span><span class="pl-smi">SqlServiceCredential</span></td>
</tr>
<tr>
<td id="L16" class="blob-num js-line-number"></td>
<td id="LC16" class="blob-code blob-code-inner js-file-line">SqlAgentServiceCredential <span class="pl-k">=</span> <span class="pl-k">$</span><span class="pl-smi">SqlAgentServiceCredential</span></td>
</tr>
<tr>
<td id="L17" class="blob-num js-line-number"></td>
<td id="LC17" class="blob-code blob-code-inner js-file-line">MofPath <span class="pl-k">=</span> <span class="pl-s">'C:\Mofs'</span></td>
</tr>
<tr>
<td id="L18" class="blob-num js-line-number"></td>
<td id="LC18" class="blob-code blob-code-inner js-file-line">SetupSourcePath <span class="pl-k">=</span> <span class="pl-s">'\\dsc-dc\sqlserver'</span></td>
</tr>
<tr>
<td id="L19" class="blob-num js-line-number"></td>
<td id="LC19" class="blob-code blob-code-inner js-file-line">SQLSysAdminAccounts <span class="pl-k">=</span> <span class="pl-s">'DSC\Administrator'</span></td>
</tr>
<tr>
<td id="L20" class="blob-num js-line-number"></td>
<td id="LC20" class="blob-code blob-code-inner js-file-line">ClusterName <span class="pl-k">=</span> <span class="pl-s">'DSCTestCluster'</span></td>
</tr>
<tr>
<td id="L21" class="blob-num js-line-number"></td>
<td id="LC21" class="blob-code blob-code-inner js-file-line">ClusterIP <span class="pl-k">=</span><span class="pl-s">'192.168.210.99'</span></td>
</tr>
<tr>
<td id="L22" class="blob-num js-line-number"></td>
<td id="LC22" class="blob-code blob-code-inner js-file-line">PSDscAllowPlainTextPassword <span class="pl-k">=</span> <span class="pl-k">$</span><span class="pl-c1">true</span></td>
</tr>
<tr>
<td id="L23" class="blob-num js-line-number"></td>
<td id="LC23" class="blob-code blob-code-inner js-file-line">PSDscAllowDomainUser <span class="pl-k">=</span><span class="pl-k">$</span><span class="pl-c1">true</span></td>
</tr>
<tr>
<td id="L24" class="blob-num js-line-number"></td>
<td id="LC24" class="blob-code blob-code-inner js-file-line">PrimaryAlwaysOnNode <span class="pl-k">=</span> <span class="pl-s">'DSC-SQL4'</span></td>
</tr>
<tr>
<td id="L25" class="blob-num js-line-number"></td>
<td id="LC25" class="blob-code blob-code-inner js-file-line">AvailabilityGroupName <span class="pl-k">=</span><span class="pl-k">@(</span><span class="pl-s">'AG1'</span><span class="pl-k">,</span><span class="pl-s">'AG2'</span><span class="pl-k">)</span></td>
</tr>
<tr>
<td id="L26" class="blob-num js-line-number"></td>
<td id="LC26" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
<tr>
<td id="L27" class="blob-num js-line-number"></td>
<td id="LC27" class="blob-code blob-code-inner js-file-line">@{NodeName <span class="pl-k">=</span><span class="pl-s">"DSC-SQL5"</span>}</td>
</tr>
<tr>
<td id="L28" class="blob-num js-line-number"></td>
<td id="LC28" class="blob-code blob-code-inner js-file-line">@{NodeName <span class="pl-k">=</span><span class="pl-s">"DSC-SQL6"</span>}</td>
</tr>
<tr>
<td id="L29" class="blob-num js-line-number"></td>
<td id="LC29" class="blob-code blob-code-inner js-file-line"><span class="pl-k">)</span></td>
</tr>
<tr>
<td id="L30" class="blob-num js-line-number"></td>
<td id="LC30" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
</tbody>
</table>
<h3></h3>
<h3>SecondaryAlwayson</h3>
SecondaryAlwaysOn will look very similar to PrimaryAlwaysOn.  Lets take a look at the differences in the module <a href="https://github.com/aultt/DSCSQLCompositeResources/blob/master/Modules/SQLCompositeResources/DSCResources/SecondaryAlwaysOn/SecondaryAlwaysOn.schema.psm1">SecondaryAlwaysOn.schema.psm1</a>.  Here we call SingleInstanceInstall and windows ClusterInstall just as we did in PrimaryAlwaysOn.  What's different here is that we need to wait for the Cluster to be created from the PrimaryAlwaysOn configuration before we can proceed, so we make a call to the resource xWaitForCluster.  Once the cluster has been found, we make a call to xCluster to join the cluster and then to EnableAlwaysOn to enable alwaysOn on the node.  We have now completed our alwayson configuration on our secondary.
<h3>AvailabilityGroupJoin</h3>
AvailabilityGroupJoin is utilized to join our secondary servers to our primary availability group.  Looking into the the module <a href="https://github.com/aultt/DSCSQLCompositeResources/blob/master/Modules/SQLCompositeResources/DSCResources/AvailabilityGroupJoin/AvailabilityGroupJoin.schema.psm1">AvailabilityGroupJoin.schema.psm1</a>, we see again that we are looping through each of the availability group names passed.  First we call out to resource xWaitForAvailabilityGroup to ensure the AvailabilityGroup was created on the primary.  Once it has been found, we will leverage xSQLServerAlwaysOnAvailabilityGroupReplica to create the replica and join the server to the availability group.

<span>The remainder of the example is the same way we copy resources to the server, generate the configuration mof files and push the configuration.</span>
<h2>Conclusion</h2>
Composite resources allow you to simplify your configurations so they are not as complex to read, and more importantly allow you to reuse code so that it is not duplicated but rather referenced.  Please let me know if there are questions or if there is any confusion around how the resource is put together.  I will be working on the FCI resources and examples and will be publishing them to the GitHub repo and blogging on them here.

Call out to Ashley McGlone as I leveraged the his PowerShell module to build the composite resources.  You can read about how to utilize them on his <a href="https://blogs.technet.microsoft.com/ashleymcglone/2015/02/25/helper-function-to-create-a-powershell-dsc-composite-resource/">blog</a>.

&nbsp;

&nbsp;

&nbsp;

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Automating Lab Environments with LabInaBox on Prem or in the Cloud.</title>
      <link>https://docs.microsoft.com/archive/blogs/troy_aults_blog/automating-lab-environments-with-labinabox-on-prem-or-in-the-cloud</link>
      <pubDate>Wed, 30 Aug 2017 14:48:12 GMT</pubDate>
      <dc:creator><![CDATA[Troy Ault]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/troy_aults_blog/?p=595</guid>
      <description><![CDATA[Today building out repeatable demo/lab environments quickly has become a necessity.  Previous this...]]></description>
      <content:encoded><![CDATA[Today building out repeatable demo/lab environments quickly has become a necessity.  Previous this year I released LabInaBox which provided for a quick way to build out lab environments on a Windows 10 machine using Hyper-V.  As more and more customers are looking at Azure I wanted to provide a similar experience for cloud lab deployment.  Today I will walk through the new GUI interface which has been deployed with this release and discuss how you can leverage LabInaBox to build test environments in Hyper-V or in Azure.
<h2>Install LabInaBox</h2>
First things first we need to install LabInaBox.  The installation msi can be found on GitHub <a href="https://github.com/Microsoft/DSC-data-driven-deployment/tree/dev/utility/LabInaBox/ConfigurationUtility/LabInaBox.msi">here</a>.  Simply download the msi locally to your machine.  After downloading you will need to unblock the file before you can execute the msi.  You can do this by right clicking on the executable and selecting properties then clicking the unblock box.

<a href="https://msdnshared.blob.core.windows.net/media/2017/08/unblockfile.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/08/unblockfile.png" alt="" width="341" height="429" class="alignnone size-full wp-image-596" /></a>

After executing you will be prompted for the installation Folder by default it will place in the C:\LabInaBox folder.  The installation path can be modified, however I would recommend not placing it in the program files folder as files are created by the application in this directory which would require administrative privileges.  After the setup completes you should have a folder structure with supporting files which resembles the below:

<a href="https://msdnshared.blob.core.windows.net/media/2017/08/LabinaboxFolderstructure.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/08/LabinaboxFolderstructure.png" alt="" width="412" height="311" class="alignnone size-full wp-image-605" /></a>

At this point we have all the files required to move forward Azure Deployment.  If we want to also leverage the Hyper-V lab scenario we will need to provide a sysprepped Windows2016 image in the ParentVMDisks folder.  Due to licensing and size of the file I was not able to package this into the installation.  If you need further instructions on creating the sysprepped image further details can be found in the <a href="https://github.com/Microsoft/DSC-data-driven-deployment/tree/dev/utility/LabInaBox">ReadMe</a> under installation.
<h2>LabInaBox Layout</h2>
LabInaBox has a GUI configuration utility which will aid you in generating files you will leverage to build out your labs.    To further understand the layout I will walk through the steps for creating these files then go into the detail of what the files are and how to leverage them.  So lets get started by launching LabInaBox. Once you launch you will be presented with the screen below.

<a href="https://msdnshared.blob.core.windows.net/media/2017/08/LabinaboxstartScreen.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/08/LabinaboxstartScreen.png" alt="" width="879" height="771" class="alignnone size-full wp-image-615" /></a>

You have the option of starting from scratch selecting which type of Lab you want to build and filling out the appropriate fields, however for simplicity I have have provided templates which you can open and modify then generate your lab files.  We will walk through the Azure one first.  To utilize these click File..Open and select DefaultAzureConfig.json.
<h2>Azure LabInaBox</h2>
<h3>Generate Azure Lab Automation Scripts</h3>
Below you see the values which have been pre-populated from the template.  Notice there are three values which are either blank or have XXXX that you will need to provide the details for.  These are Azure Login Certificate Name, Azure ApplicationID and Azure Tenant ID.  The Azure Lab scripts require you to have created a service principal name with a certificate so that you can automatically log into azure from your machine without user input.  If you have not read and completed this step please refer to my previous <a href="https://blogs.msdn.microsoft.com/troy_aults_blog/2017/08/21/loginazurewithoutprompt/">blog</a> where I walk you through the steps.

<a href="https://msdnshared.blob.core.windows.net/media/2017/08/AzureConfig.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/08/AzureConfig.png" alt="" width="879" height="771" class="alignnone size-full wp-image-617" /></a>

Once you provide the three required values discussed above you could click Finish and the fields will be generated with the values provided.  However, you may want to change a few things here though so lets walk through some of these items and explain.  Lab Machine Prefix is utilized to create a folder structure on disk where the scripts are stored.  You will also see this same prefix is what I chose to pass for my Domain Name and I prepended it to each machine name.  I prefer this as I know when looking at the machine what lab it is tied to.  Other items you will likely want to change are the Domain Admin Username and Password and the VMUserName and Password.  Domain Admin is as it sounds the domain administrator for the domain and VMUsername is the local administrator on the machine.  Azure Publisher, Azure Offer, AzureSku and OS are all values which determine which azure template is utilized to build the VM.  Three additional items of interest which you may not immediately follow are Azure Automation Account, Azure Automation Resource Group, and DSC Configuration.  Azure Automation Account is the name of the automation account which will be generated via the PowerShell scripts and it will be created in the Azure Automation Resource Group.  All DSC Scripts, modules ect. will be uploaded to this location.  A separate resource group is leveraged here so that in if we have a nightly destroy script to remove resource groups we can easily filter out our automation account.  DSCConfiguration is the final item of interest here.  When you install LabInaBox two configurations are provided DomainConfig and SQLAzureConfig.  Additional ones can be added overtime as the community feels needed.  Make your changes and click Finish.  Upon clicking Finish the application will close and open windows explorer showing the files it has generated.  You should see something similar to below.  Notice its created in the LabConfig directory under TST which was our LabPrefix.  Each file is prefaced with our prefix.

<a href="https://msdnshared.blob.core.windows.net/media/2017/08/AzureLabFiles.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/08/AzureLabFiles.png" alt="" width="418" height="269" class="alignnone size-full wp-image-626" /></a>
<h3>What are these files generated and how do I leverage them?</h3>
Notice we have three files here, one JSON file and two ps1 files.  Lets take a look at the JSON file first.  I am utilizing Visual Studio Code to analyse the file.  Below we see the contents of the JSON file.  Notice first I did not provide the Certificate Subject, ApplicationID, or TenantID but I was able to generate the scripts.  If I ran the scripts currently they would error because these are required to connect to Azure.  Throughout the JSON file we see all the information we input into the GUI tool and some additional ones which are automatically generated.

<a href="https://msdnshared.blob.core.windows.net/media/2017/08/AzureJSONFile.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/08/AzureJSONFile.png" alt="" width="785" height="963" class="alignnone size-full wp-image-635" /></a>

There is nothing we need to change here I just wanted to show this file is generated and the PowerShell scripts will consume these values.  We could modify/create this file manually if we wanted however we could also open the file in the tool and modify it and click finish and the scripts will be updated.

The next file listed is TST_Create.ps1 contents of it are showed below:

<a href="https://msdnshared.blob.core.windows.net/media/2017/08/AzureCreate.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/08/AzureCreate.png" alt="" width="849" height="190" class="alignnone size-full wp-image-637" /></a>

First item in the script is to load a custom module LabinaBox.psm1.  You will notice it has a WarningAction of Silently Continue.  This suppresses the warning message which is generated because Login-AzureCert doesnt comply with naming standards.  Next we see a series of cmdlet calls which will build out our AzureLab environment and configure it.  Notice each cmdlet takes a parameter of configuration.  Configuration is the JSON file we looked at previously.  Within each module this json file will be converted into a PSCustom Object so that each property can be dot source referenced.  A quick run down of each cmdlet and what it is used for is listed below for reference:

New-AzureLab
<ul>
 	<li>Creates ResourceGroup for Lab</li>
 	<li>Creates Azure Virtual Network</li>
 	<li>Creates Each Azure VM requested</li>
</ul>
Publish-AzureDSModules
<ul>
 	<li>Creates ResourceGroup for Automation Account</li>
 	<li>Creates Automation Account</li>
 	<li>Creates Storage Account</li>
 	<li>Creates StorageContainer</li>
 	<li>Uploads DSC Modules from Install Location\LabInaBox\DSCResources\AzureAutomation to container</li>
 	<li>Creates AzureAutomationModule from uploaded file</li>
</ul>
New-AzureDSCConfigurations
<ul>
 	<li>Creates Credentials in Automation account</li>
 	<li>Imports DSC Configurations to AutomationAccount</li>
</ul>
Compile-AzureDSCConfiguration
<ul>
 	<li>Compiles each configuration for each node requested</li>
</ul>
Set-AzureDSCNodeConfigurations
<ul>
 	<li>Registers each Node with AzureAutomation DSC</li>
 	<li>Applies configuration requested</li>
</ul>
The final final <span>TST_Remove.ps1 is listed below.</span>

<span> <a href="https://msdnshared.blob.core.windows.net/media/2017/08/AzureRemove.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/08/AzureRemove.png" alt="" width="843" height="105" class="alignnone size-full wp-image-646" /></a></span>

Below describes what each of these cmdlets do:

RemoveAzureDSCNodeConfiguration
<ul>
 	<li>Removes Configuration from server</li>
 	<li>Unregisters server from Azure Automation DSC</li>
</ul>
Remove-AzureLab
<ul>
 	<li>Removes Lab Resource Group and all items in ResouceGroup</li>
</ul>
<h2>Hyper-V LabInaBox</h2>
Similarly you can generate a Lab onprem on a Hyper-V server.  In this case as mentioned before we will need Windows10 as well as a sysprepped image before we can move on.  Once we have these we can again click File...Open and select Default_Private_Config.json.  You should now be presented with a screen that looks like the following:

<a href="https://msdnshared.blob.core.windows.net/media/2017/08/HyperVNew.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/08/HyperVNew.png" alt="" width="879" height="771" class="alignnone size-full wp-image-655" /></a>

Similar to the Azure LabInaBox you may want to change a few properties here.  To Start Lab Machine Prefix similar to the Azure will drive how the folder structure is created for the scripts.  Unlike the Azure component this is prepended by default to all VMs which are created because we do not have a Resource Group to break them out we need to ensure we dont overlap Vms.  Moving down the list in this example I name the switch based on the subnet I am utilizing for the lab, this is not required but something I found easier to identify later.  As you move down the list there are Folder paths to set.  This allows you move things around if you have more than one drive in your machine and you want to segregate the IO workload.  Servers is just a comma separated list of server names you want created, keep in mind the lab prefix will be pre-pended to the name.   ISO selection allows you to mount ISOs as drives on the domain controller so you can install additional software later.  Once you select the ISO FOlder Path the values will populate in the drop down.  If we stop here in this example we will get three machines.  One Domain controller named PRV-DC and two windows servers named PRV-SQL1 and PRV-SQL2.  Our domain controller will have DHCP,DNS, AD, and certificate services configured so we are ready to begin playing with DSC configurations.  If we are looking for additional functionality we look at the last four boxes.  Developer Machine will create another windows machine PRV-DEV which will be leveraged for any scripting or development.  DSC Central will create an additional vm named PRV-DSC.  PRV-DSC will have a DSC configuration applied to it which installs SQL Server and sets up the <a href="https://github.com/Microsoft/DSC-data-driven-deployment">DSC Data Driven Deployment</a> solution found on GitHub.  Clicking Finish as before will present us with the scripts which are generated.

<a href="https://msdnshared.blob.core.windows.net/media/2017/08/HyperVfiles.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/08/HyperVfiles.png" alt="" width="414" height="239" class="alignnone size-full wp-image-657" /></a>

Notice with Hyper-V we have several additional scripts which are generated.  With HyperV we have scripts to Start, Stop, Update, Create, Remove and Checkpoint a Lab.  Hyper-V scripts are setups the same as the Azure LabInabox in that each cmdlet also takes configuration as a parameter where configuration is a JSON.
<h2>Wrap-Up</h2>
All of the cmdlet code can be found in the one module LabInaBox.psm1.  In general my approach with here was to be able to easily and quickly generate a lab in Hyper-V or Azure.  With that being said all the PowerShell cmdlets can be used as examples of how you could automate your workloads in your environment.  Please feel free to comment or contribute to the solution on GitHub.

Happy Automating till Next Time!]]></content:encoded>
    </item>
    <item>
      <title>Utilizing Key Vault to create credentials for automation.</title>
      <link>https://docs.microsoft.com/archive/blogs/troy_aults_blog/utilizing-key-vault-to-create-credentials-for-automation</link>
      <pubDate>Tue, 29 Aug 2017 12:42:21 GMT</pubDate>
      <dc:creator><![CDATA[Troy Ault]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/troy_aults_blog/?p=547</guid>
      <description><![CDATA[Working with PowerShell I often find myself doing demos which require me to have some form of...]]></description>
      <content:encoded><![CDATA[Working with PowerShell I often find myself doing demos which require me to have some form of credentials or other sensitive data.  In the past I've used really generic passwords which are easy to work with but always leave a bad taste in your mouth because the passwords are stored in plain text.  Azure has a very nice service called Key Vault which is a great solution to this problem.  To demonstrate I put together a simple script to build a credential and then utilize the credential to login into a virtual machine which is hosted in Azure.
<h2><span>Prerequisites</span></h2>
Prior to running this script you will need to have setup a way to automatically login to Azure, if you have not done this please read my previous log post <a href="https://blogs.msdn.microsoft.com/troy_aults_blog/2017/08/21/loginazurewithoutprompt/">here</a> first.

Next we will need a function called <a href="https://gallery.technet.microsoft.com/scriptcenter/Connect-Mstsc-Open-RDP-2064b10b">Connect-Mstsc</a> which is available on the PowerShell Gallery.
<h2>Creating The Key Vault</h2>
First thing we need to do is setup Key Vault in our subscription.  You have a couple options we can do it online through the online through the portal or in PowerShell.  Since I lend to automation I will demonstrate PowerShell.  Below is an example script to setup your first Key Vault.  We will want to run the setup under our personal account so we have the ability to also add/update/delete to the Key Vault in the web.  For instance adding in new keys we will do online because its a onetime task and we don't want our secrets in plain text.  So to enable this when setting up the Key Vault we will utilize Login-AzureRMAccount.  We capture the output into the variable $login so we can extract our accountid and grant ourselves all permissions to the secrets.  In addition we need to provide a couple of details to create.  We need to provide a name for the Key Vault, a resource group, and if we want to automate with PowerShell, we will also need to provide our Service Principal so we can grant it privileges.
<strong> $login = Login-AzureRmAccount</strong>

<strong>$KeyVaultName = 'MyKeyVault100'</strong>
<strong> $ResourceGroup = "$($KeyVaultName)RG"</strong>
<strong> $location = 'EastUS2'</strong>
<strong> $ServicePrincipal = 'https://ManageInternalAzureApp'</strong>
<strong> $UserPrincipal = $login.Context.Account.id</strong>

<strong>New-AzureRmResourceGroup -Name $ResourceGroup -Location $location</strong>
<strong> New-AzureRmKeyVault -VaultName $KeyVaultName -ResourceGroupName $ResourceGroup -Location $location</strong>
<strong> Set-AzureRmKeyVaultAccessPolicy -VaultName $KeyVaultName -ServicePrincipalName $ServicePrincipal -PermissionsToSecrets get</strong>
<strong> Set-AzureRmKeyVaultAccessPolicy -VaultName $KeyVaultName -userPrincipalName $UserPrincipal -PermissionsToSecrets all</strong>

As you see above this script will create a new Resource Group, Key Vault and then grant privileges to the Key Vault.  For this demo it is granting my automation ServicePrincipal get only privileges.  Therefore utilizing my automation I will not be able to update or delete the secrets.  My credentials I logged in to create the Key Vault will have all permissions on Secrets which will give me the ability to add new/update/delete secrets from the portal.

After running the script we now have a Key Vault and we need to go put some secrets in to retrieve.  Now browse to ResourceGroups&gt;MyKeyVault100RG&gt;MyKeyVault100.  Here we will see Assets (Keys, Secrets) and Monitoring (Access Policies).  First if we look at Access Policies we will see our application and user which we granted get and all privileges to above.  Next we will go to Secrets.  Here we want to click + Add change our upload options to Manual and fill in the required fields.   Below we see the required fields.  We will do this for both the AdminUser and AdminPass.

<a href="https://msdnshared.blob.core.windows.net/media/2017/08/Create-Secret.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/08/Create-Secret.png" alt="" width="737" height="865" class="alignnone size-full wp-image-556" /></a>

After we have added both of our secrets we can refresh our Secrets page and we should see something like below:

<a href="https://msdnshared.blob.core.windows.net/media/2017/08/KeyVaultSecrets.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/08/KeyVaultSecrets.png" alt="" width="735" height="323" class="alignnone size-full wp-image-566" /></a>
<h2>Accessing Key Vault</h2>
We are now ready to consume our secrets!!  We can make calls out to KeyVault and build a credential.  Below is some sample code showing this.

<strong>Login-AzurebyCert</strong>
<strong> $AdminUserName = 'AdminUser'</strong>
<strong> $AdminPassName = 'AdminPass'</strong>
<strong> $AdminUser = Get-AzureKeyVaultSecret -VaultName $KeyVaultName -Name $AdminUserName</strong>
<strong> $AdminPass = Get-AzureKeyVaultSecret -VaultName $KeyVaultName -Name $AdminPassName</strong>
<strong> $mycred = New-Object System.Management.Automation.PSCredential ("$($AdminUser.SecretValueText)", $AdminPass.SecretValue)</strong>

First we leverage Login-AzurebyCert which is explained in earlier post.  We define which secrets we want to retrieve in this case AdminUser and AdminPass.  We retrieve the values for these then build a credential from them.  After we run the above script if we take a look at $mycred we will see we now have a PSCredential.

<a href="https://msdnshared.blob.core.windows.net/media/2017/08/KeyvaultCred.png"><img src="https://msdnshared.blob.core.windows.net/media/2017/08/KeyvaultCred.png" alt="" width="900" height="175" class="alignnone size-full wp-image-575" /></a>

I can now leverage this credential to pass to any other PowerShell cmdlet which takes a credential as an input.  For my example here I am going to pass it to a PowerShell function I referenced earlier <a href="https://gallery.technet.microsoft.com/scriptcenter/Connect-Mstsc-Open-RDP-2064b10b">Connect-Mstsc</a> which will allow me to RDP into a windows machine.  This machine could be local in azure or any where for that matter.  I will be automatically logged in without having the need to know or pass credentials.  Below is the actual call.

Connect-Mstsc -ComputerName 192.168.10.1:3389 -Credential $mycred

Having the ability to store secrets helps aid in cleaning up our automation/demo scripts to ensure we are being good stewards of our sensitive data.

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Automation with Azure? How to securely script login?</title>
      <link>https://docs.microsoft.com/archive/blogs/troy_aults_blog/loginazurewithoutprompt</link>
      <pubDate>Mon, 21 Aug 2017 15:53:17 GMT</pubDate>
      <dc:creator><![CDATA[Troy Ault]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/troy_aults_blog/?p=516</guid>
      <description><![CDATA[Do you have a need to login to azure securely without being prompted?  Often times I am doing demos...]]></description>
      <content:encoded><![CDATA[Do you have a need to login to azure securely without being prompted?  Often times I am doing demos or writing automation routines which interact with Azure.  Typically you will see one of two things:
<ol>
 	<li>Get-Credential</li>
 	<li>
<div><span>$PlainPassword</span><span> </span><span>=</span><span> </span><span>"P@ssw0rd"</span>
<span>$SecurePassword</span><span> </span><span>=</span><span> </span><span>$PlainPassword</span><span> </span><span>|</span><span> </span><span>ConvertTo-SecureString</span><span> </span><span>-AsPlainText</span><span> </span><span>-Force</span></div></li>
</ol>
The first one is painful because it requires input from the user running the script and the second one well... is obviously not secure.  Since neither one of these are desirable for automation I went searching for a better solution.  What I found is described in the following article -&gt; <a href="https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-authenticate-service-principal">Use Azure PowerShell to create a service principal to access resources</a>

Since i use this often I wrapped things into a couple of functions which exist in <a href="https://github.com/Microsoft/DSC-data-driven-deployment/tree/dev/utility/LabInaBox">LabInaBox</a>.  The two functions I am going to talk about here are New-AzureCertAuthentication and Login-AzurebyCert.

<span>New-AzureCertAuthentication is called one time per subscription or resource group depending on how you are looking to secure the authentication.  The function has two mandatory parameters and two optional parameters.  ApplicationDisplayName is required and is the name of the service principal which will be created in your azure subscription which will be granted the permissions required.  You will find this under the subscriptions blade, followed by selecting the subscription then selecting Access control (IAM).  Here you will see the ApplicationDisplayName after you call the function.  Subject is the second required parameter which corresponds to the subject name of the self-signed certificate which will be generated and used for connecting to the service principal url which is created.  Once the function has been called you will find this certificate in the Current User personal certificate folder.  Subscription parameter is not required and will default to your default subscription if not passed.  Resource Group is also not required and should only be passed if you want your permission to be scoped to a particular resource group.  For LabinaBox and everything I do myself I want subscription access so I can create and remove resource groups.  If you have a need to scope at the resource group level the functionality is there.  So this provides up with three possible ways you can call this function which are documented below:</span>
<ol>
 	<li>Securing authentication to the Resource Group Level you would pass the following
<ul>
 	<li><span>New-AzureCertAuthentication -ResourceGroup 'MyResourceGroup' -SubscriptionID 'MySubscriptionID' -ApplicationName 'MyApplicationName' -Subject 'MyCertSubject'</span></li>
</ul>
</li>
 	<li>Securing authentication to the Subscription level and passing the subscription you want to utilize.
<ul>
 	<li><span>New-AzureCertAuthentication -SubscriptionID 'MySubscriptionID' -ApplicationName 'MyApplicationName' -Subject 'MyCertSubject'</span></li>
</ul>
</li>
 	<li><span>Securing authentication to the Subscription level using our default subscription</span>
<ul>
 	<li><span>New-AzureCertAuthentication -ApplicationName 'MyApplicationName' -Subject 'MyCertSubject'</span></li>
</ul>
</li>
</ol>
<span>New-AzureCertAuthentication only needs to be called once.  When you call it it will prompt for your credentials to connect to your azure subscription.  After it completes it will want to capture the following information:</span>
<ol>
 	<li>Cert Subject - corresponds to Subject passed to New-AzureCertAuthentication</li>
 	<li>ApplicationID - This is returned function</li>
 	<li>TennantID -  This is returned from the function</li>
</ol>
Now we have all the plumbing in place to connect to azure within a script from our machine.  We can simply call Login-AzurebyCert and pass three pieces of information and we will be connected to our subscription and be able to interact with any azure cmd-let.  Below is an example of a call :
<div>
<div><span>Import-module</span><span> </span><span>-</span><span>name </span><span>"C:\YourPathtoModule\modules\LabinaBox.psm1"</span></div>
</div>
Login-AzurebyCert -Certsubject <span>'MyCertSubject' -ApplicationID 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' -TennantID 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'</span>

Because I wanted to easily be able to interact with Azure I modified my function to default to my certsubject, applicationid, and tennantid.  Simplifies if I am at PowerShell prompt and want a connection to my subscription.

Stay tuned in my next article I will talk about utilizing this cmd-let and Azure Key Vault to build a credential and login to a Azure VM without being prompted.

&nbsp;

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Creating a SQL container that's always the Latest build</title>
      <link>https://docs.microsoft.com/archive/blogs/troy_aults_blog/creating-a-sql-container-thats-always-the-latest-build</link>
      <pubDate>Tue, 02 May 2017 13:07:00 GMT</pubDate>
      <dc:creator><![CDATA[Troy Ault]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/troy_aults_blog/?p=515</guid>
      <description><![CDATA[Want to stay current with the latest SQL server builds so you can test new features?  Or want the...]]></description>
      <content:encoded><![CDATA[Want to stay current with the latest SQL server builds so you can test new features?  Or want the ability to have a quick SQL instance up and running as a development environment?  Now with Docker for Windows and Windows 10 there is a quick and easy way to do both.  In this blog post I will walk through the steps to get you up and running and provide links to further get you familiar with containers.

First things first you will need to install Docker for Windows.  There is a great article you can find <a href="https://docs.docker.com/docker-for-windows/#general">here</a>.  This will walk you through installing and all the options you have to configure.  If you are looking to do some automation you will want to enable at least one shared drive.  The article referenced above will walk you through this configuration as well.  Since we are building a SQL Server container make sure to configure Docker for a minimum of 4GB of memory as this is required for the container to start.

Now that we have Docker running on windows we can leverage the PowerShell to enable a simple way to launch a development environment.  Ensure you have SQL Server PowerShell cmd-lets installed as the script references Invoke-SQLcmd.  To verify if you have it installed you can run get-command invoke-sqlcmd.  If you have it installed it will return a record with the Source.  In my case I have it from SQLPS.  If it does not find it you can install the latest SQLServer PowerShell module by running install-module sqlserver.

What I have done is created a script and placed it on my desktop.  I right click the script and execute with PowerShell.  The script checks if I currently have the container created if so it will remove it then check to ensure I have the latest SQL Server bits if not it will update them.  Once updated it will create a new container mapping the shared drive we created earlier.  Note I shared my d drive and I created a folder off the root called Docker.  Anything I place in this directory will be available to my container located in the following path in my container /volumes/docker.  Now I have a container running SQL Server and I will loop until SQL Server can get a consistent connection for three attempts.  Once I have a good connection I will restore the backup I have placed in my shared folder.  Notice I need to redirect my paths so SQL Server knows where to place them in my container.  Finally I launch SQL Server Management studio so we can connect and do some testing.

Once you are in SSMS if you would like to change any of server configuration properties you can do that with the exception of SQL Server Authentication, it is the only security mode you can run.  SQL on linux container provides the core sql engine,  if you need SSAS, SSIS, SSRS these are not included in the container.

Now anytime I want to test with the latest SQL Server bits I simple run one PowerShell script and within a couple seconds I have a new instance of SQL Server with a database I can query.

$Container = 'LatestSQL'
$Database = "AdventureWorks2016CTP3"

#Check for existance of Container
$Current = docker ps --filter "name=$Container"

#Remove our current container so we can replace it
if ($Current){docker rm -v $Container -f}

#pulls latest sql docker image
docker pull microsoft/mssql-server-linux

#Creates new container using the latest bits
docker run -v d:\Docker://volumes/Docker --name $Container -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=P@ssw0rd' -p 1433:1433 -d microsoft/mssql-server-linux

#Loop until SQL is up
Do
{
try {Start-Sleep -Seconds 2
$Test = Invoke-Sqlcmd -ServerInstance . -U sa -P P@ssw0rd -Query "Select @@version" -ErrorAction SilentlyContinue
if ($test) {$loop = $loop+1}

}
catch {Write-Output "Waiting for SQL to Start...."}
}
until ($loop -eq 3)

#Restore a backup of my Sample Database
Write-Output "Restoring Database to SQL Server...."
$Query ="RESTORE DATABASE [$($Database)] FROM DISK = N'/volumes/Docker/$($Database).bak' WITH FILE = 1, MOVE N'$($Database)_Data' TO N'/var/opt/mssql/data\$($Database)_Data.mdf', `
MOVE N'$($Database)_Log' TO N'/var/opt/mssql/data\$($Database)_Log.ldf', MOVE N'$($Database)_mod' TO N'/var/opt/mssql/data\$($Database)_mod', NOUNLOAD, STATS = 5"

Invoke-Sqlcmd -ServerInstance . -U sa -P P@ssw0rd -Query $Query

#Launch SSMS
Invoke-Item "C:\Program Files (x86)\Microsoft SQL Server\140\Tools\Binn\ManagementStudio\Ssms.exe"]]></content:encoded>
    </item>
    <item>
      <title>Automating installation of SSMS with DSC</title>
      <link>https://docs.microsoft.com/archive/blogs/troy_aults_blog/automating-installation-of-ssms-with-dsc</link>
      <pubDate>Fri, 13 Jan 2017 08:40:20 GMT</pubDate>
      <dc:creator><![CDATA[Troy Ault]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/troy_aults_blog/?p=475</guid>
      <description><![CDATA[Over the past few months I've had a couple of customers ask me, "Now that SQL 2016 doesn't include...]]></description>
      <content:encoded><![CDATA[Over the past few months I've had a couple of customers ask me, "Now that SQL 2016 doesn't include SSMS how am I supposed to automate the installation?".  Typically my response is you shouldn't be installing it on your servers as its just an additional item that will require patching.  However there are times its necessary and often times customers have dedicated management servers where they want to automate the installation or you want to automate it on your workstation.  Either way DSC is here to assist, installing any .exe or .msi with DSC is relatively simple with the Package resource which is included with DSC.  There are likely other pieces of software you may want to automate on your SQL installations also.  Here I am providing a code example of specifically how SSMS can be installed but it can be modified for other uses.  This is again "Sample Code" so you will notice I am allowing for the use of plain text passwords, not something you would want to do in a production environment.

&nbsp;
<div></div>
<div></div>
<div></div>
<div>This is a simple configuration, its only intended purpose is to install SSMS.  To do this there are only a couple of parameters you will need to set.</div>
<div>Name: Actual file name of the package we want to install</div>
<div>Path: Full path to the executable or msi we want to install.</div>
<div>Arguments:  This is an optional parameter but required for SSMS so it doesn't generate prompts on install</div>
<div>ProductId: This is the GUID found in the uninstall key of the registry.  This allows DSE to remove the software if we set Ensure to "Absent"</div>
<div>Credential:  Credential of the user which has the privileges to install the software.</div>
<div></div>
<div><a href="https://msdnshared.blob.core.windows.net/media/2017/01/DevConfigPic.jpg"><img width="882" height="821" class="alignnone size-full wp-image-505" alt="devconfigpic" src="https://msdnshared.blob.core.windows.net/media/2017/01/DevConfigPic.jpg" /></a></div>
<div>Adding a link to the file as formatting is getting lost when pasted into the blog.</div>
<div></div>
<div></div>
<div>For reference below is the link for additional details on the Package Resource.</div>
<div><a href="https://msdn.microsoft.com/en-us/powershell/dsc/packageResource">https://msdn.microsoft.com/en-us/powershell/dsc/packageResource</a></div>
<div></div>
<div>DSC has a lot of flexibility for automating your infrastructure stay tuned next I will be talking about modifying environment Variables and running PowerShell scripts with DSC.</div>]]></content:encoded>
    </item>
    <item>
      <title>Introducing LabInaBox</title>
      <link>https://docs.microsoft.com/archive/blogs/troy_aults_blog/introducing-labinabox</link>
      <pubDate>Tue, 22 Nov 2016 09:56:58 GMT</pubDate>
      <dc:creator><![CDATA[Troy Ault]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/troy_aults_blog/?p=465</guid>
      <description><![CDATA[Do you have a need to spin up a sandbox lab environment quickly to test DSC configurations, updates...]]></description>
      <content:encoded><![CDATA[Do you have a need to spin up a sandbox lab environment quickly to test DSC configurations, updates or really anything?  In writing DSC configurations over the last year I have found the need to do this often.  To simplify things I put together a few configurations and scripts to assist going forward.  The solution can be found in a GitHub repo along with the documentation on how to get started.  Stay tuned as updates will be coming to enhance this in the future.

<a href="https://github.com/Microsoft/DSC-data-driven-deployment/tree/dev/utility/LabInaBox">https://github.com/Microsoft/DSC-data-driven-deployment/tree/dev/utility/LabInaBox</a>

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Introducing DSC Data Driven Deployment</title>
      <link>https://docs.microsoft.com/archive/blogs/troy_aults_blog/introducing-dsc-data-driven-deployment</link>
      <pubDate>Fri, 09 Sep 2016 15:37:59 GMT</pubDate>
      <dc:creator><![CDATA[Troy Ault]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/troy_aults_blog/?p=435</guid>
      <description><![CDATA[Working with customers over the past year, many have asked: How can...]]></description>
      <content:encoded><![CDATA[Working with customers over the past year, many have asked: How can we manage SQL Server configurations at scale in a large enterprise?  PowerShell DSC provides a configuration framework out of the box, however, there isn’t a way to quickly build SQL deployment templates and provision in a DevOps fashion without using a third party product.

A colleague and I took on the task of developing a proof of concept data driven deployment solution backed by a SQL database. The solution provides default SQL configurations (templates) and the ability to add additional configurations as you see fit. Meta data for the configuration is stored within the database as well as setup credentials stored in a secure manner.  DevOps users may quickly queue requests which can be pushed manually or via some orchestration (even just a scheduled task).

Initially available in the project are two configurations: SQLStandAlone and SQLAlwaysOn. Steps to setup and deploy the solution are all documented in the Readme file. Currently the solution is a push deployment which consists of a Test-Configuration at the end to validate it was successful. Future plans are to add include the following:
<ol>
 	<li>Provide a mechanism to validate the configuration and redeploy</li>
 	<li>Provide history tracking of configuration overtime</li>
 	<li>Provide reporting/auditing of configurations</li>
</ol>
Over the past couple of months I have spoken with many of you about this solution, and it is now publicly available as a sanctioned open source project on GitHub –&gt; <a href="https://github.com/Microsoft/DSC-data-driven-deployment">https://github.com/Microsoft/DSC-data-driven-deployment</a>

<span style="color: #333333;font-family: 'Segoe UI',sans-serif;font-size: 10.5pt">Please feel free to add Issues/Feature requests and Contribute to the project</span>

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>SQL DSC Encrypted Configuration</title>
      <link>https://docs.microsoft.com/archive/blogs/troy_aults_blog/sql-dsc-encrypted-configuration</link>
      <pubDate>Mon, 25 Apr 2016 14:02:01 GMT</pubDate>
      <dc:creator><![CDATA[Troy Ault]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/troy_aults_blog/?p=245</guid>
      <description><![CDATA[Following up on my last post about new changes coming to xSQLServer. Today I want to talk about two...]]></description>
      <content:encoded><![CDATA[Following up on my last post about new changes coming to xSQLServer. Today I want to talk about two additional Example scripts which have been provided with the new updates. The first script is DSCSqlBuild.ps1. This new script adds a couple of items SQLPush_SingleServer.ps1 doesn't have. DSCSQLBuild.ps1 like DSCClusterSQLBuild.ps1 adds a timer to the configuration as well as the StartConfiguration and TestConfiguration are provided as workflows so configurations can be done in parallel. Moving on to the second script DSCSQLBuildEncrypted.ps1. This script will allow you to push a configuration to a server encrypting all the credentials ensuring we are secure across our environment. In order to do this, we need to have certificates for each of our servers in place with the document encryption property. You can use self-signed certificates for this, however, in an enterprise environment, you will likely want to have a certificate authority with a GPO which automatically enrolls your server with the certificate. In my lab, I have setup a Windows 2008R2 certificate authority, and I will walk through the steps of how to configure your servers with certificates. In addition, I will then walk through the example script and explain how the script can leverage the certificate to encrypt the passwords.

The first thing we will need to do is duplicate an existing template. Since we will be assigning to a computer I will duplicate the Computer Template and name it DSC Password Mgmt.

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/DuplicateTemplate.png"><img class="alignnone size-full wp-image-265" src="https://msdnshared.blob.core.windows.net/media/2016/04/DuplicateTemplate.png" alt="DuplicateTemplate" width="1018" height="241" /></a>

Once I've done this I'm presented with an option of Windows Server 2003 Enterprise or Windows Server 2008 Enterprise.   We want to choose Windows 2003 Enterprise to make sure we use the older CSP since DSC doesn’t support CNG certificates. If your CA is 2012 R2 you wont have to do this since its default behavior is the older CSP.

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/Choose2003Enterprise.png"><img class="alignnone size-full wp-image-257" src="https://msdnshared.blob.core.windows.net/media/2016/04/Choose2003Enterprise.png" alt="Choose2003Enterprise" width="400" height="246" /></a>

Walking through the remaining options of the Certificate Template:

Set the name and validity period.

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/Template-Properties.png"><img class="alignnone size-full wp-image-325" src="https://msdnshared.blob.core.windows.net/media/2016/04/Template-Properties.png" alt="Template Properties" width="413" height="529" /></a>

Select Encryption Purpose on the Request Handling tab.

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/EncryptionPurpose.png"><img class="alignnone size-full wp-image-355" src="https://msdnshared.blob.core.windows.net/media/2016/04/EncryptionPurpose.png" alt="EncryptionPurpose" width="283" height="363" /></a>

Extensions Tab. Edit the Application Policies.

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/ApplicationPoliciesEdit.png"><img class="alignnone size-full wp-image-345" src="https://msdnshared.blob.core.windows.net/media/2016/04/ApplicationPoliciesEdit.png" alt="ApplicationPoliciesEdit" width="406" height="520" /></a>

Remove Client Authentication and Server Authentication

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/RemoveClientServer.png"><img class="alignnone size-full wp-image-356" src="https://msdnshared.blob.core.windows.net/media/2016/04/RemoveClientServer.png" alt="RemoveClientServer" width="297" height="347" /></a>

Then click Add.

On Add Application Policy click New then provide values shown below.

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/NewApplicationPolicy.png"><img class="alignnone size-full wp-image-305" src="https://msdnshared.blob.core.windows.net/media/2016/04/NewApplicationPolicy.png" alt="NewApplicationPolicy" width="405" height="524" /></a>

Click OK and Apply changes to Template. We should now see the new Template in the list as below.

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/New-Template-list.png"><img class="alignnone size-full wp-image-295" src="https://msdnshared.blob.core.windows.net/media/2016/04/New-Template-list.png" alt="New Template list" width="1099" height="606" /></a>

Now we can make the template available for clients to enroll against. We do this by using the new option under Certificate Templates.

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/CertificatetoIssue.png"><img class="alignnone size-full wp-image-255" src="https://msdnshared.blob.core.windows.net/media/2016/04/CertificatetoIssue.png" alt="CertificatetoIssue" width="859" height="478" /></a>

We select the new Certificate Template from the dialog and then its available for computers to use during enrollment

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/EnableCertTemp.png"><img class="alignnone size-full wp-image-366" src="https://msdnshared.blob.core.windows.net/media/2016/04/EnableCertTemp.png" alt="EnableCertTemp" width="449" height="280" /></a>

At this point we could create a GPO to auto enroll this certificate. As there are blog posts already on this, I won't walk through this here.

Next, let's look at the script which will leverage this certificate. The first thing we set as usual is the $computers variable and the $OutputPath. Additionally, we will now set a $KeyPath. This is where we will be storing the public keys of the computers we will push configurations to.

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/ScriptVariables.png"><img class="alignnone size-full wp-image-315" src="https://msdnshared.blob.core.windows.net/media/2016/04/ScriptVariables.png" alt="ScriptVariables" width="599" height="187" /></a>

Let's create a function we can use to go export the public certificate of the target computer on our machine we are pushing configurations from. We will then call this function for each computer we are pushing the configuration to and the machine we are pushing the configuration from. This gives us all the certificates we need to deploy an encrypted configuration.

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/GetCertFunc.png"><img class="alignnone size-full wp-image-285" src="https://msdnshared.blob.core.windows.net/media/2016/04/GetCertFunc.png" alt="GetCertFunc" width="1321" height="461" /></a>Next we set the LCM for each node. Notice here we set a couple of different properties we didn’t in our other configurations. ConfigurationID which we set to a GUID and CertificateID which we are setting to the Thumbprint of the computer we are targeting. Here we use the Get-PfXCertificate cmdlet to help us get the thumbprint easily.

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/LocalConfig.png"><img class="alignnone size-full wp-image-365" src="https://msdnshared.blob.core.windows.net/media/2016/04/LocalConfig.png" alt="LocalConfig" width="1459" height="501" /></a>Three additional places in our original script need to be modified as well and are noted below. The DSCLocalConifgurationManager just inside the $AllNodes.NodeName. We need to again note the certificateId with the Nodes Thumbprint.

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/SQLBuild.png"><img class="alignnone size-full wp-image-367" src="https://msdnshared.blob.core.windows.net/media/2016/04/SQLBuild.png" alt="SQLBuild" width="614" height="326" /></a>

Within $ConfigurationData we need to set the CertificateFile property to the Thumbprint of the BuildServer. Again here we leverage Get-PfxCertifcate cmdlet

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/ConfigData.png"><img class="alignnone size-full wp-image-375" src="https://msdnshared.blob.core.windows.net/media/2016/04/ConfigData.png" alt="ConfigData" width="1202" height="289" /></a>And finally need to set the Thumbprint for each Computer in the $ConfigurationData. Since we dynamically build this property we only set it once just using the same cmdlet.

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/Final.png"><img class="alignnone size-full wp-image-385" src="https://msdnshared.blob.core.windows.net/media/2016/04/Final.png" alt="Final" width="1152" height="298" /></a>The remainder of our script is unchanged from the DSCSQLBuild.ps1.  So why go to all this work? Let's take a look at a mof file which is generated with DSCSQLBuild.ps1 compared to one generated from DSCSQLBuildEncrypted.ps1. This is just a portion of the mof file. Notice password is stored clear text.

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/UnencryptedMof.png"><img class="alignnone size-full wp-image-335" src="https://msdnshared.blob.core.windows.net/media/2016/04/UnencryptedMof.png" alt="UnencryptedMof" width="503" height="306" /></a>

Contrast that with the mof file from the DSSQLBuildEncrypted.ps1

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/EncryptedMof.png"><img class="alignnone size-full wp-image-275" src="https://msdnshared.blob.core.windows.net/media/2016/04/EncryptedMof.png" alt="EncryptedMof" width="1498" height="180" /></a>Our Password here is encrypted and longer than I can get a screen shot of.  Overall, a little bit of work may be required to get the environment ready, but in the end worth the effort to ensure your passwords are stored securely.

&nbsp;

Additional Reference:

https://blogs.msdn.microsoft.com/powershell/2015/10/01/powershell-dsc-faq-sorting-out-certificates/

&nbsp;

&nbsp;]]></content:encoded>
    </item>
  </channel>
</rss>