<?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>NCDevGuys' ramblings on connected bits....</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/ncdevguy/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/ncdevguy/feed.xml</link>
    <description />
    <lastBuildDate>Tue, 16 Apr 2019 05:21:56 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>[Service Fabric] Auto-scaling your Service Fabric cluster–Part II</title>
      <link>https://docs.microsoft.com/archive/blogs/ncdevguy/service-fabric-auto-scaling-your-service-fabric-cluster-part-ii</link>
      <pubDate>Thu, 30 Nov 2017 01:34:52 GMT</pubDate>
      <dc:creator><![CDATA[Larry Wall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ncdevguy/?p=1765</guid>
      <description><![CDATA[In Part I of this article, I demonstrated how to set up auto-scaling on the Service Fabric clusters...]]></description>
      <content:encoded><![CDATA[In Part I of this <a href="https://blogs.msdn.microsoft.com/ncdevguy/2017/11/30/service-fabric-auto-scaling-your-service-fabric-cluster-part-i/">article</a>, I demonstrated how to set up auto-scaling on the Service Fabric clusters scale set based on a metric that is part of a VM scale set (Percentage CPU). This setting doesn't have much to do at all with the applications that are running in your cluster, it's just a pure hardware scaling that may take place because of your services CPU consumption or some other thing consuming CPU.

There was a recent addition to the auto-scaling capability of a Service Fabric cluster that allows you to use an Application Insights metric, reported by your service to control the cluster scaling. This capability gives you more finite control over not just auto-scaling, but which metric in which service to provide the metric values.

<b>Creating the Application Insights (AI) resource</b>

Using the Azure portal, the cluster resource group appears to have a few strange issues in how you create your AI resource. To make sure you build the resource correctly, follow these steps.

1. Click on the name of the resource group where your cluster is located.

2. Click on the<b> +Add</b> menu item at the top of the resource group blade.

3. Choose to create a new AI resource. In my case, I created a resource that used a General application type and used a different resource group that I keep all my AI resources in.

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image0018.png"><img width="198" height="244" title="clip_image001" style="margin: 0px" alt="clip_image001" src="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image001_thumb7.png" border="0" /></a>

4. Once the AI resource has been created, you will need to retrieve and copy the<i> Instrumentation Key</i>. To do this, click on the name of your newly created AI resource and expand the Essentials menu item, you should see your instrumentation key here:

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image0035.png"><img width="244" height="108" title="clip_image003" style="margin: 0px" alt="clip_image003" src="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image003_thumb4.png" border="0" /></a>

You'll need the instrumentation key for your Service Fabric application, so either paste it in to Notepad or somewhere where you can access it easily.

<b>Modify your Service Fabric application for Application Insights</b>

In Part I of this article, I was using a simple stateless service app <a href="https://github.com/larrywa/blogpostings/tree/master/SimpleStateless">https://github.com/larrywa/blogpostings/tree/master/SimpleStateless</a> and inside of this code, I had commented out code for use in this blog post.

I left my old AI instrumentation key in-place so you can see where to place yours.

1. If you already have the solution from the previous article (or download it if you don't), the solution already has the NuGet package for <b>Microsoft.ApplicationInsights.AspNetCore</b> added. If you are using a different project, add this NuGet package to your own service.

2. Open <b>appsettings.json</b> and you will see down at the bottom of the file where I have added my instrumentation key. Pay careful attention to where you put this information in this file, brackets, colons etc can really get you messed up here.

3. In the <b>WebAPI.cs</b> file, there are a couple of things to note:
<blockquote><span style="font-size: small">a. The addition of the 'using Microsoft.ApplicationInsights;' statement.</span>

<span style="font-size: small">b. Line 31 - Uncomment the line of code for our counter.</span>

<span style="font-size: small">c. Line 34 - Uncomment the line of code that create a new TelemetryClient.</span>

<span style="font-size: small">d. Lines 43 - 59 - Uncomment out the code that creates the custom metric named 'CountNumServices'. Using myClient.TrackMetric, I can create any custom metric of any name that I wish. In this example, I am counting up to 1200 (20 minutes of time) and then I count down from there to 300, 1 second at a time. Here, I am trying to provide ample time for the cluster to react appropriately for the scale-out and scale-in.</span></blockquote>
4. Rebuild the solution.

5. Deploy your solution to the cluster.

Here is a catchy situation. To actually be able to setup your VM scale set to scale based on an AI custom metric, you have to deploy the code to start generating some of the custom metric data, otherwise it won't show up as a selection. But, if you currently have a scaling rule set, as in Part I, the nodes may still be reacting to those rules and not your new rules. That's ok, we will change that once the app is deployed and running in the cluster. And, you need to let the app run for about 10 minutes to start generating some of these metrics.

<b>Confirming custom metric data in Application Insights</b>

Before considering testing out our new custom metric, you need to make sure the data is being generated.

1. Open your AI resource that you recently created. The key was placed in the appsettings.json file.

2. Make sure you are on the Overview blade, then select the <b>Metrics Explorer</b> menu item.

3. On either of the charts, click on the very small Edit link at the upper right-hand corner of the chart.

4. In the Chart details blade, down toward the bottom, you should see a new 'Custom' section. Select <b>CountNumServices</b>.

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image0049.png"><img width="333" height="403" title="clip_image004" alt="clip_image004" src="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image004_thumb9.png" border="0" /></a>

5. Close the Chart details blade. It is handy to have this details chart so you can see what the current count it to predict whether the cluster should be scaling out or in.

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image00612.jpg"><img width="486" height="263" title="clip_image006" alt="clip_image006" src="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image006_thumb12.jpg" border="0" /></a>

<b>Modifying your auto-scaling rule set</b>

1. Make sure you are on the Scaling blade for your VM scale set.

2. In the current rule set, either click on the current Scale out rule, Scale based on a metric or click on the <b>+Add</b> rule link.

3. In my case, I clicked on <i>Scale based on a metric</i>, so we'll go with that option. Select <b>+Add</b> a rule.

4. Here is the rule I created:
<blockquote><span style="font-size: small">a. Metric source: Application Insights</span>

<span style="font-size: small">b. Resource type: Application Insights</span>

<span style="font-size: small">c. Resource: aiServiceFabricCustomMeric ~ this is my recently created AI resource</span>

<span style="font-size: small">d. Time aggregation: Average</span>

<span style="font-size: small">e. Metric name: CountNumServices ~ remember, if you don't see it when you try to scroll and find the metric to pick from, you may not have waited long enough for data to appear.</span>

<span style="font-size: small">f. Time grain: 1 minute</span>

<span style="font-size: small">g. Time grain statistic: Average</span>

<span style="font-size: small">h. Operator: Greater than</span>

<span style="font-size: small">i. Threshold: 600</span>

<span style="font-size: small">j. Duration: 5 minutes</span>

<span style="font-size: small">k. Operation: Increase count by</span>

<span style="font-size: small">l. Instance count: 2</span>

<span style="font-size: small">m. Cool down: 1 minute</span></blockquote>
Basically, after the count reaches 600, increase by two nodes. Wait 1 minute before scaling up any more nodes (note, in real production, this number should be at least 5 minutes). Actually, the number will be greater than 600 because we are using Average as the time aggregation and statistic.

5. In the Scale rule options blade

6. Select the <b>Add</b> button.

7. To create a scale in rule, I followed the same process but with slightly different settings:
<blockquote><span style="font-size: small">a. Metric source: Application Insights</span>

<span style="font-size: small">b. Resource type: Application Insights</span>

<span style="font-size: small">c. Resource: aiServiceFabricCustomMeric ~ this is my recently created AI resource</span>

<span style="font-size: small">d. Time aggregation: Average</span>

<span style="font-size: small">e. Metric name: CountNumServices ~ remember, if you don't see it when you try to scroll and find the metric to pick from, you may not have waited long enough for data to appear.</span>

<span style="font-size: small">f. Time grain: 1 minute</span>

<span style="font-size: small">g. Time grain statistic: Average</span>

<span style="font-size: small">h. Operator: <b>Less than</b></span>

<span style="font-size: small">i. Threshold: <b>500</b></span>

<span style="font-size: small">j. Duration: 5 minutes</span>

<span style="font-size: small">k. Operation: <b>Decrease count by</b></span>

<span style="font-size: small">l. Instance count: <b>1</b></span>

<span style="font-size: small">m. Cool down: 1 minute</span></blockquote>
Notice that while decreasing, I am decreasing at a lesser rate than when increasing. This is to just make sure we don't make any dramatic changes that could upset performance.

8. Save the new rule set.

9. If you need to add or change who gets notified for any scale action, go to the <b>Notify</b> tab, make your change and save it.

10. At this point, you could wait for an email confirmation of a scale action or go in to the Azure portal AI resource and view the metrics values grow. Remember though, what you see in the chart are 'averages', not a pure count of the number of incremented counts. Also, when scaling, it uses averages.

In case you are curious what these rules would look like in an ARM template, it looks something like this:

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image0089.jpg"><img width="244" height="170" title="clip_image008" alt="clip_image008" src="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image008_thumb9.jpg" border="0" /></a>

I'll provide the same warning here that I did in Part I. Attempting to scale out or in in any rapid fashion will cause instability in your cluster. When scaling out, you may consider to increase the number of nodes that are added at one time to keep you from having to wait so long for performance improvements (if that is what you are going for).]]></content:encoded>
    </item>
    <item>
      <title>[Service Fabric] Auto-scaling your Service Fabric cluster–Part I</title>
      <link>https://docs.microsoft.com/archive/blogs/ncdevguy/service-fabric-auto-scaling-your-service-fabric-cluster-part-i</link>
      <pubDate>Thu, 30 Nov 2017 01:28:16 GMT</pubDate>
      <dc:creator><![CDATA[Larry Wall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ncdevguy/?p=1515</guid>
      <description><![CDATA[Like most people, whenever I need to build an ARM template to do something with Service Fabric, I'm...]]></description>
      <content:encoded><![CDATA[Like most people, whenever I need to build an ARM template to do something with Service Fabric, I'm browsing around Github or where ever else I can find the bits and pieces of JSON that I need.

I was recently working on a project where they needed 3 things:

1. They wanted their Service Fabric cluster to use managed disks instead of Azure Storage accounts.

2. They wanted to have auto-scaling setup for their virtual machine scale set (VMSS). In this case, we started out using the Percentage CPU rule, which is based on the VM scale set hardware and nothing application specific. In Part II, I'll talk about auto-scaling via custom metrics and Application Insights.

3. They had a stateless service where they wanted to register their service event source to output logging information in to the WADETWEventTable.

This template includes those 3 implementations. You can find a link to the files here <a href="https://github.com/larrywa/blogpostings/tree/master/VMSSScaleTemplate">https://github.com/larrywa/blogpostings/tree/master/VMSSScaleTemplate</a>. This is a secure cluster implementation so you'll have to have your primary certificate in Azure Key Vault etc.

<b>Using managed disks</b>

Some of the newer templates you'll find out on Github already use managed disks for the Service Fabric cluster, but in case the one you are using doesn't, you need to find the location in your JSON file, in the Microsoft.Compute/virtualMachineScaleSets resource provider and make the following modifications.

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image00221.jpg"><img width="563" height="251" title="clip_image002" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image002_thumb21.jpg" border="0" /></a>

Another important setting you need to make sure you have is the overProvision = false setting (here placed in a variable)

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image0033.png"><img width="366" height="84" title="clip_image003" alt="clip_image003" src="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image003_thumb3.png" border="0" /></a>

This variable is actually used in the Microsoft.Compute/virtualMachineScaleSets resource provider properties:

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image0052.jpg"><img width="370" height="109" title="clip_image005" alt="clip_image005" src="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image005_thumb2.jpg" border="0" /></a>

More information about overprovisioning can be found here <a href="https://docs.microsoft.com/en-us/rest/api/compute/virtualmachinescalesets/create-or-update-a-set">https://docs.microsoft.com/en-us/rest/api/compute/virtualmachinescalesets/create-or-update-a-set</a>, but if this setting is missing or set to true, you may see more than the requested number of machines and nodes created at deployment and then the ones that are not in use are turned off. This will cause errors to appear in the Service Fabric Explorer. Service Fabric will eventually go behind and clean up itself but when you first see the errors, you'll think you did something wrong.

<b>Setting Up Auto-scale on your VMSS</b>

At first my idea was to go to my existing cluster, turn on auto-scaling inside of the VMSS settings and then export the template from the Azure portal. I then discovered that my subscription did not have permission to use the <i>microsoft.insights</i> resource provider. Not sure you'll run in to this, but if you do you can either enable it in the portal under <b>Subscriptions -&gt; your subscription -&gt; Resource providers -&gt; Microsoft.Insights</b>.

The 'microsoft.insights/autoscalesettings' resource provider is placed at the same level in the JSON file as the other major resource providers like the cluster, virtual machine scale set etc. This scaleset, although it is found as a setting for the scaleset, is not a sub-section of the resource provider for the VMSS, it is actually a separate resource provider as shown in the next screenshot.

In the Json outline editor, the auto-scale resource will look like this:

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image0067.png"><img width="244" height="157" title="clip_image006" style="margin: 0px" alt="clip_image006" src="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image006_thumb6.png" border="0" /></a>

There is a rule with conditions for scaling up and scaling down based on Percentage CPU metrics. Before deployments, go in and set your own desired levels in the capacity area, line 838 in this sample. The values for the Percentage CPU I have set in this sample are ridiculously low just to be able to see something happen, and if you're impatient, you can make them even lower just to see scaling take place.

<b>Registering your Event Source provider</b>

To register an event source provider, you need to add your event source provider to the Microsoft.Compute/virtualMachineScaleSets resource provider in the Microsoft.Azure.Diagnostics section.

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image0088.jpg"><img width="522" height="377" title="clip_image008" alt="clip_image008" src="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image008_thumb8.jpg" border="0" /></a>

You will of course need to make sure that the 'provider' listed above matches the EventSource name in your ServiceEventSource.cs file of your service. This is what I have for my stateless service that I'll deploy to the cluster once it's up and running.

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image0106.jpg"><img width="463" height="136" title="clip_image010" alt="clip_image010" src="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image010_thumb4.jpg" border="0" /></a>

<b>Template Deployment</b>

For deployment to create the Service Fabric cluster, there is a <b>deploy.ps1</b> PowerShell script included but you can really deploy the ARM template with whatever script you normally would use for your other ARM templates. Make sure you go through the process or creating your cluster certificate and put it in the Azure Key Vault first though, you will need that type of information for any secure cluster.

Note that in this example on Github, the parameters file is named 'empty-sfmanageddisk.parameters.json' and to get the deploy.ps1 to work, you need to get rid of the 'empty-' part of the name.

Once your cluster is up and running….confirm your auto-scale settings

Within your cluster resource group, click on the name of your VM scale set. Then click on the Scaling menu item. What you should see is something like this:

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image0125.jpg"><img width="525" height="332" title="clip_image012" alt="clip_image012" src="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image012_thumb5.jpg" border="0" /></a>

If you want to make changes to the levels for Scale out and Scale in, just click on the 'When' rules and an edit blade will appear where you can make those changes. Then click the Update button.

Next, to get notified of an auto-scale event, click on the <b>Notify</b> tab, enter an email address and then click the <b>Save</b> button.

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image0132.png"><img width="427" height="207" title="clip_image013" alt="clip_image013" src="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image013_thumb2.png" border="0" /></a>

Before moving on to the next step, make sure that your cluster nodes are up and running by clicking on the name of your cluster in your resource group and looking for a visual confirmation of available nodes:

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image0151.jpg"><img width="445" height="155" title="clip_image015" alt="clip_image015" src="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image015_thumb1.jpg" border="0" /></a>

<b>Publish your Service Fabric application</b>

For this example, I have a simple stateless ASP.Net Core 2.0 sample that uses the Kestrel communications listener. You can either choose a dynamic port or specify a specific port number in your ServiceManifest.xml file. Publish the service to the cluster using Visual Studio 2017.

In the WebAPI.cs file, you will notice some code that is commented out. I'll use this in part II of this article when I discuss scaling via custom metrics.

You can find this code sample at <a href="https://github.com/larrywa/blogpostings/tree/master/SimpleStateless">https://github.com/larrywa/blogpostings/tree/master/SimpleStateless</a>

<b> </b>

<b>Email from Azure during auto-scale event</b>

Each time an auto-scale event happens, you will receive an email similar to the one below:

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image0171.png"><img width="491" height="450" title="clip_image017" alt="clip_image017" src="https://msdnshared.blob.core.windows.net/media/2017/11/clip_image017_thumb1.png" border="0" /></a>

WARNING: The values that I have set for my auto-scale ranges are extremely aggressive. This is just so that initially I can see something happening. In an actual production environment, you cannot expect rapid scale-up and scale-down of Service Fabric nodes. Remember, a node (machine is first created) and then the Service Fabric bits are installed on the VM and then all that has to be spun up, registered and the rest of the Service Fabric magic. You are looking at several minutes of time for this to take place. If your scale-up and scale-down parameters are too aggressive, you could actually get the cluster in a situation where it is trying to spin up a node why taking down the same node. Your node will then go in to an unknown state in which you will have to manually correct by turning off auto-scaling until things settle down.]]></content:encoded>
    </item>
    <item>
      <title>[Service Fabric] How Not to use DefaultServices in your ApplicationManifest file</title>
      <link>https://docs.microsoft.com/archive/blogs/ncdevguy/service-fabric-how-not-to-use-in-your-applicationmanifest-file</link>
      <pubDate>Mon, 25 Sep 2017 13:48:16 GMT</pubDate>
      <dc:creator><![CDATA[Larry Wall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ncdevguy/?p=975</guid>
      <description><![CDATA[This is a bit of a cross post, but wanted to make sure that those who read through my blog can find...]]></description>
      <content:encoded><![CDATA[This is a bit of a cross post, but wanted to make sure that those who read through my blog can find the article I wrote on not using &lt;DefaultServices&gt; in your ApplicationManifest.xml file.

https://blogs.msdn.microsoft.com/premier_developer/2017/08/15/how-not-to-use-service-fabric-default-services/]]></content:encoded>
    </item>
    <item>
      <title>[Service Fabric] Full/Incremental backup and restore sample</title>
      <link>https://docs.microsoft.com/archive/blogs/ncdevguy/azure-service-fabric-fullincremental-backup-and-restore-sample</link>
      <pubDate>Mon, 25 Sep 2017 13:25:45 GMT</pubDate>
      <dc:creator><![CDATA[Larry Wall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ncdevguy/?p=965</guid>
      <description><![CDATA[I recently worked with a client who said that they had had trouble implementing incremental backup...]]></description>
      <content:encoded><![CDATA[I recently worked with a client who said that they had had trouble implementing incremental backup and restore for their stateful services, so I was set to the task to build a sample that would do both a full and incremental backups to Azure blob storage.

I fully expect great improvements to happen in Service Fabric in the coming months regarding backup and restore, but for now, the customer needed to get moving.

I've posted the Visual Studio solution on GitHub for you to look at if you are needing something like this:

<a href="https://github.com/larrywa/blogpostings/tree/master/SFBackup">https://github.com/larrywa/blogpostings/tree/master/SFBackup</a>

I am using Visual Studio 2017 15.3.3 with the Service Fabric SDK v2.7.198.

Here are some notes for the code you'll find in the sample. I've put as many comments as seem logical within the code, but more description is always better.

<span>Stateful1.cs</span>
<ul type="disc">
 	<li><span>At the top of the file is a int named </span><span>backupCount</span><span> - this is a counter that specifies after how many counts to do before you do the next full or incremental backup.</span></li>
 	<li><span>In </span><span>RunAsync</span><span>, there is an bool, </span><span>takeBackup</span><span> that will keep track of whether a backup needs to take place</span></li>
 	<li><span>When </span><span>takeBackup</span><span> is true, based on the logic I'm using, a full backup will take place first, then after this, incremental backups. There is a flag, </span><span>takeFullBackup</span><span> and an incremental counter </span><span>incrementalCount</span><span>, that will need to be replaced by your own logic on when you want to do backups and under what conditions.</span></li>
 	<li><span>BackupCallbackAsync</span><span> - this is the primary backup method. This method calls SetupBackupManager (discussed below) and ArchiveBackupAsync in the AzureBackupStore.cs file.  ArchiveBackupAsync is the method that will take the data that needs to be backed up, zip it up and push it out to blob storage. If this is a full backup, any files sitting in your blob storage container will be deleted because you should not need them at this point. (Here, you may want to do archiving if you are not sure of your backup strategy). For a stateful service with multiple partitions, you would generally have multiple blob containers, one for each partition.</span></li>
 	<li><span>SetupBackupManager</span><span> - this method gets settings from the Settings.xml file in .\PackageRoot\Config to determine storage account keys, names etc. Then, an instance of the AzureBlobBackupManager class is created. This method is called right before you perform a backup or a restore just to make sure a connection is available.</span></li>
 	<li><span>OnDataLossAsync</span><span> - this method is called when you execute the .\SFBackup\Scripts\EnumeratePartitions.ps1. This method calls the backup managers RestoreLatestBackupToTempLocation which is responsible for:</span>
<ul type="disc">
 	<li><span>Getting a list of the blobs in blob storage that make up the backup</span></li>
 	<li><span>Looping through each blob and downloading/extracting it to your hard drive (in a folder you specify).</span></li>
 	<li><span>Once unzipped, deleting the zip file from your hard drive</span></li>
 	<li><span><span>Returning the root directory under which you have the unzipped full backup plus all incremental backups. The correct structure of a full + incremental backup should look like:</span></span>Backup Folder (the root folder)/
<ul type="disc">
 	<li><span>Full/ (name may be different depending on your naming convention)</span></li>
</ul>
</li>
 	<li style="list-style-type: none">
<ul type="disc">
 	<li><span>SM/</span></li>
 	<li><span>LR/ </span></li>
 	<li><span>Metadata</span>
<ul type="disc">
 	<li><span>Incremental0 (name may be different depending on your naming convention)</span></li>
</ul>
</li>
 	<li><span>LR/ </span></li>
 	<li><span>Metadata</span>
<ul type="disc">
 	<li><span>Incremental1 (name may be different depending on your naming convention)</span></li>
</ul>
</li>
 	<li><span>LR/ </span></li>
 	<li><span>Metadata</span></li>
</ul>
</li>
</ul>
</li>
</ul>
Next, the RestoreAsync command is called which looks at your root backup directory, then cycles through the full backup and incremental backups to do the restore. The root directory is then deleted after a restore.

<span>Settings.xml</span>
<ul type="disc">
 	<li><span>For the parameters in this file, I have commented so you'll know what they mean. Note that you are going to need to add code to the app to programmatically create the directory where your backup files are dropped in to. I'm not calling this the 'root' directory because the root directory IS created programmatically and the name will change based on the partition name/logic.</span></li>
</ul>
<span>AzureBackupStore.cs</span>
<ul type="disc">
 	<li><span>I won't go in to each method here because I've commented the utility methods pretty well, but one key thing to watch for is in the constructor, it is showing you how to get the parameters out of the Settings.xml file that you need. Note how the tempRestoreDir (that is the folder YOU create on your hard drive) is combined to the partitionId name/number to form the actual 'root' folder which will be later deleted after you have done the restore.</span></li>
</ul>
&nbsp;

So, how do you run this application?

&nbsp;
<ol type="1">
 	<li value="1"><span>Open the solution and build the app to get your NuGet packages pulled down.</span></li>
 	<li><span>Create an Azure storage account with a container to use for blob storage backup</span></li>
 	<li><span>Create a directory on your hard drive to store the backup files</span></li>
 	<li><span>Fill in the information in settings.xml</span></li>
 	<li><span>Open EnumeratePartitions.ps1 in PowerShell ISE</span></li>
 	<li><span>F5</span></li>
</ol>
&nbsp;

When you start running the app, you can set breakpoints in various places to see how it runs, but for me, I let it go through a few backups and write down where I ended up at on the count (from the diagnostics window). Then approximately half way in the middle of another count run, I will execute the PS script. it will take a few seconds to trigger the restore.

The way the app is written is that when you trigger a restore, it does the restore and then after the restore, the next backup is a full backup etc. Something you will notice though as you do restores is that the service (the particular partition), will seem to freeze while the restore is taking place. This is because a 'restore' is expected to be a disaster recovery situation where the service partition would not normally be available. Other partitions may still be running, but not the one being restored.

Hope this helps you in your backup and restore efforts!]]></content:encoded>
    </item>
    <item>
      <title>[Service Fabric] Securing an Azure Service Fabric cluster with Azure Active Directory via the Azure Portal</title>
      <link>https://docs.microsoft.com/archive/blogs/ncdevguy/securing-an-azure-service-fabric-cluster-with-azure-active-directory-via-the-azure-portal-2</link>
      <pubDate>Mon, 09 Jan 2017 21:41:46 GMT</pubDate>
      <dc:creator><![CDATA[Larry Wall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ncdevguy/?p=945</guid>
      <description><![CDATA[To make sure appropriate credit is given to a great article on this topic, I did take some of the...]]></description>
      <content:encoded><![CDATA[To make sure appropriate credit is given to a great article on this topic, I did take some of the information for the steps below from this article <a href="https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-cluster-creation-via-arm">https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-cluster-creation-via-arm</a>. The article found at the link focuses on using an ARM template to do the deployment and secure setup. Using ARM would be the way you would want to set this up in a production environment.

My post is going to be using a more manual approach where you set the cluster up via the portal, for those of you who are just testing this out and want to learn how things are done via the portal. Some of the steps for setting this up in the portal will be short and will point to another article for portal setup of the cluster, but it’s the security setup we want to focus on.

So we will discuss:
<ul>
 	<li>Setup of your cluster certificate</li>
 	<li>Setup of Azure AD</li>
 	<li>Azure Cluster creation</li>
 	<li>Testing your Admin and Read-only user login</li>
</ul>
<strong><span style="font-size: medium">Setting up your cluster certificate</span></strong>

My purpose for using Azure Active Directory (AAD) was to setup an admin user and a read-only user so they could access the Service Fabric Explorer with those permissions. You still need to have a cluster certificate to secure the cluster though.
<ol>
 	<li>Open PowerShell ISE as an Administrator.</li>
 	<li>In the PowerShell command window, log in to your Azure subscription using 'Login-AzureRMAccount'. When you do this, in the command window you will see the subscriptionID. You need to copy the subscriptionID, because you will need that in the PowerShell script to create the Azure AD application. Also copy the tenantID value.</li>
 	<li>Run the following PS script. This script create a new resource group for your key vault, a key vault, a self-signed certificate and a secret key. You will need to record the information that appears in the PS command prompt output window after the successful execution of this script. Fill in the variables with your own values. Note that it is usually best just to save the script code below to a PS file first.</li>
</ol>
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:1507f2ce-6961-462a-a323-eb4a5db67274" style="float: none;margin: 0px;padding: 0px">
<pre>#-----You have to change the variable values-------#
# This script will:
#  1. Create a new resource group for your key vaults
#  2. Create a new key vault
#  3. Create, export and import (to your certificate store) a self-signed certificate
#  4. Create a new secret and put the cert in key vault
#  5. Output the values you will need to supply to your cluster for cluster cert security.
#     Make sure you copy these values before closing the PowerShell window
#--------------------------------------------------#

#Name of the Key Vault service
$KeyVaultName = "&lt;your-vault-name&gt;" 
#Resource group for the Key-Vault service. 
$ResourceGroup = "&lt;vault-resource-group-name&gt;"
#Set the Subscription
$subscriptionId = "&lt;your-Azure-subscription-ID&gt;" 
#Azure data center locations (East US", "West US" etc)
$Location = "&lt;region&gt;"
#Password for the certificate
$Password = "&lt;certificate-password&gt;"
#DNS name for the certificate
$CertDNSName = "&lt;name-of-your-certificate&gt;"
#Name of the secret in key vault
$KeyVaultSecretName = "&lt;secret-name-for-cert-in-vault&gt;"
#Path to directory on local disk in which the certificate is stored  
$CertFileFullPath = "C:\&lt;local-directory-to-place-your-exported-cert&gt;\$CertDNSName.pfx"

#If more than one under your account
Select-AzureRmSubscription -SubscriptionId $subscriptionId
#Verify Current Subscription
Get-AzureRmSubscription -SubscriptionId $subscriptionId


#Creates the a new resource group and Key-Vault
New-AzureRmResourceGroup -Name $ResourceGroup -Location $Location
New-AzureRmKeyVault -VaultName $KeyVaultName -ResourceGroupName $ResourceGroup -Location $Location -sku standard -EnabledForDeployment 

#Converts the plain text password into a secure string
$SecurePassword = ConvertTo-SecureString -String $Password -AsPlainText -Force

#Creates a new selfsigned cert and exports a pfx cert to a directory on disk
$NewCert = New-SelfSignedCertificate -CertStoreLocation Cert:\CurrentUser\My -DnsName $CertDNSName 
Export-PfxCertificate -FilePath $CertFileFullPath -Password $SecurePassword -Cert $NewCert
Import-PfxCertificate -FilePath $CertFileFullPath -Password $SecurePassword -CertStoreLocation Cert:\LocalMachine\My 

#Reads the content of the certificate and converts it into a json format
$Bytes = [System.IO.File]::ReadAllBytes($CertFileFullPath)
$Base64 = [System.Convert]::ToBase64String($Bytes)

$JSONBlob = @{
    data = $Base64
    dataType = 'pfx'
    password = $Password
} | ConvertTo-Json

$ContentBytes = [System.Text.Encoding]::UTF8.GetBytes($JSONBlob)
$Content = [System.Convert]::ToBase64String($ContentBytes)

#Converts the json content a secure string
$SecretValue = ConvertTo-SecureString -String $Content -AsPlainText -Force

#Creates a new secret in Azure Key Vault
$NewSecret = Set-AzureKeyVaultSecret -VaultName $KeyVaultName -Name $KeyVaultSecretName -SecretValue $SecretValue -Verbose

#Writes out the information you need for creating a secure cluster
Write-Host
Write-Host "Resource Id: "$(Get-AzureRmKeyVault -VaultName $KeyVaultName).ResourceId
Write-Host "Secret URL : "$NewSecret.Id
Write-Host "Thumbprint : "$NewCert.Thumbprint

</pre>
</div>
The information you need to record will appear similar to this:

Resource Id: /subscriptions/&lt;your-subscriptionID&gt;/resourceGroups/&lt;your-resource-group&gt;/providers/Microsoft.KeyVault/vaults/&lt;your-vault-name&gt;

Secret URL : <a href="https://%3cyour-vault-name%3e.vault.azure.net:443/secrets/%3csecret%3e/%3cgenerated-guid%3e">https://&lt;your-vault-name&gt;.vault.azure.net:443/secrets/&lt;secret&gt;/&lt;generated-guid&gt;</a>

Thumbprint : &lt;certificate-thumbprint&gt;

<strong><span style="font-size: medium">Setting up Azure Active Directory</span></strong>
<ol>
 	<li>To secure the cluster with Azure AD, you will need to decide which AD directory in your subscription you will be using. In this example, we will use the 'default' directory. In step 2 above, you should have recorded the 'tenantID'. This is the ID associated with your default Active directory. NOTE: If you have more than one directory (or tenant) in your subscription, you are going to have to make sure you get the right tenantID from your AAD administrator. <span style="font-size: small">The first piece of script you need to save to a file named <strong>Common.ps1</strong> is:</span></li>
</ol>
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:1d91ed10-0dbe-412e-b504-2e1b12eea7a8" style="float: none;margin: 0px;padding: 0px">
<pre>&lt;#
.VERSION
1.0.3

.SYNOPSIS
Common script, do not call it directly.
#&gt;

if($headers){
    Exit
}

Try
{
    $FilePath = Join-Path $PSScriptRoot "Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
    Add-Type -Path $FilePath
}
Catch
{
    Write-Warning $_.Exception.Message
}

function GetRESTHeaders()
{
	# Use common client 
    $clientId = "1950a258-227b-4e31-a9cf-717495945fc2"
    $redirectUrl = "urn:ietf:wg:oauth:2.0:oob"
    
    $authenticationContext = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext -ArgumentList $authString, $FALSE

    $accessToken = $authenticationContext.AcquireToken($resourceUrl, $clientId, $redirectUrl, [Microsoft.IdentityModel.Clients.ActiveDirectory.PromptBehavior]::RefreshSession).AccessToken
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $headers.Add("Authorization", $accessToken)
    return $headers
}

function CallGraphAPI($uri, $headers, $body)
{
    $json = $body | ConvertTo-Json -Depth 4 -Compress
    return (Invoke-RestMethod $uri -Method Post -Headers $headers -Body $json -ContentType "application/json")
}

function AssertNotNull($obj, $msg){
    if($obj -eq $null -or $obj.Length -eq 0){ 
        Write-Warning $msg
        Exit
    }
}

# Regional settings
switch ($Location)
{
    "china"
    {
        $resourceUrl = "https://graph.chinacloudapi.cn"
        $authString = "https://login.partner.microsoftonline.cn/" + $TenantId
    }

    default
    {
        $resourceUrl = "https://graph.windows.net"
        $authString = "https://login.microsoftonline.com/" + $TenantId
    }
}

$headers = GetRESTHeaders

if ($ClusterName)
{
    $WebApplicationName = $ClusterName + "_Cluster"
    $WebApplicationUri = "https://$ClusterName"
    $NativeClientApplicationName = $ClusterName + "_Client"
}

</pre>
</div>
You do not need to execute this script, it will be called by the next script, so make sure you have Common.ps1 in the same folder as the next script.

2.  Create a new script file and paste in the code below. Name this file <strong>SetupApplications.ps1</strong>. Note that you will need to record some of the output from the execute of this script (explained below) for later use.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:a0ce6fff-3c2a-4614-b011-7e529162995e" style="float: none;margin: 0px;padding: 0px">
<pre>&lt;#
.VERSION
1.0.3

.SYNOPSIS
Setup applications in a Service Fabric cluster Azure Active Directory tenant.

.PREREQUISITE
1. An Azure Active Directory tenant.
2. A Global Admin user within tenant.

.PARAMETER TenantId
ID of tenant hosting Service Fabric cluster.

.PARAMETER WebApplicationName
Name of web application representing Service Fabric cluster.

.PARAMETER WebApplicationUri
App ID URI of web application.

.PARAMETER WebApplicationReplyUrl
Reply URL of web application. Format: https://&lt;Domain name of cluster&gt;:&lt;Service Fabric Http gateway port&gt;

.PARAMETER NativeClientApplicationName
Name of native client application representing client.

.PARAMETER ClusterName
A friendly Service Fabric cluster name. Application settings generated from cluster name: WebApplicationName = ClusterName + "_Cluster", NativeClientApplicationName = ClusterName + "_Client"

.PARAMETER Location
Used to set metadata for specific region: china. Ignore it in global environment.

.EXAMPLE
. Scripts\SetupApplications.ps1 -TenantId '4f812c74-978b-4b0e-acf5-06ffca635c0e' -ClusterName 'MyCluster' -WebApplicationReplyUrl 'https://mycluster.westus.cloudapp.azure.com:19080'

Setup tenant with default settings generated from a friendly cluster name.

.EXAMPLE
. Scripts\SetupApplications.ps1 -TenantId '4f812c74-978b-4b0e-acf5-06ffca635c0e' -WebApplicationName 'SFWeb' -WebApplicationUri 'https://SFweb' -WebApplicationReplyUrl 'https://mycluster.westus.cloudapp.azure.com:19080' -NativeClientApplicationName 'SFnative'

Setup tenant with explicit application settings.

.EXAMPLE
. $ConfigObj = Scripts\SetupApplications.ps1 -TenantId '4f812c74-978b-4b0e-acf5-06ffca635c0e' -ClusterName 'MyCluster' -WebApplicationReplyUrl 'https://mycluster.westus.cloudapp.azure.com:19080'

Setup and save the setup result into a temporary variable to pass into SetupUser.ps1
#&gt;

Param
(
    [Parameter(ParameterSetName='Customize',Mandatory=$true)]
    [Parameter(ParameterSetName='Prefix',Mandatory=$true)]
    [String]
	$TenantId,

    [Parameter(ParameterSetName='Customize')]	
	[String]
	$WebApplicationName,

    [Parameter(ParameterSetName='Customize')]
	[String]
	$WebApplicationUri,

    [Parameter(ParameterSetName='Customize',Mandatory=$true)]
    [Parameter(ParameterSetName='Prefix',Mandatory=$true)]
	[String]
    $WebApplicationReplyUrl,
	
    [Parameter(ParameterSetName='Customize')]
	[String]
	$NativeClientApplicationName,

    [Parameter(ParameterSetName='Prefix',Mandatory=$true)]
    [String]
    $ClusterName,

    [Parameter(ParameterSetName='Prefix')]
    [Parameter(ParameterSetName='Customize')]
    [ValidateSet('china')]
    [String]
    $Location
)

Write-Host 'TenantId = ' $TenantId

. "$PSScriptRoot\Common.ps1"

$graphAPIFormat = $resourceUrl + "/" + $TenantId + "/{0}?api-version=1.5"
$ConfigObj = @{}
$ConfigObj.TenantId = $TenantId

$appRole = 
@{
    allowedMemberTypes = @("User")
    description = "ReadOnly roles have limited query access"
    displayName = "ReadOnly"
    id = [guid]::NewGuid()
    isEnabled = "true"
    value = "User"
},
@{
    allowedMemberTypes = @("User")
    description = "Admins can manage roles and perform all task actions"
    displayName = "Admin"
    id = [guid]::NewGuid()
    isEnabled = "true"
    value = "Admin"
}

$requiredResourceAccess =
@(@{
    resourceAppId = "00000002-0000-0000-c000-000000000000"
    resourceAccess = @(@{
        id = "311a71cc-e848-46a1-bdf8-97ff7156d8e6"
        type= "Scope"
    })
})

if (!$WebApplicationName)
{
	$WebApplicationName = "ServiceFabricCluster"
}

if (!$WebApplicationUri)
{
	$WebApplicationUri = "https://ServiceFabricCluster"
}

if (!$NativeClientApplicationName)
{
	$NativeClientApplicationName =  "ServiceFabricClusterNativeClient"
}

#Create Web Application
$uri = [string]::Format($graphAPIFormat, "applications")
$webApp = @{
    displayName = $WebApplicationName
    identifierUris = @($WebApplicationUri)
    homepage = $WebApplicationReplyUrl #Not functionally needed. Set by default to avoid AAD portal UI displaying error
    replyUrls = @($WebApplicationReplyUrl)
    appRoles = $appRole
}

switch ($Location)
{
    "china"
    {
        $oauth2Permissions = @(@{
            adminConsentDescription = "Allow the application to access " + $WebApplicationName + " on behalf of the signed-in user."
            adminConsentDisplayName = "Access " + $WebApplicationName
            id = [guid]::NewGuid()
            isEnabled = $true
            type = "User"
            userConsentDescription = "Allow the application to access " + $WebApplicationName + " on your behalf."
            userConsentDisplayName = "Access " + $WebApplicationName
            value = "user_impersonation"
        })
        $webApp.oauth2Permissions = $oauth2Permissions
    }
}

$webApp = CallGraphAPI $uri $headers $webApp
AssertNotNull $webApp 'Web Application Creation Failed'
$ConfigObj.WebAppId = $webApp.appId
Write-Host 'Web Application Created:' $webApp.appId

#Service Principal
$uri = [string]::Format($graphAPIFormat, "servicePrincipals")
$servicePrincipal = @{
    accountEnabled = "true"
    appId = $webApp.appId
    displayName = $webApp.displayName
    appRoleAssignmentRequired = "true"
}
$servicePrincipal = CallGraphAPI $uri $headers $servicePrincipal
$ConfigObj.ServicePrincipalId = $servicePrincipal.objectId

#Create Native Client Application
$uri = [string]::Format($graphAPIFormat, "applications")
$nativeAppResourceAccess = $requiredResourceAccess +=
@{
    resourceAppId = $webApp.appId
    resourceAccess = @(@{
        id = $webApp.oauth2Permissions[0].id
        type= "Scope"
    })
}
$nativeApp = @{
    publicClient = "true"
    displayName = $NativeClientApplicationName
    replyUrls = @("urn:ietf:wg:oauth:2.0:oob")
    requiredResourceAccess = $nativeAppResourceAccess
}
$nativeApp = CallGraphAPI $uri $headers $nativeApp
AssertNotNull $nativeApp 'Native Client Application Creation Failed'
Write-Host 'Native Client Application Created:' $nativeApp.appId
$ConfigObj.NativeClientAppId = $nativeApp.appId

#Service Principal
$uri = [string]::Format($graphAPIFormat, "servicePrincipals")
$servicePrincipal = @{
    accountEnabled = "true"
    appId = $nativeApp.appId
    displayName = $nativeApp.displayName
}
$servicePrincipal = CallGraphAPI $uri $headers $servicePrincipal

#OAuth2PermissionGrant

#AAD service principal
$uri = [string]::Format($graphAPIFormat, "servicePrincipals") + '&amp;$filter=appId eq ''00000002-0000-0000-c000-000000000000'''
$AADServicePrincipalId = (Invoke-RestMethod $uri -Headers $headers).value.objectId

$uri = [string]::Format($graphAPIFormat, "oauth2PermissionGrants")
$oauth2PermissionGrants = @{
    clientId = $servicePrincipal.objectId
    consentType = "AllPrincipals"
    resourceId = $AADServicePrincipalId
    scope = "User.Read"
    startTime = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffffff")
    expiryTime = (Get-Date).AddYears(1800).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffffff")
}
CallGraphAPI $uri $headers $oauth2PermissionGrants | Out-Null
$oauth2PermissionGrants = @{
    clientId = $servicePrincipal.objectId
    consentType = "AllPrincipals"
    resourceId = $ConfigObj.ServicePrincipalId
    scope = "user_impersonation"
    startTime = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffffff")
    expiryTime = (Get-Date).AddYears(1800).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffffff")
}
CallGraphAPI $uri $headers $oauth2PermissionGrants | Out-Null

$ConfigObj

#ARM template
Write-Host
Write-Host '-----ARM template-----'
Write-Host '"azureActiveDirectory": {'
Write-Host ("  `"tenantId`":`"{0}`"," -f $ConfigObj.TenantId)
Write-Host ("  `"clusterApplication`":`"{0}`"," -f $ConfigObj.WebAppId)
Write-Host ("  `"clientApplication`":`"{0}`"" -f $ConfigObj.NativeClientAppId)
Write-Host "},"

</pre>
</div>
3.  Execute the following command from the PS command prompt window:

<span style="font-family: Courier New;font-size: small">.\SetupApplications.ps1 -TenantId '&lt;your-tenantID&gt;' -ClusterName '&lt;your-cluster-name&gt;.&lt;region&gt;.cloudapp.azure.com' -WebApplicationReplyUrl '</span><a href="https://%3cyour-cluster-name%3e.%3cregion%3e.cloudapp.azure.com:19080/Explorer/index.html"><span style="font-family: Courier New;font-size: small">https://&lt;your-cluster-name&gt;.&lt;region&gt;.cloudapp.azure.com:19080/Explorer/index.html</span></a><span style="font-family: Courier New;font-size: small">'</span>

<span style="font-size: small">The <strong>ClusterName</strong> is used to prefix the AAD applications created by the script. It does not need to match the actual cluster name exactly as it is only intended to make it easier for you to map AAD artifacts to the Service Fabric cluster that they're being used with. This can be a bit confusing because you haven't created your cluster yet. But, if you know what name you plan to give your cluster, you can use it here.</span>

<span style="font-size: small">The <strong>WebApplicationReplyUrl</strong> is the default endpoint that AAD returns to your users after completing the sign-in process. You should set this to the Service Fabric Explorer endpoint for your cluster, which by default is:</span>

<a href="https://%3ccluster_domain%3e:19080/Explorer"><span style="font-size: small"></span></a><span style="font-size: small"><a href="https://&lt;cluster_domain&gt;:19080/Explorer">https://&lt;cluster_domain&gt;:19080/Explorer</a></span><span style="font-size: small"></span>

<span style="font-size: small">Record the information at the bottom of the command prompt window. You will need this information when you deploy your cluster from the portal. The information will look similar to what you see below.</span>
<blockquote><span style="font-size: small">"azureActiveDirectory": {</span>

<span style="font-size: small">"tenantId":"&lt;Your-AAD-tenantID&gt;",</span>

<span style="font-size: small">"clusterApplication":"1xxxxxxxx-x68e-490a-89c8-2894e4b8686a",</span>

<span style="font-size: small">"clientApplication":"xxxxxxx-7825-4e1e-a586-f0ff8d9e679e"</span>

<span style="font-size: small">NOTE: You may receive a Warning that you have a missing assembly. You can ignore this warning.</span></blockquote>
4.  After you run the script in step 6, log in to the classic Azure portal at <a href="https://manage.windowsazure.com">https://manage.windowsazure.com</a>. For now you need to use the classic Azure portal because the production portal Azure Active Directory features are still in preview.

5.  Find your Azure Active Directory in the list and click on it.

<a href="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image001.jpg"><img width="474" height="167" title="clip_image001" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="clip_image001" src="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image001_thumb.jpg" border="0" /></a>

6.  Add 2 new users to your directory. Name them whatever you want just as long as you know which one is Admin and which one would be the read-only user. Make sure to record the password that is initially generated, because the first time you try to log in to the portal as this user, you will be asked to change the password.

7.  Within your AAD, click on the Applications menu. In the Show drop-down box, pick Applications My Company Owns and then click on the check button over to the right to do a search.

<a href="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image0029.jpg"><img width="502" height="62" title="clip_image002" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image002_thumb7.jpg" border="0" /></a>

8.  You should see two applications listed. One will be for Native client applications and the other for Web Applications. Click on the application name for the web application type. Since we will be doing our connectivity test connecting to the Service Fabric Explorer web UI, this is the application we need to set the user permissions on.

<a href="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image003.png"><img width="455" height="109" title="clip_image003" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="clip_image003" src="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image003_thumb.png" border="0" /></a>

9.  Click on the Users menu.

10.  Click on the user name that should be the administrator and then select the Assign button at the bottom of the portal Window.

11.  In the Assign Users dialog box, pick Admin from the dropdown box and select the check button.

<a href="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image0042.jpg"><img width="358" height="147" title="clip_image004" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="clip_image004" src="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image004_thumb1.jpg" border="0" /></a>

12.  Repeat 10 and 11 but this time, for the read-only user select Read-only from the Assign Users drop-down. This step completes what you will need to do in the classic portal, so you can close the classic portal window.

13.  You now have all the information you need to create your cluster in the portal. Log in to the Azure Portal at <a href="https://portal.azure.com">https://portal.azure.com</a>.

<strong><span style="font-size: medium">Creating your Service Fabric cluster</span></strong>
<ol>
 	<li>Create a new resource group and then within the resource group start the process of adding a new Service Fabric Cluster to the resource group. As you are stepping through creating the cluster, you will find 4 core blades with information you need to provide:</li>
</ol>
<ul>
<ul>
 	<li>Basic - unique name for the cluster, operating system, username/password for RDP access etc.</li>
 	<li>Cluster configuration - node type count, node configuration, diagnostics etc.</li>
 	<li>Security - This is where we want to focus in the next step….</li>
</ul>
</ul>
<blockquote><span style="font-size: small">NOTE: If you want more details about creating your Service Fabric cluster via the portal, go to </span><a href="https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-cluster-creation-via-portal"><span style="font-size: small">https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-cluster-creation-via-portal</span></a><span style="font-size: small"> ~ the procedures at this link uses certificates for Admin and Read-only user setup, not AAD.</span></blockquote>
2.  In the cluster Security blade, make sure the Security mode is set to Secure. It is by default.

3.  The output from the first PS script you executed will contain the information you need for the Primary certificate information. After you enter your recorded information, make sure to select the Configure advanced settings checkbox.

<a href="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image005.png"><img width="269" height="353" title="clip_image005" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="clip_image005" src="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image005_thumb.png" border="0" /></a>

4.  By selecting the Configure advanced settings checkbox, the blade will expand (vertically) and you can scroll down in the blade to find the area where you need to enter the Active Directory information. The information you recorded when you executed SetupApplications.ps1 will be used here.

<a href="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image006.png"><img width="298" height="221" title="clip_image006" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="clip_image006" src="https://msdnshared.blob.core.windows.net/media/2017/01/clip_image006_thumb.png" border="0" /></a>

5.  Select the <strong>Ok</strong> button in the Security blade.

6.  Complete the Summary blade after the portal validates your settings.

<strong><span style="font-size: medium">Testing your Admin and Read-only user access</span></strong>
<ol>
 	<li>Once the cluster has completed the creation process, make sure you log out of the Azure portal. This assures that when you attempt to log in as the Admin or Read-only user, you will not accidentally log in to the portal as the subscription administrator.</li>
 	<li>Log in to the portal as either the Admin or Read-only user. You will need to change the temporary password you were provided early and then the log in will complete.</li>
 	<li>Open up a new browser window and log in to <a href="https://msdnshared.blob.core.windows.net/media/2017/01/Setting-up-a-Service-Fabric-Cluster-secured-by-Azure-AD.docx">https://&lt;yourfullclustername&gt;:19080/Explorer/</a>. Test the Explorer functionality.</li>
</ol>
&nbsp;

Hope this helps you in your work with Azure Service Fabric!]]></content:encoded>
    </item>
    <item>
      <title>[Service Fabric] Azure Service Fabric with Azure Diagnostics and Nlog log retrieval</title>
      <link>https://docs.microsoft.com/archive/blogs/ncdevguy/azure-service-fabric-with-azure-diagnostics-and-nlog-log-retrieval</link>
      <pubDate>Sun, 25 Dec 2016 14:27:12 GMT</pubDate>
      <dc:creator><![CDATA[Larry Wall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ncdevguy/?p=815</guid>
      <description><![CDATA[I was recently working with a customer where we were migrating some of their Azure Cloud Services...]]></description>
      <content:encoded><![CDATA[I was recently working with a customer where we were migrating some of their Azure Cloud Services over to Azure Service Fabric.

Within their current Cloud Services, there is a process where NLog will drop a log file to a Local Resource folder. Azure Diagnostics is then used to pick up this log file and place it in a container in Azure storage for another process to pick up for processing.

With Service Fabric, we do not have the same concept of a Local Resource folder. Also, with Service Fabric, or more importantly Azure Resource Manager deployments, the only way to set Azure Diagnostics settings is to do this through an ARM template.

In order to get the NLog process of dropping the file to a folder to work, the following JSON code has to be added to the ARM template:

<a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image0018.png"><img width="635" height="251" title="clip_image001" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="clip_image001" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image001_thumb8.png" border="0" /></a>

In order to find where to put the above code, you need to find the Service Fabric VM Scale set cluster (shown below in Visual Studio), select it, then in the JSON code, scroll down to where you see “publisher” : “Microsoft.Azure.Diagnostics”:

<a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image0025.png"><img width="605" height="435" title="clip_image002" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image002_thumb5.png" border="0" /></a>

The blob storage account, blob container name, node folder and VM Scale set node name can be parameterized for more flexibility.

At this point in time, what cannot be parameterized or modified is how Azure Diagnostics places the file in to the blob container. Azure Diagnostics setups up a specific folder structure under the container that looks like this:

<a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image0037.png"><img width="580" height="230" title="clip_image003" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="clip_image003" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image003_thumb6.png" border="0" /></a>

For more information on some of the differences between Cloud Services and Service Fabric, check out:

<a href="https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-cloud-services-migration-differences" title="https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-cloud-services-migration-differences">https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-cloud-services-migration-differences</a>

&nbsp;

Hope this helps you in your work with Azure Service Fabric!]]></content:encoded>
    </item>
    <item>
      <title>[Service Fabric] Connecting to a remote Azure Service Fabric cluster using PowerShell</title>
      <link>https://docs.microsoft.com/archive/blogs/ncdevguy/connecting-to-a-remote-azure-service-fabric-cluster-using-powershell</link>
      <pubDate>Sun, 25 Dec 2016 14:17:36 GMT</pubDate>
      <dc:creator><![CDATA[Larry Wall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ncdevguy/?p=745</guid>
      <description><![CDATA[If you have struggled with getting the syntax and parameters correct on the...]]></description>
      <content:encoded><![CDATA[If you have struggled with getting the syntax and parameters correct on the Connect-ServiceFabricCluster PowerShell cmdlet like I have, I've decided to post the command with associated parameters that I know works every time.

This command is typically used to test connectivity from your personal machine to a .X509 secured cluster in Azure.
<blockquote><span style="font-family: Courier New;font-size: small">$ClusterName= "&lt;your-full-cluster-name&gt;:19000"</span>

<span style="font-family: Courier New;font-size: small">$CertThumbprint= "&lt;your-certificate-thumbprint&gt;" </span>

<span style="font-family: Courier New;font-size: small">Connect-ServiceFabricCluster -ConnectionEndpoint $ClusterName -KeepAliveIntervalInSec 10 `    -X509Credential `</span>

<span style="font-family: Courier New;font-size: small">    -ServerCertThumbprint $CertThumbprint  `</span>

<span style="font-family: Courier New;font-size: small">    -FindType FindByThumbprint `</span>

<span style="font-family: Courier New;font-size: small">    -FindValue $CertThumbprint `</span>

<span style="font-family: Courier New;font-size: small">    -StoreLocation CurrentUser `</span>

<span style="font-family: Courier New;font-size: small">    -StoreName My</span></blockquote>
Upon successful connection, you should see something similar to

<a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image0017.png"><img width="708" height="268" title="clip_image001" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="clip_image001" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image001_thumb7.png" border="0" /></a>

Hope this helps you in your work with Azure Service Fabric!]]></content:encoded>
    </item>
    <item>
      <title>[Service Fabric] The signed in user is not assigned to a role for the application</title>
      <link>https://docs.microsoft.com/archive/blogs/ncdevguy/the-signed-in-user-is-not-assigned-to-a-role-for-the-application</link>
      <pubDate>Sun, 25 Dec 2016 14:07:22 GMT</pubDate>
      <dc:creator><![CDATA[Larry Wall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ncdevguy/?p=715</guid>
      <description><![CDATA[If you have setup an Azure Service Fabric cluster and secured it using Azure Active directory, you...]]></description>
      <content:encoded><![CDATA[If you have setup an Azure Service Fabric cluster and secured it using Azure Active directory, you may run in to the same problem I did when I went to deploy an application from Visual Studio 2015. You can refer back to my other post on this if you are not sure how this is setup <a href="https://blogs.msdn.microsoft.com/ncdevguy/2016/12/21/securing-an-azure-service-fabric-cluster-with-azure-active-directory-via-the-azure-portal/" title="https://blogs.msdn.microsoft.com/ncdevguy/2016/12/21/securing-an-azure-service-fabric-cluster-with-azure-active-directory-via-the-azure-portal/">https://blogs.msdn.microsoft.com/ncdevguy/2016/12/21/securing-an-azure-service-fabric-cluster-with-azure-active-directory-via-the-azure-portal/</a>.

In Visual Studio, whenever you publish an application to the cluster, you will be prompted to log in to Azure with your Azure subscription credentials. As you can see in the screenshot, you will see both your certificate thumbprint and AzureActiveDirectory = true.

<a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image0016.png"><img width="456" height="369" title="clip_image001" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="clip_image001" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image001_thumb6.png" border="0" /></a>

Since I had all this setup, I then attempted to deploy the application. The deployment failed and I was presented with this error in the Visual Studio output window.
<blockquote><span style="font-family: Courier New;font-size: small">1&gt;------ Build started: Project: HealthApp, Configuration: Debug x64 ------</span>

<span style="font-family: Courier New;font-size: small">2&gt;------ Publish started: Project: HealthApp, Configuration: Debug x64 ------</span>

<span style="font-family: Courier New;font-size: small">2&gt;AADSTS50105: The signed in user is not assigned to a role for the application '1458052a-a261-4d8a-8bf3-e7529ce62ba8'.</span>

<span style="font-family: Courier New;font-size: small">2&gt;Trace ID: 4b8ad5d7-94e3-456d-a0f8-13a13144eb9d</span>

<span style="font-family: Courier New;font-size: small">2&gt;Correlation ID: 75cddc9f-f9af-405f-8593-42af6dfd8c85</span>

<span style="font-family: Courier New;font-size: small">2&gt;Timestamp: 2016-12-14 19:58:18Z</span></blockquote>
As you may recall, when you do a publish, you have to log in to your Azure subscription from the publish dialog box.

If these log in credentials, or rather this user, is not also assigned the Admin role in AAD for the web client app, then Visual Studio will not be able to connect to the cluster and therefore can’t do a publish. Normally you will add specific users that are assigned the Admin and Read-Only user roles for the app and it can be easy to forget to setup app permissions for the user logging in to Azure.

So, add that subscription user as an Admin for the Web Client app in AAD.

You should now be able to deploy the application to your secure cluster in Azure.

Hope this helps you in your work with Azure Service Fabric!]]></content:encoded>
    </item>
    <item>
      <title>[Service Fabric] Unable to determine whether the application is installed on the cluster or not</title>
      <link>https://docs.microsoft.com/archive/blogs/ncdevguy/unable-to-determine-whether-the-application-is-installed-on-the-cluster-or-not</link>
      <pubDate>Wed, 21 Dec 2016 03:53:53 GMT</pubDate>
      <dc:creator><![CDATA[Larry Wall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ncdevguy/?p=695</guid>
      <description><![CDATA[&nbsp;

I was working with a customer that was attempting to deploy a simple Service Fabric...]]></description>
      <content:encoded><![CDATA[&nbsp;

I was working with a customer that was attempting to deploy a simple Service Fabric application from within Visual Studio 2015 to a secure cluster in Azure.

The cluster itself was secured via an .X509 certificate stored in Azure Key Vault. There were currently no applications deployed to the Azure cluster.

When we opened up the publish dialog in Visual Studio, the first thing we noticed was the red circular 'x' icon over to the right of the name of the cluster endpoint address. The error message shown here is actually a pretty common one that can be caused by connectivity issues with the remote cluster 'Failed to contact the server. Please try again later or get help from "How to configure secure connections"

<a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image0014.png"><img width="2030" height="510" title="clip_image001" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="clip_image001" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image001_thumb4.png" border="0" /></a>

&nbsp;

We decided first to confirm that the thumbprint was correct and that it was installed on the machine from where the deployment was being attempted.

We then decided to go ahead and attempt to publish the app to the Azure cluster just to see what happens and see what error message appears. In the output window, we saw this:

&nbsp;
<blockquote><span style="font-size: small">1&gt;------ Build started: Project: HealthApp, Configuration: Debug x64 ------ </span>

<span style="font-size: small">2&gt;------ Publish started: Project: HealthApp, Configuration: Debug x64 ------ </span>

<span style="font-size: small">2&gt;Unable to determine whether the application is installed on the cluster or not </span>

<span style="font-size: small">========== Build: 1 succeeded, 0 failed, 3 up-to-date, 0 skipped ========== </span>

<span style="font-size: small">========== Publish: 0 succeeded, 1 failed, 0 skipped ==========</span></blockquote>
&nbsp;

Strange error. Was Visual Studio actually connecting to the cluster and then could not confirm that the app was there or was Visual Studio actually NOT connecting to the cluster so of course, it could not determine if the app was there?

To make sure that from the deployment machine we could actually connect to the cluster, we opened PowerShell ISE (as an administrator) and ran the following command:

&nbsp;
<blockquote><span style="font-family: Courier New;font-size: small">$ClusterName= "myclustername.eastus.cloudapp.azure.com:19000"</span>

<span style="font-family: Courier New;font-size: small">$CertThumbprint= "&lt;my-certificate-thumbprint&gt;" </span>

<span style="font-family: Courier New;font-size: small">Connect-serviceFabricCluster -ConnectionEndpoint $ClusterName -KeepAliveIntervalInSec 10 `</span>

<span style="font-family: Courier New;font-size: small">-X509Credential `</span>

<span style="font-family: Courier New;font-size: small">-ServerCertThumbprint $CertThumbprint `</span>

<span style="font-family: Courier New;font-size: small">-FindType FindByThumbprint `</span>

<span style="font-family: Courier New;font-size: small">-FindValue $CertThumbprint `</span>

<span style="font-family: Courier New;font-size: small">-StoreLocation CurrentUser `</span>

<span style="font-family: Courier New;font-size: small">-StoreName My</span></blockquote>
&nbsp;

We confirmed cluster connectivity:

<a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image0024.png"><img width="1511" height="569" title="clip_image002" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border-width: 0px" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image002_thumb4.png" border="0" /></a>

What ensued over the next few hours were redeployments of certificates, testing other apps for deployment, testing from other machines.

&nbsp;

Eventually we discovered that the problem was there was a hidden white space in front of the value for the thumbprint in the publish dialog:

<a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image0036.png"><img width="742" height="339" title="clip_image003" style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" alt="clip_image003" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image003_thumb5.png" border="0" /></a>

And when I say hidden, I mean there was no indication at all that there was anything there. Until we manually re-entered the certificate thumbprint and tried a new deployment, it still appeared that Visual Studio did not have connectivity to the cluster. Once we deployed successfully, the red icon went away.

&nbsp;

Hope this helps you in your work with Azure Service Fabric!]]></content:encoded>
    </item>
    <item>
      <title>[Service Fabric] Default service descriptions must not be modified as part of an upgrade</title>
      <link>https://docs.microsoft.com/archive/blogs/ncdevguy/default-service-descriptions-must-not-be-modified-as-part-of-an-upgrade</link>
      <pubDate>Tue, 20 Dec 2016 16:49:01 GMT</pubDate>
      <dc:creator><![CDATA[Larry Wall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ncdevguy/?p=255</guid>
      <description><![CDATA[Recently (Service Fabric SDK v 2.4.145) I had deployed a Service Fabric application to my local...]]></description>
      <content:encoded><![CDATA[Recently (Service Fabric SDK v 2.4.145) I had deployed a Service Fabric application to my local cluster from Visual Studio. As part of an upgrade process after I changed something in the Settings.xml file for my service, I was executing the following PowerShell code:

&nbsp;
<blockquote><span style="font-size: small"><span style="font-family: Courier New">Connect-ServiceFabricCluster localhost:19000</span> </span>

<span style="font-family: Courier New"></span><span style="font-size: small">  </span><span style="font-size: small"><span style="font-family: Courier New">Copy-ServiceFabricApplicationPackage -ApplicationPackagePath '.' `</span> </span>

<span style="font-family: Courier New;font-size: small">-ImageStoreConnectionString '</span><a href="/SfDevCluster/Data/ImageStoreShare"><span style="font-family: Courier New;font-size: small">file:C:\SfDevCluster\Data\ImageStoreShare</span></a><span style="font-size: small"><span style="font-family: Courier New">' -ApplicationPackagePathInImageStore 'SFConfigModified'</span> </span>

<span style="font-family: Courier New"></span><span style="font-size: small"> </span><span style="font-size: small"><span style="font-family: Courier New">Register-ServiceFabricApplicationType -ApplicationPathInImageStore 'SFConfigModified' -TimeoutSec 300</span> </span>

<span style="font-size: small"><span style="font-family: Courier New">Start-ServiceFabricApplicationUpgrade `</span> </span>

<span style="font-size: small"><span style="font-family: Courier New">-ApplicationName 'fabric:/SFConfigModified' `</span> </span>

<span style="font-size: small"><span style="font-family: Courier New">-ApplicationTypeVersion '1.0.17' `</span> </span>

<span style="font-size: small"><span style="font-family: Courier New">-Monitored `</span> </span>

<span style="font-size: small"><span style="font-family: Courier New">-ForceRestart `</span> </span>

<span style="font-family: Courier New;font-size: small">-FailureAction Rollback</span>

<span style="font-family: Courier New"></span></blockquote>
This is when I received the following error in the PowerShell command window:

&nbsp;
<blockquote><span style="font-size: small"><span style="font-family: Courier New">Registering application type…</span> </span>

<span style="font-size: small"><span style="font-family: Courier New">Register application type succeeded</span> </span>

<span style="font-family: Courier New;font-size: small">Start-ServiceFabricApplicationUpgrade : Default service descriptions must not be modified as </span>

<span style="font-size: small"><span style="font-family: Courier New">part of upgrade. Modified default service: fabric:/SFConfigModified/StatelessWebApi</span> </span>

<span style="font-size: small"><span style="font-family: Courier New">At C:\Workshops\AzureSF\HelperFiles\testconfigchanged.ps1:13 char:1</span> </span>

<span style="font-size: small"><span style="font-family: Courier New">+ Start-ServiceFabricApplicationUpgrade `</span> </span>

<span style="font-size: small"><span style="font-family: Courier New">+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span> </span>

<span style="font-family: Courier New;font-size: small">+ CategoryInfo : InvalidOperation: (Microsoft.Servi...usterConnection:ClusterConne </span>

<span style="font-size: small"><span style="font-family: Courier New">ction) [Start-ServiceFabricApplicationUpgrade], FabricException</span> </span>

<span style="font-family: Courier New;font-size: small">+ FullyQualifiedErrorId : UpgradeApplicationErrorId,Microsoft.ServiceFabric.Powershell.Star </span>

<span style="font-family: Courier New;font-size: small">tApplicationUpgrade</span></blockquote>
&nbsp;

For some reason, the upgrade thinks I have modified my ApplicationManifest.xml file in the &lt;DefaultServices&gt; section, although I know I did not modify it.

&nbsp;

I have discovered that this issue is something that will be corrected in the near future, but how do you get this working again to be able to do updates from PowerShell?

&nbsp;

Here is what I had to do to get things working again:
<ol>
 	<li>Open Service Fabric Explorer and remove the application from the cluster.</li>
 	<li>In my PS script, after the Register-ServiceFabricApplicationType command, execute the command to do a new deployment:
New-ServiceFabricApplication -ApplicationName 'fabric:/SFConfigModified' -ApplicationTypeName 'SFConfigModifiedType' -ApplicationTypeVersion 1.0.15</li>
 	<li>Comment out the New-ServiceFabricApplication line of code.</li>
</ol>
&nbsp;

From this point on, I could do upgrades to my application.]]></content:encoded>
    </item>
  </channel>
</rss>