Shawn Cicoria - CedarLogic

Perspectives and Observations on Technology

Recent Posts

Sponsors

Tags

General





Community

Email Notifications

Blogs I Read

Archives

Other

Use OpenDNS

Creating a VHD from ISO using WIM2VHD Convert-WindowsImage …

 

This script here helps in creating VHD’s on the fly. Recently I needed to quickly create some VHDX from an ISO that are “arm-able” for some labs.

The tool  I used is:

Convert-WindowsImage.ps1 — WIM2VHD for Windows 10 (also Windows 8 and 8.1)

Convert-WindowsImage is the new version of WIM2VHD designed specifically for Windows 8 and above. Written in PowerShell, this command-line tool allows you to rapidly create sysprepped VHDX and VHDX images from setup media for Windows 7/Server 2008 R2, Windows 8/8.1/Server 2012/R2

https://gallery.technet.microsoft.com/scriptcenter/Convert-WindowsImageps1-0fe23a8f

Here’s the basic script I used…

 

$iso = 'E:\users\shawn\Downloads\en_windows_server_2012_r2_with_update_x64_dvd_6052708.iso'
$workdir = 'e:\temp\iso'
$vhdpath = 'e:\temp\iso\thevhd.vhdx'

# Load (aka "dot-source) the Function 
. .\Convert-WindowsImage.ps1 
# Prepare all the variables in advance (optional) 
$ConvertWindowsImageParam = @{  
    SourcePath          = $iso 
    RemoteDesktopEnable = $True  
    Passthru            = $True  
    Edition    = "ServerDataCenter"
    VHDFormat = "VHDX"
    SizeBytes = 60GB
    WorkingDirectory = $workdir
    VHDPath = $vhdpath
    VHDPartitionStyle = 'GPT'
}

$VHDx = Convert-WindowsImage @ConvertWindowsImageParam


Simple Azure Blob Storage Performance (upload) testing

Azure Blob Storage Perf Testing Tool

This is a simple testing tool using Mocha that provides upload speed testing when modifying the parallelOperationThreadCount
setting that is available in the Azure Storage Nodejs tools.

Setup

Install Nodejs and npm for your environment

Review what Nodejs.org says for your environment in order to get Nodejs and npm running.

Clone the repo

git clone https://github.com/cicorias/blobTool
chdir blobTool
npm install

Run the mocha test

npm test

Review the package.json

This file will show what the script calls - this uses babel-core to polyfill ES6 support
and runnable on node >=10.x

{
  "name": "blobtool",
  "version": "1.0.0",
  "description": "Simple Blob upload check",
  "main": "app.js",
  "scripts": {
    "start": "node ./app.js",
    "test": "node ./node_modules/mocha/bin/mocha --compilers js:babel/register"
  },
  "author": "shawn cicoria",
  "license": "ISC",
  "dependencies": {
    "azure-storage": "^0.5.0",
    "nconf": "^0.7.2",
    "node-uuid": "^1.4.3"
  },
  "devDependencies": {
    "babel": "^5.8.23",
    "babel-core": "^5.8.24",
    "mocha": "^2.3.2",
    "performance-now": "^0.2.0",
    "qunit": "^0.7.6"
  }
}

Configuration

The config.1.json file needs to be updated to include your test container name, storage account name, and the storage key.

{
    "CONTAINER_NAME" : "<containername>",
    "STORAGE_NAME": "<storageaccount>",
    "STORAGE_KEY": "<key>"
}

Example test results

Below are some console output captures of results.
Note that for the most part anything above 2 parallel operations is really not helping. Perhaps 3. Note that the
service limit on Standard Storage is 60 MBS see this for more information.

The tests were run from East -> East 2 to hopefully accomplish eliminating things like my ISP’s stuff, keep it on the Azure backbone, but also from something other than the direct Region / Datacenter.

From local Mac

local mac

From an A2 machine

A2 in East to East2

From an A8 machine

A8 in East to East2

Posted: 09-17-2015 1:48 PM by cicorias | with no comments
Filed under: ,
Using Multiple Devices for 2-step verification to save time !

2-step verification is becoming more prevalent. This is the process where when you logon to a web site, or application, you might provide something you know (username & password) and then using a special "Authenticator" application that might be on your phone, keychain, or even your computer, you enter a challenge code.

This approach has been around for decades. If you recall the old RSA SecurID cards, now keyfobs, now soft-keyfobs that exist they use a similar principle.

These token generators basically, using the current date + time, plus some "seed" value, they both apply the same algorithm TOTP that generates a numeric code (usually 6 digits) that when presented on the OTP device, you enter on the site.

In some instances, like with Azure Authentication, you can have a notification sent to your device that the App there will just ask you to Verify. Some configurations of Azure Authentication (like with MSIT) we have to supply a PIN in addition.

Links to apps

The following are links for several of the following used. They all implement the same base algorithm and for some the source code is public.

How this applies

So, the example I'm providing here works well with Github and allows you to have several devices that will all provide the same Token at time of challenge. I've been running this for a while and so far, they are all generarting the same TOken at the same time for the same (or very close) grace period.

Making life simple

Now, If i'm on my Mac, or only have either my iPhone, or Nexus, and if say Azure Authenticator app isn't working say for a recent update (this happens), you have a backup.

You can see here how they are all the same code...

Setup

The setup requires a little coordination. You need to have each OTP program ready. So, on my iPhone and Nexus I have Google Authenticator, Azure Authenticator, on Mac I have OTP Manager, and Windows 10 - well, nothing yet.

  1. First line up all up
  2. Get to the point in Github where it's showing you the QR code
  3. Then, for the phone apps, you can just start the add process and just point at the QR code
  4. For the Mac or PC base app, you need to get the long "code" that you can either cut & paste into the OTP app or just type it in.
Posted: 09-10-2015 10:42 AM by cicorias | with no comments
Filed under: ,
Federation Metadata generation tool on Github

I get from various folks some requests for updates, information, etc. about this tool, so, I’ve put it up on Github so others can just contribute or copy as they see fit.

https://github.com/cicorias/federationmetadatagenerator

http://blogs.msdn.com/b/scicoria/archive/2010/08/18/federation-metadata-generation-tool.aspx

CSL for Pace University–IEEE based using custom author sort

 

<?xml version="1.0" encoding="utf-8"?>
<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="sort-only">
  <info>
    <title>Pace University - DPS - custom author sort</title>
    <id>http://www.zotero.org/styles/ieee-custom-authorsort</id>
    <link href="http://www.zotero.org/styles/ieee" rel="self"/>
    <author>
      <name>Shawn Cicoria</name>
      <email>shawn@cicoria.com</email>
    </author>
    <category field="engineering"/>
    <category field="generic-base"/>
    <category citation-format="numeric"/>
    <updated>2011-08-18T16:08:33+00:00</updated>
    <rights>This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License: http://creativecommons.org/licenses/by-sa/3.0/</rights>
    <link href="http://www.ieee.org/portal/cms_docs_iportals/iportals/publications/authors/transjnl/stylemanual.pdf" rel="documentation"/>
    <link href="http://www.ieee.org/documents/auinfo07.pdf" rel="documentation"/>
  </info>
  <!-- Macros -->
  <macro name="edition">
    <choose>
      <if type="bill book chapter graphic legal_case legislation motion_picture paper-conference report song" match="any">
        <choose>
          <if is-numeric="edition">
            <group delimiter=" ">
              <number variable="edition" form="ordinal"/>
              <text term="edition" form="short" suffix="." strip-periods="true"/>
            </group>
          </if>
          <else>
            <text variable="edition" text-case="capitalize-first" suffix="."/>
          </else>
        </choose>
      </if>
    </choose>
  </macro>
  <macro name="issued">
    <choose>
      <if type="article-journal report" match="any">
        <date variable="issued">
          <date-part name="month" form="short" suffix=" "/>
          <date-part name="year" form="long"/>
        </date>
      </if>
      <else-if type=" bill book chapter graphic legal_case legislation motion_picture paper-conference song thesis" match="any">
        <date variable="issued">
          <date-part name="year" form="long"/>
        </date>
      </else-if>
      <else>
        <date variable="issued">
          <date-part name="day" form="numeric-leading-zeros" suffix="-"/>
          <date-part name="month" form="short" suffix="-" strip-periods="true"/>
          <date-part name="year" form="long"/>
        </date>
      </else>
    </choose>
  </macro>
  <macro name="author">
    <names variable="author">
      <name initialize-with=". " delimiter=", " and="text"/>
      <label form="short" prefix=", " text-case="capitalize-first" suffix="." strip-periods="true"/>
      <substitute>
        <names variable="editor"/>
        <text macro="title"/>
      </substitute>
    </names>
  </macro>
  <macro name="editor">
    <names variable="editor">
      <name initialize-with=". " delimiter=", " and="text"/>
      <label form="short" prefix=", " text-case="capitalize-first" suffix="." strip-periods="true"/>
    </names>
  </macro>
  <macro name="locators">
    <group delimiter=", ">
      <text macro="edition"/>
      <group delimiter=" ">
        <text term="volume" form="short" suffix="." strip-periods="true"/>
        <number variable="volume" form="numeric"/>
      </group>
      <group delimiter=" ">
        <number variable="number-of-volumes" form="numeric"/>
        <text term="volume" form="short" suffix="." plural="true" strip-periods="true"/>
      </group>
      <group delimiter=" ">
        <text term="issue" form="short" suffix="." strip-periods="true"/>
        <number variable="issue" form="numeric"/>
      </group>
    </group>
  </macro>
  <macro name="title">
    <choose>
      <if type="bill book graphic legal_case legislation motion_picture song" match="any">
        <text variable="title" font-style="italic"/>
      </if>
      <else>
        <text variable="title" quotes="true"/>
      </else>
    </choose>
  </macro>
  <macro name="publisher">
    <choose>
      <if type=" bill book chapter graphic legal_case legislation motion_picture paper-conference song" match="any">
        <text variable="publisher-place" suffix=": "/>
        <text variable="publisher"/>
      </if>
      <else>
        <group delimiter=", ">
          <text variable="publisher"/>
          <text variable="publisher-place"/>
        </group>
      </else>
    </choose>
  </macro>
  <macro name="event">
    <choose>
      <if type="paper-conference">
        <choose>
          <!-- Published Conference Paper -->
          <if variable="container-title">
            <group delimiter=", ">
              <text variable="container-title" prefix="in " font-style="italic"/>
              <text variable="event-place"/>
            </group>
          </if>
          <!-- Unpublished Conference Paper -->
          <else>
            <group delimiter=", ">
              <text variable="event" prefix="presented at the "/>
              <text variable="event-place"/>
            </group>
          </else>
        </choose>
      </if>
    </choose>
  </macro>
  <macro name="access">
    <choose>
      <if type="webpage">
        <choose>
          <if variable="URL">
            <group delimiter=". ">
              <text value="[Online]"/>
              <text variable="URL" prefix="Available: "/>
              <group prefix="[" suffix="]">
                <date variable="accessed" prefix="Accessed: ">
                  <date-part name="day" form="numeric-leading-zeros" suffix="-"/>
                  <date-part name="month" form="short" suffix="-" strip-periods="true"/>
                  <date-part name="year" form="long"/>
                </date>
              </group>
            </group>
          </if>
        </choose>
      </if>
    </choose>
  </macro>
  <macro name="page">
    <group>
      <label variable="page" form="short" suffix=". " strip-periods="true"/>
      <text variable="page"/>
    </group>
  </macro>
  <!-- Citation -->
  <citation collapse="citation-number">
    <sort>
      <key variable="citation-number"/>
    </sort>
    <layout prefix="[" suffix="]" delimiter=",">
      <text variable="citation-number"/>
    </layout>
  </citation>
  <!-- Bibliography -->
  <bibliography entry-spacing="0" second-field-align="flush">
    <sort>
      <key macro="author"/>
      <key macro="year-date"/>
      <key variable="title"/>
    </sort>
    <layout suffix=".">
      <!-- Citation Number -->
      <text variable="citation-number" prefix="[" suffix="]"/>
      <!-- Author(s) -->
      <text macro="author" prefix=" " suffix=", "/>
      <!-- Rest of Citation -->
      <choose>
        <!-- Specific Formats -->
        <if type="article-journal">
          <group delimiter=", ">
            <text macro="title"/>
            <text variable="container-title" font-style="italic" form="short"/>
            <text macro="locators"/>
            <text macro="page"/>
            <text macro="issued"/>
          </group>
        </if>
        <else-if type="paper-conference">
          <group delimiter=", ">
            <text macro="title"/>
            <text macro="event"/>
            <text macro="issued"/>
            <text macro="locators"/>
            <text macro="page"/>
          </group>
        </else-if>
        <else-if type="report">
          <group delimiter=", ">
            <text macro="title"/>
            <text macro="publisher"/>
            <group delimiter=" ">
              <text variable="genre"/>
              <text variable="number"/>
            </group>
            <text macro="issued"/>
          </group>
        </else-if>
        <else-if type="thesis">
          <group delimiter=", ">
            <text macro="title"/>
            <text variable="genre"/>
            <text macro="publisher"/>
            <text macro="issued"/>
          </group>
        </else-if>
        <else-if type="webpage">
          <group delimiter=", " suffix=". ">
            <text macro="title"/>
            <text variable="container-title" font-style="italic"/>
            <text macro="issued"/>
          </group>
          <text macro="access"/>
        </else-if>
        <else-if type="patent">
          <text macro="title" suffix=", "/>
          <text variable="number" prefix="U.S. Patent "/>
          <text macro="issued"/>
        </else-if>
        <!-- Generic/Fallback Formats -->
        <else-if type="bill book graphic legal_case legislation motion_picture report song" match="any">
          <group delimiter=", " suffix=". ">
            <text macro="title"/>
            <text macro="locators"/>
          </group>
          <group delimiter=", ">
            <text macro="publisher"/>
            <text macro="issued"/>
            <text macro="page"/>
          </group>
        </else-if>
        <else-if type="article-magazine article-newspaper broadcast interview manuscript map patent personal_communication song speech thesis webpage" match="any">
          <group delimiter=", ">
            <text macro="title"/>
            <text variable="container-title" font-style="italic"/>
            <text macro="locators"/>
            <text macro="publisher"/>
            <text macro="page"/>
            <text macro="issued"/>
          </group>
        </else-if>
        <else-if type="chapter paper-conference" match="any">
          <group delimiter=", " suffix=", ">
            <text macro="title"/>
            <text variable="container-title" prefix="in " font-style="italic"/>
            <text macro="locators"/>
          </group>
          <text macro="editor" suffix=" "/>
          <group delimiter=", ">
            <text macro="publisher"/>
            <text macro="issued"/>
            <text macro="page"/>
          </group>
        </else-if>
        <else>
          <group delimiter=", " suffix=". ">
            <text macro="title"/>
            <text variable="container-title" font-style="italic"/>
            <text macro="locators"/>
          </group>
          <group delimiter=", ">
            <text macro="publisher"/>
            <text macro="page"/>
            <text macro="issued"/>
          </group>
        </else>
      </choose>
    </layout>
  </bibliography>
</style>
Cleaning up IIS Express sites v2

This one deals with a single site…

Again, I’m a tidy person.

$appCmd = "C:\Program Files (x86)\IIS Express\appcmd.exe"
$result = Invoke-Command -Command {& $appCmd 'list' 'sites' '/text:SITE.NAME' }

function deleteSite($site){

   Invoke-Command -Command {& $appCmd 'delete' 'site'  $site }
}


if ($result -is [system.array]){
     for ($i=0; $i -lt $result.length; $i++)
     {
         deleteSite($result[$i])
     }
}
else {
     deleteSite($result)
 }
Cheap and easy IP blocking in Azure Web Apps

Sometimes you just need to resort to something simple.

I don’t recommend this in anyway for a real security plan / hardening. You should be using something proper if you’re under these kinds of malicious attacks.

But, in Azure Web Apps you can add IP Address blocking via the IIS “Dynamic IP Restrictions” Module [1].

While I think this is the “wrong” way to do this (a real firewall should be in place), I was able to “block” IP addresses in Azure Web Apps (site) by using an applicationHost.xdt transform like so:

This becomes a “site” extension – and is deployed as a Site Extension https://github.com/projectkudu/kudu/wiki/Azure-Site-Extensions

This modifies the applicationHost.config for your Web App. https://azure.microsoft.com/en-us/documentation/articles/web-sites-transform-extend/

 

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <system.webServer>
    <security>
      <ipSecurity allowUnlisted="true" xdt:Transform="Replace">
         <add  ipAddress="191.237.6.194"/>
      </ipSecurity>
    </security>
  </system.webServer>
</configuration>

 

[1] http://www.iis.net/downloads/microsoft/dynamic-ip-restrictions

AngularJS intellisense NuGet package added

Using the work of John Bledsoe, a NuGet package has been added that takes a dependency on AngularJS.Core – and provides the angular.intellisense.js file to your project.

Via Nuget.org: https://www.nuget.org/packages/AngularJS.Intellisense/

Referenced here: http://blogs.msdn.com/b/visualstudio/archive/2015/02/05/using-angularjs-in-visual-studio-2013.aspx

This approach takes the ‘per’ project approach and puts this into the /scripts directory of your project.

_references.js – auto-update

In addition, the package delivers a default _references.js file that allows for auto-update. If you want to at any time regernated the references, in Visual Studio open _references.js and then choose “Update JavaScript References”.

/// <autosync enabled="true" />
/// <reference path="angular.js" />
/// <reference path="angular-mocks.js" />
/// <reference path="project.js" />

The source for the intellisense is here:

https://github.com/jmbledsoe/angularjs-visualstudio-intellisense 

Thanks to Jim Bledsoe for his hard work on this…  https://twitter.com/jmbledsoe

Posted: 02-27-2015 2:09 PM by cicorias | with no comments
Filed under: ,
Troubleshooting tool–Azure WebJob TCP Ping

I’ve dropped a quick Visual Studio solution that has a simple Azure WebJob intended to run Continuously that does a Socket open (TCPPing) for a specific IP address and Port – intended to aid in identifying any network transient errors over time.

Located on Github here: https://github.com/cicorias/webjobtcpping

Azure Web Job - TCP Ping


Overview

Visual Studio 2013 Solution

The solution file contains several things:

  1. JobRunnerShell - simple wrapper class that handles some of the basic management of the process/job for Azure Web Job Classes/Assemblies
  2. TcpPing - an implementation of a simple Azure Web Job - intended to be run continuously - that will do a basic TcpPing (open a socket) every second.
  3. SimpleTcpServer - a very basic Tcp Listener service that echo's back a simple string (1 line) in reverse.

Purpose

The intent of the solution is to provide a very basic diagnostic tool that can be run continuously in an Azure WebSite deployment that will 'ping' (open a socket) to a server -- this is intended for testing availability of a server using IPv4 addresses (ie. 10.0.1.1) across Virtual Networks (VNET) in Azure.

This can be used against any Server listener service - as it only does a Socket.Open() - of course, the Server should be resilient to these Socket Opens and immediate close.

NOTE: *Make sure you Open the Windows Server firewall if using Windows Server as your 'host' for this.

