I read this post the other day: How To Compete Against Yourself: Don’t Do Your Best, Do Better Than Your Personal Average. It’s got some great points on how to establish better habits and be more productive.

One of the big points was to find measurable stats and track them, and try to beat your average (not your best, because you’re putting out a high level of effort constantly which will burn you out).

I though to myself, “self, what’s a good stat for coding?” Doesn’t have to be a perfect model, but something simple and traceable. I thought of grabbing lines changed per day.

I did a bunch of research, and there’s not an easy way to get that data, not from git tools, not from github stats.

So I wrote the following PowerShell snippet that grabs the entire git log by author and date, parses the insertion/deletion counts, and sums it all up:

git log --pretty=oneline --shortstat --no-notes -C --after 2016-01-22 --before 2016-01-23 --author=chris | # grab git log. replace dates and author
Select-String '(\d+) insertion.*?(\d+) deletion' -AllMatches | # find insertion/deletion line and capture values
ForEach-Object { $_.Matches } | # pull in the regex
ForEach-Object { New-Object psobject -Property @{ Adds = $_.Groups[1].Value; Deletes = $_.Groups[2].Value } } | # for each match, capture adds/deletes into a ps object
Measure-Object -Property @("Adds","Deletes") -Sum # sum up the values

Replace my name with yours and use the dates you want (after yesterday and before today) and you’ll get some useful output like:

Count    : 7
Average  :
Sum      : 704
Maximum  :
Minimum  :
Property : Adds

Count    : 7
Average  :
Sum      : 95
Maximum  :
Minimum  :
Property : Deletes

I’m sure someone with some better PowerShell-fu could simplify the snippet. If that’s you, let me know!

How do you get a numeric-only string and ignore all non-numeric characters, using just standard SQL functions? There’s SQL replace and pattern functions, but they only work once on a string. So barring 53 nested REPLACE functions, it’s tough. I’ve run into this issue many times before while writing import scripts and the like.

Today, I had a stroke of brilliance – what if it could be done using FOR XML and spt_values to parse the entire string? A bit of googling and stack overflowing later, and some gluging of different parts together, and I came up with the following:

        SELECT SUBSTRING(FieldToStrip, Number, 1)
        FROM master..spt_values
        WHERE Type='p' AND Number <= LEN(FieldToStrip) AND
            SUBSTRING(FieldToStrip, Number, 1) LIKE '[0-9]' FOR XML Path(''))
    AS xml) AS varchar(MAX)))

Replace SourceTable with your table and FieldToStrip with your field, and away you go. If you want to include other allowed characters, change the pattern in the LIKE -- that specifies which characters to retain. All other fields will be removed.

Every time I need to set up a new server with Web Deploy/MSDeploy, I end up having to do a bunch of googling and tweaking and it never ends up being simple. The error messages are so arcane it's hard to know what the issue is when it doesn't work. There are several different ways to set up Web Deploy as well, from the IIS management service to a separate web deploy service. It’s fairly straightforward once you’ve got a good procedure to follow, but there are so many moving parts and the docs are horrible – fragmented blogs strewn everywhere each with a piece of the puzzle.

This most recent time I put together a comprehensive guide while I was working through the configuration.

First, set up IIS remote management services. You can do this through the UI:

  • Open role manager
    • Web Server -> Add Role Services
    • Management Tools -> Management Service
  • Open IIS Manager
    • <servername> -> Management Service
      • Check "Enable Remote Connections"
      • Check "Windows or IIS Manager"

Or batch file commands:

dism /online /enable-feature /featurename:IIS-WebServerRole
dism /online /enable-feature /featurename:IIS-WebServerManagementTools
dism /online /enable-feature /featurename:IIS-ManagementService

reg Add HKLM\Software\Microsoft\WebManagement\Server /V EnableRemoteManagement /T REG_DWORD /D 1

net start wmsvc
sc config wmsvc start= auto

Then, set up the Web Deploy service and connect it to IIS Manager:

  • Install web deploy from http://www.iis.net/downloads/microsoft/web-deploy
    • Make sure to install the deployment handler with delegation and non admin
  • Open IIS Manager
  • In the server configuration, add an IIS Manager user
  • Go to each website, IIS Manager Permissions and give user permissions
  • Add Web Management Service (wmsvc) permissions for each physical location where the site files will be located (Local Service, or whatever user wmsvc is running under)
  • Set WmSvc to start auto
  • (re)Start wmsvc
  • Open port 8172 on all relevant firewalls. If you're using Windows Firewall, you can use this:
    netsh firewall add portopening TCP 8172 WdeployAgent

