Delete a file and its history from TFS


What if you need to delete a file and all its history from tfs for some reason. Maybe someone checked in a password or api key?

tf destroy /startcleanup "$/" /collection:http://:8080/tfs/DefaultCollection

This also works for folders depending on how specific the filepath is. You can add /preview to see what files will be destroyed.

More Info at: https://docs.microsoft.com/en-us/azure/devops/repos/tfvc/destroy-command-team-foundation-version-control?view=vsts

notepad++ regex replace


Problem: I have a file with many variable length lines with a decimal number on the end (i.e. a transaction statement that was not formatted very well) and I needed to extract just the decimal value on the end.

Solution: I used the regular expression replace feature in Notepad++. The regular expression is some like "for each line match the decimal number at the end). The magic part is on the Replace with field I needed \1 to replace each line with just the matched section. I could probably have expanded on this to retain all the values and put tab separators in so it could copy and paste it into excel!


Import IIS logs into SQL Server table

There are lots of IIS log parsers out there, but I found a simple SQL script that will load them into your own SQL Server table for you to query how you like.

CREATE TABLE dbo.IISLOG (
 [DATE] [DATE] NULL,
 [TIME] [TIME] NULL,
 [s-ip] [VARCHAR] (48) NULL,
 [cs-method] [VARCHAR] (8) NULL,
 [cs-uri-stem] [VARCHAR] (255) NULL,
 [cs-uri-query] [VARCHAR] (2048) NULL,
 [s-port] [VARCHAR] (5) NULL,
 [s-username] [VARCHAR] (128) NULL,
 [c-ip] [VARCHAR] (48) NULL,
 [cs(User-Agent)] [VARCHAR] (1024) NULL,
 [cs(Referer)] [VARCHAR] (4096) NULL,
 [sc-STATUS] [BIGINT] NULL,
 [sc-substatus] [INT] NULL,
 [sc-win32-STATUS] [INT] NULL,
 [time-taken] [INT] NULL
)

BULK INSERT dbo.IISLOG
FROM 'c:\temp\u_ex171205.log'
WITH (
 FIRSTROW = 5,
 FIELDTERMINATOR = ' ',
 ROWTERMINATOR = '\n'
)


SELECT [cs-uri-stem], avg([time-taken])
FROM dbo.IISLOG
WHERE [cs-uri-stem] like '%.svc'
GROUP BY [cs-uri-stem]
ORDER BY avg([time-taken]) desc


This tip is based on this post, but contains fixed field lengths and bulk import statement.

How to script SQL server database role permissions

SELECT 'GRANT ' + database_permissions.permission_name +
    CASE database_permissions.class_desc
        WHEN 'SCHEMA' THEN ' ON ' +schema_name(major_id)
        WHEN 'OBJECT_OR_COLUMN' THEN
            CASE WHEN minor_id = 0 THEN ' ON ' +object_name(major_id) COLLATE Latin1_General_CI_AS_KS_WS
            ELSE ' ON ' +(SELECT object_name(object_id) + ' ('+ name + ')'
                  FROM sys.columns
                  WHERE object_id = database_permissions.major_id
                  AND column_id = database_permissions.minor_id) end
        ELSE ''
    END +
    ' TO ' + database_principals.name COLLATE Latin1_General_CI_AS_KS_WS
FROM sys.database_permissions
JOIN sys.database_principals
ON database_permissions.grantee_principal_id = database_principals.principal_id
LEFT JOIN sys.objects --left because it is possible that it is a schema
ON objects.object_id = database_permissions.major_id
WHERE permission_name in ('SELECT','INSERT','UPDATE','DELETE','EXECUTE') AND database_principals.NAME = ''

How can I see what certificates are installed on a Windows computer with PowerShell

Using PowerShell to view certificates is easy. PowerShell has a provider that exposes the certificates store which is part of the pki and security modules, which are loaded automatically as long as you’re on version 3 or greater. You do not need to manually load the modules, they auto-load from PowerShell v3 and above.
To view the certificates in the local users personal certificate store/local machine store I would use the following:  
#Change to the location of the personal certificates
Set-Location Cert:\CurrentUser\My

#Change to the location of the local machine certificates
Set-Location Cert:\LocalMachine\My

#Get the installed certificates in that location
Get-ChildItem | Format-Table Subject, FriendlyName, Thumbprint -AutoSize

Compare Branches with Beyond Compare

After I do a big merge I always like to compare my source and target branches to review the differences. My tool of choice for this is Beyond Compare as its folder compare is extremely quick and it lets me easily exclude file types and folders that of no consequence and generate noise.

