Sunday, August 12, 2012

Enabling and disabling Windows Features from the command line

This blog post briefly describes how to use the DISM.EXE command to enable or disable Windows Features from the command line. Normally you’d use the Programs and Features –> Turn Windows features on or off dialog in the Control Panel to enable a Windows feature such as IIS or MSMQ. I prefer to use the command line for anything I can, partly because of a left-over habit from my DOS (and some Linux) days, but mostly because it means I can automate things in batch files.

Start an elevated command prompt. (Right-click on Command Prompt and click "Run as administrator").

To find the name of the feature you want to enable or disable, first list all the installed features. To list all the features available on the PC, whether enabled or not, run:

C:\> dism /Online /Get-Features

This will display the long list of all the available features and their Enabled/Disabled state.

Filter to the list to find the name of the specific feature you're looking for.  For example, to find the Hyper-V features:

C:\> dism /Online /Get-Features /Format:Table | find "Hyper"
Microsoft-Hyper-V-All                                 | Disabled
Microsoft-Hyper-V-Tools-All                           | Disabled
Microsoft-Hyper-V                                     | Disabled
Microsoft-Hyper-V-Management-Clients                  | Disabled
Microsoft-Hyper-V-Management-PowerShell               | Disabled

When you find the name of the feature (for example Microsoft-Hyper-V), you can enable it with:

C:\> dism /Online /Enable-Feature /FeatureName:Microsoft-Hyper-V /All

Deployment Image Servicing and Management tool
Version: 6.2.9200.16384

Image Version: 6.2.9200.16384

Enabling feature(s)
[==========================100.0%==========================]
The operation completed successfully.
Restart Windows to complete this operation.
Do you want to restart the computer now? (Y/N)

Similarly, to disable the feature again, run:

C:\> dism /Online /Disable-Feature /FeatureName:Microsoft-Hyper-V-All

Deployment Image Servicing and Management tool
Version: 6.2.9200.16384

Image Version: 6.2.9200.16384

Disabling feature(s)
[==========================100.0%==========================]
The operation completed successfully.
Restart Windows to complete this operation.
Do you want to restart the computer now? (Y/N)

This should work on Windows 8 as well as Windows 7 and Windows Server 2008 R2.

Saturday, June 09, 2012

Using SQL UPDATE with ROW_NUMBER()

The problem:

The application is displaying a list of “To-do” tasks from a SQL Server database table, but the rows are currently displayed in an arbitrary order which is not necessarily in the order the user wants them to be displayed. We want to add a new feature to the application to allow the user to specify the order of the To-do items in the list (i.e. a priority for each To-do item).

We want to introduce a new “sort order” (or sequence number) column to the table to allow the user to specify the order in which the rows are to be displayed.

Adding a new column to the “create table” script (for new databases) is obviously straightforward.  But the problem is that we also need to be able to upgrade (migrate) existing customers to the new table structure.

Therefore we need to create a SQL migration script to add a new priority / sort-order column to the existing Todo table.

Currently the Todo table structure looks like this:

create table Todo
(
TodoId bigint not null primary key identity,
Priority nvarchar(10) not null,
Title nvarchar(200) not null,
DateDone datetime null
)

The following query used by the application to retrieve the Todo list illustrates the problem:

select * from Todo order by Priority

Result:











































TodoIdPriorityTitleDateDone
4HighCall JoeNULL
2HighBackup computerNULL
3LowWash carNULL
5LowMow the lawnNULL
6LowGroceriesNULL
7MediumPick up package at post officeNULL
1MediumTake the dog for a walkNULL

Notice above that the first two ‘High’ priority items are shown in an arbitrary order.  We may want to order it by the “TodoId” column which is perhaps slightly better, but still not necessarily in the order the user wants to see the tasks.


The solution:


We have to produce two SQL scripts: one is the script used for new installations, the second is to upgrade/migrate existing databases to the new structure.


