Showing posts with label Azure. Show all posts
Showing posts with label Azure. Show all posts

0 comments

Azure VPN Gateway Sizes

Published on Friday, September 4, 2015 in

One of the things I’ve been finding very confusing is the VPN Gateway sizing. Especially the mismatch between the pricing table and what the systems show you. Here’s the technical information:

image

Source: Azure.com: About VPN Gateways The same table is more or less available on the pricing page as well. There you can clearly see that the price difference is real. Pricing goes from 0,0304€ over 0,1603€ to 0,4133€/GW hour. As a VPN Gateway runs 24/7 this might have an impact on your bill. Pricing Source From a technical point of view both basic and standard offer the same features/performance for NON Express Route VPNs.

Conclusion #1: If you don’t need Express Route, there’s no difference between Standard and Basic.

Now what was bothering me: in many blogs/documentation people explain how to change the Gateway SKU. They always mention Default or HighPerformance. When you create a Gateway from the “old” portal this is how the resulting Gateway looks in PowerShell:

2015-09-03_9-31-57

As you can see the GatewaySKU is Default. Now it might be just me, but how the hell on earth are we supposed to know what value default is? Luckily there’s a place like Azure Advisors on Yammer where get to ask questions like this. The Microsoft PM’s do a great job of helping is out and gathering feedback on various topics. The answer I got there is: Default is the same as Basic. Which does make sense in a way as we initially had either Basic or HighPerformance. But it does suck a bit that instead of using a default value they are setting default as a value. If you catch my drift…

Here’s the PowerShell cmdlet reference for the New-AzureVNetGateway cmdlet There you can see that the PowerShell cmdlet takes Basic, Standard and HighPerformance as parameters for the GatewaySKU parameter.

Conclusion #2: Default SKU == Basic SKU

Another area that might confuse you is how the new Portal displays the Gateway sizes. For all types (basic, standard and high performance) a size of Small is shown. Lucian also mentions this on his blog: blog.kloud.com: Azure VNET gateway: basic, standard and high performance But I must admit that I haven’t looked into this. I primarily cared about sku vs pricing.

0 comments

Azure Management Portal: Properly Remove Co-Adminstrators Permissions

Published on Wednesday, August 26, 2015 in ,

Something I’ve noticed for a while now: whenever I perform an Add-AzureAccount I see more subscriptions being returned than I’d expect. The list I have to choose from in the old portal (manage.windowsazure.com) is definitely not showing that much subscriptions. The new portal (portal.azure.com) displays also more subscriptions than I’d expect. The problem to sort those out is that many of those belong to subscriptions I’ve once have gotten access to, but now I no longer have. Either from customers or test subscriptions from colleagues.

For test purpose subscriptions I don’t really care whether people take my permissions away or not. But for production subscriptions I feel more at ease when I don’t have any permissions I don’t need anyway. Lately a customer mentioned my permissions were taken away, but I still saw their entry in the new Portal. Hmm, odd! Here’s how that’s possible:

First off, Initially I was granted access on my Microsoft Account (invisibal_at_gmail.com) through the old Portal:

image

Now I could manage that subscription through both old and new Portal.

image

And as I also worked for another “customer”, I had multiple subscriptions to manage, Setspn and RealDolmen Azure POC:

image

After my work was done, the customer removed me from the list of Administrators of the Setspn subscription.

subvs

su2

Now when I log in to the old Portal (manage.windowsazure.com) I’ll only see the other subscription.

image

However, when I log on to the new Portal, it’s still there!

image

Trying to show “all resources” of the Setspn subscription shows nothing. As expected.

image

The same is observed through PowerShell:

image

Now the only solution I could think is to also remove the live ID from the Azure Active Directory the subscription is linked to.

Capture3

Captur4e

After removing the user from the Azure AD, you’ll no longer see the subscription in the new Portal:

image

Well as you can see, not exactly… Typically when you try to reproduce things for screenshots, it doesn’t happen or it goes wrong. This is a case “it goes wrong”.  I tried a few times, but the GUID (belonging to the Azure AD I was part of) kept appearing… All I can say whenever the customer actually removed me from their Azure AD it got properly removed from my Azure Portal UI and PowerShell experience….

Conclusion:

I’m pretty sure the only reason you keeping seeing the entry in the new Portal is because you still have the User role assigned in the Azure Active Directory instance. So in a way you’re not really seeing the subscription, but rather the Azure Active Directory instance. But the issue remains the same, it clutters your PowerShell (get-AzureSubscription) and Portal UI experience. So whenever someone takes your co-administrator permissions away, ask them to also remove you from the Azure AD instance.

10 comments

Azure Quick Tip: Block or Allow ICMP using Network Security Groups

Published on Tuesday, August 18, 2015 in ,

For a while now Azure allows administrators to restrict network communications between virtual machines in Azure. Restrictions can be configured through the use of Network Security Groups (NSGs). Those can be linked to both subnets or virtual machines. Check the following link if you want some more background information: https://azure.microsoft.com/en-us/documentation/articles/virtual-networks-nsg/

A NSG always contains some default rules. By default all outbound traffic is allowed, and inbound from other subnets (not the internet) is also allowed. Typically if you ping between VM’s on different subnets (same VNET) you’ll see that the machines respond as expected.

Now what if you want to restrict traffic between subnets but still allow ICMP? ICMP is great for troubleshooting connectivity. Set-AzureNetworkSecurityRule allows you to provide the protocol parameter. In a typical firewall scenario this value would contain TCP, UDP, ICMP, … Ping uses ICMP which is neither TCP or UDP… Azure only seem to allow TCP, UDP and * for the protocol:

image

Now how can we block all traffic but allow ICMP? Simple, by explicitly denying UDP and TCP but allowing *. In this example I included the allow rule, but it should be covered by the default rules anyhow.

001
002
003
004
005
006

#allow ping, block UDP/TCP
Get-AzureNetworkSecurityGroup -name "NSG-1" | Set-AzureNetworkSecurityRule -Name BlockTCP -Type Inbound -Priority 40000 -Action Deny -SourceAddressPrefix "*"  -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange '*' -Protocol "TCP"

Get-AzureNetworkSecurityGroup -name "NSG-1" | Set-AzureNetworkSecurityRule -Name BlockUDP -Type Inbound -Priority 40001 -Action Deny -SourceAddressPrefix "*"  -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange '*' -Protocol "UDP"

Get-AzureNetworkSecurityGroup -name "NSG-1" | Set-AzureNetworkSecurityRule -Name AllowPing -Type Inbound -Priority 40002 -Action Allow -SourceAddressPrefix "*"  -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange '*' -Protocol "*"

If we want to work the other way round: allow UDP/TCP but block ICMP we can turn the logic around:

001
002
003
004
005
006

#block ping, allow UDP/TCP
Get-AzureNetworkSecurityGroup -name "NSG-1" | Set-AzureNetworkSecurityRule -Name AllowTCP -Type Inbound -Priority 40000 -Action Allow -SourceAddressPrefix "*"  -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange '*' -Protocol "TCP"

Get-AzureNetworkSecurityGroup -name "NSG-1" | Set-AzureNetworkSecurityRule -Name AllowUDP -Type Inbound -Priority 40001 -Action Allow -SourceAddressPrefix "*"  -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange '*' -Protocol "UDP"

Get-AzureNetworkSecurityGroup -name "NSG-1" | Set-AzureNetworkSecurityRule -Name BlockPing -Type Inbound -Priority 40002 -Action Deny -SourceAddressPrefix "*"  -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange '*' -Protocol "*"

The source/destination information is pretty open as I use * for those, but that’s just an example here. It’s up to you to decide for which ranges to apply this. And you might probably open up some additional ports for actual traffic to be allowed. The above logic is also mentioned in the information I linked at the beginning of the article:

The current NSG rules only allow for protocols ‘TCP’ or ‘UDP’. There is not a specific tag for ‘ICMP’. However, ICMP traffic is allowed within a Virtual Network by default through the Inbound VNet rules that allow traffic from/to any port and protocol ‘*’ within the VNet.

Kudos to my colleague Nichola (http://www.vnic.be) for taking the time to verify this.

0 comments

Quick Tips: Azure: Where did my Public IP go?

Published on Friday, July 3, 2015 in

Over the past few months I’ve been working more and more on Azure and here is a small tip I’d like to share. I’ve seen various customers that are not aware about the following:

Whenever you start the first VM in a cloud service, the cloud service gets a public IP from the Azure infrastructure. Suppose you have an IIS server in it and you want to expose it to the internet, you might create a 443/80 endpoint for it. In order to point users to it you’ll probably rather want http://web.contoso.com than http://contosoweb.cloudapp.net Chances are you’ll start fiddling around in your public DNS zone. If you want to achieve this, there’s some options for you:

  • Create a CNAME (alias) record web.contoso.com –> contosoweb.cloudapp.net
  • Creata an A record web.contoso.com –> public IP of the cloud service

Which option you prefer is up to you, but watch out with the last option! By default cloud services get a dynamic public IP. Once all VM’s are stopped (deallocated) in the cloud service, the cloud service stops as well and the public IP is released. Whenever you start your VM’s again, they’ll be no longer reachable on that old public IP! There’s an option to reserve your IP though, you can even reserve 5 for free with each subscription. For pricing details: http://azure.microsoft.com/en-us/pricing/details/ip-addresses/

Some relevant screenshots:

Before: “Virtual IP-Address” > Dynamic

Dyn

After: “Virtual IP-Address” > Reserved

dyn2

Assigning an IP is pretty straight forward, first we create one:

2

Then we reserve it:

3

Note: the reserved IP will not be the same as the IP currently in use, so make sure to coordinate this with your DNS record update!

0 comments

Azure DSC and Configuration Archive Case Sensitiveness

Published on Monday, June 29, 2015 in , ,

Lately I’ve been working on my Azure Automation skills. More precisely I want to have a script that is able to create a virtual machine and creates a new Active Directory (domain controller) on it. The are several ways of doing this. One way is to create a PowerShell script that is executed through the Azure script extension. An other way is through the Desired State Configuration (DSC) extension. In my opinion the latter is the best option. DSC is really great at getting your server configured with minimal scripting. If you’re unfamiliar with DSC you might be experiencing quite some issues in the beginning. Having a working DSC extension is one thing, but getting it to work through the Azure DSC extension has it’s own challenges. Most of these so called issues have probably to do with me being at the bottom of the DSC learning curve…

A while back I wrote a simple DSC extension to get the time zone right (Working with PowerShell DSC and Azure VM’s based on Windows 2012). That simple example went pretty well. Now I wasn’t even getting my DSC script to properly download to the target system. Now how on earth could something that simple be that hard? Here’s the error I was having:

Log file location: C:\WindowsAzure\Logs\Plugins\Microsoft.Powershell.DSC\1.10.1.0\DscExtensionHandler.3.20150627-211133

VERBOSE: [2015-06-27T21:11:42] File lock does not exist: begin processing
VERBOSE: [2015-06-27T21:11:42] File
C:\Packages\Plugins\Microsoft.Powershell.DSC\1.10.1.0\bin\..\DSCWork\2-Completed.Install.dsc exists; invoking extension
handler...
VERBOSE: [2015-06-27T21:11:43] Reading handler environment from
C:\Packages\Plugins\Microsoft.Powershell.DSC\1.10.1.0\bin\..\HandlerEnvironment.json
VERBOSE: [2015-06-27T21:11:44] Reading handler settings from
C:\Packages\Plugins\Microsoft.Powershell.DSC\1.10.1.0\RuntimeSettings\3.settings
VERBOSE: [2015-06-27T21:11:47] Applying DSC configuration:
VERBOSE: [2015-06-27T21:11:47]     Sequence Number:              3
VERBOSE: [2015-06-27T21:11:47]     Configuration Package URL:   
https://thvuystoragetest.blob.core.windows.net/windows-powershell-dsc/MyDC.ps1.zip
VERBOSE: [2015-06-27T21:11:47]     ModuleSource:                
VERBOSE: [2015-06-27T21:11:47]     Configuration Module Version:
VERBOSE: [2015-06-27T21:11:47]     Configuration Container:      MyDC.ps1
VERBOSE: [2015-06-27T21:11:47]     Configuration Function:       MyDC (2 arguments)
VERBOSE: [2015-06-27T21:11:47]     Configuration Data URL:      
https://thvuystoragetest.blob.core.windows.net/windows-powershell-dsc/MyDC-69d57a1f-2522-41d7-b5ac-3b635c63ba93.psd1
VERBOSE: [2015-06-27T21:11:47]     Certificate Thumbprint:       FC89BDBF395EFC39EA3633BBDEAE9BB7AA7C475E
VERBOSE: [2015-06-27T21:11:47] Creating Working directory:
C:\Packages\Plugins\Microsoft.Powershell.DSC\1.10.1.0\bin\..\DSCWork\MyDC.ps1.3
VERBOSE: [2015-06-27T21:11:48] Downloading configuration package
VERBOSE: [2015-06-27T21:11:48] Downloading
https://thvuystoragetest.blob.core.windows.net/windows-powershell-dsc/MyDC.ps1.zip?sv=2014-02-14&sr=b&sig=k38XoVn5%2Bn5P1UIMM8q
mh9bc7YBD7Q5ZNV%2B5aqvP2xs%3D&se=2015-06-27T20%3A10%3A16Z&sp=rd to
C:\Packages\Plugins\Microsoft.Powershell.DSC\1.10.1.0\bin\..\DSCWork\MyDC.ps1.3\MyDC.ps1.zip
VERBOSE: [2015-06-27T21:11:48] An error occurred processing the configuration package; removing
C:\Packages\Plugins\Microsoft.Powershell.DSC\1.10.1.0\bin\..\DSCWork\MyDC.ps1.3
VERBOSE: [2015-06-27T21:11:48] [ERROR] An error occurred downloading the Azure Blob: Exception calling "DownloadFile" with "2"
argument(s): "The remote server returned an error: (404) Not Found."
The Set-AzureVMDscExtension cmdlet grants access to the blobs only for 1 hour; have you exceeded that interval?
VERBOSE: [2015-06-27T21:11:49] Writing handler status to C:\Packages\Plugins\Microsoft.Powershell.DSC\1.10.1.0\Status\3.status
VERBOSE: [2015-06-27T21:11:49] Removing file lock


The most interesting part:

VERBOSE: [2015-06-27T21:11:48] [ERROR] An error occurred downloading the Azure Blob: Exception calling "DownloadFile" with "2"
argument(s): "The remote server returned an error: (404) Not Found."
The Set-AzureVMDscExtension cmdlet grants access to the blobs only for 1 hour; have you exceeded that interval?

I found the following URL from the log file: https://thvuystoragetest.blob.core.windows.net/windows-powershell-dsc/MyDC.ps1.zip?sv=2014-02-14&sr=b&sig=k38XoVn5%2Bn5P1UIMM8qmh9bc7YBD7Q5ZNV%2B5aqvP2xs%3D&se=2015-06-27T20%3A10%3A16Z&sp=rd

Some googling led me to some results, but nothing relevant. I took the URL and copy pasted into a browser:

StorageContainerXMLChrome

It showed me an XML type response stating: BlobNotFound: The specified blob does not exist. By accident I used an open chrome instance as I typically use IE. If I visited this URL using IE I simply got a page not found error. That’s probably something that can be tweaked in the IE settings, but still good to know. After seeing that error page I went to the Azure management portal:

StorageContainer

I drilled down till I found my .ps1.zip file and copy pasted its URL in a notepad++ windows:

image

As you can see the only difference is the casing of “MyDC.ps1”… The URL in the log file is constructed by the Azure DSC extension. More particular by the following PowerShell lines:

001
002
003
004
005
006
007
008
009
010
011
012

$configurationArchive = "MyDC.ps1.zip"
$configurationName = "MyDC" 
$configurationData = "C:\Users\Thomas\SkyDrive\Documenten\Work\Blog\DSC\Final\myDC.psd1"

$VM = get-AzureVM -Service $svcname -name 
$vmname
$vm
 = Set-AzureVMDSCExtension -VM $vm `
    -ConfigurationArchive $configurationArchive `
    -ConfigurationName $configurationName `
    -ConfigurationArgument $configurationArguments `
-ConfigurationDataPath 
$configurationData

$vm
 | update-azurevm

Updating my $configurationArchive to myDC.ps1.zip was all I needed to do to get this baby running.

Summary

Whenever creating storage accounts, containers or blobs on them, make sure to watch out for case sensitiveness. In my opinion using an all lower case approach might be the best way forward.

0 comments

Azure Billing Changes

Published on Friday, June 26, 2015 in

A bit less technical for once, but a few days ago I noticed several announcements for billing related changes that I though were worth mentioning. And besides that, my personal test subscription got disabled once more because I ran out of credit… So what else is there to do? ; )