Reporting is done to the Azure Web Jobs dashboard and is also visible via Azure WebSite's Streaming Logs

The easiest way is just go the the Azure Portal or use Visual Studio Azure Explorer - which comes with the Azure Tools for Visual Studio.


Deployment

Azure WebJob

The Azure WebJob - 'TcpPing' utilizes the NuGet packaging that 'lights up' the "Publish as Azure Webjob" tooling in Visual Studio. Otherwise, this can be deployed using alternate methods - see How to Deploy Azure WebJobs to Azure Websites

Settings

Within the TcpPing project - examine the "app.confg" you will find 'appSettings' and 'connectionStrings' that you should review. The connectionStrings are dependant upon your Azure Storage Account information which you can retrieve from the Azure Portal

AppSettings

The following settings are used to open the socket - adjust to your need.

<appSettings>
  <add key="sqlIp" value="10.3.0.4"/>
  <add key="sqlPort" value="8999"/>
</appSettings>
Connection Strings

Make sure you put in your 'connectionString' - which comes from the Azure Portal for the Storage Account.

<connectionStrings>
<!--WEBJOBS_RESTART_TIME  - please set in porta to seconds like 60.-->
<!--WEBJOBS_STOPPED   setting to 1 means stopped-->
<!-- The format of the connection string is "DefaultEndpointsProtocol=https;AccountName=NAME;AccountKey=KEY" -->
<!-- For local execution, the value can be set either in this config file or through environment variables -->
<add name="AzureWebJobsDashboard"
 connectionString="DefaultEndpointsProtocol=https;AccountName=<accountName>;AccountKey=<accountKey>" />
<add name="AzureWebJobsStorage"
 connectionString="DefaultEndpointsProtocol=https;AccountName=<accountName>;AccountKey=<accountKey>" />
</connectionStrings>
Simple TCP Server

The solution also contains a simple TCP Server that is intended to be installed on within the Virtual Network - for example in an IaaS instance -- that you are attempting to validate connectivity and continuous reporting on.

Again, you should be able

Settings

There is only 1 setting in the app.config under appSettings. If this is absent, the Simple TCP Server listens on IPv4 addresses only (actually all the time) and uses port 8999

<appSettings>
 <add key="serverPort" value="8999"/>
</appSettings>
Posted: 02-15-2015 4:27 PM by cicorias | with no comments
Filed under: ,
Azure Resource Manager–Creating an IaaS VM within a VNET

NOTE: Azure Resource manager is in Preview. Thus, anything posted here may change. However, the approach for identifying what resources are available for update and registered for Subscriptions should be the same.

Here are the prior posts:

For this walkthrough I’m going to build up a Linux VM instance off of a VHD that I have within a storage account. I use the ARM REST API calls direct, bypassing the Templates that are coming to ARM.

Azure Resource Manager Templates

The REST API calls that I’m illustrating below are NOT using Azure Resource Manager (ARM) Templates. You can review some of the articles below for more information on ARM Templates.

 

Currently, ARM Templates are in preview and as of this writing, only 3 templates are available. Those are listed in the tooling. in the links above.

ARM Templates Basics

ARM Templates provided a template language that establishes the dependencies amongst the composition of supporting resources. In addition, the backend to ARM Templates provides the management and control over provisioning all these dependency upon submission of the ARM Template provision request. Ultimately, it is built upon ARM – which for this post is accessible via the ARM REST API calls.

Creating a VM using ARM REST API – not using Templates

This blog post is NOT about ARM Templates. I cover the underlying ARM REST API directly and create composition through a series of client side REST API calls (if that makes any sense).

Preparation steps:

 

$blob1 = Start-AzureStorageBlobCopy -srcUri $srcUri `
	-SrcContext $srcContext `
	-DestContainer $containerName `
	-DestBlob "testcopy1.vhd" `
	-DestContext $destContext 

 

 

Resource Manager Composition

If you examine an existing VM via the REST API you will see within the JSON response several sections contained within the properties JSON object.

Any of these, for example ‘domainName’, ‘networkProfile/virtualNetworks’, ‘storageProfile/operatingSystemDisk/storageAccount’ are additional resources that you must compose or create prior to making the REST API call to create (PUT) the VM that you want to provision. If you refer back to the prior posts that lists the /providers for a subscription, you will find providers as follows:

  • Networks - Microsoft.ClassicNetwork – with resource types of ‘virtualNetworks’, ‘reservedIps’, ‘quotas’, and ‘gatewaySupportedDevices’
  • Domain Name - Microsoft.ClassicCompute – with resource providers of ‘domainNames’, ‘virtualMachines’, ‘capabilities, ‘quotas’, etc.

 

You will see ‘storageAccount’ listed in the GET response for each disk – OS and data disks – that are used by the existing VM. Note that there is an ‘id’ property. That’s the ‘id’ or reference that will be used in the final PUT request at the end of the post for each of the associated resources.

Prior Posts

In prior posts, I cover the creation of a Resource Group and a Storage Account.  Here is a screen shot of the Resource Group creating using Postman (I won’t repeat the Storage Account creation).

SNAGHTML1671163

Create Domain Name