Finally, set up a delegation rule to allow users to create applications. This is called a "Mark Folders as Applications" rule, using the createApp provider. If your applications are already existing and won't be created during deploy, you still need this because the rule is used required to verify that the application exists. You can skip the modify grant permission on applicationHost.config if you'll never be actually creating an application during deploy.

  • Create a user account (I call it "CreateAppUser")
  • Grant read permission to %windir%\system32\inetsrv\config.
  • Grant modify permission to %windir%\system32\inetsrv\config\applicationHost.config. Skip this step if you won't be creating any applications during deploy
  • Open Management Service Delegation in IIS Manager
  • Add a Mark Folders as Applications Rule
  • Set the CreateAppUser as the Run As user, using a Specific User type
  • Click OK and a Add User To Rule dialog will come up
  • Enter * in the Name and click OK. This will allow all users to create applications.

And… done!

The first time you open VS and try to publish, go through the whole wizard to make sure settings are correct. You'll likely get a popup about the untrusted certificate used by IIS Manager -- accept the certificate.

You also may need to add the following rules (templates are included in the Add Rule box) to do a full publish:

  • Deploy Applications with Content
  • Set Permissions for Applications
When you set those up, use the defaults, and * for the Name in the Add User To Rule dialog.

By default, SQL Server 0’s out database files as it allocates space for them. This can be good for security/reliability in a production environment, but it means SQL Server is writing a bunch of extra data. Turn on instant file initialization in dev/stage/test environments for dramatically faster database creation and backup/restore operations.

There’s no switch for this in SQL Server, strangely enough. To get instant file initialization enabled, you’ve got to grant the “Perform volume maintenance tasks” permission to the SQL Server service account.

Brad McGehee’s got a great detailed analysis of what happens with instant file initialization and walkthrough steps with screenshots.

Microsoft’s Dynamic Linq library has been floating around the internet in one form or another for years. Its been distributed as a raw .cs file, not a NuGet or any sort of supported package. The most central location I’ve found for this is King Wilder’s System.Dynamic.Linq GitHub repo and NuGet package.

I needed support for a couple of things that weren’t included in the original version, namely Sum/Average/Min/Max functions, and that in a dynamically callable way. So I built that, cribbing off of a Sum function found on StackOverflow. The code takes the name of the function you want to call and the name of the property you want to aggregate. It then uses reflection to grab the extension method of the correct type based on the property type you specify and executes it against the IQueryable, returning the result.

After a bit of jiggering, I realized that Sum and Average have totally different signatures than Min/Max for some reason. Adding in separate branches to the code did the trick and I came up with:

/// <summary>
/// Dynamically runs an aggregate function on the IQueryable.
/// </summary>
/// <param name="source">The IQueryable data source.</param>
/// <param name="function">The name of the function to run. Can be Sum, Average, Min, Max.</param>
/// <param name="member">The name of the property to aggregate over.</param>
/// <returns>The value of the aggregate function run over the specified property.</returns>
public static object Aggregate(this IQueryable source, string function, string member)
    if (source == null) throw new ArgumentNullException("source");
    if (member == null) throw new ArgumentNullException("member");

    // Properties
    PropertyInfo property = source.ElementType.GetProperty(member);
    ParameterExpression parameter = Expression.Parameter(source.ElementType, "s");
    Expression selector = Expression.Lambda(Expression.MakeMemberAccess(parameter, property), parameter);
    // We've tried to find an expression of the type Expression<Func<TSource, TAcc>>,
    // which is expressed as ( (TSource s) => s.Price );

    var methods = typeof(Queryable).GetMethods().Where(x => x.Name == function);

    // Method
    MethodInfo aggregateMethod = typeof(Queryable).GetMethods().SingleOrDefault(
        m => m.Name == function
            && m.ReturnType == property.PropertyType // should match the type of the property
            && m.IsGenericMethod);

    // Sum, Average
    if (aggregateMethod != null)
        return source.Provider.Execute(
                aggregateMethod.MakeGenericMethod(new[] { source.ElementType }),
                new[] { source.Expression, Expression.Quote(selector) }));
    // Min, Max
        aggregateMethod = typeof(Queryable).GetMethods().SingleOrDefault(
            m => m.Name == function
                && m.GetGenericArguments().Length == 2
                && m.IsGenericMethod);

        return source.Provider.Execute(
                aggregateMethod.MakeGenericMethod(new[] { source.ElementType, property.PropertyType }),
                new[] { source.Expression, Expression.Quote(selector) }));

I've submitted a pull request with this function to kahnau's repo, and he seems pretty responsive about accepting pull requests, so this will likely be in that NuGet soon.