Azure Billing Detailed Usage Change

Every time I talk to a customer who is new to Azure and is starting to get into IAAS, I explain how Virtual Machines are billed. Roughly there’s 4 things to take into account:

  • Compute hours: depends on the uptime/tier
  • Storage space consumed: the bigger the VM,….
  • Storage transactions: the more disk IO VM performs, ….
  • Network IO: “upload”/”download” where download is free

Now a lot of customers want to, or foresee, that they want to split the bill to the responsible department, project or another factor. Before the recent changes there were 2 ways to do this:

  • Separate subscriptions
  • Creating your VM’s on separate storage accounts/in separate cloud services

Personally I’m not too fond of the separate subscriptions idea. It will bring you overhead in terms of network connectivity and the overall picture might become more difficult to see. I’m aware that there are definitely cases where you clearly want to provide a group of people “full control” on “their” stuff and you want to be able to just send the bill of everything they use. But in many cases I feel having many subscriptions will become a PITA to manage. What if your billing scheme changes, instead of per department, you have to have a picture per application. Do you really want to tie your subscriptions to that?

Now I’m more in favor of creating VM’s in separate storage accounts and cloud services. Still not ideal if you have to restructure, but the impact should be less. Here’s how the detailed usage looked before June:

Type Unit Granularity
Networking Data Transfer In( GB) Cloud Service
Networking Data Transfer Out (GB) Cloud Service
Storage Standard IO – Page Blob/DISK (GB) Storage Account
Virtual Machines Compute Hours Cloud Service\Tier
Data Management Storage Transactions (in 10,000s) Storage Account