The domain name represents the ‘cloud service’ – which essentially represents the wrapper and associated public IP address that the VM when created be behind – think firewall. In the new portal (https://portal.azure.com) these show as Domains (thus that is what ARM uses). In the current production portal (https://manage.windowsazure.com) they appear as Cloud Services – a term that anybody doing Worker and Web Roles in PaaS are quite familiar with.

 

The PUT request contains a JSON body that is quite simple.

PUT https://management.azure.com/subscriptions/<subscriptionId>/resourceGroups/demo2/providers/Microsoft.ClassicCompute/domainNames/scicoriacentosnew?api-version=2014-06-01

Content-Type: application/json
Authorization: Bearer: <token>

{
     "properties": {
         "label": "scicoriacentosnew",
         "hostName": "scicoriacentosnew.cloudapp.net"
     },
     "name": "scicoriacentosnew",
     "type": "Microsoft.ClassicCompute/domainNames",
     "location": "eastus2"
}

SNAGHTML16786d1

Create Domain Response

For this call, the HTTP response comes back as ‘201 – created’ – you’ll see in the other requests, as they are longer running, you will get a ‘202 – Accepted’ – and with that response headers that you can obtain the operation request ID and ask Azure for the status of the request. That is key to identifying any issues beyond the simple serialization issues for bad JSON PUT payloads.

Create Virtual Network

For a VNET (virtual network) I’m going to create with my ‘demo2’ resource group a VNET with –well, the JSON below should be fairly explanatory (that’s what’s nice about JSON and REST of these things).

PUT https://management.azure.com/subscriptions/<subscriptionId>/resourceGroups/demo2/providers/Microsoft.ClassicNetwork/virtualNetworks/scicoriacentosnew?api-version=2014-06-01

Content-Type: application/json
Authorization: Bearer <token>

{
    "properties": {
        "addressSpace": {
            "addressPrefixes": [
                "10.1.0.0/16"
            ]
        },
        "subnets": [
            {
                "name": "Subnet-1",
                "addressPrefix": "10.1.0.0/24"
            },
            {
                "name": "Subnet-2",
                "addressPrefix": "10.1.1.0/24"
            }
        ]
    },
    "id": "/subscriptions/<subscriptionId>/resourceGroups/demo2/providers/Microsoft.ClassicNetwork/virtualNetworks/scicoriacentosnew",
    "name": "scicoriacentosnew",
    "type": "Microsoft.ClassicNetwork/virtualNetworks",
    "location": "eastus2"
}

Explanation

For those that aren’t familiar, the VNET will be created covering a CIDR range of addresses 10.1.*.*/16 – and, in addition, within that top-level range, I’ve created a 2 subnets covering 10.1.0.*/24 & 10.1.1.*/24.

Additional subnets can be specified within the JSON array [] if needed. Validation will occur at submission and provisioning time – so, you need to check for a ‘202 – Accepted’ response, and with that operations ID, validate status.. I could’ve also specified additional ranges for the address prefixes as well – just as you can do in the Azure Management portal.

 

SNAGHTML169aba5

Create Virtual Machine

Now that we have the following, we’re ready to issue an ARM REST API PUT request to create the virtual machine.:

  1. Storage Account with a VHD ready to use
  2. Resource Group
  3. Domain Name
  4. Virtual Network

 

This one is rather lengthy. You should note the ‘nested’ referred to resource that were created in the prior steps. Again, once submitted and no deserialization issues, URI issues, etc., you should get back a ‘202 – Accepted’ – from that response you have to check the Operation Status using the provided status ID:

//PUT https://management.azure.com/subscriptions/<subscriptionId>/resourceGroups/demo2/providers/Microsoft.ClassicCompute/virtualMachines/scicoriacentosnew?api-version=2014-06-01
{
    "properties": {
        "hardwareProfile": {
            "platformGuestAgent": true,
            "size": "Basic_A2",
            "deploymentName": "scicoriacentosnew",
            "deploymentLabel": "scicoriacentosnew",
        },
        "domainName": {
            "id": "/subscriptions/<subscriptionId>resourceGroups/demo2/providers/Microsoft.ClassicCompute/domainNames/scicoriacentosnew",
            "name": "scicoriacentosnew",
            "type": "Microsoft.ClassicCompute/domainNames"
        },
        "storageProfile": {
            "operatingSystemDisk": {
                "diskName": "scicoriacentosnew-os-20150212",
                "caching": "ReadWrite",
                "operatingSystem": "Linux",
                "ioType": "Standard",
                //"sourceImageName": "5112500ae3b842c8b9c604889f8753c3__OpenLogic-CentOS-65-20140926",
                "vhdUri": "https://scicoriademo.blob.core.windows.net/vhds/testcopy1.vhd",
                "storageAccount": {
                    "id": "/subscriptions/<subscriptionId>resourceGroups/demo/providers/Microsoft.ClassicStorage/storageAccounts/scicoriademo",
                    "name": "scicoriademo",
                    "type": "Microsoft.ClassicStorage/storageAccounts"
                }
            }
        },
        "networkProfile": {
            "inputEndpoints": [
                {
                    "endpointName": "SSH",
                    "privatePort": 22,
                    "publicPort": 22,
                    "protocol": "tcp",
                    "enableDirectServerReturn": false
                }
            ],
            "virtualNetwork": {
                "subnetNames": [
                    "Subnet-1"
                ],
                "id": "/subscriptions/<subscriptionId>resourceGroups/demo/providers/Microsoft.ClassicNetwork/virtualNetworks/scicoriacentos",
                "name": "scicoriacentos",
                "type": "Microsoft.ClassicNetwork/virtualNetworks"
            }
        }
    },
    "location": "eastus2",
    "name": "scicoriacentosnew"
}


Response

If all is OK from a formatting and basic validation, you should see an ‘202 – Accepted’ – from that obtain the operation ID – and use the API call to check that operation’s status.

SNAGHTML16bd423

Checking Operation Status

 

Take a look at the documentation for the structure of that call.

https://msdn.microsoft.com/en-us/library/azure/ee460783.aspx

A Succeeded Operation

SNAGHTML1690757

An InProgress Operation

SNAGHTML1681c7a

 

An Error Operation Status

SNAGHTML16a181b 

Azure Resource Manager – Creating Storage Accounts

NOTE: Azure Resource manager is in Preview. Thus, anything posted here may change. However, the approach for identifying what resources are available updatable, and registered for Subscriptions should be the same.

In a prior post I walked through adding an SSL certificate then associating that certificate with an Azure Websites. While some sample C# code was provided, for this post it will entirely via using a REST tool – Fiddler or PostMan suffices for this.

The last post I walked through adding a VNET. To cleanup, remember that with REST an HTTP DELETE is all you need to cleanup…

Getting Available Resource Providers

Again, from the prior posts, if you want to see the list of resource providers for a subscription, issue an authenticated call to the /providers resource:

https://msdn.microsoft.com/en-us/library/azure/dn790572.aspx

I’ve glossed over authentication quite a bit in the prior posts, take a look here: https://msdn.microsoft.com/en-us/library/azure/dn790557.aspx which uses the ADAL library for Managed code.  Again, you can do the calls via REST as well – I’ll try to cover that in a future post.

Creating a Storage Account

Again, the best way to ‘learn’ the representation of these resources is to review an existing one.

Here, issuing a GET request to the following gives me the resource properties.

GET https://management.azure.com/subscriptions/<subscriptionId>/resourceGroups/somegroup/providers/Microsoft.ClassicStorage/storageAccounts/<resourceName>?api-version=2014-06-01

{
    "properties": {
        "provisioningState": "Succeeded",
        "status": "Created",
        "endpoints": [
            "https://<accountName>.blob.core.windows.net/",
            "https://<accountName>.queue.core.windows.net/",
            "https://<accountName>.table.core.windows.net/",
            "https://<accountName>.file.core.windows.net/"
        ],
        "accountType": "Standard-LRS",
        "geoPrimaryRegion": "East US",
        "statusOfPrimaryRegion": "Available",
        "geoSecondaryRegion": "",
        "statusOfSecondaryRegion": "",
        "creationTime": "2014-12-19T19:18:59Z"
    },
    "id": "/subscriptions/<subscriptionId>/resourceGroups/somegroup/providers/Microsoft.ClassicStorage/storageAccounts/<accountName>",
    "name": "<accountName>",
    "type": "Microsoft.ClassicStorage/storageAccounts",
    "location": "eastus2"
}

Creating a Locally Redundant Storage Account (LRS)

Ok, we trim back the JSON properties to what we just need to create. Note that when you’re in the portal, there’s really not too many options to set other than the Name and the Pricing level. Same for the JSON properties here.

PUT https://management.azure.com/subscriptions/<subscriptionId>/resourceGroups/demo2/providers/Microsoft.ClassicStorage/storageAccounts/<resourceName>?api-version=2014-06-01

Authorization: Bearer <token>
Content-Type: application/json

{
    "properties": {
        "accountType": "Standard-LRS",
    },
    "name": "<reourceName>",
    "type": "Microsoft.ClassicStorage/storageAccounts",
    "location": "eastus2"
}

 

Here’s the screenshot from Postman – note the 202 – Accepted

 

SNAGHTMLf393b6 

Azure Resource Manager– Creating a Resource Group and a VNET

NOTE: Azure Resource manager is in Preview. Thus, anything posted here may change. However, the approach for identifying what resources are available updatable, and registered for Subscriptions should be the same.

In a prior post I walked through adding an SSL certificate then associating that certificate with an Azure Websites. While some sample C# code was provided, for this post it will entirely via using a REST tool – Fiddler or PostMan suffices for this.

Getting a Token

I’m not going to go into the token acquisition process here. The easiest way to obtain a token for this walkthrough is to just open a session to https://portal.azure.com then view the network traffic as you open up some Blades – for example, open up the “Resource Group” blade – look for an “Authorization” header.  It should show up as “Bearer ….”.  It’s a JWT which if you’d like (WARNING you’re giving your token to a 3rd party to decipher) http://jwt.io/  - this site is managed by the http://auth0.com folks.

If you want to decode this yourself, note that the JWT token is presented in 3 parts, separated by a ‘.’ and each part base64 encoded. The parts are header, payload, and signature.

Getting your subscription ID

In the prior post and the sample code here: http://bit.ly/azrmsamples  there’s some sample code in helper classes to list subscription ID’s for a login. I’m not reviewing that here.

You can logon to the https://portal.azure.com and then go to subscriptions. Click on the subscription that you will be using and then you’ll see a lower case Guid for that subscription.

Available Providers and Capabilities

Not everything is available now, but, you can do a GET request as follows to see what sub-capabilities within that Resource Provider is available.

GET https://management.azure.com/subscriptions/<subscriptionId>/providers?api-version=2015-01-01

Authorization: Bearer <token>

You can take a look at the results from 1 of my subscriptions here:

https://gist.github.com/cicorias/604286f96c833f246a37

Resource Provider – Microsoft

From the response, let’s look at the Virtual Network provider and it’s manageable resources:

            "id": "/subscriptions/<subscriptionId>/providers/Microsoft.ClassicNetwork",
            "namespace": "Microsoft.ClassicNetwork",
            "resourceTypes": [
                {
                    "resourceType": "virtualNetworks",
                    "locations": [
                        "East US",
                        "East US 2",
                        "West US",
                        "North Central US (Stage)"
                    ],
                    "apiVersions": [
                        "2014-06-01",
                        "2014-01-01"
                    ]
                },
                {
                    "resourceType": "reservedIps",
                    "locations": [
                        "East Asia",
                    ],
                    "apiVersions": [
                        "2014-06-01",
                        "2014-01-01"
                    ]
                },
                {
                    "resourceType": "quotas",
                    "locations": [],
                    "apiVersions": [
                        "2014-06-01",
                        "2014-01-01"
                    ]
                },
                {
                    "resourceType": "gatewaySupportedDevices",
                    "locations": [],
                    "apiVersions": [
                        "2014-06-01",
                        "2014-01-01"
                    ]
                }
            ],
            "registrationState": "Registered"
        },

 

