Remove orphan collection item without related database in TFS 2013 with Update 2

Last week, the Configuration Manager in our company tested to create a collection in Team Foundation Server (TFS for short) 2013 with Update 2. After test, the database of this collection is deleted directly from SqlServer by mistake and there is no backup for it. So an orphan item for this collection is still existed there and have to be removed manually.

 

First, I try to remove it from Team Foundation Server Administration Console (TfsMgmt.exe). It failed in detach process.

Then, I try to do it with TFSconfig.exe in console mode. I’m pretty sure that’s work in previous version of TFS, maybe 2012. But in 2013 with Update 2, it failed the same as TfsMgmt.

I tried to use a database from another collection by renaming it as the deleted one, or even use a database created with another TFS instance with the same collection name, all failed.

At that time, I turned to MSDN forum. One MVP provided some tables within Tfs_Configuration database. Some deleting operations should be taken there. After that, the collection is removed from the TfsMgmt but it still can be found in Visual Studio at client side.

Finally, I detached all collections and redeployed the whole TFS instance. That works as predictable.

 

If somebody falls into the same jam, the detachment and redeployment is the only way to correct it, unless you have the backup of that deleted database.

 

Related: http://social.msdn.microsoft.com/Forums/vstudio/en-US/3a072d51-298a-48b5-a57e-301f5ef2670f/how-to-delete-a-collection-without-related-database-connected-tfs-2013-update-2?forum=tfsgeneral

Visual Studio 2013 Update 1 is not compatible with Windows 8.1 with Update (MSDN CD) while using sysprep

While the new installation CD named Windows 8.1 with Update launched for MSDN subscriptions user, I downloaded it and try to upgrade all the images from the Windows Deployment Service in my company. But I found the new version of Windows 8.1 might have some problem with Visual Studio 2013 Update 1.

 

Coz I need to upgrade some related images in batch, this is my way:

Create a VM and install Windows 8.1 (x64 enterprise version with update, downloaded from MSDN subscriptions site);

  1. Install Office 2013 with Service Pack 1 (VL version, coz there is a KMS in our company);
  2. Update to the latest patches;
  3. Run Cleanmgr to minimal the system;
  4. Create a snapshot named Office 2013;
  5. Use Sysprep to boot into the audit mode;
  6. Remove the current user;
  7. Use Sysprep to boot into the OOBE mode with Generalize checked;
  8. Use WDS to capture this status and upload, named as Office 2013. Before capturing, I deleted the pagefile, swap file and the contents within temp folder.

It works great.

Then,

  1. Reverse to snapshot Office 2013;
  2. Install Visual Studio 2013 with Blend, Office Developer Tools, SQL Server Data Tools, Web Developer Tools, Silverlight Development Kit; (No C++, nor mobile things)
  3. Install Update 1 from iso;
  4. Install Visual Studio SDK;
  5. Update to the latest patches;
  6. Run Cleanmgr to minimal the system;
  7. Create a snapshot named Visual Studio;
  8. Use Sysprep to boot into the audit mode;
  9. Remove the current user;
  10. Use Sysprep to boot into the OOBE mode with Generalize checked;
  11. Use WDS to capture this status and upload, named as Visual Studio. Before capturing, I deleted the pagefile, swap file and the contents within temp folder.

It looks familiar right? Actually, it WON’T WORK.

After deploy from this Visual Studio and create a new user, system end with this text:

The User Profile Service service failed the sign-in.

User profile cannot be loaded.

Even when trying to boot from the template VM in current status, it failed in the same way.

But if I try to install Team Explorer from Team Foundation Server with Update 2 CD instead, or using the Office 2013 image created above, it works like a charm. Even just use the old Windows 8.1 CD instead of the new one, it still works great.

I’ve check by using reg in command line. There is nothing wrong like this KB mentioned: http://support.microsoft.com/kb/947215.

I have no clue about this but just leave a message here for avoiding others go into the same jam.

 

 

Update: It fixed in VS 2013 with Update 2.

Install dotNet framework 3.5 on Win8 / WinSvr2012

We know that from Windows Vista, the original optical media is useless after you finish system installation. Enabling a role of feature do not require that media any more.

But in Windows 8 / Windows Server 2012, for some reason we don’t know, the situation is changed a little. The setup package of dotNet framework 3.5 is not pre-copied to your hard drive. It will have to be downloaded from Microsoft while enabling that feature.

If you hate this, luckily, that setup package is on installation media also. We just need to tell the system to use that instead of downloading.

You may want to run this as administrator:

DISM /Online /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:d:\sources\sxs

where:

  • /Online targets the operating system you’re running (instead of an offline Windows image).
  • /Enable-Feature /FeatureName:NetFx3 specifies that you want to enable the .NET Framework 3.5.
  • /All enables all parent features of the .NET Framework 3.5.
  • /LimitAccess prevents DISM from contacting Windows Update.
  • /Source specifies the location of the files needed to restore the feature (in this example, the D:\sources\sxs directory).

Source: http://msdn.microsoft.com/en-us/library/hh506443.aspx

C#: Convert a tree node and sub nodes to text

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TreeToText
{
    class TreeToText
    {
        const string LineMid = "├─";
        const string LineLast = "└─";
        const string Line = "│  ";
        const string Space = "    ";

        /// <summary>
        /// Convert a tree node to text
        /// </summary>
        /// <param name="node">Root node to convert</param>
        /// <returns>Text</returns>
        public static string Tree2Text(TreeNode node)
        {
            if (node == null) return null;
            StringBuilder builder = new StringBuilder();
            builder.AppendLine(TreeNodeText(node));
            Tree2Text(builder, node, "");
            return builder.ToString();
        }

        static string TreeNodeText(TreeNode node)
        {
            return node.Text;
        }

        static void Tree2Text(StringBuilder builder, TreeNode parent, string prefix)
        {
            int nodesCount = parent.Nodes.Count;
            if (nodesCount == 0) return;
            int nodeMaxIndex = nodesCount - 1;
            for (int i = 0; i < nodesCount; i++)
            {
                builder.Append(prefix);
                TreeNode node = parent.Nodes[i];
                if (i != nodeMaxIndex)
                {
                    builder.Append(LineMid);
                    builder.AppendLine(TreeNodeText(node));
                    Tree2Text(builder, node, prefix + Line);
                }
                else
                {
                    builder.Append(LineLast);
                    builder.AppendLine(TreeNodeText(node));
                    Tree2Text(builder, node, prefix + Space);
                }
            }
        }
    }
}

中国IP地址段抽取工具

本工具可以将所有中国的IP v4地址段抽取出来,并按照用户给定的格式保存。
通常可以用于制作特定的路由表。

IP信息来源:每次运行时自动获取自APNIC。
运行需要:dotnet Framework 4.0

运行前,请用文本编辑器打开CNRouteExtractor.exe.config,按照注释修改其中的Format字符串。
运行时的格式:CNRouteExtractor filename
将生成filename作为目标输出文件。如不指定filename则不输出(仅测试下载与抽取)。

下载地址

C#: Split a Distinguished Name of Active Directory into array of string

class DistinguishedNameSplit
{
    static string[] hexCodes = new string[] { "0""1""2""3""4""5""6""7""8""9""a""A""b""B""c""C""d""D""e""E""f""F" };
 
    public static List<string> Split(string distinguishedName)
    {
        List<string> pool = new List<string>();
        StringBuilder working = new StringBuilder();
        string hexHigh = "";
        MachineStatus status = MachineStatus.A;
        int index = 0;
        int indexMax = distinguishedName.Length - 1;
 
        while (index <= indexMax)
        {
            string value = distinguishedName.Substring(index, 1);
            switch (status)
            {
                case MachineStatus.A:
                    if (value == ",")
                    {
                        pool.Add(working.ToString());
                        working.Clear();
                    }
                    else if (value == "\"")
                    {
                        working.Append("\"");
                        status = MachineStatus.B;
                    }
                    else if (value == "\\")
                    {
                        status = MachineStatus.C;
                    }
                    else
                    {
                        working.Append(value);
                    }
                    break;
                case MachineStatus.B:
                    if (value == "\"")
                    {
                        working.Append("\"");
                        status = MachineStatus.A;
                    }
                    else if (value == "\\")
                    {
                        status = MachineStatus.E;
                    }
                    else
                    {
                        working.Append(value);
                    }
                    break;
                case MachineStatus.C:
                    if (value == "," || value == "\"" || value == "\\")
                    {
                        working.Append(value);
                        status = MachineStatus.A;
                    }
                    else if (hexCodes.Contains(value))
                    {
                        hexHigh = value;
                        status = MachineStatus.D;
                    }
                    else
                    {
                        throw new ArgumentException("The distinguished name specified is not typed legally.");
                    }
                    break;
                case MachineStatus.D:
                    if (hexCodes.Contains(value))
                    {
                        working.Append((char)Convert.ToByte(String.Format("{0}{1}", hexHigh, value), 16));
                        status = MachineStatus.A;
                    }
                    else
                    {
                        throw new ArgumentException("The distinguished name specified is not typed legally.");
                    }
                    break;
                case MachineStatus.E:
                    if (value == "," || value == "\"" || value == "\\")
                    {
                        working.Append(value);
                        status = MachineStatus.B;
                    }
                    else if (hexCodes.Contains(value))
                    {
                        hexHigh = value;
                        status = MachineStatus.F;
                    }
                    else
                    {
                        throw new ArgumentException("The distinguished name specified is not typed legally.");
                    }
                    break;
                case MachineStatus.F:
                    if (hexCodes.Contains(value))
                    {
                        working.Append((char)Convert.ToByte(String.Format("{0}{1}", hexHigh, value), 16));
                        status = MachineStatus.B;
                    }
                    else
                    {
                        throw new ArgumentException("The distinguished name specified is not typed legally.");
                    }
                    break;
            }
            index++;
        }
 
        if (status == MachineStatus.A)
        {
            pool.Add(working.ToString());
            return pool;
        }
        else
        {
            throw new ArgumentException("The distinguished name specified is not ended correctly.");
        }
    }
 
    enum MachineStatus
    {
        A, B, C, D, E, F
    }
}