This is a good starting point for the filters. It excludes your compiled code, test results, files with user settings which don't usually get checked in. 
Filter Expression: -*.dll;-*.suo;-*.pdb;-*.user;-UpgradeLog.htm;-*.lnk;-*.vspscc;-*.vssscc;-bin\;-obj\;-.vs\;-TestResults\;-.git\

This is what it looks like in Beyond compare which is a bit easier to digest

You can also save this filter by clicking "Add To Presets" and it will be added to your file filter dropdown ready to go for next time!

Convert object to csharp object initialization code

Below is a class that will convert any object into c# code that would statically initialize that object.

Why is this cool? - Suppose you need to write unit tests for a web service with quite complex structures (I'm looking at you swift/iso22000). Manually coding data into tests could take quite a while but if you already have some examples from logged requests or sample XML files you could use something like the below class to emit c# object initialization code and BAM your template code is written.

public static class ObjectInitializationSerializer
{
    private static string GetCSharpString(object o)
    {
        if (o is bool)
        {
            return $"{o.ToString().ToLower()}";
        }
        if (o is string)
        {
            return $"\"{o}\"";
        }
        if (o is int)
        {
            return $"{o}";
        }
        if (o is decimal)
        {
            return $"{o}m";
        }
        if (o is DateTime)
        {
            return $"DateTime.Parse(\"{o}\")";
        }
        if (o is Enum)
        {
            return $"{o.GetType().FullName}.{o}";
        }
        if (o is IEnumerable)
        {
            return $"new {GetClassName(o)} \r\n{{\r\n{GetItems((IEnumerable)o)}}}";
        }

        return CreateObject(o).ToString();
    }

    private static string GetItems(IEnumerable items)
    {
        return items.Cast().Aggregate(string.Empty, (current, item) => current + $"{GetCSharpString(item)},\r\n");
    }

    private static StringBuilder CreateObject(object o)
    {
        var builder = new StringBuilder();
        builder.Append($"new {GetClassName(o)} \r\n{{\r\n");

        foreach (var property in o.GetType().GetProperties())
        {
            var value = property.GetValue(o);
            if (value != null)
            {
                builder.Append($"{property.Name} = {GetCSharpString(value)},\r\n");
            }
        }

        builder.Append("}");
        return builder;
    }

    private static string GetClassName(object o)
    {
        var type = o.GetType();

        if (type.IsGenericType)
        {
            var arg = type.GetGenericArguments().First().Name;
            return type.Name.Replace("`1", $"<{arg}>");
        }

        return type.Name;
    }

    public static string Serialize(object o)
    {
        return $"var newObject = {CreateObject(o)};";
    }
}

How to write confusing angular - Changing the default angular delimiter.

I just spent a wasted hour trying to figure out why an angular app written by one of my employers contracts was behaving so strangely. Apparently in angular you can override the default {{}} delimiter like so:

var myApp = angular.module('myApp', [], function($interpolateProvider) {
    $interpolateProvider.startSymbol('[[');
    $interpolateProvider.endSymbol(']]');
});
You would now define a template{{ var }} as [[ var ]]

Check the documentation on the $interpolate service here: http://docs.angularjs.org/api/ng.$interpolate
I really can't think of a reason why you would want to do this offhand - unless you are trying to be a troll Javascript hipster!

Great trap for young players.

WCFExtras XML comment doesn't work?

WCFExtra's is an awesome addition to any WCF project which enables you to include your code comments as documentation in the generated wsdl.

The documentation is pretty ordinary though. To make the XMLComments work first we need to follow the instructions here: https://wcfextrasplus.codeplex.com/wikipage?title=XML%20Comments&referringTitle=Documentation

Next, you need to enable XML document generation in your WCF project properties as follows: 
  1. Right click on your project and select properties
  2. Go to the build tab
  3. Tick XML documentation file. Leave the generated filename as is.

Repeat this process for any other references projects that are used in your service contract.

Now we should see wsdl:documentation tag appeared in our WSDL

How to ignore non-trival differences in files with Beyond Compare

If you want to ignore something that can't be handled by a replacements because the to-state isn't easily defined such as mismatching page numbers you need to use a regular expression grammer to ignore certain strings.
In my case I needed to ignore Page numbers in a document footer
Here is how to do it:
  1. Load your comparison in Beyond Compare
  2. Click the Rules toolbar button (referee icon).
  3. On the Importance tab, click Edit Grammar.
  4. Click New.
  5. In Text matching enter your regex e.g. "Page\s\d{1,3}\sof\s\d{1,3}"
  6. Tick Regular Expression
  7. Click OK.
  8. Click OK.
  9. Un-check the element in the Grammar elements list to make it unimportant.
  10. Click OK
Your grammar should now be marked as unimportant (blue text)