Within the ‘resourceTypes’ array, we can see that ‘virtualNetworks’ is available.

Updating – first review an existing VNET

Resource Manager is in early preview; thus, documentation is very limited. However, this is REST – so, the conventions of REST (for the HTTP verbs) and the shape of the JSON for updating can be somewhat determined through reviewing existing resources.

{
    "value": [
        {
            "properties": {
                "provisioningState": "Succeeded",
                "status": "Created",
                "siteId": "<siteId>",
                "inUse": false,
                "addressSpace": {
                    "addressPrefixes": [
                        "10.1.0.0/16"
                    ]
                },
                "subnets": [
                    {
                        "name": "Subnet-1",
                        "addressPrefix": "10.1.0.0/24"
                    }
                ]
            },
            "id": "/subscriptions/<subscriptionId>/resourceGroups/demo2/providers/Microsoft.ClassicNetwork/virtualNetworks/myVnet",
            "name": "myVnet",
            "type": "Microsoft.ClassicNetwork/virtualNetworks",
            "location": "eastus2"
        }
    ]
}

 

From the above, you can see the shape of the VNET resource, and also take note of the ‘id’ property as it illustrates the existence of the VNET within the resource group – here ‘demo2’.  Also note that the URI has the Resource name on the URL itself – this will be important when we PUT a new VNET.

Create a Resource Group

Let’s first create a new Resource Group using a PUT

PUT
https://management.azure.com/subscriptions/<subscriptionId>/resourceGroups/demo2?api-version=2015-01-01

Content-Type: application/json
Authorization:Bearer <token>

{
"name": "demo2",
"location": "eastus2",
}

 

This should give you a HTTP 201 – Created response.

newrg

 

Creating a VNET

If you saw above, the shape of the VNET resource has a set of properties.  The REST call is shaped as follows:

 

https://management.azure.com/subscriptions/<subscriptionId>/resourceGroups/demo2/providers/Microsoft.ClassicNetwork/virtualNetworks/myVnet?api-version=2014-06-01

Authorization: Bearer <token>
Content-Type: application/json
{
	"name": "myVnet",
	"type": "Microsoft.ClassicNetwork/virtualNetworks",
	"location": "eastus2",
	"properties": {
        "addressSpace": {
            "addressPrefixes": [
                "10.1.0.0/16"
            ]
        },
        "subnets": [
            {
                "name": "Subnet-1",
                "addressPrefix": "10.1.0.0/24"
            }
        ]
    }
}

 

