Use PowerShell DSC to Enable Screencast Recording on Azure VMs

Do you ever record screencasts, and post them to YouTube, or some other video sharing site? Well, maybe you do, maybe you don’t, but I sure do (when I find time)! For the sake of simplicity, I use an older, free Microsoft tool called Expresion Encoder 4.0 with Service Pack 2 (SP2). You can download it, again for free, from here! In some cases, it might be preferable to invoke screencast recording on a remote session, rather than recording on your local computer, however. In this post, we will take a look at how to use PowerShell Desired State Configuration (DSC) to automatically install Microsoft Expression Encoder 4.0 SP2 onto cloud-hosted Microsoft Azure Virtual Machines!

Unless you’re a MSDN subscriber, with access to Windows 8.1 VM images in Azure, most of your Azure Virtual Machines will be running some class of Windows Server. In this case, we’ll be using a Windows Server 2012 R2 VM. The first thing to point out is that Windows Server 2012 R2 requires the “Desktop-Experience” Windows Feature to be installed, in order to successfully run Microsoft Expression Encoder 4 SP2. If this Windows Feature isn’t installed, you’ll get a nasty error telling you that wmvcore.dll is missing, when you try to run the Expression Encoder program.

While working with Expression Encoder in Azure, one limitation you’ll want to keep in mind is that Expression Encoder has a problem rendering your screencast content inside the editor. So, if you want to make any modifications to your screencast, after you’ve recorded it, you’ll have to download the content locally onto your computer.

With all of that out of the way, let’s get DS-configuring! The first thing we need to do is ensure that the “Desktop-Experience” Windows Feature is installed. To do that, we will use the built-in WindowsFeature DSC resource. To start building our configuration, let’s use this code:

configuration ExpressionEncoder4SP2 {    
    WindowsFeature DesktopExperience {
        Ensure = 'Present';
        Name = 'Desktop-Experience';
    }
}

First, we start by declaring a configuration block, and giving it a name. Inside the configuration block, we declare a WindowsFeature resource, and give it a unique name as well. The WindowsFeature resource has a couple properties that we need to set. We need to set Ensure to Present, and then set the Name property to Desktop-Experience. Speaking in plain English, this DSC resource will “ensure” that the “Desktop-Experience” WindowsFeature is installed on the target host!

Next, we will add a Script Resource to handle the detection and installation of Microsoft Expression Encoder 4.0 SP2. The DSC Script Resource has three key properties: GetScript, SetScript, and TestScript. The GetScript defines a PowerShell script that will be executed when you run the Get-DscConfiguration command. It will more or less perform the same detection as the TestScript does, but it will also return the settings of the Script Resource, so we can examine the configuration that is being applied to the system, for purposes of troubleshooting. Finally, the Script Resource offers a DependsOn property that allows us to specify which other DSC configurations are prerequisites to it. Of course, we will specify the WindowsFeature Resource as a prerequisite, because we need that feature to be present before we install the Expression Encoder software.

So without further ado, let’s take a look at the Script Resource!

Script ExpressionEncoder4SP2 {
    DependsOn = '[WindowsFeature]DesktopExperience';
    GetScript = {
        Write-Verbose -Message 'Executing GetScript';
        $Result = @{ 
            Result = $false;
            GetScript = $GetScript;
            SetScript = $SetScript;
            TestScript = $TestScript;
            };
        if (!(Test-Path -Path HKLM:SoftwareClassesInstallerProducts3FB2C5F36B8D50242ADACB0B1A3E064A)) {
            Write-Verbose -Message 'Path does not exist! System is non-compliant.';
        }
        else {
            Write-Verbose -Message 'Path already exists! System is compliant.';
            $Result.Result = $true;
        }
        $Result;
        Write-Verbose -Message 'Finished running GetScript';
    }
    SetScript = {
        Write-Verbose -Message 'Executing SetScript';

        $DownloadUri = 'http://download.microsoft.com/download/4/3/2/4328EFC5-4F3B-47C8-B21D-75CAD2E575C2/Encoder_en.exe';
        $TargetFile = '{0}tempEncoder_en.exe' -f $env:windir;
        Invoke-WebRequest -Uri $DownloadUri -OutFile $TargetFile;

        Write-Verbose -Message 'Installing Microsoft Expression Encoder 4 SP2';
        Start-Process -FilePath $TargetFile -ArgumentList '-q' -Wait;
        Write-Verbose -Message 'Finished running SetScript';
    }
    TestScript = { 
        Write-Verbose -Message 'Executing TestScript';
        if (!(Test-Path -Path HKLM:SoftwareClassesInstallerProducts3FB2C5F36B8D50242ADACB0B1A3E064A)) {
            Write-Verbose -Message 'Path does not exist! System is non-compliant.';
            $false;
        }
        else {
            Write-Verbose -Message 'Path already exists! System is compliant.';
            $true;
        }
        Write-Verbose -Message 'Finished running TestScript';
    }
}

Make sure you copy/paste that inside of your existing configuration block. The TestScript returns either “true” or “false.” If it returns “false,” then the SetScript will be executed, to automatically “remediate” the configuration, otherwise no action will be taken. In this case, the TestScript is using the registry to detect if Microsoft Expression Encoder is already installed or not.

The SetScript code will download the installer for Microsoft Expression Encoder 4.0 SP2, and then invoke the installation of it silently. Notice that, in all three of the script properties, we make liberal use of the Write-Verbose command, to help us troubleshoot when something goes wrong. Any time you are writing a custom DSC resource, or implementing the Script DSC Resource, you will want to make sure that you write out as much useful information as possible, in case you encounter any problems.

It’s important to remember that the DSC Local Configuration Manager (LCM) runs under the Local System account, so any silent installation process will be invoked under that account. If you need to test out a silent installation under the Local System account, without using DSC, then I would recommend downloading Sysinternals PSexec, and using the -s parameter to launch a Command Prompt (cmd.exe). From there, you can invoke the silent installation command line, and monitor for success.

Once you’ve got the complete DSC configuration, you are ready to apply it to your Azure VM! Fire up the PowerShell ISE on the VM, copy/paste the configuration block, and then add the following lines at the end, before executing it:

ExpressionEncoder4SP2 -OutputPath c:dscExpressionEncoder4SP2;
Start-DscConfiguration -Wait -Verbose -Path c:dscExpressionEncoder4SP2;

Once you invoke the Start-DscConfiguration command, the Local Configuration Manager will begin processing the configuration. The Desktop-Experience Windows Feature will be installed, and will most likely output a warning, saying that you need to restart the system. Go ahead and reboot the system when prompted, and then the LCM will continue on to install Expression Encoder after the system comes back up.

I hope this article helps you understand DSC, and a practical use case for standardizing your Microsoft Azure Virtual Machine configurations! Feel free to reach out to me if you have any questions at pcgeek86@gmail.com. Until next time, take care!