Wednesday, 18 November 2015

Extract All Azure Management Certificates In Powershell

The following powershell snippet will extract all management certificates for your azure subscriptions into separate PFX files.

You can download your publish settings file from the azure management site.

$azurePublishSettings = "azure-settings.publishsettings"
$nodes = Select-Xml -Path $azurePublishSettings -XPath '//PublishData/PublishProfile/Subscription'
foreach($node in $nodes){
    $node.Node.ManagementCertificate | Out-File "$($node.Node.Name).pfx"

Monday, 12 October 2015

Add FluentValidation Rules to Swagger Schema

The following code uses the FluentValidation IValidator profiles to add extra data to the swagger schema such as required and min/max lengths.




public class AddFluentValidationRules : ISchemaFilter
        public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
            var validator = GetValidator(type);
            if (validator == null)
            schema.required = new List<string>();
            var validatorDescriptor = validator.CreateDescriptor();
            foreach (var key in
                foreach (var propertyValidator in validatorDescriptor.GetValidatorsForMember(key))
                    if (propertyValidator is NotEmptyValidator)
                    if (propertyValidator is LengthValidator)
                        var lengthValidator = (LengthValidator) propertyValidator;
                        if (lengthValidator.Max > 0)
                  [key].maxLength = lengthValidator.Max;
              [key].minLength = lengthValidator.Min;
                    if (propertyValidator is RegularExpressionValidator)
                        var regexExpressionValidator = (RegularExpressionValidator) propertyValidator;
              [key].pattern = regexExpressionValidator.Expression;
        private IValidator GetValidator(Type t)
            // use IoC or FluentValidatorFactory to get AbstractValidator<T> instance

Sunday, 8 January 2012

Failed to run method 'Microsoft.Web.Farm.SyncApplicationsRemoteMethod'on server

I have currently been having an issue with Web Farm Framework 2 not provisioning my applications correctly. I would receive and error message saying that it could not delete the temp app pool file on the secondary server.

Failed to run operation 'ProvisionApplications'.
Failed to run method 'Microsoft.Web.Farm.SyncApplicationsRemoteMethod' on server 'xx.xx.xx.xx'.
Exception in response stream. An error was encountered when processing operation 'Delete File' on 'APCE41E.tmp'.
The error code was 0x80070020.
The process cannot access 'C:\inetpub\temp\appPools\APCE41E.tmp' because it is being used by another process.
Exception in response stream. An error was encountered when processing operation 'Delete File' on 'APCE41E.tmp'.
The error code was 0x80070020.
The process cannot access 'C:\inetpub\temp\appPools\APCE41E.tmp' because it is being used by another process.

This can be resolved by ignoring the appPool temp files from the sync. To do edit the the ignore list in c:\windows\system32\inetsrv\config\applicationHost.config on the web farm controller so that the web farm includes the following skip directives.

<applicationProvision offlineWhileSync="true" syncWebServerFromPrimary="true" periodicSync="00:00:30">
<clear />
<skip name="appPools" skipDirective="objectName=dirPath,absolutePath=.*appPools.*" />
<skip name="logFiles" skipDirective="objectName=dirPath,absolutePath=.*LogFiles.*" />

Backup IIS Server Package to Amazon S3 using C#

I recently updated our backup process at work to store our backups on Amazon S3. I wanted a simple process to that would backup the IIS server configuration and website files that can be easily be restored on a new server in case of a major problem. Luckily Microsoft have release MSDeploy which can be installed using the Web Platform Installer.

Within IIS you can backup everything to a server package by opening the context menu selecting depoy, then “Export Server Package”. This will create the server package containing the IIS configuration along with all the sites and their files. This is all good however it is still a manual process that is likely to be forgotten about after a while. Likely there are a series of libraries we can use to automate this process.

The namespace Microsoft.Web.Deployment provide the functionality we need to backup IIS, this is provided by Microsoft.Web.Deployment.dll. To backup the server we need to use the DeploymentManager to create an object use to create the package, we can then use this to “sync” the server setting to a package.

After we have backed up the site package we need to upload it to Amazon S3. To do this we can use the AWSSDK .NET library. The library can be installed via NuGet by searching for “AWS SDK”. This will install the required assemblies.

We can use the AWS SDK to upload our server package zip to S3 using the TransferUtilityUploadRequest to create our request to use with the TransferUtility to upload our file.

When this is all tied together we have an app that will backup and upload the server package to S3.

Tuesday, 3 January 2012

MVC Update User Online via Action Filter

Action filter to update the currently logged in users last online time to allow you to identify which of your users are online

/// <summary>
/// User Online Action Filter Attribute
/// </summary>
public class UserOnlineActionFilterAttribute : ActionFilterAttribute
/// <summary>
/// Called by the ASP.NET MVC framework after the action method executes.
/// </summary>
/// <param name="filterContext">The filter context.</param>
public override void OnActionExecuted(ActionExecutedContext filterContext)
if (filterContext.HttpContext != null && filterContext.HttpContext.User != null && filterContext.HttpContext.User.Identity != null)
Membership.Provider.GetUser(filterContext.HttpContext.User.Identity.Name, true);
// BAD: Swallow the exception to prevent it messing with the users action


Add the action filter to the global list inside the global.asax Application_Start.

GlobalFilters.Filters.Add(new UserOnlineActionFilterAttribute());

Saturday, 3 December 2011

NAnt FTP Task

An NAnt task to allow file uploads using FTP allowing FTP+SSL to used.

<target name="ftp">
<include name="NAnt.Task.Ftp/bin/**/*.dll"/>

using System.IO;
using System.Net;
using System.Text;
using NAnt.Core;
using NAnt.Core.Attributes;
using NAnt.Core.Types;

namespace NAnt.Task.Ftp
public class FtpTask : NAnt.Core.Task
public string Server { get; set; }

public string Username { get; set; }

public string Password { get; set; }

public int Port { get; set; }

public string BaseDirectory { get; set; }

public bool UseSSL { get; set; }

[BuildElement("fileset", Required = true)]
public virtual FileSet FileSet { get; set; }

public FtpTask()
Port = 21;

protected override void ExecuteTask()
if (FileSet != null)
foreach (var file in FileSet.FileNames)
if (File.Exists(file))
Log(Level.Info, file);
var ftpRequest = CreateUploadRequest(new FileInfo(file).Name);
// Copy the contents of the file to the request stream.
var sourceStream = new StreamReader(file);
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
ftpRequest.ContentLength = fileContents.Length;

var requestStream = ftpRequest.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);

var response = (FtpWebResponse) ftpRequest.GetResponse();
Log(Level.Info, "Upload Complete: {0}", response.StatusDescription);
Log(Level.Error, "File doesn't exists: {0}", file);

protected FtpWebRequest CreateUploadRequest(string fileName)
var ftpServer = string.Format("ftp://{0}:{1}/{2}/{3}", Server, Port, BaseDirectory, fileName);

Log(Level.Info, "Preparing Upload: {0} => {1}", fileName, ftpServer);
var ftpRequest = (FtpWebRequest)WebRequest.Create(ftpServer);

if (!string.IsNullOrWhiteSpace(Username) && !string.IsNullOrWhiteSpace(Password))
ftpRequest.Credentials = new NetworkCredential(Username, Password);

if (UseSSL)
Log(Level.Info, "Using ssl");
ftpRequest.EnableSsl = true;

ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;

return ftpRequest;

Monday, 30 May 2011

Gnome 3 - Stupid Power Options Fix

Upgraded to Fedora 15 and Gnome 3 everything is working well and the new interface is looking slick. The gnome guys have done a very good job and am very impressed. However I have come across on thing that, for a while, really pissed me off. They removed the ability to easily change the power options when you close the lid on your laptop. The default option is to suspend the computer. This isn't a problem for a lot of people, even if there is a bug on the dell M1330 laptop which causes a crash when starting from a suspended state. I digress, a lot of work has done into this and has already been discussed in detail.

However all the discussion did not cover my use case, which occurs on a daily basis:

  1. Play audio book.

  2. Run command to shutdown laptop after half an hour.

  3. close laptop lid turn off lights and go to sleep.

You can resolve this using the solution, provided by timlau, to use gsetting to manually set the power setting (He post links to a script to automatically set this using a zenity dialog).

gsettings set org.gnome.settings-daemon.plugins.power lid-close-ac-action “blank”
gsettings set org.gnome.settings-daemon.plugins.power lid-close-battery-action “blank”

End Rant.