Add network card to Azure VM

Posted: 5th February 2015 by Anders Bengtsson in Azure, Scripts

This is a script I wrote when Pete and I were preparing our System Center Universe session a couple of Days ago. The scenario is that you have a VM running in Azure with one network card. Now you want to add another network card. It is only possible to add a network card when creating the VM. This script will delete the current VM, keep the disk, create a new VM with two network card and attach the disk again.

Things to add to this script can be how to handle VM size. Depending on the VM size you can have different number of network cards, for example if you have 8 CPU cores you can have 4 network cards. It would be good if the script could handle that. It would also be good if the script could handle multiple disk on the original VM. That might show up in vNext :)

$VMName = “SCU001″
$ServiceName = “SCU001″
$InstanceSize = “ExtraLarge”
$PrimarySubNet = “Subnet-1″
$SecondarySubnet = “Subnet-2″
$VNET = “vnet001″

#Get the current disk
$disk = Get-AzureDisk | where {$_.AttachedTo -like “*RoleName: $VMName*”}

### Shutdown the VM
Get-AzureVM -Name $VMName -ServiceName $ServiceName | Stop-AzureVM -Force

# Remove the VM but keep the disk
Remove-AzureVM -Name $VMName -ServiceName $ServiceName

# Deploy a new VM with the old disk
$vmconf = New-AzureVMConfig -Name $VMName -InstanceSize $InstanceSize -DiskName $disk.DiskName |
Set-AzureSubnet -SubnetNames $PrimarySubNet |
Add-AzureNetworkInterfaceConfig -name “Ethernet2″ -SubnetName $SecondarySubnet |
Add-AzureEndpoint -Protocol tcp -LocalPort 3389 -PublicPort 3389 -Name “Remote Desktop”

New-AzureVM -ServiceName $ServiceName -VNetName $vnet -VMs $vmconf

List all containers in all storage accounts

Posted: 10th January 2015 by Anders Bengtsson in Azure, Scripts

This script list all containers in all storage accounts, in your Azure subscription. It is handy when looking for a container or a blob end point.

$accounts = Get-AzureStorageAccount
Foreach ($account in $accounts)
$sa = Get-AzureStorageAccount -StorageAccountName $account.storageAccountName
$saKey = Get-AzureStorageKey -StorageAccountName $sa.StorageAccountName
$ctx = New-AzureStorageContext -StorageAccountName $sa.StorageAccountName -StorageAccountKey $saKey.Primary
Get-AzureStorageContainer -Context $ctx



My Recorded Sessions from System Center Universe and TechEd

Posted: 30th October 2014 by Anders Bengtsson in Microsoft Event

Channel 9 have published my sessions from TechEd Europe 2014 and System Center Universe Europe 2014.

  • TechEd Europe. In-Depth Introduction to Service Management Automation, link
  • System Center Universe. Advanced Orchestrator Runbook Authoring and Management, link
  • System Center Universe. Optimize Azure Virtual Machines for performance and availability, link

Check them out!

Last week I tried Microsoft Azure RemoteApp together with System Center Service Manager. Azure RemoteApp is a service that you can use to support your organization to stay productive anywhere and on almost any device. Your applications runs on servers in Azure or locally, clients install a Microsoft Remote Desktop client and can then access the applications same way as if they were running locally. The great value is that you don’t need to administrate a service to publish applications to clients, you buy that component as a service. The application that you publish can run in Azure or it can run locally, or a combination.

When you deploy RemoteApp you can set it up in either Cloud only mode or Hybrid mode. Hybrid mode comes with VPN to local datacenter and all users must be users from your local Active Directory. It also have an option to join the custom template to a domain.

When running in Cloud only mode everything is running in Azure and your users can be a Microsoft account. There is no option to join your custom template machine to a domain.

In this blog post I want to show a couple of screens and share some experience from when I configured RemoteApp in Hybrid mode together with Service Manager.

I wanted to run the Service Manager console in RemoteApp, therefor I needed to build a custom template. There is a default Windows Server template (think with Office) that you can use if you just want to test RemoteApp a bit. But in this scenario I installed a local virtual machine and installed the Service Manager console on it. Then I ran Sysprep. All steps you need to go through to build a customer template are documented here.

