Thursday, June 14, 2018

Set-AzureRmAppServicePlan throws “Long running operation failed with status 'Conflict'” error

I was trying to go from a standard tier to the free tier and I got a conflict error.

There are many reasons that you might get this error and they are typically related to some functionality not available in the free tier that you enabled in paid tiers. To figure out why, go into your App Service Plan and look at your activity log. You should an entry for operation name: “Update hosting plan” with a status of failed. If you look at the “Json” and search for “statusMessage”, you should be able to figure out why.

In my case the error was caused by the fact that I was using a hybrid connection.

"Cannot change to the target SKU 'Free' because the Hybrid Connections count will exceed the new limit of '0'\"

Wednesday, June 13, 2018

Connect to Azure RM using a Service Principal

$applicationId = "Guid"
$tenantId = "Guid"
$subscriptiondId = "Guid"
$sharedSecret = "SharedSecretKey"

#convert to securestring
$secpasswd = ConvertTo-SecureString $sharedSecret -AsPlainText –Force

#create credential object
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $applicationId, $secpasswd

#connect to Azure
Connect-AzureRmAccount -ServicePrincipal -Credential $credential -TenantId $tenantId -SubscriptionId $subscriptionId

#test it!
Get-AzureRmResourceGroup

Tuesday, May 22, 2018

Creating an Azure Service Principal for Visual Studio

When you need to deploy from VSTS (VisualStudio.com) either via a build or via the release pipeline, you need a service principal that allows VSTS to access your Azure subscription. When the Azure subscription is connected directly to your VSTS account, you can use the simple version of the “New Service Endpoint” dialog. But, if the VSTS or Azure subscriptions are disconnected, then you need to use the full version of the “New Service Endpoint” dialog. This post goes into how you can manually do that:

What you need on the Azure side:

  1. Azure Active Directory instance. If you dont have one, create it. The free tier will do.
    1. After you create the AAD instance, open the AAD resource and select “Properties”. Copy the value for “Directory Id”.
  2. The Service Principal is created by creating an “App Registration”.
    1. Click on “App Registrations” and then “New Application Registration”.
    2. Enter a name for the App Registration. You need to remember this name.
    3. Leave type as “web app/API”
    4. Enter a sign-on URL (it just needs to start with http:// or https://. Doesnt matter and can be any fake URL).
    5. Open the newly created “App Registration”
    6. Copy the “Application ID” value.
    7. Click on settings.
    8. Click on Required permissions and then, “Add”
      1. Select Microsoft Visual Studio Team Services (Microsoft Visual Studio Online).
      2. The permission should be “Have full access to Visual Studio Team Services REST APIs”.
    9. Click Save.
    10. Click on Key
      1. Enter anything for “Key Description”
      2. Duration can be “Never Expirer”
      3. When you save, you will see a string value in the “Value” box. Copy and save this value (this is the client secret).
  3. Provide the service principal you created in step (2) access to your subscription.
    1. Go to your subscription in Azure portal.
    2. Choose Access Control
    3. Click Add and you can provide the SP direct access as a contributor to your subscription. Alternatively:
    4. You can provide access just to a specific Resource Group, which you can do by opening the RG and then updating the Access Control by providing access to the SP to that RG.
      1. Note: in a production or a lock down environment, I would provide access to the Service Principal either to a resource group or the resource directly. Providing access directly to the subscription, may allow anybody to deploy and create resources directly in production, which may or may not be ideal for your use-case.
    5. Also, go to the “Overview” section of your Azure Subscription and copy the “Subscription Id” and Subscription Name


In Visual Studio:

  1. Open your VSTS project.
  2. Click on the gear icon at the top and choose “Services”
  3. Click “New Service Endpoint” and then “Azure Resource Manager”
  4. At the bottom choose “use the full version of the endpoint dialog”. You should see this dialog:
    image
    1. Subscription Id: from 3.5
    2. Subscription Name: from 3.5
    3. Service Principal Client Id: from 2.6
    4. Service Principal Key: from 2.10.3
    5. Tenant Id: from 1.1

Now click on “Verify Connection” and it should come back with a value of “verified”.

Friday, May 18, 2018

Using CURL for some timing test

curl url -s --write-out "Total Time: %{time_total}  Code: %{http_code} downloadsize: %{size_download}" -o output

eg:

curl https://www.google.com -s --write-out "Total Time: %{time_total}  Code: %{http_code} downloadsize: %{size_download}" -o output

outputs: Total Time: 0.234000  Code: 200 downloadsize: 24744

Saturday, March 10, 2018

My experience with a tankless water heater

The house that I lived in had a 50 gallon storage water heater which was installed when the house was built (around 1995). In 2017, it had put in almost 22 years of service and instead of waiting for it to fail and deal with all the problems that might come with it, I decided to proactively replace it.

One of the options I wanted to investigate was replacing the old water heater with a tankless water heater, which are supposed to be more efficient in their energy usage. What I found was that the price for tank + labor was quite a bit more: $1800 for storage water heater vs $4500 for a tankless (approximately). There are lots of variables in the quotes as it depends on features, permits that you might have to pull and installation location. Its normally cheaper to replace the storage water heater with another storage water heater, as it typically will go into the original location with very little plumbing changes. Whereas, with a tankless water heater, you need to move it to a location where you can mount it (typically a wall) and it needs venting, etc. Apart from the price of a tankless water heater, something else that people complain about is the amount of time it takes to get hot water out of the faucet.

Having looked at my 2 major options, I opted to go with a tankless water, and the main reason was to get more space in my small basement. I dont think the energy savings will justify the price difference (at least in the short run of 5 to 10 years), but I think the extra space I get when I finish my basement will definitely make it worth it.

Water-Heater-Old

Water-Heater-new

The above pictures show the old storage water heater and the new tankless water heater and it shows the amount of space I saved by going to a tankless system thats mounted on the wall.

There are many tankless water heater models: Rheem, Navien and Rinnai, just to name a few. I really liked the Navien for its looks, but I settled on the Rinnai RUR98in. RUR98in is a 9.8 gallon per minute (i.e. it can heat by a certain amount 9.8 gallons of water per minute. A RUR80 model would be able to heat by the same amount, 8 gallons of water per minute). Rinnai has a nice tool on their site that can recommend a tankless water heater model for your home: Residential Product Finder. The IN stands for indoor natural gas. The R in the RUR, stands for recirculation and what that means is that this water heater comes with an inbuilt recirculation pump (that Rinnai calls ThermaCirc360 technology).

Water-Heater-new-2

The ReCirc technology, requires a special bypass valve to be installed at one of your farthest sinks. Once you have the by-pass valve installed, you can set up the water heater to automatically turn on at predetermined times and it will begin circulating water and pre-heating it, so that you dont have to wait for hot-water, which is the biggest complaint that people have with tankless water heaters. In my experience, with the old storage water heater, it used to take about 1 minute until hot water began flowing from the faucet in the mornings (at the sink that was the farthest from the water heater). With the tankless water heater and recirc mode turned off, I find that it now takes about 2 minutes before hot-water flows from the faucet (I have high efficiency faucets, which means 1.5 gallons per minute). Obviously, with the recirc mode turned on, there is no waiting for hot water ( maybe 15 to 20 seconds). One issue I have with the Rinnai RUR98in, is that you get to only control the time at which you turn on the recirc pump in 1 hour increments. This seems inefficent and I wish it was controllable at a finer grain of time (15 minutes or 30 minutes). So, for now, I have the recirc pump turned off as I am trying to figure out the difference in energy consumption between using the Recirc mode and not using it. Something else to note is that Rinnai has multiple ways to turn on the Recirc pump (wifi, sensors, etc). These dont come standard with the tank and have to be bought separately.

Installation Experience

I got estimates from multiple companies. Some were proper plumbing companies, others were local plumbers. The price difference between 2 groups was on average about $750 (local plumber being cheaper). With both groups, I requested that the work be done with all the proper permits being pulled. I choose to use a local plumber, not only because they were slightly cheaper, but because I wanted to support somebody that was local and they came with good recommendations from the community. I bought the water heater personally from Lowes, as I was able to put it on my credit card, which worked out well for me. This option didnt turn out so well for me, as the plumber was very busy and the entire process from when I bought the tank to when it got installed almost took 4 months. So your mileage might vary. Something I would advice on is that, which ever option you pick, you must ask for a permit to be pulled. The main reason for this is, this is a gas appliance and you want all the safety measures to be taken during installation. Again, this is where my experience was not the best: if you look closely at my tankless water installation, there is no valve on the gas in-line to the tank, this is required for safety reasons and a building inspector would not pass the permit until this is installed. Another piece, that I think is missing is an expansion tank that should be put on the water-in line. Now, I need to find a different plumber who can remediate these issues and finish up the permit process. But apart from those 2 issues (that I know of), the local plumber did a good job of installation and everything is nice and clean and is still working 3 months since it went online.

I also, installed a Explosive Gas and Carbon Monoxide Alarm in the basement, just to be sure that there were no leaks, etc (amazon link).

I will continue to post here any future updates I have with my experience with my tankless water heater.

Here are some extremely useful videos regarding Tankless water heaters:

Flushing/Descalling

Tankless water heaters should last a long time (20+ years as opposed to 10 years for modern storage water heaters). But there is maintenance that one needs to do. Approximately every year or 2, you need to perform a flush to descale the inside. Here is a video that shows you how this is done:

Wednesday, August 02, 2017

Dynamics CRM–Retrieving optionset values from the database

SELECT o.name,
        a.Value,
        l.label
FROM AttributePicklistValueView a
      JOIN OptionSetView o ON o.OptionSetId = a.OptionSetId
      JOIN LocalizedLabelView l ON l.ObjectId = a.AttributePicklistValueId
WHERE o.Name = ‘optionSetName';

Monday, July 17, 2017

Dynamics CRM–Where is Status transition data stored in the DB

I was curious as to how status transition data is stored in the database for CRM and here is what I found:

The data is stored in the AttributePicklistValue table in the field “TransitionData” as string that represents xml

The XML looks like this:

<allowedtransitions xmlns="http://schemas.microsoft.com/crm/2009/WebServices">
     <allowedtransition sourcestatusid="803000000" tostatusid="803000001" />
     <allowedtransition sourcestatusid="803000000" tostatusid="803000002" />
     <allowedtransition sourcestatusid="803000000" tostatusid="2" />
</allowedtransitions>

Here is some SQL that allows you to pull the data.

SELECT DISTINCT
        e.LogicalName,
        a.LogicalName,
        sm.Value,
        apv.State_Status_Value,
        apv.TransitionData
FROM Entity e
      JOIN Attribute a ON a.EntityId = e.EntityId
      JOIN AttributePicklistValue apv ON apv.OptionSetId = a.OptionSetId
      JOIN StringMap sm ON sm.ObjectTypeCode = e.ObjectTypeCode
                           AND sm.AttributeValue = apv.value
WHERE LEN(apv.TransitionData) > 0
ORDER BY e.LogicalName,
          a.LogicalName,
          sm.Value,
          apv.State_Status_Value,
          apv.TransitionData;

Here is a query that can pull back the OptionSets and their corresponding values

SELECT o.Name,
        v.Value,
        l.Label
FROM AttributePicklistValueAsIfPublishedView v
      INNER JOIN LocalizedLabelAsIfPublishedView l ON v.AttributePicklistValueId = l.ObjectId
                                                      AND l.ObjectColumnName = 'DisplayName'
      INNER JOIN OptionSetAsIfPublishedView o ON v.OptionSetId = o.OptionSetId
WHERE o.name LIKE 'opportunity_%'
ORDER BY o.Name;


Finally, the correct way to get at this data is via the service and here is the sample code: Retrieve valid status transitions https://msdn.microsoft.com/en-us/library/dn689060.aspx

Friday, July 14, 2017

Debugging dynamic scripts injected into CRM Ribbon

If you need to debug javascript code thats invoked via the ribbon and the javascript is getting injected dynamically into the page, then you need a way to stop at a breakpoint.

One thing you can do is add a line at the top of your script with the following code:
debbugger;

This will cause the debugger to stop at that line and you can then work your way through the file.

But an even cooler way to do it (when using Google Chrome) is to add the following line at the very bottom:

//# sourceURL=dynamicScript.js

Now, when the code gets injected into Chrome, you will find it in the “Sources” tab.

image

Notes:
You can name the file anything, and so if you have multiple points of injection, you can name each one differently.
Your breakpoints are preserved across reloads of the page (which is unlike using the debugger statement).
You need to look under the (no domain) header for the file.

And when using the log, use this function:

function logToConsole(message) { if (typeof console != 'undefined') { console.log(message); } }

Note: the reason I dont override log function is because I want to play nice with other JS scripts that maybe getting loaded within CRM. You need to use this especially in IE, as when the debugger is not shown, the console object can be null.

Saturday, July 08, 2017

Taking apart the Ryobi Expand-it string trimmer head

For some reason my Ryobi Expand-it electric trimmer head got stuck and would no longer spool out its line. I tried to take apart the head, but unfortunately, the instructions were not very clear.

It turns out that you turn the red knob right (in the same direction as the “Wind” arrows), when you have the bottom of the trimmer head facing you.

image

And obviously to tighten it, you turn it to the left. (Its the opposite of the righty tighty and lefty loosey rule!)

Also, I found that its a lot easier to refill the reel, once you take apart the head.

Thursday, June 29, 2017

Setting up CRM certificate on an environment restored from CRM Online

Download the certificate from your online instance (Settings >> Customizations >> Developer Resources)

image

Install the certificate into the user certificates:

Search for: Manager User Certificates
image

Right click on Personal >> Certificates and choose Import.

Browse and select the certificate you downloaded from CRM online

Right click on the certificate “*.crm.dynamics.com” and choose All Tasks >> Export

image

Choose “Base-64 encoded X.509 (.cer) as the format and click next and export it to a file.

Attach the certificate to CRM.

Open a powershell command window in Admin mode.

Add the CRM powershell snamp in by running: Add-PSSnapin Microsoft.Crm.PowerShell

Next install the certificate by running (replacing the path to the data file with the file from the step where you exported the base-64 file above:

Set-CrmCertificate -certificatetype appfabricissuer -StoreName My -StoreLocation LocalMachine -StoreFindType FindBySubjectDistinguishedName -DataFile C:\base64-crm.dynamics.com.cer

Finally validate that it worked by running: Get-CrmCertificate

More info:

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