You Want Wingdings Installed Where?

Last week I received what I considered an unusual request from one of my development teams.  The request was to install some fonts on our web services servers.  According to this development group, if these fonts aren’t installed on each and every server that their service is installed on, their web service won’t work.  This was a new one on me and this request seemed odd for a couple of reasons.  Why does a web service need fonts I asked?  It turns out that this particular web service generates PDFs of various types, so it seemed reasonable that it would require fonts with which to generate the documents.  But why would you want to install them on the server, instead of bundling them with your application I asked?  Microsoft offers a way to package fonts with your applications, and that seems like the right DevOps way to do it.

Wherever possible we try to keep the apps as independent of the servers and other infrastructure as possible. That way we can move them around much easier, and upgrades to the servers are usually much easier too. There’s also a huge advantage to keeping down the number of people or teams needed to deploy and support each app. If an application can be deployed with just the developers and application support staff then great, but add network and server dependancies and watch how much more complicated deployments get. But although this group of developers liked the idea of bundling the fonts with their application, they explained that they had no time or testing budget to change direction now.  That meant that I would have no choice, I would have to manage the fonts on our 2012 core servers for them.

But our web services servers are Windows 2012 R2 core servers. These servers are built entirely by PowerShell DSC scripts.  No one ever logs into these servers to configure anything by hand.  All changes to server configuration must be made via PowerShell DSC and checked into source control.  So I checked to see if anyone had written a PowerShell DSC resource for fonts, but not surprisingly, considering the unusual nature of this request, I didn’t find one.  Then I briefly considered rolling our own, I have written many of our own custom DSC resources, but that seemed like more work than it would be worth.  After all, how often am I going to need to manage fonts on servers?  So I choose to use the PowerShell DSC shortcut resource, the Script resource.  If you ever need to get something done quickly that you probably won’t ever have to repeat, this is your resource.

Now the request I had was to install 3 fonts, one for each of our company’s brands.  So the first wag was to add the following lines to this application’s other configuration code, and repeat for each brand’s fonts. Notice that I’m checking for the font’s file name, not the actual font name. On 2012 with a GUI you would test for the full font name, but on core only the file name is returned. Not elegant, but functional.

And so I thought that I was done. But not really, because then the request came to install a few more fonts. Could we also have Calibri and wait for it… Wingdings! Yes folks, I had an official request to install Windings on all of our Web Service servers. I guess there are lots of useful symbols in Windings so it kind of made sense, at least once you accept the idea of having the server admins managing an application’s fonts on all of our web services servers. So I added a couple more PowerShell DSC Script resources to the application’s config and thought that that would be the end of it. But I was wrong.

The next request came a few days later and it was to install all of the fonts that the developers had on their Windows 7 machines, about 300 of them.  See, the developers of this application weren’t sure which fonts the application might require (kind of depended on how the end-user used the app), so they thought that we should just install all of them, and yes this included every language, every script, and even Comic Sans!!

This is about the time I resent the development team the link to packaging fonts with your applications from Microsoft.  But alas, they still weren’t willing to move in this direction.  “No time to code, no time to test”. So if I was going to be responsible for making sure hundreds of fonts are installed on various servers, I was going to have to take a different approach.  We still needed to install them with PowerShell DSC, but I couldn’t keep updating the scripts and checking in changes every time they wanted to add a font. And I couldn’t manage each and every font individually like I had been either, it wouldn’t scale.  So I decided to write a new DSC Script resource that would check a source location (a git repository) for fonts and scan the destination folder to see if they were installed or not.  If not, DSC will install them.  Here’s how this looks.

So now the developers can manage the fonts that get installed by checking them into the git repository we set up, and each time DSC runs I’ll check and see if there are any new fonts to install. No code changes on my side when they decide to add a new font. Is this a great solution? Definitely not! I really don’t like adding the application dependency to the servers instead of leaving it with the application where it belongs. But sometimes in a DevOps world, we have to make concessions to get the apps into production, and PowerShell DSC can help make that possible.

Returning All Records When Querying the Splunk REST API

In my current environment the Windows 2012 R2 server builds are completely automated via PowerShell 4 DSC. This includes the installation of IIS Web Sites and Web Applications. We use Splunk to monitor all the IIS Logs and the .Net Web Application logs, and if you don’t have the Splunk configs automated, managing them can be a bear. Fortunately you can use PowerShell to manage Splunk via the Splunk REST API. This has been working well for us, but recently I came across an issue where the REST API on some of my servers wouldn’t return all of the monitors. These queries were working fine on most of my servers, but some would not return all of the results via the REST API, even though the Splunk command line did return all the monitors.

I found out from Splunk support that when querying the REST API for installed monitors that the results are limited to 30. To get all the results add “count=-1” as a query string to the URI for the endpoint you are calling. This isn’t documented anywhere that I could find. Here’s how it looks in PowerShell when querying the local host using the default username and password.