Once the image was uploaded I created a RemoteApp service, as I want to access resources in my local datacenter I selected “Create with VPN”. When deploying the RemoteApp template you can’t select which virtual network it should be deployed in. Instead it will create a new virtual network. If you want to connect your RemoteApp host machine to an existing virtual network in Azure you can build a VNET-2-NET connection, see this blog post. If you have for example have a domain controller or application server running in a VNET today, in Azure, and you want your RemoteApp template to connect to those servers you will need to configure a VNET-2VNET connection as the blog post describes.

Once RemoteApp is deployed you can upload the customer template image. You can upload it with a script that you will find in the Azure management portal. In the portal under RemoteApp/Template Image you can click Upload. A wizard will start and give you a script that should be used to upload the VHD file.

In the RemoteApp service, in the Azure management portal, you get a “wizard” to step through to configure everything. First part is about connecting local network with the new RemoteApp network in Azure. Second part is about linking a RemoteApp template image. Third is about configure programs to publish and configure user access. In the need is the URL for the client software.

You can connect an existing virtual network or create a new network. “Get Script” will give you a script you can run on your locally edge device to configure a VPN. “Get Key” will show the VPN IP to use to connect to the RemoteApp network and it will also show the pre-shared key for the VPN.

“Link a RemoteApp template image” let you pick the remote app you uploaded earlier.

Options to join the local domain


Options to publish applications either by a path or by start menu. I installed the Service Manager console on the template image machine before running Sysprep. I can now select the Service Manager console from the start menu programs option, as it was in the start menu on the template machine.


Programs published to my users

Users can now start the Microsoft RemoteApp client and start a published application


The Service Manager console running in Azure RemoteApp connected to a Service Manager server running in a VNET in Azure. I looks very much as it is running locally J


Summary. We use Azure RemoteApp to publish consoles to applications that are running either in Azure only or in both Azure and locally. Azure RemoteApp works on many different types of devices. The service is easy to get started with, especially if compared running to Remote Application infrastructure locally.

Scaling Azure VM with Azure Automation, with help of Azure SQL

Posted: 8th September 2014 by Anders Bengtsson in Azure, Scripts

I am running a number of virtual machines in Microsoft Azure, some of them just a couple of hours and some I keep running 24/7. Often I don’t need them during the night, but some I still want to keep online to make sure database sync jobs runs. Previous I have been using a couple of different Powershell scripts that start and stop virtual machines, but now I have built a new solution, and want to share the idea with you. This new solution involves two components, except the virtual machines, it includes Azure Automation and Azure SQL. Azure Automation (current in preview) is an automation engine that you can buy as a service in Microsoft Azure. If you have been working with Service Management Automation (SMA) you will recognize the feature. You author runbooks in PowerShell workflow and execute them in Microsoft Azure, same way as with SMA, just that you don’t have to handle the SMA infrastructure. Azure SQL is another cool cloud service, a relational database-as-a-service.

Figur 1 Azure Automation

Figur 2 Azure SQL Database

In Azure Automation I have created two runbooks (VM-MorningStart and VM-EveningStop). One that runs every morning and one that runs every evening. These runbooks read configuration from the Azure SQL database about how the virtual machines should be configured during night and day. Azure Automation have a feature, schedule, which can trigger these runbooks once every day, shown in figure 3.

Figur 3 Schedule to invoke runbook

Both runbooks are built the same way. They check in the database for servers and then compare the current settings with the settings in the database. The database has one column for day time server settings and one for Night time server settings. If the current setting is not according to the database the virtual machine is shutdown, re-configured and restarted again. I use Azure AD to connect to the Azure subscription according to this blog post, and I use SQL authentication to logon to the SQL server. If a virtual machine is set to size 0 in the database it seems the machine should be turned of during the Night.

