<?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>JJ’s Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/juliajauss/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/juliajauss/feed.xml</link>
    <description>Julia Jauß about the cloud</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:13:02 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>A self-contained Azure Media Service (AMS) end-to-end szenario with dynamic AES128 encryption</title>
      <link>https://docs.microsoft.com/archive/blogs/juliajauss/a-self-contained-azure-media-service-ams-end-to-end-szenario-with-dynamic-aes128-encryption</link>
      <pubDate>Thu, 22 Dec 2016 10:25:05 GMT</pubDate>
      <dc:creator><![CDATA[juliajauss]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/juliajauss/?p=136</guid>
      <description><![CDATA[Microsoft Azure Media Services enables you to deliver Http-Live-Streaming (HLS) and Smooth Streams...]]></description>
      <content:encoded><![CDATA[<span>Microsoft Azure Media Services enables you to deliver Http-Live-Streaming (HLS) and Smooth Streams encrypted with AES128 (Advanced Encryption Standard using 128-bit encryption keys). </span>To easily demonstrate a simple szenario for using AES123 encryption, I developed a self-contained solution that you can find in <a href="https://github.com/juliajauss/AMSAes128EndToEnd">my GitHub repository</a>. The use case is an intranet video portal to show training videos to employees. Depending on their role in a directory service (e.g. Active Directory) they can see different content. This demo can be started easily, without the need of setting up a directory service. Here you can see an overview of the architecture:

<a href="https://msdnshared.blob.core.windows.net/media/2016/12/general_overview.png"><img src="https://msdnshared.blob.core.windows.net/media/2016/12/general_overview-1024x568.png" alt="general_overview" width="1024" height="568" class="size-large wp-image-176 aligncenter" /></a>

&nbsp;

<strong>I want to give a short description of what happens:</strong>
<ol>
 	<li>An employee logs in to the CMS using corp credentials.</li>
 	<li>The CMS will redirect the user to the ADFS (in this demo: a mockup using IdentityServer) for authentication.</li>
 	<li>If the validation of the client credentials is successful, ADFS returns a bearer token and redirects the user back to the CMS.</li>
 	<li>The user is now signed in to the intranet application. In this demo, this is a simple website showing the videos dedicated to this user. At this point, the video is encrypted.</li>
 	<li>CMS requests a JWT Token from the Identity Provider (in this demo: a class in my CMS project (JWT Helper)). The Identity Provider checks the rights of the user and queries the database (in this demo: database mockup using a simple JSON file) for available videos for this user. A JWT Token is generated using the primary verification key of the video.</li>
 	<li>JWT Token is returned.</li>
 	<li>The video player shows the JWT token to Azure Media Key Services and gets the decryption key for the videos, if valid.</li>
 	<li>The video fragments are decrypted dynamically in the browser.</li>
</ol>
A more detailed description of the components of the solution can be found in the GitHub Readme. In the following article, I will focus on how to do the encryption of the assets.

&nbsp;

<strong>So, what do I have to do to encrypt my assets? </strong>

To encrypt an asset, you need to associate an content key with the asset, configure a authorization policy for the key and define a delivery policy for the asset:
<ol>
 	<li><u>Content key</u>
Is used to dynamically encrypt your content using AES encryption when a stream is requested.</li>
 	<li><u>Authorization Policy</u>
Or: how do you get the encryption key (from a service specified in the Delivery Policy), via a <em>token</em> or <em>PlayReady</em>?
If token: TokenRestrictionTemplate
- Authorization via  JWT or SWT (JSON Web Token or Simple Web Token)?
- Who is the issuer of the token?
- Who has access (audience)?</li>
 	<li><u>Delivery Policy</u>
The Delivery Policy for an asset specifies how this asset will be delivered:
- Key Acquisition URL (where can I get the encryption key for this asset? (AMS Key Services || PlayReady || Widevine)
- Into which streaming protocol should your asset be packaged? (HLS, DASH, Smooth Streaming)
- Should the asset be dynamically encrypted? And how? (envelope || common encryption)</li>
</ol>
&nbsp;

In my demo, the AuthorizationPolicy is set to a token-based authorization. To get the encryption key, the player will request it from the <em>Azure Media Services Key Delivery Service</em> using a JWT Token:

<a href="https://msdnshared.blob.core.windows.net/media/2016/12/flow.png"><img src="https://msdnshared.blob.core.windows.net/media/2016/12/flow-1024x279.png" alt="flow" width="1024" height="279" class="size-large wp-image-205 aligncenter" /></a>

&nbsp;

<strong>Got it! And how does it look like in code? </strong>

[code language="csharp"]
private static async void SetupAESEncryptionAsync(CloudMediaContext context, IAsset encodedAsset,  string audience, Settings settings)
{
   //1.Create a content key and associate it with the encoded asset
   IContentKey key = CreateEnvelopeTypeContentKey(encodedAsset, context);

   //2.Configure the content keys authorization policy 
   string tokenTemplateString = await AddTokenRestrictedAuthorizationPolicy(context: context, contentKey: key, audience: audience, contentKeyIdentifierClaim: true,  issuer: settings.Issuer, primaryVerificationKey: settings.primaryVerificationKey);

   //3.Create Asset Delivery Policy (Dynamic or non-dynamic encryption)
   CreateAssetDeliveryPolicy(encodedAsset, key, context);
}
[/code]

Let's step through this!

&nbsp;

<strong>1.Create a content key and associate it with the encoded asset</strong>
You have to use <em>ContentKeyType.EnvelopeEncryption</em> in order to use AES-128 encryption.

[code highlight="13" language="csharp"]
 static public IContentKey CreateEnvelopeTypeContentKey(IAsset asset, CloudMediaContext context)
 {
    //Check if there is already a content key associated with the asset
    IContentKey contentKey = asset.ContentKeys.FirstOrDefault(k =&gt; k.ContentKeyType == ContentKeyType.EnvelopeEncryption);

    // Create envelope encryption content key, Associate the key with the asset
    if (contentKey == null)
    {
       contentKey = context.ContentKeys.Create(
       keyId: Guid.NewGuid(),
       contentKey: GetKeyBytes(16),
       name: &quot;ContentKey&quot;,
       contentKeyType: ContentKeyType.EnvelopeEncryption);

       asset.ContentKeys.Add(contentKey);
    }

    return contentKey;
 }
[/code]

<strong>2.Configure the Authorization Policy for the content key</strong>

ContentKeyDeliveryType.BaselineHttp specifies to use the AES key server from AMS.

[code highlight="6,7,23" language="csharp"]
 public static async Task&lt;string&gt; AddTokenRestrictedAuthorizationPolicy(CloudMediaContext context, IContentKey contentKey, string issuer, string audience, bool contentKeyIdentifierClaim, byte[] primaryVerificationKey)
 {
    string tokenTemplateString = GenerateTokenRequirements(
       issuer: issuer, 
       audience: audience, 
       contentKeyIdentifierClaim: contentKeyIdentifierClaim,
       primaryVerificationKey: primaryVerificationKey);

    IContentKeyAuthorizationPolicy policy = await context.ContentKeyAuthorizationPolicies.CreateAsync(name: &quot;Token restricted authorization policy&quot;);
    List&lt;ContentKeyAuthorizationPolicyRestriction&gt; restrictionList = new List&lt;ContentKeyAuthorizationPolicyRestriction&gt;
    {
       new ContentKeyAuthorizationPolicyRestriction
       {
          Name = &quot;Token Authorization Policy&quot;,
          KeyRestrictionType = (int)ContentKeyRestrictionType.TokenRestricted,
          Requirements = tokenTemplateString
       }
    };

    //You could have multiple options; BaselineHttp specifies that we use the AES key server from AMS 
    IContentKeyAuthorizationPolicyOption policyOption = context.ContentKeyAuthorizationPolicyOptions.CreateAsync(
       name: &quot;Token Authorization policy option&quot;, 
       deliveryType: ContentKeyDeliveryType.BaselineHttp, 
       restrictions: restrictionList,
       keyDeliveryConfiguration: null).Result; // no key delivery data is needed for HLS 

    policy.Options.Add(policyOption);

    // Add ContentKeyAutorizationPolicy to ContentKey
    contentKey.AuthorizationPolicyId = policy.Id;
    IContentKey updatedKey = await contentKey.UpdateAsync();

    return tokenTemplateString;
 }
[/code]

<strong>3.Create Asset Delivery Policy (Dynamic or non-dynamic encryption)</strong>

[code highlight="3,14,15" language="csharp"]
static public async void CreateAssetDeliveryPolicy(IAsset asset, IContentKey key, CloudMediaContext context)
{
   Uri keyAcquisitionUri = await key.GetKeyDeliveryUrlAsync(ContentKeyDeliveryType.BaselineHttp);

   const string assetDeliveryPolicyName = &quot;AssetDeliveryPolicy for HLS, SmoothStreaming and MPEG-DASH&quot;;
   IAssetDeliveryPolicy assetDeliveryPolicy = context.AssetDeliveryPolicies
      .Where(p =&gt; p.Name == assetDeliveryPolicyName)
      .ToList().FirstOrDefault();

    if (assetDeliveryPolicy == null)
    {
       assetDeliveryPolicy = await context.AssetDeliveryPolicies.CreateAsync(
          name: assetDeliveryPolicyName,
          policyType: AssetDeliveryPolicyType.DynamicEnvelopeEncryption,
          deliveryProtocol: AssetDeliveryProtocol.SmoothStreaming | AssetDeliveryProtocol.HLS | AssetDeliveryProtocol.Dash,
          configuration: new Dictionary&lt;AssetDeliveryPolicyConfigurationKey, string&gt; {{ 
               AssetDeliveryPolicyConfigurationKey.EnvelopeBaseKeyAcquisitionUrl, 
               keyAcquisitionUri.AbsoluteUri }});

        // Add AssetDelivery Policy to the asset
        asset.DeliveryPolicies.Add(assetDeliveryPolicy);
    }
}
[/code]

In the <strong>TokenRestrictionTemplate</strong> you define three things:
<ol>
 	<li>The type of the Token (JWT || SWT)</li>
 	<li>The issuer of the Token. In my case the issuer is IdentityServer (ADFS-mockup in my solution), running locally ("https://localhost:5000/identity"). In a production scenario, this could be any IdentityProvider.</li>
 	<li>The audience of the token - the people who are able to view the video. I defined two audiences in IdentityServer: staff and management. In a production scenario, this could be e.g. groups in your Active Directory.</li>
</ol>
&nbsp;

[code highlight="3,11" language="csharp"]
 static private string GenerateTokenRequirements(string issuer, string audience, bool contentKeyIdentifierClaim, byte[] primaryVerificationKey)
 {
    var template = new TokenRestrictionTemplate(TokenType.JWT)
    {
        PrimaryVerificationKey = new SymmetricVerificationKey(primaryVerificationKey),
        Issuer = issuer,
        Audience = audience
    };
            
    if (contentKeyIdentifierClaim)
       template.RequiredClaims.Add(TokenClaim.ContentKeyIdentifierClaim);

    //You can create a test token, useful to debug your final token if anything is not working as you want
    string testToken = TokenRestrictionTemplateSerializer.GenerateTestToken(template);

    return TokenRestrictionTemplateSerializer.Serialize(template);
}
[/code]

You can specify if your token should include the ContentKeyIdentifierClaim. Here is a picture of a sample JWT token (grabbed using <a href="https://www.telerik.com/fiddler">Fiddler</a>), using <a href="https://jwt.io/">https://jwt.io/</a> to take a closer look at the token of the <a href="https://ampdemo.azureedge.net/?url=%2F%2Famssamples.streaming.mediaservices.windows.net%2F830584f8-f0c8-4e41-968b-6538b9380aa5%2FTearsOfSteelTeaser.ism%2Fmanifest&amp;aes=true&amp;aestoken=Bearer%3DeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1cm46bWljcm9zb2Z0OmF6dXJlOm1lZGlhc2VydmljZXM6Y29udGVudGtleWlkZW50aWZpZXIiOiI5ZGRhMGJjYy01NmZiLTQxNDMtOWQzMi0zYWI5Y2M2ZWE4MGIiLCJpc3MiOiJodHRwOi8vdGVzdGFjcy5jb20vIiwiYXVkIjoidXJuOnRlc3QiLCJleHAiOjE3MTA4MDczODl9.lJXm5hmkp5ArRIAHqVJGefW2bcTzd91iZphoKDwa6w8">Azure Media Player Sample with AES128 encryption</a> sample with ContentKeyIdentifierClaim (urn:microsoft: ...):

&nbsp;

<img src="https://msdnshared.blob.core.windows.net/media/2016/12/jwt-1024x391.png" alt="jwt" width="1024" height="391" class="size-large wp-image-215 aligncenter" />

&nbsp;

&nbsp;

The complete solution and code can be found on <a href="https://github.com/juliajauss/AMSAes128EndToEnd">GitHub</a>. Please reach out to me if you have any questions!
I'm also on Twitter: <a href="https://twitter.com/BlauJule">@blaujule</a>.

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Create Azure billing alerts</title>
      <link>https://docs.microsoft.com/archive/blogs/juliajauss/create-azure-billing-alerts</link>
      <pubDate>Thu, 28 Apr 2016 15:49:36 GMT</pubDate>
      <dc:creator><![CDATA[juliajauss]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/juliajauss/?p=115</guid>
      <description><![CDATA[Go to this website and select "Try it now" for the Billing Alert...]]></description>
      <content:encoded><![CDATA[<p style="text-align: left"> Go to <a href="https://account.windowsazure.com/PreviewFeatures">this website</a> and select "Try it now" for the Billing Alert Service:</p>
&nbsp;

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/billingalertservice1.png"><img class="alignleft wp-image-135 size-large" src="https://msdnshared.blob.core.windows.net/media/2016/04/billingalertservice1-1024x221.png" alt="billingalertservice" width="1024" height="221" /></a>

&nbsp;

&nbsp;

&nbsp;

Afterwards you can see the <em>Alerts section</em> when you select a subscription <a href="https://account.windowsazure.com/Home/Index">here</a>:

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/alerts.png"><img class="alignleft wp-image-126" src="https://msdnshared.blob.core.windows.net/media/2016/04/alerts-300x164.png" alt="alerts" width="600" height="328" /></a>]]></content:encoded>
    </item>
    <item>
      <title>Quick deletion and shutdown of Azure Resources</title>
      <link>https://docs.microsoft.com/archive/blogs/juliajauss/quick-deletion-and-shutdown-of-azure-resources</link>
      <pubDate>Thu, 28 Apr 2016 14:06:57 GMT</pubDate>
      <dc:creator><![CDATA[juliajauss]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/juliajauss/?p=86</guid>
      <description><![CDATA[[caption id="attachment_95" align="aligncenter" width="300"] Click to play gif![/caption]

You...]]></description>
      <content:encoded><![CDATA[[caption id="attachment_95" align="aligncenter" width="300"]<a href="https://msdnshared.blob.core.windows.net/media/2016/04/DeleteRG.gif"><img class="wp-image-95 size-medium" src="https://msdnshared.blob.core.windows.net/media/2016/04/DeleteRG-300x118.gif" alt="Click to play gif!" width="300" height="118" /></a> Click to play gif![/caption]

You played with Azure all the day and you are in a hurry getting home on time?
Here is how you can delete your resource group (or shut down all your VMs) with only one Powershell command - like you can see in the gif. Just type <em>DeleteResourceGroup</em>, login to your Azure Account and select the Resource Group you want to delete - finished.

More exiting: Type <em>ShutDownAllVMs</em> and all your VMs are stopped and no costs will be produced anymore (of course except of the vhd storage costs, but these are just a few cents).

&nbsp;

<strong>So, how am I doing this?</strong>
The whole magic comes with Powershell profiles.
<ul>
	<li>Do you already have one? Check it with:
<code> Test-Path $profile
</code></li>
	<li>If it returns <em>True</em> you already have a profile. If it returns <em>False</em> you can create one by using this command:
<code> New-Item -path $profile -type file -force</code></li>
	<li>You can edit your profile at everytime using:
<code>notepad $profile</code></li>
	<li>So these are the lines in <a href="https://github.com/juliajauss/Quickly-delete-and-shutdown-Azure-Resources/blob/master/Jules_PowerShell_profile.ps1">my Powershell Profile</a> to use the Shortcuts (= functions) <em>ShutDownAllVMs</em>:
<code> function ShutDownAllVMs</code><code>{
Invoke-Expression "&amp; 'C:\Users\jule\Scripts\ShutDown-All-VMs-in-All-RGs.ps1' "}</code></li>
</ul>
Scripts for <a href="https://github.com/juliajauss/Quickly-delete-and-shutdown-Azure-Resources/blob/master/Delete-RSGroup.ps1">deleting a selected Resource Group</a>, <a href="https://github.com/juliajauss/Quickly-delete-and-shutdown-Azure-Resources/blob/master/ShutDown-All-VMs.ps1">stopping all VMs</a> and <a href="https://github.com/juliajauss/Quickly-delete-and-shutdown-Azure-Resources/blob/master/Shut-Down-All-VMs-In-A-ResourceGroup.ps1">stopping all VMs in a selected Resource Group</a> are available on GitHub.

I hope your 150€ trial money will now remain a bit longer :)

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Install Custom Script Extension via Powershell on existing Azure VM</title>
      <link>https://docs.microsoft.com/archive/blogs/juliajauss/install-custom-script-extension-via-powershell-on-existing-azure-vm</link>
      <pubDate>Wed, 27 Apr 2016 16:25:59 GMT</pubDate>
      <dc:creator><![CDATA[juliajauss]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/juliajauss/?p=75</guid>
      <description><![CDATA[You want to install something on your Windows VM on Azure using a Custom Script Extension via...]]></description>
      <content:encoded><![CDATA[You want to install something on your Windows VM on Azure using a Custom Script Extension via Powershell? Here is how you can do it!

I wanted to install the <a href="https://azure.microsoft.com/en-us/documentation/articles/storage-use-azcopy/">AzCopy </a>(Windows command-line utility designed for copying data to and from Microsoft Azure Blob, File, and Table storage using simple commands with optimal performance) Tool on my Windows Server VM. To do so, I uploaded a <a href="https://github.com/juliajauss/InstallCustomScriptExtension/blob/master/Install-AzCopy.ps1">Powershell script</a> to my Storage Account that downloads and installs AzCopy.

This script should be executed on my Windows Server VM using Custom Script Extension. Therefore, I wrote and executed <a href="https://github.com/juliajauss/InstallCustomScriptExtension/blob/master/Install-CustomScriptExtension.ps1">this Powershell script</a> on my local Machine. The most important command is this one, which grabs your VM and sets the CustomScriptExtension by providing the location of your custom script and tells your VM to run this script.

[code language="powershell"]
Get-AzureRmVM -Name $myVM.Name -ResourceGroupName $rg.ResourceGroupName |
Set-AzureRmVMCustomScriptExtension -Name MyCSETest -VMName $myVM.Name -ResourceGroupName $rg.ResourceGroupName -StorageAccountName $storageAccount.StorageAccountName -StorageAccountKey $storageAccountKey.Key1 -ContainerName $storageContainer -FileName $fileName -Run $fileName

[/code]


The other lines are just basics, like logging in to Azure and selecting the Subscription you want to work in; selecting the Resource Group of your VM; selecting the VM you want to attach the Custom Script Extension; the Storage Account and Container which contains the custom script and its file name.

After running this script, AzCopy (or any other tool you want to install) is installed on your Windows VM :)]]></content:encoded>
    </item>
    <item>
      <title>Download Azure Billing and Usage Information automatically</title>
      <link>https://docs.microsoft.com/archive/blogs/juliajauss/download-azure-billing-and-usage-information-automatically</link>
      <pubDate>Thu, 31 Mar 2016 15:40:27 GMT</pubDate>
      <dc:creator><![CDATA[juliajauss]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/juliajauss/?p=31</guid>
      <description><![CDATA[Using the Billing API to download your Azure Billing and Usage information requires a manual...]]></description>
      <content:encoded><![CDATA[Using the Billing API to download your Azure Billing and Usage information requires a manual authentification against Azure everytime. I will show you how to programatically fetch the information without the requirement of a manual login using a certificate (of course we don't want to hardcode the password).

You can find this instruction <strong>in German</strong> and the Code on <a href="https://github.com/juliajauss/AutomatedBillingInformation/tree/master/Documentation">GitHub</a>. The steps in the Azure Portal and all other steps can also be done by a <a href="https://github.com/juliajauss/AutomatedBillingInformation/blob/master/JuliaAutomatedBilling.ps1">Powershell script</a>.

&nbsp;

<strong>What do I need?</strong>
<ul>
	<li>Visual Studio 2015</li>
	<li>Visual Studio Developer Command Prompt</li>
	<li>makecert.exe (Windows SDK)</li>
	<li>Azure AD module for Powershell</li>
	<li>Internet Connection</li>
	<li>Azure Subscription</li>
</ul>
&nbsp;

<strong>Steps</strong>
<ol>
	<li>Download the Code on <a href="https://github.com/juliajauss/AutomatedBillingInformation/tree/2a2cae3cec09a1307262ad7fd21d142e2144c7e8/Documentation">GitHub</a>.</li>
	<li>Create an Azure AD Web App.</li>
	<li>Create a Certificate.</li>
	<li>Convert your Certificate to a X509 Certificate</li>
	<li>Add the Certificate to the local certificate store</li>
	<li>Create a Service Principal.</li>
	<li>Modify the C# Project configuration.</li>
	<li>Automatically download your Billing Information! :)</li>
</ol>
&nbsp;

<strong>Step 2: Create an Azure AD Web App </strong>

[caption id="attachment_33" align="alignnone" width="300"]<a href="https://msdnshared.blob.core.windows.net/media/2016/03/azure-add-app.gif"><img class="wp-image-33 size-medium" src="https://msdnshared.blob.core.windows.net/media/2016/03/azure-add-app-300x296.gif" alt="Create an Azure AD Web App " width="300" height="296" /></a> Click to Play this gif[/caption]

&nbsp;

Note down the following for step 7:
<em>Client Id:</em><span class="Apple-converted-space"> 038c63e3-f657-4c62-a139-b58c1781185d</span>-**********
<em>Tenant Id:</em><span class="Apple-converted-space"> </span>c015601b-39cc-441b-a15b-************
<em>Subscription Id:</em><span class="Apple-converted-space"> </span>00dd302a-92a9-*<strong><em>-</em></strong><em>-</em>***********

&nbsp;

<em>How can I find the Client ID?</em>

<a href="https://msdnshared.blob.core.windows.net/media/2016/03/copy-client-id.png"><img class="alignleft size-thumbnail wp-image-41" src="https://msdnshared.blob.core.windows.net/media/2016/03/copy-client-id-150x150.png" alt="Copy Client ID" width="150" height="150" /></a>

&nbsp;

&nbsp;

Select your App <strong>JuliaBillingBlog</strong> in your Default Directory. Select <strong>Configure</strong> and copy the Client Id.

&nbsp;

&nbsp;

&nbsp;

<em>How can I find the Tenant ID?</em>

<a href="https://msdnshared.blob.core.windows.net/media/2016/03/app-endpoints.png"><img class="alignleft size-thumbnail wp-image-43" src="https://msdnshared.blob.core.windows.net/media/2016/03/app-endpoints-150x150.png" alt="Get Tenant ID" width="150" height="150" /></a>

&nbsp;

Select your App <strong>JuliaBillingBlog</strong> in your Default Directory. Select <strong>View</strong> <strong>Endpoints</strong> (at the bottom of the page)<strong> </strong>and copy the Tenant Id.

&nbsp;

&nbsp;

<em> </em>

<em>How can I find my Subscription ID?</em>

<strong><em><a href="https://msdnshared.blob.core.windows.net/media/2016/03/subscription-id.png"><img class=" size-thumbnail wp-image-53 alignleft" src="https://msdnshared.blob.core.windows.net/media/2016/03/subscription-id-150x150.png" alt="subscription id" width="150" height="150" />
</a></em></strong>

&nbsp;

Select <strong>Settings </strong>in the left navigation pane. your Default Directory. Select <strong>View</strong> <strong>Endpoints </strong>and copy the Subscription Id.

&nbsp;

&nbsp;

<strong>Step 3: Create a Certificate</strong>

1. Open Visual Studio Command Prompt.

2. Create a Certificate:

<code>  makecert -r -pe -n "CN=JuliasCertificate" -ss My -len 2048 “C:\JuliasCertificate.cer“</code>

&nbsp;

<strong>Step 4: Convert your Certificate to a X509 Certificate</strong>

1. Open Powershell.

2. Create a new X509 Certificate:

<code>  $cer = New-Object System.Security.Cryptography.X509Certificates.X509Certificate</code>

3. Import the Certificate created in the previous step (Step 3: Create a Certificate):

<code>  $cer.Import("C:\JuliasCertificate.cer”)</code>

4. Save the raw data of the Certificate:

<code>  $binCert = $cer.GetRawCertData()</code>

5. Convert the raw data from unsigned 8-bit integers into base 64 :

<code>  $credValue = [System.Convert]::ToBase64String($binCert)</code>

&nbsp;

<strong>Step 5: Add the Certificate to the local certificate store</strong>

1. Get the Thumbprint of your created Certificate:

<code>  dir Cert:\LocalMachine\My</code>

2. Add the Certificate to your trusted root store:

<code>$cert = (get-item cert:\LocalMachine\My\A70E0D9E39C32B482E8A8D7776462A9470DEF441)
$store = (get-item cert:\Localmachine\Root)
$store.Open("ReadWrite")
$store.Add($cert)
$store.Close()</code>

3. Check if the Certificate was added:

<code>  dir Cert:\LocalMachine\Root</code>

&nbsp;

<strong>Step 6: Create a Service Principal </strong>

1. Open Azure Powershell as Admin.

2. Login to Azure:

<code>  Login-AzureRmAccount #This will pop up a login dialogue</code>

3. Select your subscription:

<code>  Select-AzureRmSubscription -SubscriptionId "&lt;your-sub-id&gt;"</code>

4. Open Windows Azure Active Directory Powershell Modul and connect to Azure AD.

<code>  connect-msolservice</code>

5. Create a new Service Principal:

<code>  New-AzureRmADServicePrincipal -ApplicationId "&lt;your-client-Id&gt;"</code>

<code>  New-AzureRmRoleAssignment -ServicePrincipalName <span style="font-family: Courier New">"&lt;your-client-Id&gt;"</span> -RoleDefinitionName Contributor</code>

6. Check with <code>Get-AzureRmRoleAssignment</code> if the assignment was successful.

&nbsp;

<strong>Step 7: Modify the C# Project configuration</strong>

1. Open Visual Studio and the Project from <a href="https://github.com/juliajauss/AutomatedBillingInformation/tree/2a2cae3cec09a1307262ad7fd21d142e2144c7e8/Documentation">GitHub</a>.

2. Open the <strong>App.config</strong> file and replace the parameters with your Parameters you noted in Step2.

3. Run the Project and get your Billing Information :)

&nbsp;

&nbsp;]]></content:encoded>
    </item>
  </channel>
</rss>