For this VNET – called ‘myVnet’ under the ‘demo2’ resource group, I’ll be using the 10.1.0.0/16 address space (CIDR format) along with defining a single subnet – called ‘Subnet-1’ that is a segment 10.1.0.0/24.

Again, once this runs, you receive a HTTP 201 – Created if all is OK.

SNAGHTMLd27cd3

 

Now, you an switch back to the Portal to take a look at your VNET and review the settings.

 

image

 

NOTE: I want to stress again that not all aspects of each service within Azure is available today through Resource Manager. It is still in preview and as capabilities are added they will appear under the various /providers that are associated with your subscriptions.

Registered Resource Providers

One last note, review the /providers result and identify IF your subscription is even “Registered” for that resource provider. For my subscription as an example, the status is as follows:

https://management.azure.com/subscriptions/<subscriptionId>/providers?api-version=2015-01-01

providers/microsoft.batch
providers/microsoft.cache
providers/Microsoft.DataFactory
providers/Microsoft.DocumentDb
providers/Microsoft.Insights
providers/Microsoft.KeyVault
providers/Microsoft.OperationalInsights
providers/Microsoft.Search
providers/Microsoft.StreamAnalytics
providers/successbricks.cleardb
providers/Microsoft.ADHybridHealthService
providers/Microsoft.Authorization
/providers/Microsoft.Features
providers/Microsoft.Resources
providers/Microsoft.Scheduler
providers/Microsoft.Sql
providers/microsoft.visualstudio
providers/Microsoft.Web",
            

Classic:
providers/Microsoft.ClassicCompute
providers/Microsoft.ClassicNetwork
providers/Microsoft.ClassicStorage


Not registered:
providers/Microsoft.ApiManagement
providers/Microsoft.BizTalkServices
providers/Microsoft.IntelligentSystems
providers/microsoft.support
providers/NewRelic.APM

 

Resource Provider Registration

For registering a subscription with a Resource provider, check the Azure Resource Manager REST API Reference: https://msdn.microsoft.com/en-us/library/azure/dn790548.aspx

Azure Resource Manager – Adding and Assigning Certificates to a Website

Overview

This post is going to cover working with Azure Resource Manager using the REST interfaces [1] and specifically the “Microsoft.Web/sites” and “Microsoft.Web/certificates” providers.

You can review the list of Resource Providers by issuing an authenticated REST call to the Uri below, replacing {subscriptionId} with your tenant id.

https://management.azure.com/subscriptions/{subscriptionId}/providers?api-version=2015-0101 [2]

For this sample, I’m going to make use of the Active Directory Authentication Library for .NET – primarily to make the REST calls for acquiring an Access Token [3]. You don’t have to use these libraries, but for this sample and to abbreviate the token dance with AAD, I’m using them.

It’s important to note that Certificates are now part of the Resource Group itself, and can be assigned to multiple web sites within that Resource Group.

Basic Steps

The basic steps for adding a certificate and assigning it to an Azure Website are as follows.

Note: All of these preparation steps can be done via script or REST calls as well; this sample is just demonstrating certificate upload and assignment to an existing Azure Web Site that already has DNS names (custom) assigned to them. You will also incur additional charges for the custom domain and SSL as warned during the portal method – you will not see warnings via code. Please review pricing information to understand the impact.

Preparation

1. Using an AAD credential that is part of the AAD Domain that the Resource Group is part of – for this example, I add a credential for the AAD user store.

2. Creation of an Application in the AAD Domain for the Resource Group

3. Assigning permissions to the credential for the Resource Group via RBAC

4. Have a Web site running already with custom DNS names already assigned; this will be in a Resource Group that is protected by Role Based Access Control (RBAC)

5. Creation of a SSL Certificate – for this I used ‘makecert.exe’ and created a wildcard certificate

Uploading and Assigning Certificate

6. Make a call to the /certificates resource provider to ‘ADD (PUT)’ a new Certificate to the Resource Group

7. Make a call to the /sites resource provider to ‘Update (PUT)’ the assignment of the cer5iridate to the DNS name

And that’s it. So, for steps 1 – 5, let’s review some of the setup steps:

1. Adding an AAD Credential for this sample – since we’re going to use Username / Password authentication to acquire a token, I’ll need the Password. This will require an initial sign on. The easiest way to do this is once you create a user, just login via a private browser sessions with that credential to https://portal.azure.com or https://manage.windowsazure.com

2. Creation of an Application in your AAD domain – same one where the credential is.

1) Sign in to the Azure management portal https://manage.windowsazure.com.

2) Click on Active Directory in the left hand nav.

3) Click the directory tenant where you wish to register the sample application.

4) Click the Applications tab.

5) In the drawer, click Add.

6) Click "Add an application my organization is developing".

7) Enter a friendly name for the application, for example "AADDemoCertificates", select "Native Client Application", and click next.

8) For the sign-on URL, enter the base URL for the sample, you’ll need this for the sample later: https://localhost:8080/login

After done, we need to retrieve the ClientID; for that app:

9) In the Azure portal, click configure

10) Retrieve the ClientID and save it

3. Next, in the “New Portal” - https://portal.azure.com we need to assign the user permissions to the respective Resource Group

1) Click Browse

2) Find “Resource Groups”

3) Locate the Resource Group that the Azure Web Site is in that we will be assigning the certificate to.

4) In the “Blade” go to the bottom tile labeled “Access” and click on “Owner”

5) Another blade opens showing any existing Owners

6) Click on “+ Add”

7) You should see existing Users in the domain; find the User or enter the ‘user@domain’ in the Search box

8) Select that user, then click “Select” at the bottom of the blade – this will add that user to the group

4. Looking at your Web site in Azure – ensure and jot down:

a. Name of the Resource Group (should be same as above step)

b. Name of the Site

c. DNS names – add a custom DNS domain – see the Azure portal for instructions

i. This is under “Custom Domains and SSL” – you have to choose a “Basic” plan or higher for Custom Domains and SSL

5. For making a self-signed cert, these are the commands I used:

REM make the root
makecert -n "CN=Development Test Authority" -cy authority -a sha1 -sv "DevelopmentTestAuthority.pvk" -r "DevelopmentTestAuthority.cer"

