Friday, August 26, 2016

Unable to add multiple listen rule keys or subscriptions to a Topic in an Azure Service Bus in an Azure Resource Group template

I recently ran across a problem wherein I was unable to add multiple Listen rules for my applications to my Topics in Azure Service Bus within an Azure Resource Group Template. I would run my template and it would fail to create the keys for the Topic or the Subscription for the topic of there was more than one of either of those for the Topic. It wouldn't even be consistent: it would switch back and forth between them between runs of the template. After a discussion with one of the Solution Architects at Microsoft, I found out there is, at the time of this writing, a bug in the Azure Resource Manager for Topics within Service Buses that prevents Topic access rules and subscriptions from being simultaneously created. As a work around, I was instructed to introduce an artificial dependency between each of the subscriptions to force the resource manager to create them serially rather than in parallel and this did the trick.

For example:

// TODO:

Tuesday, August 23, 2016

Getting verbose output from an Invoke-Command -ScriptBlock in PowerShell

It's often very useful to invoke commands on other machines, e.g. in deployment scripts. It can be even more useful to have logging of what actually gets executed on those other machines, e.g.

$myJob = Invoke-Command -AsJob -ScriptBlock {
    Param()

    Do-Thing -Verbose
}

However, in this instance, you wouldn't get the output of the Do-Thing command because it's writing to the Verbose stream of a script block being executed on a separate machine. Now, it's not that PowerShell can't collect the output of that Verbose stream for you, it can. You just need to instruct it how. The difference:

$myJob = Invoke-Command -AsJob -Verbose -ScriptBlock {
    [CmdletBinding()]
    Param()

    Do-Thing -Verbose
}

Now you'll be able to collect the Verbose output of your script block. The difference is that you need to pass the Verbose flag to the script block, and make it a cmdlet by adding the [CmdletBinding()] attribute to your block.

Tuesday, August 16, 2016

Wednesday, August 10, 2016

Finally ... how to debug the startup of a Windows Service application

Do what this guy says: http://einaregilsson.com/run-windows-service-as-a-console-program/

Pasted here for posterity, here's the example of how to write a Windows Service such that it can execute in a console and a developer can debug the startup routine:

using System;
using System.ServiceProcess;
 
public partial class DemoService : ServiceBase
{
    static void Main(string[] args)
    {
        DemoService service = new DemoService();
 
        if (Environment.UserInteractive)
        {
            service.OnStart(args);
            Console.WriteLine("Press any key to stop program");
            Console.Read();
            service.OnStop();
        }
        else
        {
            ServiceBase.Run(service);
        }
 
    }
    public DemoService()
    {
        InitializeComponent();
    }
 
    protected override void OnStart(string[] args)
    {
        // TODO: Add code here to start your service.
    }
 
    protected override void OnStop()
    {
        // TODO: Add code here to perform any tear-down
        //necessary to stop your service.
    }
}

Wednesday, August 03, 2016

WADK Deployment Tools on Windows Server 2008 giving error "The program can't start because api-ms-win-downlevel-advapi32-l4-1-0.dll is missing from your system"

Got this error at an extremely inconvenient time when trying to write some automation scripts for Windows Optional Features using the DISM module as part of the Windows Assessment and Deployment Kit running on Windows Server 2008 R2: "The program can't start because api-ms-win-downlevel-advapi32-l4-1-0.dll is missing from your system"

It turns out that the installer for this particular product isn't reliable when you uninstall and then reinstall the ADK. The problem turned out to be that the PATH variable hadn't been updated on the second install, so the PowerShell module that was invoking the DISM.exe executable wasn't able to find the required DLLs, even though they were in the same path as the executable. Go figure.

Tuesday, August 02, 2016

MSDeploy: The underlying connection was closed: An unexpected error occurred on a send.

Our company has started deploying all of its numerous web applications via automated (or at least scripted) deployment with MSDeploy. This has worked fine, up until very recently where one machine in particular seemed to be cursed and simply didn't want to work. Even when we nuked the VM and completely recommissioned it from scratch from our VM web server template, we still kept getting the following error:

Error: Could not complete the request to remote agent URL 'https://myserver:10987/MSDeployAgentService'.
Error: The underlying connection was closed: An unexpected error occurred on a send.
Error: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
Error: An existing connection was forcibly closed by the remote host
Error count: 1.

The problem turned out to be caused by the fact that we hadn't correctly configured the Management Service for MSDeploy (even though we use a custom port for the MsDepSvc deployment service, the Web Management Service (WMSvc) wasn't correctly configured): 
  1. Because we were behind a load balancer, we needed to specifically set the IP address of the server
  2. We were attempting to use SSL, but we didn't have a certificate specified in the Management Service configuration.
Here's what our configuration looked like in the end, obfuscated to protect the guilty:

Step 1:

Step 2: