<?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>Chris Mitchell</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/chmitch/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/chmitch/feed.xml</link>
    <description>Data and Analytics Insights</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:21:03 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Complete guide to setting up Power BI connecting to Postgres w/ refresh enabled.</title>
      <link>https://docs.microsoft.com/archive/blogs/chmitch/complete-guide-to-setting-up-power-bi-connecting-to-postgres-w-refresh-enabled</link>
      <pubDate>Mon, 04 Jun 2018 15:09:09 GMT</pubDate>
      <dc:creator><![CDATA[Chris Mitchell]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/chmitch/?p=375</guid>
      <description><![CDATA[You may or may not have seen but Microsoft announced a couple new database services, namely Postgres...]]></description>
      <content:encoded><![CDATA[You may or may not have seen but Microsoft announced a couple new database services, namely Postgres and MySQL. What's unique about these two database services is they work very similar to SQL Azure, in particular there is no VM for you to provision or manage. When you provision the resource you get an endpoint to connect to that allows you to create databases and the content on those databases. I was recently working on a scenario that needed to leverage the new Postgres service from Power BI, and while connecting everything works, it was not as straightforward as I expected.

&nbsp;

In my endeavors I had to wade through four different sources to piece everything together, so in the interest of saving you time here are the complete steps to getting Power BI Desktop to connect to Postgres plus setting up the gateway service so you can refresh a published model from the Azure Postgres service.

&nbsp;

As I mentioned, I pieced together a variety of sources to get to the correct steps.  I referenced a series of both community blogs and azure documentation to get this running, those sources are (and what I got from each):
<ul>
 	<li style="list-style-type: none">
<ul>
 	<li style="list-style-type: none">
<ul>
 	<li><a href="https://community.powerbi.com/t5/Community-Blog/Configuring-Power-BI-Connectivity-to-PostgreSQL-Database/ba-p/12567">https://community.powerbi.com/t5/Community-Blog/Configuring-Power-BI-Connectivity-to-PostgreSQL-Database/ba-p/12567</a> - This source covers the prerequisites necessary for connecting to Postgres but not specifically the Azure Postgres Service</li>
 	<li><a href="https://community.powerbi.com/t5/Integrations-with-Files-and/Azure-PostgreSQL-Direct-Query/td-p/308220">https://community.powerbi.com/t5/Integrations-with-Files-and/Azure-PostgreSQL-Direct-Query/td-p/308220</a> - At the end of this post there is commentary specifically about needing the 3.1.8 version of the driver.</li>
 	<li><a href="https://docs.microsoft.com/en-us/azure/postgresql/concepts-ssl-connection-security">https://docs.microsoft.com/en-us/azure/postgresql/concepts-ssl-connection-security</a> - this covers the specifics of getting the appropriate certificate and installing it for connecting to Postgres on Azure.</li>
 	<li><a href="https://community.powerbi.com/t5/Integrations-with-Files-and/Connecting-to-PostgresSQL-hosted-on-AWS-RDS/m-p/135666">https://community.powerbi.com/t5/Integrations-with-Files-and/Connecting-to-PostgresSQL-hosted-on-AWS-RDS/m-p/135666</a> - this is where I got the tip to use the trusted root CA (appdata directory config in the previous article isn't appropriate for the gateway).</li>
</ul>
</li>
</ul>
</li>
</ul>
&nbsp;

Since there are a ton of steps here, I've broken it into a few logical parts. This keeps things better organized and helps you skip over sections that are irrelevant to your scenario. The parts are:
<ul>
 	<li style="list-style-type: none">
<ul>
 	<li style="list-style-type: none">
<ol>
 	<li>Part 1 - Provision your Azure Postgres Database and install the components for connecting to Postgres</li>
 	<li>Part 2 - Register the appropriate certificate so SSL connections to Postgres work.</li>
 	<li>Part 3 - Connect to your Postgres database with Power BI Desktop.</li>
 	<li>Part 4 - Setup and configure the Power BI Gateway for cloud refresh.</li>
</ol>
</li>
</ul>
</li>
</ul>
&nbsp;

&nbsp;

<b>Part 1 - Provision your Azure Postgres Database and install the components for connecting to Postgres</b>

&nbsp;

In case you haven't provisioned an Azure Postgres database, here are the basic steps to creating a new instance of the Postgres database service via the Azure Portal.

&nbsp;
<ul>
 	<li style="list-style-type: none">
<ul>
 	<li style="list-style-type: none">
<ol>
 	<li>Login to the Azure Portal, and select "Create a resource"
<img width="163" height="50" class="alignnone wp-image-385 " alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p01-300x92.png" /></li>
 	<li>Search the marketplace for "Azure Postgres", and select the top search result. (Note: there are several other marketplace templates for Postgres, but for the purposes of this blog I'm focusing on the Azure Database for PostgreSQL)
<img width="255" height="63" class="alignnone wp-image-395" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p02.png" /></li>
 	<li>Click "Create"</li>
 	<li>Fill out the form for the new server including the Server name, Resource group, Server admin login name, password, and click "Create". (Note: there are other settings here like the Postgres version and the number of cores, but they aren't important to this scenario).
<img width="256" height="518" class="alignnone wp-image-405" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p03-506x1024.png" /></li>
 	<li>While your database is being provisioned there are a couple of things you can go ahead and setup.</li>
 	<li>Install Npgsql 3.1.8 via the MSI (note this is version specific), you can find the installer here: <a href="https://github.com/npgsql/npgsql/releases/tag/v3.1.8">https://github.com/npgsql/npgsql/releases/tag/v3.1.8</a></li>
 	<li>By default the postgres service has SSL enabled. You need to download and trust a specific certificate so SSL communication will work. (you could turn off SSL for the server in Azure, but that's cheating).</li>
</ol>
</li>
</ul>
</li>
</ul>
&nbsp;

<b>Part 2 - Register the appropriate certificate so SSL connections to Postgres work.</b>

&nbsp;

There official version of these instructions can be found here: <a href="https://docs.microsoft.com/en-us/azure/postgresql/concepts-ssl-connection-security">https://docs.microsoft.com/en-us/azure/postgresql/concepts-ssl-connection-security</a>. These directions are intended to be generic and therefore cover many scenarios.   Since the directions are a bit terse and interleave linux directions with windows directions, I decided to give you an abbreviated step by step specific to Windows (Note: Power BI and the Gateway presently only run on Windows):
<ul>
 	<li style="list-style-type: none">
<ul>
 	<li style="list-style-type: none">
<ol>
 	<li>Download the encrypted cert from: <a href="https://www.digicert.com/CACerts/BaltimoreCyberTrustRoot.crt">https://www.digicert.com/CACerts/BaltimoreCyberTrustRoot.crt</a>.</li>
 	<li>Download and install openssl to decrypt the cert <a href="https://slproweb.com/download/Win32OpenSSL_Light-1_1_0h.exe">https://slproweb.com/download/Win32OpenSSL_Light-1_1_0h.exe</a>.</li>
 	<li>Run the command: openssl x509 -inform DER -in BaltimoreCyberTrustRoot.crt -text -out root.crt (Note: depending on where you install openssl and/or where you dowloaded the .crt file to you may need to amend this command to deal with paths.)</li>
 	<li>Double click on the created root.crt file, you'll be presented the certificate info. Click "Install Certificate…"
<img width="284" height="355" class="alignnone wp-image-415" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/P04.png" /></li>
 	<li>Select "Local Machine", and click "Next"
<img width="370" height="358" class="alignnone wp-image-425" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p05-1024x990.png" /></li>
 	<li>Select "Place all certificates in the following store", and "Browse"
<img width="383" height="373" class="alignnone wp-image-435" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/P06-1024x999.png" /></li>
 	<li>Select "Trusted Root Certification Authorities", and click "Ok"
<img width="254" height="245" class="alignnone wp-image-445" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/P07.png" /></li>
 	<li>Click "Next".</li>
 	<li>Click "Finish".</li>
</ol>
</li>
</ul>
</li>
</ul>
&nbsp;

&nbsp;

<b>Part 3 -   Connect to your Postgres database with Power BI Desktop</b>

&nbsp;

Now that we've installed all the prerequisites I'm going to walk through all the steps necessary to connect to the database.   Since this blog is largely about Power BI, I'm going to make the wild assumption that you already have Power BI Desktop installed. Once it's installed here are the steps:

&nbsp;
<ul>
 	<li style="list-style-type: none">
<ul>
 	<li style="list-style-type: none">
<ol>
 	<li>Let's go to the azure portal for a bit to grab and configure things, login to the portal if you don't still have it open, and navigate to the Postgres resource you created</li>
 	<li>Take note of the "Server name" and "Server admin login name", you'll need these for the gateway config.       Second, click on "Connection security", and add a firewall rule for the IP address of your machine running Power BI Desktop. The easiest way to do this is with "Add Client IP", then make sure you save your changes.</li>
 	<li>Now launch Power BI Desktop.</li>
 	<li>Use the "Get Data" menu to select a data source and select "More…"
<img width="138" height="453" class="alignnone wp-image-455" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/P08.png" /></li>
 	<li>Select "Database" and "PostgreSQL Database" and click "Connect"
<img width="469" height="507" class="alignnone wp-image-465" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/P09.png" /></li>
 	<li>Enter the server name you made note of in step 1, and the database name. (Note: for my purposes I'm just using the default database postgres as I'm only proving the scenario works).
<img width="511" height="194" class="alignnone wp-image-475" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p10.png" /></li>
 	<li>Enter your username and password, and click "Connect" (Note: the username needs to be in the format username@servername)
<img width="507" height="227" class="alignnone wp-image-485" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p11.png" /></li>
 	<li>In the data source navigator, select the tables you want to include in the model and click "Load".
<img width="595" height="474" class="alignnone wp-image-495" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p12.png" /></li>
 	<li>Check the "Fields" pane to ensure you've got some tables in your data model.
<img width="394" height="279" class="alignnone size-full wp-image-505" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p13.png" /></li>
 	<li>You're done, save a local copy of the file for later publishing, or publish directly to Power BI using the "Publish" button.</li>
</ol>
</li>
</ul>
</li>
</ul>
<ul>
 	<li style="list-style-type: none">
<ul>
 	<li style="list-style-type: none"></li>
</ul>
</li>
</ul>
&nbsp;

&nbsp;

&nbsp;

<b>Part 4 - Setup and configure the Power BI Gateway for cloud refresh</b>

&nbsp;

At this point all you have a Power BI model connected to Postgres, but most companies I talk to actually want to publish their models, share them with others, and most importantly do some sort of a scheduled refresh on the data. In order to do this you're going to have to setup the Power BI Gateway somewhere.   This gateway can be installed on a Windows machine ranging from your personal desktop to a server. The most important things are that the machine should be on all the time, and it should have internet connectivity; therefore, installing it on your laptop is typically not a good idea. I chose to provision a Windows VM in my Azure subscription. Once you've decided where you're going to install the gateway here are the steps to get it running:
<ul>
 	<li style="list-style-type: none">
<ul>
 	<li style="list-style-type: none">
<ol>
 	<li>Go through all the steps in "Part 2" again on the gateway host machine. (Pro Tip: You've already decrypted the certificate with OpenSSL on your Power BI Desktop machine, so you can bypass steps 2 &amp; 3 by copying the root.cer file to the target machine).</li>
 	<li>Download and install the Power BI Data Gateway from: <a href="https://powerbi.microsoft.com/en-us/gateway/">https://powerbi.microsoft.com/en-us/gateway/</a> and click "DOWNLOAD GATEWAY"
<img width="277" height="60" class="alignnone size-full wp-image-515" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p14.png" /></li>
 	<li>In the installer, you can accept all the defaults. In particular, make sure you select this option in the installer
<img width="482" height="107" class="alignnone size-full wp-image-625" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p27.png" /></li>
 	<li>Once the install is complete you'll be taken through the configuration steps. First enter the email address you use to login to Power BI and click "Sign In"
<img width="404" height="372" class="alignnone wp-image-525" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p15.png" /></li>
 	<li>Next, select "Register New Gateway" (Note, the other option is useful if you need to migrate a gateway to another machine or are rebuilding a machine).</li>
 	<li>Now you need to configure your gateway by giving it a unique name so you can find it in the Power BI Portal, and set your recovery password which is necessary if you ever need to move / restore your gateway.       (Note: for more advanced install scenarios you can add your gateway to a gateway cluster enabling high availability for the gateway).
<img width="414" height="406" class="alignnone wp-image-535" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p16.png" /></li>
 	<li>Gateway installation and configuration is complete, you should see a screen like:
<img width="414" height="413" class="alignnone wp-image-545" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p19.png" /></li>
 	<li>Now that the gateway is installed, we need to register the datasource with the gateway. This is done in the Power BI portal.</li>
 	<li>Login to <a href="https://www.powerbi.com/">www.powerbi.com</a>, and on your main screen select manage gateways, you'll find this under the settings gear.
<img width="143" height="243" class="alignnone wp-image-555" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p20.png" /></li>
 	<li>This will take you to the Add Datasource page, select the gateway corresponding to the name you gave the gateway in step 6.
<img width="182" height="209" class="alignnone wp-image-565" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p21.png" /></li>
 	<li>Click the ellipsis (…) and select "ADD DATA SOURCE"
<img width="544" height="190" class="alignnone wp-image-575" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p22.png" /></li>
 	<li>Name your datasource and pick the appropriate type.</li>
 	<li>Just like we did with Power BI Desktop, lets jump over to the azure portal for a bit to grab and configure things. First, take note of the "Server name" and "Server admin login name", you'll need these for the gateway config. Second, click on "Connection security", and add a firewall rule for the IP address of your gateway server.
<img width="797" height="225" class="alignnone wp-image-585" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p23-1024x289.png" />
<img width="402" height="139" class="alignnone wp-image-595" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/P24.png" /></li>
 	<li>Fill out the necessary server and database settings, for my purposes I just used the default database to prove it works.       (Note: Pay close attention to the fact that the admin login is username@servername), and click "Add"
<img width="435" height="478" class="alignnone wp-image-605" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p25.png" /></li>
 	<li>Note, if you get the following error its typically because you entered your password wrong, or you didn't add a firewall rule:
<img width="593" height="125" class="alignnone wp-image-615" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/06/p26.png" /></li>
</ol>
</li>
</ul>
</li>
</ul>
&nbsp;

Ok, you're all finished. Now when you decided to publish your Power BI Desktop file to the Power BI portal, you'll be able to manually refresh or setup a scheduled refresh on the data. At refresh time Power BI will use the gateway server to connect to the database and issue queries using the correct driver and feed the results back to the Power BI Service.]]></content:encoded>
    </item>
    <item>
      <title>Connecting to Blob Storage with a Shared Access Signature in Power BI</title>
      <link>https://docs.microsoft.com/archive/blogs/chmitch/connecting-to-blob-storage-with-a-shared-access-signature-in-power-bi</link>
      <pubDate>Thu, 31 May 2018 11:57:38 GMT</pubDate>
      <dc:creator><![CDATA[Chris Mitchell]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/chmitch/?p=165</guid>
      <description><![CDATA[As you're likely aware Power BI supports dozens of data sources out of the box enabling you to mash...]]></description>
      <content:encoded><![CDATA[<span style="font-family: Calibri"><span style="color: #000000">As you're likely aware Power BI supports dozens of data sources out of the box enabling you to mash up data from a variety of sources.  Each one of these sources of data has a unique </span><span>configuration</span><span style="color: #000000"> governed by the capabilities of the source (ie. text files vs. a database).  At times you may also find that the capabilities of the connector can be governed by what features the developers of the connector chose to implement.  I ran into such a scenario recently using the Power BI connector for Blob Storage.  You may have notice</span><span>d</span></span><span style="color: #000000;font-family: Calibri"> that out of the box the connector only supports two authentication methods.
</span>

<img width="705" height="257" class="alignnone size-full wp-image-175" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/05/P01.png" />

<span style="color: #000000;font-family: Calibri"></span>
<ol>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Anonymous - this will only work if you've made your blob container public.  (I find this is invalid for most scenarios).</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Account Key - This is the master account key, which has full permissions to the storage account.</span></span></li>
</ol>
<span style="color: #000000;font-family: Calibri"> </span>

<span style="font-family: Calibri"><span style="color: #000000">If you're familiar with Blob Storage, it has another option for authentication called "Shared Access Signatures".  This mechanism provides for much more granular security as it allows you to define at the container or blob level the type of access (Read/Write/Delete/List), and also when said access will expire.  (For more details see:  </span><a href="https://docs.microsoft.com/en-us/azure/storage/common/storage-dotnet-shared-access-signature-part-1">https://docs.microsoft.com/en-us/azure/storage/common/storage-dotnet-shared-access-signature-part-1</a><span style="color: #000000">)  Because of these added features it's a far more secure model to use SAS tokens as you can prevent users of the data from maliciously or accidentally abusing the data.  Unfortunately the Power BI Connector does not support the SAS token method of authentication. </span><span>(Please upvote this feature request here: <a href="https://ideas.powerbi.com/forums/265200-power-bi-ideas/suggestions/9953427-connect-to-azure-tables-via-shared-access-signatur">https://ideas.powerbi.com/forums/265200-power-bi-ideas/suggestions/9953427-connect-to-azure-tables-via-shared-access-signatur</a> )</span></span>

<span style="color: #000000;font-family: Calibri"> </span>

<span style="color: #000000;font-family: Calibri">Fortunately Power BI can talk to all manner of unanticipated data sources that have an HTTP endpoint via the Web connector.  I find this particularly useful in two scenarios:</span>
<ol>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Using an oData source that provides an authentication mechanism that is not exposed in the oData provider, most commonly oAuth2.</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Using a REST enabled endpoint.</span></span></li>
</ol>
<span style="color: #000000;font-family: Calibri"> </span>

<span style="font-family: Calibri"><span style="color: #000000">Azure Blob Storage happens to have a REST endpoint, so I set out on a mission to query Azure Blob Storage with a SAS token via the REST endpoint using Power BI's Web connector.</span><span>  This was truly a mission, so I want to share this with you to reduce your heartache and encourage you again to upvote this feature in Power BI and share this with your friends.</span></span>

&nbsp;

<span style="color: #000000;font-family: Calibri">In order to create this scenario I have to make some assumptions.  For our purposes here I'm assuming:</span>
<ol>
 	<li><span style="color: #000000"><span style="font-family: Calibri">You have a storage account and container created already.</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">You want to process more than one file in the storage container (processing one file is actually just a dramatically simplified version of this).</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">The storage container has some blobs in it.</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">The blobs in the storage container all have the same format.</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">The format of the files in the container is CSV (it should be pretty obvious where you'd change this logic in the process).</span></span></li>
</ol>
&nbsp;

Since there are several steps, I decided to break it up into three parts to better organize the process.  The three key steps are:
<ol>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Generate the shared access signature.</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Enumerate the files in your storage container in Power BI with the shared access signature.</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Manipulate the M script in Power BI to download the CSV files.</span></span></li>
</ol>
<b><span style="color: #000000;font-family: Calibri">Part 1 - Generate your shared access signature:</span></b>
<ol>
 	<li><span style="font-family: Calibri"><span style="color: #000000">First and foremost, you'll want to download Storage Explorer, it's by far the easiest way to generate a Shared Access Signature.  You can find Storage Explorer here:  </span><a href="https://azure.microsoft.com/en-us/features/storage-explorer/">https://azure.microsoft.com/en-us/features/storage-explorer/</a></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Once you've downloaded storage explorer connect to your storage account using the primary key, and navigate to a container in the storage account.
<img width="1024" height="485" class="alignnone size-large wp-image-185" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/05/P02-1024x485.png" />
</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Right click on the storage container, and click "Get Shared Access Signature…"
<img width="533" height="491" class="alignnone size-full wp-image-215" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/05/P03.png" />
</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Make sure "Read" and "List" are selected.  This will allow the same signature to be used to not only read items but enumerate items in the container.  (Note:  for security purposes I'm making my key very short lived.  In the real world you'll likely want to make the key have a longer lifetime).
<img width="758" height="834" class="alignnone size-full wp-image-225" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/05/P04.png" />
</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Copy and save the query string as we'll use it several times. The query string will look like:
</span></span><span style="color: #000000"><span style="font-family: Calibri">?st=2018-05-30T14%3A50%3A00Z&amp;se=2018-05-31T14%3A50%3A00Z&amp;sp=rl&amp;sv=2017-04-17&amp;sr=c&amp;sig=qb1hBqeASuJJRR1eZmPEQu1MLXTCLqn2G4bTlfDlcp4%3
</span></span><span style="color: #000000"><span style="font-family: Calibri"><img width="759" height="836" class="alignnone size-full wp-image-235" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/05/P05.png" /></span></span></li>
</ol>
&nbsp;

<b><span style="color: #000000;font-family: Calibri">Part 2 - Connect to your storage container in Power BI Desktop.</span></b>
<ol>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Launch Power BI and select "Get Data -&gt; Web"
<img width="319" height="553" class="alignnone size-full wp-image-245" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/05/P06.png" />
</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Switch to the "Advanced" view, and input the base URL in the first box, your copied query string in the second box.</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Click "Add part" and enter "&amp;restype=container&amp;comp=list" in the third box (this is the directive that tells the rest endpoint to return a an enumeration of the blobs in the container.
<img width="1024" height="385" class="alignnone size-large wp-image-255" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/05/P07-1024x385.png" />
</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Click "Ok", you will eventually be presented with a screen that shows a one row table being returned.  This is because the payload that comes back from the REST api is XML.  Click "Load"
<img width="1024" height="150" class="alignnone size-large wp-image-265" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/05/P08-1024x150.png" />
</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">This will load the table, which is not very useful, we'll need to manipulate it.  Click "Edit Queries"
<img width="128" height="201" class="alignnone size-full wp-image-275" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/05/P09.png" />
</span></span></li>
 	<li><span style="font-family: Calibri"><span style="color: #000000">Delete all columns except for "Blobs" as they are </span><span>unnecessary</span></span><span style="color: #000000;font-family: Calibri">.</span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Drill down into the Table twice to get at the underlying file names in the container.
<img width="516" height="674" class="alignnone size-full wp-image-285" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/05/P10.png" /></span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Now we have a list of filenames in the container, but we need to extract the individual files.  To do this we first need to build a complete URL for the file.  Click "Custom Column" from the "Add Column" menu.
<img width="124" height="207" class="alignnone size-full wp-image-295" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/05/P11.png" />
</span></span></li>
 	<li><span style="font-family: Calibri"><span style="color: #000000">Build a formula that uses the URL to the container, the filename, and the querystring to create a complete URL, and name the field "FileURL".  For example:  "</span><a href="https://cgmwasb.blob.core.windows.net/ambulancedemo/">https://cgmwasb.blob.core.windows.net/ambulancedemo/</a></span><span style="color: #000000;font-family: Calibri">" &amp; [Name] &amp; "?st=2018-05-30T14%3A50%3A00Z&amp;se=2018-05-31T14%3A50%3A00Z&amp;sp=rl&amp;sv=2017-04-17&amp;sr=c&amp;sig=qb1hBqeASuJJRR1eZmPEQu1MLXTCLqn2G4bTlfDlcp4%3D"</span></li>
</ol>
&nbsp;

<b><span style="color: #000000;font-family: Calibri">Part 3 - Manipulating the M script to download the blobs.</span></b>
<ol>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Under the Home menu, select the "Advanced Editor" to see the M script.
<img width="426" height="244" class="alignnone size-full wp-image-305" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/05/P12.png" />
</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">First, we need to add a comma to the end of the last line before the "in" keyword so we can add another expression.</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Second, we need to add another step to process the "Web.Contents" of each URL in our table.  To do this we can add a column to the table with the following M script.  The script will look like this:
BinaryURLContents = Table.AddColumn(#"Added Custom", "BinaryFiles", each Web.Contents([FileURL]))</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Finally, we need to change the return object after the "in" statement from the script from #"Added Custom" to BinaryURLContents.</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">The script should look like this:
<img width="1024" height="319" class="alignnone size-large wp-image-315" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/05/P13-1024x319.png" />
</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Now that we've told the M to explode each URL into a binary file, the rest of the steps can be done in the GUI.</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Remove all columns except the "BinaryFIles" column.</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Click the "Drill Down" button to expand the binary files.
<img width="114" height="106" class="alignnone size-full wp-image-325" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/05/P14.png" /></span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">You'll be presented an error, because by default Power BI will try to process the files with the excel parser.  Click "Edit"
<img width="700" height="456" class="alignnone size-full wp-image-335" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/05/P15.png" />
</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">Switch the parser to open the file as a "Csv Document" and click "OK"
<img width="435" height="483" class="alignnone size-full wp-image-345" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/05/P16.png" />
</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">You'll now be presented the "Combine Files" dialogue which lets you adjust the delimiter and codepage if necessary.  Click "OK".</span></span></li>
 	<li><span style="color: #000000"><span style="font-family: Calibri">You're done, you now have a merged set of all files in the container that were authenticated using a shared access signature.
<img width="1024" height="455" class="alignnone size-large wp-image-355" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/05/P17-1024x455.png" /></span></span></li>
</ol>
&nbsp;

Phew...  I know that was a lot of steps.  Hopefully you'll find this useful and it will save you some time.  What's I find particularly nice about this approach is that it's defined entirely in the Power BI model, and will gracefully deal with a changing list of files in the container.  As new files show up in the container you don't need to update the model, a scheduled refresh will just read them as part of this process.]]></content:encoded>
    </item>
    <item>
      <title>Introducing the Azure SQL Data Warehouse DWU Calculator</title>
      <link>https://docs.microsoft.com/archive/blogs/chmitch/introducing-the-azure-sql-data-warehouse-dwu-calculator</link>
      <pubDate>Fri, 16 Dec 2016 17:01:39 GMT</pubDate>
      <dc:creator><![CDATA[Chris Mitchell]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/chmitch/?p=156</guid>
      <description><![CDATA[Over a year ago my colleague at Microsoft, Justin Henricksen, introduce the Azure SQL Database DTU...]]></description>
      <content:encoded><![CDATA[Over a year ago my colleague at Microsoft, Justin Henricksen, introduce the <a href="https://justinhenriksen.wordpress.com/2015/05/15/introducing-the-azure-sql-database-dtu-calculator/">Azure SQL Database DTU Calculator</a> this tool is designed to examine your existing workload and estimate the service tier required to fulfill the workload when migrated to Azure SQL Database.  I discussed this effort with Justin, and we decided it would be a great idea to follow the same pattern with Azure SQL Data Warehouse.  Like the DTU Calculator the this new <a href="https://dwucalculator.azurewebsites.net/">DWU Calculator </a> is designed to be easy to use and give you a good idea where to start when provisioning your Data Warehouse.  Unlike the DTU Calculator it uses different metrics for its calculations to align better to usage patterns of data warehouses and the nuances of the Azure SQL Data Warehouse service.

While I will get into more details on this utility, the premise of it is really quite simple.
<ol>
 	<li>Run a utility via powershell or a simple executable to capture metrics from the server while under load.</li>
 	<li>Upload the captured csv file to the calculator.</li>
 	<li>Examine the recommended performance level(s) and determine your starting point.
**Note:  This step is important because typically not all of the captured workload will fit in a single performance tier.  The calculator will tell you what percentage of the observed workload fits in each tier and make a balanced recommendation.</li>
</ol>
I soft launched this utility (meaning I published it without telling anyone) back in July and haven't had any major issues.  Over the next few weeks I'll be cleaning up some documentation in advance of a more formal introduction.]]></content:encoded>
    </item>
    <item>
      <title>Sending events to IOT Hub over HTTP via REST</title>
      <link>https://docs.microsoft.com/archive/blogs/chmitch/sending-events-to-iot-hub-over-http-via-rest</link>
      <pubDate>Wed, 16 Nov 2016 14:09:15 GMT</pubDate>
      <dc:creator><![CDATA[Chris Mitchell]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/chmitch/?p=135</guid>
      <description><![CDATA[As you may know Azure IOT Hub is a scalable transport for communicating with Internet of Things...]]></description>
      <content:encoded><![CDATA[As you may know Azure IOT Hub is a scalable transport for communicating with Internet of Things devices. While conceptually what it does is quite similar to Event Hubs it actually supports several more scenarios including bi-directional communication and device specific authentication. Furthermore it supports standard IOT protocols including AMQP and MQTT out of the box. In addition to these protocols it supports an HTTPs based REST interface for communication. When I work with IOT Hub, I almost always find myself using the out of the box SDK, and therefore shielding my code from the underlying transport used.

In a recent project I found myself in a situation where I didn't have the ability to leverage the Azure SDK on the remote device, and therefore had to come up with a different way of communicating with the IOT Hub. I originally considered implementing an extra gateway at the remote site to communicate with the devices and forward messages to the IOT Hub, but this seemed like overkill because the device would literally only be grabbing the message and forwarding it on. No transformation, no aggregation, no filtering, nothing, like I said, overkill. The device in question is capable of communicating over HTTPs, so we opted to use the REST interface for communicating with the IOT Hub, and bypass the need for a gateway altogether.

While the following code is pretty simple in what it does, as doing a post to a rest endpoint should be, the key element of the solution is the device authentication. Since all devices are authenticated you have to get this right or you'll get HTTP exceptions on every call. The key takeaways that I got from security are:
<ol>
 	<li>Use SAS tokens - While each device in the device registry has a primary and secondary key, these keys cannot be used for authentication on the rest endpoint. Only a SAS token can be used.</li>
 	<li>The SAS token must be URL encoded - There are some special characters in the SAS token ("/" and "=" are the ones I noticed). To make sure these are handled appropriately they must be replaced with the URL encoded values.</li>
 	<li>The SAS tokens must have a time to live - At first I was trying to be clever and use 0 for my TTL, thinking this would be an open ended SAS token.</li>
 	<li>The SAS token must be included in a specific HTTP header. - I couldn't find this documented anywhere, and in fact had to use fiddler to examine the packets and see what the header looked like.</li>
</ol>
Here's the pieces to make all this work:
<ol>
 	<li>First we need to define the rest endpoint. The device communication endpoint for sending messages to the IOT Hub is at /devices/{deviceid}/messages/events. To address this in my code I used the following:
<blockquote>string iotHub = "[iothub]";
string deviceId = "[deviceid]";
string api = "2016-02-03";

//Build rest endpoint for the device.
string restUri = String.Format("https://{0}.azure-devices.net/devices/{1}/messages/events?api-version={2}", iotHub, deviceId, api);</blockquote>
</li>
 	<li>Next we need to generate a SAS token for the IOT device. This can be done programmatically, or using the handy Device Explorer tool included in the SDK to create a device and generate a token.   (<a href="https://github.com/Azure/azure-iot-sdks/tree/master/tools/DeviceExplorer">https://github.com/Azure/azure-iot-sdks/tree/master/tools/DeviceExplorer</a>). There are two things to keep in mind with this tool:
You must enter a valid TTL (&gt; 0):
<img width="410" height="349" class="alignnone wp-image-145" alt="p1" src="https://msdnshared.blob.core.windows.net/media/2016/11/p11-1024x873.png" />The output contains more than just the SAS token, select the portion of the SAS token after "SharedAccessSignature=", this is the URL encoded SAS token:
<img width="580" height="145" class="alignnone wp-image-155" alt="p2" src="https://msdnshared.blob.core.windows.net/media/2016/11/p21-1024x256.png" /></li>
 	<li>In order to package the header appropriately and send the message I used the following code. Here we add the generated sas token and add it to the "Authorization" header.   <i>Note the "body" is just any class that is JSON serializable.</i>
<blockquote>string sas = "SharedAccessSignature sr=cgmIOTTelemetry.azure-devices.net%2Fdevices%2FmyFirstDevice&amp;sig=hFvm0tDU4ytu85efPpE3T7VYhFUNII4NigdonRJjKoA%3D&amp;se=1479398100";

HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", sas);

var content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json");
var result = client.PostAsync(restUri, content).Result;</blockquote>
</li>
</ol>
Once all this is complete, you have a very basic authenticated call to the IOT Hub's REST endpoint. What's nice about this is unlike event hub, each device is authenticated. Therefore, if you have a problem with a specific endpoint you can disable it and/or regenrate it's keys and tokens without taking all your other devices offline. I wrote this code in C# because I'm most efficient in that language, but I hope you see that all we're doing is adding a specific authorization header and sending a json payload to a URL via an HTTP Post. Any language that can do an HTTP post, and add a string to the header can do this same logic.

As usual I've included this code in my github at: <a href="https://github.com/chmitch/azure-iot-send-via-rest">https://github.com/chmitch/azure-iot-send-via-rest</a>]]></content:encoded>
    </item>
    <item>
      <title>Long Term Backup with Azure SQL Database</title>
      <link>https://docs.microsoft.com/archive/blogs/chmitch/long-term-backup-with-azure-sql-database</link>
      <pubDate>Tue, 08 Nov 2016 14:14:28 GMT</pubDate>
      <dc:creator><![CDATA[Chris Mitchell]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/chmitch/?p=65</guid>
      <description><![CDATA[In a previous blog "Extended Backup Retention With Azure SQL Database", I outlined a method for...]]></description>
      <content:encoded><![CDATA[In a previous blog "<a href="https://blogs.msdn.microsoft.com/chmitch/2016/09/23/extended-backup-retention-with-azure-sql-database/">Extended Backup Retention With Azure SQL Database</a>", I outlined a method for extending the boundaries of the Azure SQL Database service. To refresh your memory the defaults here are 7 days for the Basic tier and 35 days for the Standard and Premium tier of Azure SQL Databases. While the method I outlined in this earlier blog post had some limits and required some automation via PowerShell, it was really the only method we had to overcome this obstacle. I'm pleased to report that the SQL Azure team heard the demand for configurable backup loud and clear, and has provided a feature to extend these limits to 10 years!

For the official announcement you can take a look at the Azure Blog, but for the sake of completeness I thought I would give a step by step guide to elaborate on a few more details that aren't spelled out in the <a href="https://azure.microsoft.com/en-us/blog/azure-sql-database-now-supporting-up-to-10-years-of-backup-retention-public-preview/">official posting</a>.
<ol>
 	<li>While we logically think about database policy at a "database" level, you actually control this feature at a "server" level. So avoid your instinct to navigate to the SQL Azure Database and go to the server instead. You'll find the tab to enable this capability under "Settings".
<img width="300" height="256" class="alignnone size-medium wp-image-75" alt="ltb_1" src="https://msdnshared.blob.core.windows.net/media/2016/11/ltb_1-300x256.png" /></li>
 	<li>Since this feature is in preview, you must accept the preview terms before it can be used.
<img width="1024" height="122" class="alignnone size-large wp-image-105" alt="ltb_4" src="https://msdnshared.blob.core.windows.net/media/2016/11/ltb_4-1024x122.png" /></li>
 	<li>As we earlier mentioned this policy applies at the server level; therefore, the next step is to select all the databases on the server you want it to apply to.
<img width="300" height="176" class="alignnone size-medium wp-image-95" alt="ltb_3" src="https://msdnshared.blob.core.windows.net/media/2016/11/ltb_3-300x176.png" /></li>
 	<li>Select the Recovery Vault you'd like to use.
<img width="300" height="36" class="alignnone size-medium wp-image-105" alt="ltb_4" src="https://msdnshared.blob.core.windows.net/media/2016/11/ltb_4-300x36.png" /></li>
 	<li>Finally define your retention policy and you're ready to go.
<img width="300" height="194" class="alignnone size-medium wp-image-115" alt="ltb_5" src="https://msdnshared.blob.core.windows.net/media/2016/11/ltb_5-300x194.png" /></li>
</ol>
A couple things to call out that were a bit of a surprise to me:
<ol>
 	<li>Presently this long term retention imposes the restrictions that the vault must be in the same subscription, region, and resource group. If you don't have this you'll see a warning as follows:
<img width="1024" height="234" class="alignnone size-large wp-image-125" alt="ltb_6" src="https://msdnshared.blob.core.windows.net/media/2016/11/ltb_6-1024x234.png" /></li>
 	<li>While this give you a far longer duration of retention than previously available, there is not an ability to do any fine grained policies (ie. keep daily backups for 1 year, and weekly backups for 3 years, etc.)</li>
</ol>]]></content:encoded>
    </item>
    <item>
      <title>Automating database migration to SQL Azure</title>
      <link>https://docs.microsoft.com/archive/blogs/chmitch/automating-database-migration-to-sql-azure</link>
      <pubDate>Mon, 03 Oct 2016 12:16:13 GMT</pubDate>
      <dc:creator><![CDATA[Chris Mitchell]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/chmitch/?p=35</guid>
      <description><![CDATA[Migrating databases to a new environment can be a tedious but necessary task.  For years DBAs have...]]></description>
      <content:encoded><![CDATA[<span style="color: #000000;font-family: Calibri">Migrating databases to a new environment can be a tedious but necessary task.</span><span><span style="color: #000000;font-family: Calibri">  </span></span><span style="color: #000000;font-family: Calibri">For years DBAs have been dealing with the process of rolling out SQL Server upgrades, and have achieved this in On Premises environments in a variety of ways including:</span>

<span><span><span style="color: #000000;font-family: Calibri">1.</span><span style="font: 7pt 'Times New Roman';margin: 0px"><span style="color: #000000">       </span></span></span></span><span style="color: #000000;font-family: Calibri">Backup and Restore database</span>

<span><span><span style="color: #000000;font-family: Calibri">2.</span><span style="font: 7pt 'Times New Roman';margin: 0px"><span style="color: #000000">       </span></span></span></span><span style="color: #000000;font-family: Calibri">Attach / Detach database</span>

<span><span><span style="color: #000000;font-family: Calibri">3.</span><span style="font: 7pt 'Times New Roman';margin: 0px"><span style="color: #000000">       </span></span></span></span><span style="color: #000000;font-family: Calibri">SAN magic (typically snapshotting LUNs or moving LUNs from one host to another)</span>

<span><span><span style="color: #000000;font-family: Calibri">4.</span><span style="font: 7pt 'Times New Roman';margin: 0px"><span style="color: #000000">       </span></span></span></span><span style="color: #000000;font-family: Calibri">In Place upgrades (Note:</span><span><span style="color: #000000;font-family: Calibri">  </span></span><span style="color: #000000;font-family: Calibri">just because you can, doesn’t mean you should)</span>

<span style="color: #000000;font-family: Calibri">Over the years a variety of tools have been created to support the tedium of these migrations including Scalability Expert’s </span><a href="https://www.scalabilityexperts.com/tools/downloads.html"><span style="color: #0563c1;font-family: Calibri">SQL Server Upgrade Assistant</span></a><span style="color: #000000;font-family: Calibri"> which aids in detecting compatibility issues with your database upgrade.</span><span><span style="color: #000000;font-family: Calibri">  </span></span>

<span style="color: #000000;font-family: Calibri">My intent in writing this blog post is to focus on brute force automation of the migration process.</span><span><span style="color: #000000;font-family: Calibri">  </span></span><span style="color: #000000;font-family: Calibri">The topics of “what tools are available to assess the compatibility of my database” and “what features in SQL Server are not supported Azure SQL” are rather well documented.</span><span><span style="color: #000000;font-family: Calibri">  </span></span><span style="color: #000000;font-family: Calibri">For the sake of completeness here are two resources to help you out in that regard:</span>

<span><span><span style="color: #000000">·</span><span style="font: 7pt 'Times New Roman';margin: 0px"><span style="color: #000000">        </span></span></span></span><span style="color: #000000;font-family: Calibri">Carl Rabeler, formerly of the SQL Customer Advisory Team, has a great article (</span><a href="https://azure.microsoft.com/en-us/documentation/articles/sql-database-cloud-migrate/"><span style="color: #0563c1;font-family: Calibri">SQL Server database migration to SQL Database in the cloud</span></a><span style="color: #000000;font-family: Calibri">) that gives a detailed audit of all the tools available for taking a database from an on Premises Database to the cloud and goes into their pros and cons of each tool.</span>

<span><span><span style="color: #000000">·</span><span style="font: 7pt 'Times New Roman';margin: 0px"><span style="color: #000000">        </span></span></span></span><span style="color: #000000;font-family: Calibri">There is also an article by Rick Byham (</span><a href="https://azure.microsoft.com/en-us/documentation/articles/sql-database-transact-sql-information/"><span style="color: #0563c1;font-family: Calibri">Azure SQL Database Transact-SQL differences</span></a><span style="color: #000000;font-family: Calibri">) that gives a good overview of specific transact SQL features that are not supported in the cloud.</span>

<span style="color: #000000;font-family: Calibri">With that backdrop let’s assume you have gone through the process of assessing your databases and determined the databases are ready for the cloud.</span><span><span style="color: #000000;font-family: Calibri">  </span></span><span style="color: #000000;font-family: Calibri">Now you are ready to execute the migration, but are looking at the volume of work and decided “right click -&gt; migrate database to sql azure” is too labor intensive, what’s next?</span><span><span style="color: #000000;font-family: Calibri">  </span></span><span style="color: #000000;font-family: Calibri">The answer… automation, to do this let’s take a brief look at what the migrate wizard does.</span>

<span style="color: #000000;font-family: Calibri"><img width="300" height="200" class="alignnone size-medium wp-image-45" alt="pic1" src="https://msdnshared.blob.core.windows.net/media/2016/10/pic1-300x200.png" /></span>

<span style="color: #000000;font-family: Calibri">Notice, this is a one step process according to the wizard, and unfortunately it doesn’t give you an opportunity to script things out either.</span><span><span style="color: #000000;font-family: Calibri">  </span></span><span style="color: #000000;font-family: Calibri">To run, it effectively asks for just a few pieces of information:</span>

<span><span><span style="color: #000000;font-family: Calibri">1.</span><span style="font: 7pt 'Times New Roman';margin: 0px"><span style="color: #000000">       </span></span></span></span><span style="color: #000000;font-family: Calibri">Source Database which is defined by which database you right click on.</span>

<span><span><span style="color: #000000;font-family: Calibri">2.</span><span style="font: 7pt 'Times New Roman';margin: 0px"><span style="color: #000000">       </span></span></span></span><span style="color: #000000;font-family: Calibri">Destination Details:</span>

<span><span><span style="color: #000000;font-family: Calibri">a.</span><span style="font: 7pt 'Times New Roman';margin: 0px"><span style="color: #000000">       </span></span></span></span><span style="color: #000000;font-family: Calibri">What Azure SQL Server do you want this database on?</span>

<span><span><span style="color: #000000;font-family: Calibri">b.</span><span style="font: 7pt 'Times New Roman';margin: 0px"><span style="color: #000000">       </span></span></span></span><span style="color: #000000;font-family: Calibri">What should the database be called?</span>

<span><span><span style="color: #000000;font-family: Calibri">c.</span><span style="font: 7pt 'Times New Roman';margin: 0px"><span style="color: #000000">       </span></span></span></span><span style="color: #000000;font-family: Calibri">What size is the database?</span>

<span><span><span style="color: #000000;font-family: Calibri">3.</span><span style="font: 7pt 'Times New Roman';margin: 0px"><span style="color: #000000">       </span></span></span></span><span style="color: #000000;font-family: Calibri">Where do I store the intermediate bacpac file? </span>

<span style="color: #000000;font-family: Calibri">To script the same capabilities, we need to use the following:</span>

<span><span><span style="color: #000000">·</span><span style="font: 7pt 'Times New Roman';margin: 0px"><span style="color: #000000">        </span></span></span></span><span style="color: #000000;font-family: Calibri">The </span><a href="https://msdn.microsoft.com/en-us/library/hh550080(v=vs.103).aspx"><span style="color: #0563c1;font-family: Calibri">SqlPackage</span></a><span style="color: #000000;font-family: Calibri"> utility, which is a command line tool that can be used to generate bacpac and dacpac files from your database among other things.</span>

<span><span><span style="color: #000000">·</span><span style="font: 7pt 'Times New Roman';margin: 0px"><span style="color: #000000">        </span></span></span></span><span style="color: #000000;font-family: Calibri">The </span><a href="https://msdn.microsoft.com/en-us/library/mt707793.aspx"><span style="color: #0563c1;font-family: Calibri">New-AzureRMSqlDabaseImport</span></a><span style="color: #000000;font-family: Calibri"> command to restore the generated bacpac file as an Azure SQL Database.</span>

<span style="color: #000000;font-family: Calibri">The following commands are snippets that conceptually handle each part of the process.</span>

<span style="color: #000000;font-family: Calibri">Part 1, execute SqlPackage to save the file locally:</span>
<div><code>
#setup the local variables.
$server = "localhost"
$database = "Database1"
$path = "c:\projects\" + $database + ".bacpac"
&nbsp;
#Define the path to the sqlpackage.exe and the command line parameters
$cmd = "C:\Program Files (x86)\Microsoft SQL Server\130\DAC\bin\sqlpackage.exe"
$params = "/Action:Export /ssn:" + $server + " /sdn:" + $database + " /tf:" + $path
$p = $params.Split(" ")
#shell out the export command for the bacpac
&amp; "$cmd" $p
</code>
</div>
<span style="color: #000000;font-family: Calibri">Part 2, upload the generated file to Azure blob storage:</span>
<div><code>
#set variables
$fileName = "Database1.bacpac"
$storageName = "[storage account]"
$storageKeyType = "StorageAccessKey"
$storageContainer = "backups"
$storageUri = "https://$StorageName.blob.core.windows.net/$storageContainer/$filename"
$localpath = "c:\Projects\$filename"
$StorageKey = "[storage key]"
&nbsp;
#Set storage context and upload blob file
$context = New-AzureStorageContext -StorageAccountName $storageName -StorageAccountKey $storageKey
Set-AzureStorageBlobContent -File $localpath -Container "backup" -Context $context
</code></div>
<span style="color: #000000;font-family: Calibri">Part 3, restore the uploaded bacpac file as a new database:</span>
<div><code>
$importRequest = New-AzureRmSqlDatabaseImport   –ResourceGroupName $ResourceGroupName `
–ServerName $ServerName `
–DatabaseName $DatabaseName `
–StorageKeytype $StorageKeyType `
–StorageKey $StorageKey `
-StorageUri $StorageUri `
–AdministratorLogin $credential.UserName `
–AdministratorLoginPassword $credential.Password `
–Edition Premium `
–ServiceObjectiveName p1 `
-DatabaseMaxSizeBytes 50000
</code></div>
<span style="color: #000000;font-family: Calibri">I pull all of these things together in a more sophisticated script that accounts for scenarios like choosing the service level of the database based on its size, and uses SQL Power Shell to enumerate the local databases.</span><span><span style="color: #000000;font-family: Calibri">  </span></span><span style="color: #000000;font-family: Calibri">Finally the script uploads the content and restores the database in SQL Azure.</span><span><span style="color: #000000;font-family: Calibri">  </span></span><span style="color: #000000;font-family: Calibri">You can find the complete script on my git hub </span><a href="https://github.com/chmitch/azure-sql-automated-migration"><span style="color: #0563c1;font-family: Calibri">page</span></a><span style="color: #000000;font-family: Calibri"> .</span>]]></content:encoded>
    </item>
    <item>
      <title>Extended “Backup” Retention with Azure SQL Database</title>
      <link>https://docs.microsoft.com/archive/blogs/chmitch/extended-backup-retention-with-azure-sql-database</link>
      <pubDate>Fri, 23 Sep 2016 09:39:26 GMT</pubDate>
      <dc:creator><![CDATA[Chris Mitchell]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/chmitch/?p=25</guid>
      <description><![CDATA[As you may or may not know, Azure SQL Database is a great tiered offering that comes with backup...]]></description>
      <content:encoded><![CDATA[As you may or may not know, Azure SQL Database is a great tiered offering that comes with backup retention capabilities out of the box.  What is awesome about this offering is it makes backing up your database braindead simple, and saves you the administrative effort of creating a maintenance plan to do this.  It also saves you the hassle of planning out the nuances of full backups, delta backups, and log backups necessary in order to achieve your recovery goals.  Finally it saves you the headache of remembering to delete aged backup files.  After all, nobody wants to find out a backup failed because you ran out of disk space.

As I mentioned before, this is a tiered offering and the out of the box backup capabilities are no exception to this.  How much backup retention you get depends entirely on what tier of our database offering you choose.  At the time of this post the retention is as follows:
<ul>
 	<li>Premium (P1 – P15) and Standard (S0 – S3) Databases – 35 days of Point in Time Restore</li>
 	<li>Basic Database (B) – 7 days of Point in Time Restore</li>
</ul>
A question I’m often asked is whether this feature is configurable on a per database basis.  Most customers I speak with would gladly pay the extra storage costs to make this a tuneable feature on the database, and add the option of sacrificing the Point in Time nature of the restore as the backups age out.  Another question I’m asked is how to best take a preemptive backup before a deployment so there is a known good state to recover to in the event of a deployment failure.   The built in backup can aid in the deployment scenario just fine, but the challenge is often understanding what “point in time” to recover to.  Those responsible for a deployment rest easier knowing there is a snapshot of the database when all else fails.

While these features (tuneable retention &amp; on demand backup) aren’t addressed as part of the built in backup capabilities of Azure SQL Database there is a way we can use other features of the database in order to achieve this namely SQL Database Copy and SQL Database Export.  While not technically “backup” these features can be used to get you a consistent copy of your database for disaster purposes, hence the quotes.  <em>(NOTE: When I put the quotes there I have a mental image of Mike Myers aka Dr. Evil doing air quotes.)</em>

Let’s explore these two features a bit…

<a href="https://azure.microsoft.com/en-us/documentation/articles/sql-database-copy/">SQL Database Copy</a> – is designed to make a transactionally consistent copy of your database leveraging the built in backup retention policy.  It first makes a copy of the tail of the transaction log, and then uses this tail plus the full, differential, and log backups retained behind the scenes in Azure SQL Database.  All this is done without interrupting the log chain of the current database retention plan (a common problem with preemptive full backups in on premises databases).

<a href="https://azure.microsoft.com/en-us/documentation/articles/sql-database-export-powershell/">SQL Database Export</a> – is designed to export a copy of your database to a .bacpac file which is an encapsulated version of the databases schema and data.  While not truly a backup file like a .bak file in a traditional SQL database, it does contain everything you need to reconstitute your database in the event of an emergency.

Based on these two descriptions, you might ask yourself “why do I need both?”.  This is the point where the fine print is important.  There are two reasons I think it’s essential to use both of these features in concert:
<ol>
 	<li>SQL Database Export is not transactionally consistent. Therefore, it is strongly recommended that you have a database that is not being actively used while you take the copy.  Hence I would recommend starting with database copy, then export, and ultimately drop the copied database.</li>
 	<li>SQL Database Copy creates a copy of your database. Therefore, if you have a 50 GB P1 database after the operation you’ll have two 50GB P1 databases, and consequently double the cost of hosting the database.  Each time you run this operation you’re increasing your cost, and each database gets its own retention schedule which is unnecessary.  Using the bacpac approach you keep the database copy around for a small amount of time and keep your costs low.  You also get a choice whether you want this retention in Azure Storage which is much cheaper than Azure SQL to use or to take the bacpac out of Azure and into your own data center.</li>
</ol>
Now that we have a good background on why I’m recommending this approach, here are a few powershell script segments to get you started.  I logically break this down into three discrete steps:
<ol>
 	<li>Initialize variables.
<div><code># Define the source datbase, server, and resoruce group
$sourceDatabase = "[source database]"
$sourceServer = "[source server]"
$sourceResourceGroup = "[source resource group]
</code></div>
<div><code># Define output location for bacpac
$storageAccount = "[blob account].blob.core.windows.net"
$storageContainer = "[blob container]"
$storageKeyType = "StorageAccessKey"
$storageKey = "[storage key]"
</code></div>
<div><code># Admin credentials for the database
$adminUser = "[admin user name]"
$adminPassword = "[admin password]"
</code></div>
<div><code><code># Generating a unique name for the databse copy and the uri for the bacpac.
$destinationDatabase = $sourceDatabase + (Get-Date).ToString("yyyyMMddHHmm")
$bacpacUri = "https://" + $storageAccount + "/" + $storageContainer + "/" + $destinationDatabase + ".bacpac"</code></code></div></li>
 	<li>Create the database copy.<code>
# Execute the copy command
New-AzureRmSqlDatabaseCopy -ResourceGroupName $sourceResourceGroup `
-ServerName $sourceServer `
-DatabaseName $sourceDatabase `
-CopyDatabaseName $destinationDatabase
</code></li>
 	<li>Export the bacpac to the storage account.<code>
# Note:  Exporting to a bacpac requires you to have an account and password for an admin.
#        If you do not include this the command will ask for it at execution time.
$exportRequest = New-AzureRmSqlDatabaseExport   –ResourceGroupName $sourceResourceGroup `
–ServerName $sourceServer `
–DatabaseName $destinationDatabase `
–StorageKey $storageKey `
-StorageUri $BacpacUri `
–StorageKeytype $storageKeyType `
–AdministratorLogin $adminUser `
–AdministratorLoginPassword $adminPassword
</code></li>
 	<li>Cleanup the database copy.<code>
#Now that the export is done, delete the databse.
Remove-AzureRmSqlDatabase  -ResourceGroupName $sourceResourceGroup `
-ServerName $sourceServer `
-DatabaseName $destinationDatabase</code></li>
</ol>
<span style="color: #000000;font-family: Calibri">This is the gist of it.</span><span><span style="color: #000000;font-family: Calibri">  </span></span><span style="color: #000000;font-family: Calibri">In order to save yourself some headaches with copy and paste, and for a complete version of the powershell script checkout my github repository @ For a complete script you can check out my <a href="https://github.com/chmitch/azure-sql-extended-archive">github repository </a></span>]]></content:encoded>
    </item>
  </channel>
</rss>