As you can see Cloud Service and Storage Account are really important if you want to separate our resources. Now things have changed, both Networking and Compute now include the VM name (next to the Cloud Service):

Type Unit Granularity
Networking Data Transfer In( GB) Cloud Service (VM Name)
Networking Data Transfer Out (GB) Cloud Service (VM Name)
Storage Standard IO – Page Blob/DISK (GB) Storage Account
Virtual Machines Compute Hours Cloud Service (VM Name)
Data Management Storage Transactions (in 10,000s) Storage Account

So assigning VM’s to cloud services is no longer an absolute requirement for building detailed bills. Other than that, there’s two more new fields:

  • Resource Group
  • Tags

From tags I know they are a V2 (Azure Resource Manager) feature. Resource groups are also available for V1 VMs. On my detailed usage overview the column resource group was empty. So it might be that this only will be filled in for V2 resources. Once V2 resources are commonly used we’ll be able to add one ore more tags to resources like VM’s. This will greatly benefit Azure Automation and Azure Billing! You’ll be able to specify information that can help identify the VM: e.g. Environment: Dev/Test/Acceptance/Production or Department: HR/IT/Sales or …

Enterprise Agreement: MSDN subscriptions

Something that has been available for a while: MSDN subscriptions below an Enterprise Agreement. If your company has both an Azure Agreement and your developers/IT Pro’s have an MSDN, they are allowed to have machines run at MSDN rates. These machines cannot belong to production! The advantage is pricing: Windows VM run at the price of the equivalent Linux VM and software available in the MSDN library is for free (e.g. SQL). You can configure this on the EA portal: https://ea.azure.com

image

Azure Billing API

In the pas there was an API available for the EA customers. Luckily the new Azure Usage API (MSDN) and Azure RateCard API (MSDN) or for all subscriptions! You can read more on these here: ScottGu: New Azure Billing APIs Available

Side note

It’s a common practice to shutdown VM’s that are not being used in order to save Azure credits. The less hours a VM turns, the better. One thing I overlooked this month is the cost of the Azure VNET Gateway. I had been playing with a site to site VPN (between two Azure VNets) and this resulted in two Gateways burning quite some credit. So I’d say: keen any eye on those gateways! They can cost quite a lot.

0 comments

Working with PowerShell DSC and Azure VM’s based on Windows 2012

Published on Wednesday, June 17, 2015 in ,

Mostly when I work with Azure VM’s I do the actual VM creation using Azure PowerShell cmdlets. I like how you can have some template scripts that create VM’s from beginning to end. Typically I create a static IP reservation, I join them to an AD domain, I add one or more additional disks,I add the Microsoft Antimalware extension…. When the VM is provisioned I log on and I’m pretty much ready to go. One of the things I noticed is that the Time Zone was set to UTC where I like it to be GMT+1. Obviously this only requires two clicks but I wanted this to be done for me. Now there are various approaches: either us traditional tooling like SCCM, GPO (is there a setting/registry key? ), …. or do it the Azure way. As far as Azure is concerned I could create a custom VM image or use PowerShell DSC (Desired State Configuration).

I prefer DSC over a custom image. The main reason is that I can apply these DSC customizations to whatever image from the gallery I feel like applying them. If the SharePoint team wants to take the latest SharePoint image from the gallery, I can just apply my DSC over it. If there’s a more recent Windows 2012 R2 image, I can just throw my DSC against it and I’m ready to go.

The following example shows how to apply a given DSC configuration to a VM.

001
002
003
004
005

$configurationArchive = "DSC_SetTimeZone.ps1.zip"
$configurationName = "SetTimeZone"
$VM = Get-AzureVM -ServiceName "contoso-svc" -Name "CONTOSO-SRV"
$VM = Set-AzureVMDSCExtension -VM $vm -ConfigurationArchive $configurationArchive -ConfigurationName 
$configurationName
$VM
 | update-AzureVM