REM makecert -n "CN=*.cicoriadev.net" -ic "DevelopmentTestAuthority.cer" -iv "DevelopmentTestAuthority.pvk" -a sha1 -sky exchange -pe -sv "wildcard.cicoriadevnet.pvk" "wildcard.cicoriadevnet.cer"

makecert -n "CN=*.cicoriadev.net" -ic "DevelopmentTestAuthority.cer" -iv "DevelopmentTestAuthority.pvk" -a sha1 -sky exchange -pe -sv "wildcard.cicoriadevnet.pvk" "wildcard.cicoriadevnet.cer"

pvk2pfx -pvk "wildcard.cicoriadevnet.pvk" -spc "wildcard.cicoriadevnet.cer" -pfx "wildcard.cicoriadevnet.pfx" -pi pass@word1

Sample Code

For the sample code, you’ll see a call via the AADL library to use a Username & Password for obtaining an AuthenticationResult object – which contains an AccessToken. Note that the resource URI that the token is generated for is https://management.azure.com/ .

Adding a Certificate via REST

The sample code makes use of JSON.NET and anonymous objects for creating the PUT HTTP request bodies. Here is what the shape of the PUT request looks like for ‘adding’ a certificate to a Resource Group.

Request

PUT https://management.azure.com/subscriptions/{subscriptionId}/
   resourceGroups/{resourceGroupName/providers/
   Microsoft.Web/certificates/{resourceName}?api-version=2014-11-01

Content-Type: application/json
Authorization: Bearer {accessToken}
Content-Length: 3675

{
  "name": "{resourceName}",
  "type": "Microsoft.Web/certificates",
  "location": "{location}",
  "properties" : {
    "pfxBlob": {base64ByteArrayOfPfx},
    "password": "pass@word1"
   }
}

Replacement Parameters

subscriptionId – this is the subscription that the Resource Group (and it’s web site) is contained within

resourceGroupName – this is the name of the resource group

resourceName – this is what the friendly name of the certificate WILL be – this is a PUT request, but the resourceName must be on the Uri in addition to the json request body – and they must match

accessToken – this is the token obtained from the AADL library call

location – for my sample, I used “East US” – which is the Azure Region. Note that not all Resource Providers are available or registered for your subscription in all regions. Review the response from the /providers REST call prior in this post to see what is available for each region, along with the ‘api-version’ that is supported.

base64ByteArrayOfPfx – this the pfx file in bytes, then converted to base64

password- this is the password of the pfx file that was used during pfx creation

Response

The HTTP Response code is a 200 – this a content body that dumps out the certificate information. I’ve abbreviated most of the response in the following. Make note of the thumbprint if you haven’t already as this is what the assignment will use, along with the Site name, to bind the SSL certificate to the web site.

{
    "id": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/certificates/{resourceName}",
    "name": "{resourceName}",
    "type": "Microsoft.Web/certificates",
    "location": "{location}",
    "properties": {
        "friendlyName": "",
        "subjectName": "*.cicoriadev.net",
        "hostNames": [
            "*.cicoriadev.net"
        ],
        "pfxBlob": null,
        "siteName": null,
        "selfLink": null,
        "issuer": "Development Test Authority",
        "issueDate": "2015-01-27T22:34:57+00:00",
        "expirationDate": "2039-12-31T23:59:59+00:00",
        "thumbprint": "DEA5DED6142EDECCDF952F4D431ED772F01D22D1",
    }
}

Assigning a Certificate via REST

For the assignment, we make use of the Resource Manager “Microsoft.Web/sites”.

Request

PUT https://management.azure.com/subscriptions/{subscriptionId}/
   resourceGroups/{resourceGroupName/providers/
   Microsoft.Web/sites/{resourceName}?api-version=2014-11-01


Content-Type: application/json
Authorization: Bearer {accessToken}
Content-Length: 567

{
  "name": "{resourceName}",
  "type": "Microsoft.Web/sites",
  "location": "{location}",
  "properties" : {
	  "hostNameSslStates": [
    {
      "name": "azw.cicoriadev.net",
      "sslState": 1,
      "thumbprint": "DEA5DED6142EDECCDF952F4D431ED772F01D22D1",
      "toUpdate": 1,
    }
  ]
}
}

Replacement Parameters

subscriptionId – this is the subscription that the Resource Group (and it’s web site) is contained within

resourceGroupName – this is the name of the resource group

resourceName – this is what the friendly name of the certificate WILL be – this is a PUT request, but the resourceName must be on the Uri in addition to the json request body – and they must match

accessToken – this is the token obtained from the AADL library call

location – for my sample, I used “East US” – which is the Azure Region. Note that not all Resource Providers are available or registered for your subscription in all regions. Review the response from the /providers REST call prior in this post to see what is available for each region, along with the ‘api-version’ that is supported.

Thumbprint – this would be the thumbprint known for that certificate in Azure – again, it should always be the same locally, but if you have any issues assigning, this must match what Azure knows in /certificates.

Response

The Response should show you the chosen site DNS name with the thumbprint associated, similar to the following:

        "hostNameSslStates": [
            {
                "name": "azw.cicoriadev.net",
                "sslState": 1,
                "ipBasedSslResult": null,
                "virtualIP": null,
                "thumbprint": "DEA5DED6142EDECCDF952F4D431ED772F01D22D1",
                "toUpdate": null,
                "toUpdateIpBasedSsl": null,
                "ipBasedSslState": 0,
                "hostType": 0
            },

 

 

Sample Solution and Source Code

The source code is located on github: http://bit.ly/azrmsamples - or direct https://github.com/cicorias/AzureResourceManagerSamples

[1] Azure Resource Manager REST API Reference https://msdn.microsoft.com/en-us/library/azure/dn790568.aspx

[2] Listing All Resource Providers https://msdn.microsoft.com/en-us/library/azure/dn790524.aspx

[3] Active Directory Authentication Library for .NET – github https://github.com/AzureAD/azure-activedirectory-library-for-dotnet

Running ASP.NET 5 applications in Linux Containers with Docker

Ahmet’s (@ahmetalpbalkan) posted an official walkthrough on getting ASP.NET 5 running under Docker in Linux.  This takes you from a Docker client running on a Linux or OS X machine against an Docker image in Azure…

Take a look -

http://blogs.msdn.com/b/webdev/archive/2015/01/14/running-asp-net-5-applications-in-linux-containers-with-docker.aspx

PDF Search Handler fix

Adobe keeps breaking my PDF search.  WHY WHY WHY…

 

reg ADD HKCR\.pdf\PersistentHandler /d {1AA9BF05-9A97-48c1-BA28-D9DCE795E93C} /f

More Posts Next page »