The first part is easy: for new installation script we just add the new column:

sortOrder int not null

But in the migration script for existing databases, we initially have to add the new “sortOrder” column as a nullable field since there are already rows in the table and we need to provide reasonable initial/default value for the new column first.  So we first add the column as a nullable, and we’ll alter the table afterwards to make it ‘not null’.


So the first step in the migration script is to add the new field to the existing Todo table:

alter table Todo add sortOrder int null

Now we need to update the Todo table to provide an appropriate initial value for the new sortOrder field in each row.


Our Todo tasks are priortised as ‘High’, ‘Medium’ or ‘Low’.  We want the sortOrder value to start from 1 and increment for each subsequent row within each of these 3 priorties.  In other words, we want the two ‘High’ priority tasks to be given a sortOrder value of 1 and 2, the same for the two ‘Medium’ tasks, and the three ‘Low’ priority tasks need to be given a sortOrder of 1, 2, and 3.


The trick is to use the SQL UPDATE statement together the SQL Server ROW_NUMBER() function.


First, let’s just select the data using the ROW_NUMBER() function to see how we can get an appropriate initial value for sortOrder for each row:

select TodoId, Priority, Title,
ROW_NUMBER() over(partition by Priority order by TodoId) as rowIndex
from Todo
order by Priority, rowIndex

Result:











































TodoIdPriorityTitlerowIndex
2HighBackup computer1
4HighCall Joe2
3LowWash car1
5LowMow the lawn2
6LowGroceries3
1MediumTake the dog for a walk1
7MediumPick up package at post office2

The “rowIndex” value in the result above gives us the correct value we’d like to update the new sortOrder column with for each row.


Now we need to combine this query with a SQL UPDATE statement to update sortOrder:

update t
set sortOrder = rowIndex
from
(
select sortOrder, ROW_NUMBER() over(partition by Priority order by TodoId) as rowIndex
from Todo
where sortOrder is null
) as t

Now “sortOrder” has the desired values partitioned by priority.


The last step is just to make the sortOrder column not null:

alter table Todo alter column sortOrder int not null

Also see:


Tuesday, May 29, 2012

Why blog?

I've decided to give blogging a try once again.

I have new questions every day and I learn something new every day. I'm very fortunate to work with an extremely talented team at the moment, and I've never learned so much from others as I am on my current project.

It would be a shame not to share some of the useful patterns and practices I'm learning from them (assuming my attempt at conveying the ideas will do it justice!).

As a developer, you inevitably have to "research" various bits and pieces every day anyway. I often feel the need to write down what I learn to help myself remember it. Sometimes I send an email to colleagues explaining something (e.g. like why I think we should use xUnit.net instead of MSTest) and then think afterwards: "I just spent 30 minutes working on this email that might get read by one or two people, I should've written it as a blog post instead!"

I'm hoping that blogging about a few of the things that I'm learning, will
(a) encourage me to dig a little deeper into the topics that I'm "researching";
(b) document my findings for my own future reference;
(c) hopefully help the occasional anonymous beginner programmer doing a Google search and somehow coming across this blog.

However, blogging isn't easy for me. I think about an idea or concept. In my mind I imagine the idea might be worth a blog post. "I've got an idea for a blog post! It's going to be epic!" My blog post ideas are usually formed around a few keywords. But as I start fleshing out the post, the structure just doesn't work. My thoughts don't come out into words the way I imaged it would when I started. Then the post just remains unfinished forever in a lost text file somewhere.

That is why I almost never blog. I'm never satisfied with the result. But I've decided to stop caring so much and just start doing it. Even the current plain theme of this blog is an example of how I'm deliberately trying to get over this time-wasting "perfectionism".

It does mean I'm revealing my perhaps unpopular opinions, biases, weaknesses and sometimes chaotic thoughts to the world (assuming anyone actually reads it) which is a slightly scary thought.

Your Blog Is The Engine of Community.