Now I wont go into all of the details, but here are some things I personally ran into.

Creating and Uploading the DSC configuration archive

Initially I had some trouble wrapping my head around how to get my script to run on a target machine. I had this cool DSC script I found on the internet and tweaked it a bit:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022

#Requires -version 4.0
Configuration SetTimeZone
{
    Param
    (
        #Target nodes to apply the configuration
        [Parameter(Mandatory = $false)]
        [ValidateNotNullorEmpty()]
        [String]$SystemTimeZone="Romance Standard Time"
    )

    Import-DSCResource -ModuleName xTimeZone

    Node localhost
    {
        xTimeZone TimeZoneExample
        {
            TimeZone = $SystemTimeZone
        }
    }
}

This script depends on the xTimeZone DSC resource. As I already knew, those DSC resources, like xTimeZone, come in waves. Would my server have the latest version? Did I have to install that out of band? It seems not. All you need to do is create a configuration archive, a ZIP file, which contains both your script and the resource it depends on. The Azure cmdlets are an easy way to do this. They’ll also make sure all the dependent DSC resources are added to the package.

We got our script in c:\users\thomas\onedrive\documenten\work\blog\DSC. Some steps further I’ll get you the information where to store the DSC resources.

DSC_1

By using the following command we can create and upload the package to the “setspn” storage account:

001
002
003
004

$subscriptionID = "af2f6ce8-e4f3-abcd-abcd-34ab4ce9c7d3"
$storageAccountName = "setspn"
Set-AzureSubscription -SubscriptionId $subscriptionID -CurrentStorageAccount $storageAccountName
Publish-AzureVMDscConfiguration -ConfigurationPath C:\Users\Thomas\OneDrive\Documenten\Work\Blog\DSC\DSC_SetTimeZone.ps1

We need to execute this from an Azure PowerShell prompt. I executed this command from a Windows 8.1 machine that is running PowerShell v4.

DSC_2

It seems to be complaining that we are running this from an x86 prompt instead of an x64 prompt. But the Azure PowerhShell prompt is an x86 prompt… The error in words:

Publish-AzureVMDscConfiguration : Configuration script 'C:\Users\Thomas\SkyDrive\Documenten\Work\Blog\DSC\DSC_SetTimeZo
ne.ps1' contained parse errors:
At C:\Users\Thomas\SkyDrive\Documenten\Work\Blog\DSC\DSC_SetTimeZone.ps1:2 char:1
+ Configuration SetTimeZone
+ ~~~~~~~~~~~~~
Configuration is not supported in a Windows PowerShell x86-based console. Open a Windows PowerShell x64-based console,
and then try again.
At C:\Users\Thomas\SkyDrive\Documenten\Work\Blog\DSC\DSC_SetTimeZone.ps1:3 char:1
+ {
+ ~
Unexpected token '{' in expression or statement.
At C:\Users\Thomas\SkyDrive\Documenten\Work\Blog\DSC\DSC_SetTimeZone.ps1:21 char:1
+ }
+ ~
Unexpected token '}' in expression or statement.
At line:1 char:1

The error is quite misleading. I tried the various “DSC” cmdlets, like Get-DSCResource, and they all failed saying that the cmdlet could not be found. So it seems I needed the WMF framework to be installed. Shame on me. Here’s some explanation towards the prerequisites: TechNet Gallery: DSC Resource Kit (All Modules) Using the WMF 5.0 installer got me further.

DSC_2b

Now off to creating the package again: again an error…

DSC_3

Now it seems to complain it can’t find the DSC resources… But I installed them?! The error in words:

VERBOSE: Parsing configuration script: C:\Users\Thomas\SkyDrive\Documenten\Work\Blog\DSC\DSC_SetTimeZone.ps1
VERBOSE: Loading module from path 'C:\Program Files
(x86)\WindowsPowerShell\Modules\xTimeZoneSource\DSCResources\xTimeZone\xTimeZone.psm1'.
Publish-AzureVMDscConfiguration : Configuration script 'C:\Users\Thomas\SkyDrive\Documenten\Work\Blog\DSC\DSC_SetTimeZo
ne.ps1' contained parse errors:
At C:\Users\Thomas\SkyDrive\Documenten\Work\Blog\DSC\DSC_SetTimeZone.ps1:16 char:9
+         xTimeZone TimeZoneExample
+         ~~~~~~~~~
Undefined DSC resource 'xTimeZone'. Use Import-DSCResource to import the resource.
At line:1 char:1