workflow VM-EveningStop
$Cred = Get-AutomationPSCredential -Name ''
Add-AzureAccount -Credential $cred
### Connect to SQL
InlineScript {
$UserName = "azuresqluser"
$UserPassword = Get-AutomationVariable -Name 'Azure SQL user password'
$Servername = ""
$Database = "GoodNightServers"
$MasterDatabaseConnection = New-Object System.Data.SqlClient.SqlConnection
$MasterDatabaseConnection.ConnectionString = "Server = $ServerName; Database = $Database; User ID = $UserName; Password = $UserPassword;"
$MasterDatabaseCommand = New-Object System.Data.SqlClient.SqlCommand
$MasterDatabaseCommand.Connection = $MasterDatabaseConnection
$MasterDatabaseCommand.CommandText = "SELECT * FROM Servers"
$MasterDbResult = $MasterDatabaseCommand.ExecuteReader()
if ($MasterDbResult.HasRows)
Select-AzureSubscription -SubscriptionName "Windows Azure MSDN - Visual Studio Ultimate"
$AzureVM = Get-AzureVM | Where-Object {$_.InstanceName -eq $MasterDbResult[1]}
Get-AzureVM -ServiceName $AzureVM.ServiceName | Stop-AzureVM -Force
If ($MasterDbResult[2] -eq "0") {
Else {
Get-AzureVM -ServiceName $AzureVM.ServiceName | Set-AzureVMSize $MasterDbResult[2] | Update-AzureVM
Get-AzureVM -ServiceName $AzureVM.ServiceName | Start-AzureVM

The database is designed according to this figure (click to make it larger)


Summary: Azure automation run one runbook in the morning to start up and scale up virtual machines, and one runbook in the evening to scale down and shut down virtual machines. All Configuration is stored in a Azure SQL database.

Note that this is provided “AS-IS” with no warranties at all. This is not a production ready management pack or solution for your production environment, just a idea and an example.

From time to time there is a need to list all instances of a specific activity type in Orchestrator. For example it is not recommended to have any send platform event activities in production, instead we can use a SQL database for logging. There are two ways to investigate if there are any send platform events in the environment, review each runbook or ask the database. In this blog post I will show you how to list all instances of a specific activity type.

The first thing we need to do is to find the uniqueID for the type of activity in the OBJECTTYPES table. The following question will give us all info about the Send Platform Event, but you can query for any kind of activity.

select * from OBJECTTYPES where name = ‘Send Platform Event’

The OBJECTTYPE table will give us the uniqueID for the activity type, in this example 87E28B20-3E83-45E0-985A-FEEA6CE09084. The table will also tell us where to look for configuration data for these activities, in the PrimaryDataTables and SecondaryDataTables. If we want to list all Send Platform Events activities we have we can run the following query. The “AND (Deleted = ‘0’) part will make sure we only list activities that are not marked as deleted.

select * from OBJECTS where (ObjectType = ’87E28B20-3E83-45E0-985A-FEEA6CE09084′) AND (Deleted = ‘0’)

If we now want to add on in which runbook we are using them we can join the ParentID from the OBJECTS table with the uniqueID in the POLICIES table, like the following query. The Objects table will give us general information about each activity.

WHERE (OBJECTS.ObjectType = ’87E28B20-3E83-45E0-985A-FEEA6CE09084′) AND (OBJECTS.Deleted = ‘0’)

We now see activity names and runbook names. But what if we also want to include configuration of the Send Platform Event activity? Then we need to join the table seen in the first query, the PrimaryDataTable for the Send Platform Event activity type, example query


AS you can see some EventDetails and EventSummary includes a GUID. When we configure a Send Platform Event activity to publish data from the data bus we see the uniqueID of the activity in the text. As we can see in the figure many of my Send Platform Events will use data from the data bus.

Earlier this week I needed to add a runbook activity to a Service Request depending on the result from a review activity. I have written about adding activities to a service request from a runbook before, here. The difference is that this time I needed to add a runbook activity and that is a bit more complicated than adding for example a review activity or manual activity.

To add a runbook activity you need two activities, first one that gets the runbook (System Center Orchestrator Runbook Item) you want to use, the second activity creates a new related runbook activity (Runbook Automation Activity) to the service request. In this example I will add a Runbook Automation Activity that runs a runbook named “12.4 Build new VM”.

For the Create Related RB activity there are more to configure compared with the “Get RB Item” activity.

  • Source Object Guid. This is the SC Object GUID from a Get Object activity that gets the Service Request that we want to add a Runbook Automation Activity to.
  • Sequence ID. This field configure where, compared with already existing activities in the Service Request, this new activity will be added. The first activity in a Service Request has sequence ID 0, the second 1 and so on. In my service request I have one review activity and then a runbook activity. This new runbook activity will be added after both of them, sequence ID 2 in other words.
  • ID. This is the id of the new runbook activity. {0} will give it next free serial number from Service Manager, “RB” is added to make sure it is named not just a number but also RB in front of the number.
  • Is Ready For Automation is set to TRUE. This will allow the Runbook Activity to be triggered when the Service Request is created and the Runbook Activity becomes In Progress.
  • Title. Title of the runbook Runbook Automation Activity, for example “Build new VM”
  • Runbook Identifier. This is the ID of the runbook you want to run, you get the ID from the previous Get RB Item activity.
  • Template Identifier. This is a bit more complicated to find, this is the Name of the template you have built for the Runbook Automation Activity in Service Manager. If you start Service Manager Shell (Service Manager PowerShell) you can run “Get-SCSMObjectTemplate | ft Name, DisplayName” and you will find the value you need. Most likely your template name starts with Template.
  • Status. Status of the new activity, configure it to Pending
  • Property Mapping. This is parameters that we pass to the new Runbook Automation Activity.
    • <NAME> is the name of the input parameter in the runbook, the parameter set in in the Initialize Data activity
    • <ID> is the ID of the parameter in Orchestrator. Each parameter has a unique ID. You can list get the connection between parameter, activity and runbook with the following SQL query. In my example query I ask for all input parameters named “SR”.


    • <VALUE> the value I pass to the new runbook is the Runbook Automation Activity ID. Based on that ID you can find the for example related service request
    • <RunbookID> is the ID of the Runbook Item. You can get it from the Get Runbook activity or you can use Service Manager Shell to get it. To get it with Service Manager Shell run “Get-scsmclass –name Microsoft.SystemCenter.Orchestrator.RunbookItem | get-scsmclassinstance | where-object {$_.Name –like “*12.4*”} | ft Name, Id
      In this example I ask for a runbook activity that I know is named something with 12.4.


Those two activities is the two activities you need to add a Runbook Automation Activity. I notice that it works better if you also mark the current runbook as completed, from the runbook itself instead of from Service Manager. When adding activities in general I have notice that mark the current runbook as completed makes the service request process work better.

In the runbook you invoke you will get the Runbook Automation Activity SC GUID as input parameter. From there you can use a Get Relationship activity to find the related Service Request.


Once you have the Service Request you can read for example all use input data, in my example settings for a new virtual machine. User Input, everything the user has input in for example the self-service portal when submitting the service request, is stored in XML format. For example

To get only “Stockholm” you can use a Query XML activity



Summary: In this blog post we have looked at how we can use a Runbook Automation Activity in a Service Request to add another Runbook Automation Activity. We have also looked at how to pass data to the new runbook. This scenario is useful if you for example want to add activities based on the answer from a review activity.

Runbook PID

Posted: 28th May 2014 by Anders Bengtsson in Orchestrator

Yesterday I was investigating runbooks consuming much memory. We had a number of runbooks running Powershell scripts and we could see that the Runbook server was almost out of memory. When looking in Task Manager we saw a lot of PolicyModule.exe processes, some using a lot of memory, but we had no mapping between running runbooks and running PolicyModule.exe process. We needed to figure out which script/runbook is consuming all the memory.

This can be done in a couple of different ways. One way is to publish Runbook Process ID for any activity in a runbook. To use Runbook Process ID you need to enable “Show common Published Data” in the Published Data dialog box. The published data will show you the PID for the PolicyModule.exe process.

Another way to get the PID is to look in the Orchestrator database. The following SQL query will show you runbook name, start and stop time and process ID.


When playing with Windows Azure Pack I received this error. When searching on the Internet the solution is to add the user to the local “MgmtSvc Operators” security group. That is a bit difficult, as Microsoft removed that group in Update 1. Instead you should use PowerShell “Add-MgmtSvcAdminUser” to assign users permissions. When I ran get-MgmtSvcAdminUser I had the WAP server local administrator’s group member of the WAP Admin role, and my user was member of that local administrator group. Normally a member of a group has all permissions that the group has, but not in this case, instead I needed to add my user account direct to the admin role. Thanks to the oracle Patrik Sundqvist who enlighten me about that. I ran the following PowerShell line and then it worked

Add-MgmtSvcAdminUser –ConnectionString ‘Server=SCDB01;Initial Catalog=Microsoft.MgmtSvc.Store;Trusted_Connection=True;’ –principal ‘demo\anders.bengtsson’

SCDB01 is the database server hosting the Microsoft.MgmtSvc.Store database. DEMO is the domain name.

I have been preparing our TechEd session last weeks. During this I have solved a number of challenges in Windows Azure Pack. In this post I will share challenges and solutions.

Challenge 01 – Unexpected error

This occurred when a tenant tries to deploy an instance of a VM role from the tenant portal. I started to verify the following settings on both the template VHDX file and the gallery item

  • Operating System, for example Windows Server 2012 R2 Standard
  • Family name, for example Windows Server 2012 R2 Standard
  • Tags, for example Windows
  • Version. Remember that version must be in format X.X.X.X for example

The solution was that the Library share where the VHDX file was stored was not set as a Read-Only share for the cloud. Once added the Library share to the cloud as Read-Only library share it worked to deploy VM Role instances.

Challenge 02 – …not allowed by any capability profile supported by the cloud

The cloud, Contoso Cloud for developers, had Hyper-V as capacity profile selected. But for VM Roles you cannot use a capability profile, because the VM Role model does not have a property in which to express a capability profile (because it is designed to be consistent with Azure and Azure has no notion of capability profiles). The solution was to uncheck Hyper-V Capacity on my target cloud. Update KB 2936967 removes the requirement for Hyper-V Capability Profile on the VMM Cloud. With this update it is a bit easier to handle clouds used for both VM templates and VM roles.

Challenge 03 – Product key in a VM Role resource definition

There is no option to set Windows product key when configure a resource definition. An easy way to solve it is to use the set-scvirtualharddisk cmdlet to set the product key on the virtual hard disk in VMM.

Challenge 04 – Windows Could not apply unattend settings during pass [specialize]

I connected to the Hyper-V host, opened Hyper-V managed and looked at the floppy disk that was connected to the VM. I open the floppy disk file and read the XML. There was a part about joining the domain. As DHCP configure wrong DNS that was the problem, the VM could not join the domain and hang during installation. I re-configured in VM Role Authoring Tool, imported the new gallery item, marked it as public, added it to the plan, re-login the tenant and re-deployed. Then it worked.

Challenge 05 – Error 31356

Error (31356)
Unable to find the referenced Resource Extension, containing Name=Contoso_FileSrv_ResourceExtension Publisher=Contoso and Version=
Recommended Action:
Try the operation again after fixing the Resource Definition or importing the Resource Extension.

Solution was to remove the item from the plan and save the plan. I waited until the plan was synchronized again and then re-added the item to the plan again. The root cause was that I re-import the resource extension to VMM after importing the resource definition to Windows Azure Pack portal and adding it to a plan.

Challenge 06 – Plan syncing hang

Plan remain in syncing state till all subscriptions belong to plan get synced. You can see this update happening in admin portal by going to subscriptions tab inside that plan. You will see some subscriptions which are already synced (i.e. in active Or Out-Of-Sync state) and some currently syncing (i.e. in Syncing…. State).  Once all subscriptions belong to plan get synced then plan will stop syncing. In my case the solution was to apply VMM update 1, including the scripts. I read some threads about people who had seen this issue when they had forget about the scripts in update 1.

Challenge 07 – Error (22663)

The BITS client job failed to succeed for C:\ProgramData\VirtualMachineManagerData\TempResources\3e23bd43fad847e995279686e8547841\ConfigurationFile.ini resource with the following error: The server name or address could not be resolved

Error context: The error occurred while the remote file was being processed.

Error code: -2147012889

This I solved by unchecking the VM network from the Library. If you uncheck the network, VMM will try to transfer file with ISO instead of BITS/network. Else it will try to use BITS/network for some basic configuration file. In my sandbox new VMs don’t have working IP settings, therefor any kind of network communication fails. With this setting it works anyway, as VMM will use an ISO instead.

Challenge 08 – Error (22743)

The host agent on the host hyper119.contoso.local for virtual machine MyMachine001 is not up to date and cannot provision the physical resources required for the servicing operation.
Recommended Action
Ensure the virtual machine has network connectivity to the library servers, or that the host agent is up to date, and then retry the operation.

This I solved by update to 2012 R2 Update 1 on VMM server, ran Update 1 SQL script and updated all Hyper-V host agent to Update 1.