After some googling I found out that the PowerShell prompt imports to module it finds in it’s PATH variable. As we are running from an x86 prompt, the folder that was loaded was different. Typically all DSC guides tell you to install DSC resources below C:\Program Files\WindowsPowerShell\Modules but in fact for the Azure PowerShell prompt you need to put them in C:\Program Files (x86)\WindowsPowerShell\Modules or you have to modify your PATH variable to include the x64 location…. I choose to copy the module to the x86 location:

DSC_3c

And all seems fine now:

DSC_4

Applying the DSC to a Windows 2012 VM

The DSC script I created worked fine on a newly install Windows 2012 R2 VM, but on a Windows 2012 the extension seemed to have troubles. Now that wasn’t supposed to happen… The good thing about the Azure DSC extension is that the logging is quite decent. Inside the VM you can find some log files in the following location: C:\WindowsAzure\Logs\Plugins\Microsoft.Powershell.DSC\1.10.1.0

The following extract comes from the DscExtensionHandler log file:

VERBOSE: [2015-05-28T21:43:17] Applying DSC configuration:
VERBOSE: [2015-05-28T21:43:17]     Sequence Number:              0
VERBOSE: [2015-05-28T21:43:17]     Configuration Package URL:   
https://setspn.blob.core.windows.net/windows-powershell-dsc/DSC_SetTimeZone.ps1.zip
VERBOSE: [2015-05-28T21:43:17]     ModuleSource:                
VERBOSE: [2015-05-28T21:43:17]     Configuration Module Version:
VERBOSE: [2015-05-28T21:43:17]     Configuration Container:      DSC_SetTimeZone.ps1
...
VERBOSE: [2015-05-28T21:44:27] [ERROR] Importing module xTimeZone failed with error - File C:\Program
Files\WindowsPowerShell\Modules\xTimeZone\DscResources\xTimeZone\xTimeZone.psm1 cannot be loaded because running scripts is
disabled on this system. For more information, see about_Execution_Policies at http://go.microsoft.com/fwlink/?LinkID=135170.

Now that’s a pretty well known message… Bummer. Seems the execution policy on the Windows 2012 machine is set to restricted. Now there’s a way around that. Scripts could be executed with the option “-executionpolicy bypass”. But we can’t control that as the DSC extension is responsible for this. Kind of a bummer. The Windows 2012 R2 image seems to have RemoteSigned as default execution policy…

Now this got me curious. Would the run PowerShell script extension also suffer from this? If it would not, I could have a small PowerShell script execute first that alters the execution policy!

001
002

Set-ExecutionPolicy remotesigned

I create a PowerShell script with this line in it. Saved it to disk and then used AzCopy to copy it a container in a storage account. Executing the script:

DSC_ExecScript

After executing I can confirm that the execution policy has changed:

ExecPol

The logging for this extension can be found here: C:\WindowsAzure\Logs\Plugins\Microsoft.Compute.CustomScriptExtension\1.4 From the log file we can see that the PowerShell script extension run scripts in a more robust way:

2015-05-28T21:36:58.7646763Z    [Info]:    HandlerSettings = ProtectedSettingsCertThumbprint: , ProtectedSettings: {}, PublicSettings: {FileUris: [https://storaccount.blob.core.windows.net/windows-powershell-dsc/test.ps1?sv=2014-02-14&sr=b&sig=eijcTn9I2kWuOPU1CK%2F9zQ3tAO1NIUrs8wT2gUE8z0o%3D&se=2015-05-29T21%3A07%3A00Z&sp=r], CommandToExecute: powershell -ExecutionPolicy Unrestricted -file test.ps1 }

As you can see this script is called while specifying the execution policy. Now we’ll be able to apply our DSC extension

DSC_ExecDSC

And the log file contents:

VERBOSE: [2015-05-29T00:00:00] Import script as new module:
C:\Packages\Plugins\Microsoft.Powershell.DSC\1.10.1.0\bin\..\DSCWork\DSC_SetTimeZone.ps1.1\DSC_SetTimeZone.ps1
...
VERBOSE: [2015-05-29T00:00:12] Executing Start-DscConfiguration...
...
VERBOSE: [2015-05-29T00:00:20] [SRV2012]: LCM:  [ Start  Set      ]
VERBOSE: [2015-05-29T00:00:22] [SRV2012]: LCM:  [ Start  Resource ]  [[xTimeZone]TimeZoneExample]
VERBOSE: [2015-05-29T00:00:22] [SRV2012]: LCM:  [ Start  Test     ]  [[xTimeZone]TimeZoneExample]
VERBOSE: [2015-05-29T00:00:22] [SRV2012]: LCM:  [ End    Test     ]  [[xTimeZone]TimeZoneExample]  in 0.1100 seconds.
...

Conclusion

Configuring the time zone using DSC might be a bit overkill. But it’s an excellent exercise to get the hang of this DSC stuff. For a good resource on DSC check this tweet from me. I myself plan to create more DSC scripts in the near future. I tear VM’s up and down all the time. I would love to have a DSC that creates me a Windows AD domain, a Microsoft Identity Manager installation, a ….

8 comments

Synchronizing Time on Azure Virtual Machines

Published on Friday, June 5, 2015 in ,

I’m currently setting up a a small Identity infrastructure on some Azure Virtual Machines for a customer. The components we’re installing consist of some domain controllers, a FIM server, a FIM GAL Sync server and an SQL server to support the FIM services. All of those are part of the CONTOSO domain. Besides the Azure virtual machines we also got two on-premises machines, also member of the CONTOSO domain. They communicate with the other CONTOSO servers across a site to site VPN with Azure.

Eventually I came to the task of verifying my time synchronization setup. Throughout the years there have been small variations in recommendations. Initially I had configured time synchronization like I always do: configure a GPO that targets specifically the PDC domain controller. This GPO configures the PDC domain controller to use an NTP server for it’s time.

Administrative Templates > System > Windows Time Service > Global Configuration Settings:

image

Set to AnnounceFlags to 5 so this domain controller advertise as a reliable time source. Besides that we also need to give a good source for the PDC domain controller:

Administrative Templates > System > Windows Time Service > Global Configuration Settings > Time Providers

image

In the above example I’m just using time.windows.com as a source and the type is set to NTP. Just for the reference, the WMI filter that tells this GPO to only apply on the PDC domain controller:

image

Typically that’s all what’s needed. Keep in mind, the above was done on a 2012 R2 based domain controller/GPMC. If you use older versions you might have other values for certain settings, on 2012 R2 they are supposed to be as per current recommendations. But that’s not the point of this post. For the above to work, you should make sure that the NTP client on ALL clients, servers and domain controllers OTHER than the PDC is set to NT5DS:

w32tm /query /configuration

image

Once the above is al set the following logic should be active:

Put simple: if you got a single domain, single forest topology:

  • The PDC domain controllers syncs from an internet/external source
  • The domain controllers sync from the PDC domain controller
  • The clients/member servers sync from A domain controller

You can verify this by executing w32tm /query /source:

On my PDC (DC001), on a DC (DC002) and on a member server (hosted in Azure):

time1

=> VM IC Time Synchronization Provider

On my DC (DC003)(hosted on premises on VMware):

time2

=> The PDC domain controller

On my member server (hosted on premises on VMware):

time3

=> A domain controller

As you can see, that’s a bit weird. What is that VM IC Time Synchronization Provider? If I’m not mistaken, it’s a component that gets installed with Windows, and is capable of interacting with the hypervisor (E.g. on-premises Hyper-V or Azure Hyper-V). As far as I can tell, VMware guests ignore it. Basically it’s a component that helps the guest sync the time with the physical host it runs on. Now you can imagine that if guests run on different hosts, time might start to drift slowly. In order to mitigate this, we need to ensure the time is properly synchronized using the domain hierarchy.

Luckily it seems we can easily disable this functionality. We can simply set the enabled registry key to 0 for this provider. The good news: setting from 0 –> 1 seems to require a Windows Time Service restart, but I did some tests and setting from 1 –> 0 seems to be come effective after a small period of time. The good news part 2: setting it to 0 doesn’t seem to have a side effect for on-premises VM’s as well.

In my case I opted to use group policy preferences for this:

time4

The registry path: SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\VMICTimeProvider set the Value Enabled to 0

And now we can repeat our tests again:

On my PDC (hosted in Azure):

time5

On my DC (hosted in Azure):

time6

On a member server (hosted in Azure):

time7

Summary

I’ll try to validate this with some people, and I’ll definitely update this post If I’m proven to be wrong, but as far as I can tell: whenever you host virtual machines in Azure that are part of a Windows Active Directory Domain, make sure to disable to VM IC Time Provider component.

Imho this kind of information is definitely something that should be added to MSDN: Guidelines for Deploying Windows Server Active Directory on Azure Virtual Machines or Azure.microsoft.com: Install a replica Active Directory domain controller in an Azure virtual network

References: