Monday, October 21, 2013

Windows 8.1 Install: Don't panic on the first screen

So I am creating my standard development VM's for Windows 8.1 (Visual Studio 2013 and SQL Server 2012)  and the first screen that shows up during install is:


I tend to be a meticulous chaps and was surprised I'd selected the Windows 8 ISO by mistake. To quote the late, great Douglas Adams, "Don't panic." Windows 8.1 is just a flavor of Windows 8 so the screenshot is correct but the OS being installed is Windows 8.1.

Sunday, October 20, 2013

If it's an MSDN licensed Windows 8 -- no auto upgrade to Windows 8.1

I upgraded to Windows 8 immediately when it was released. The reason was simple -- Windows 8 64-bit supports Hyper-V with 64-bit VMs. As a server developer Windows 2008 R2 and Windows 2012 are 64-bit only. Windows 8's ability to mount ISO's is also a nice perk.

So Windows 8.1 arrives and my laptop that came initially with Windows 8.0 found the update in Windows Store without issue. Alas most of my other machines are installed using the MSDN Windows 8.0 ISO. After some googling (I binged it!) I found: Not all versions of Windows 8 support the free update from the Windows Store. The black list included editions of Windows 8 installed from an MSDN ISO and activated using multiple activation keys as is the case with MSDN.

Microsoft spells it out clearly here: Why can't I find the update in the Store?

Tuesday, October 15, 2013

PowerShell: Preventing Arrays from Acting like Scalars

PowerShell like many scripting languages plays fast and loose with types. When dealing with arrays, this can be problematic because PowerShell will interpret arrays to be scalars. This is exacerbated by PowerShell using the + operator to append items to an array. If the alleged array variable is treated as a scalar and not an array, the + operator has a completely different meaning.

This write-up will demonstrate how to insure arrays behave as arrays and not scalars. This write-up will cover the simple case of arrays created programmatically and the more interesting cases of arrays created through serialization via cmdlets and arrays returned by functions.

Consider the PowerShell script that any C++/C# developer would have written where allegedly the variable's type is specified ([Array] $BadArray):

[Array] $BadArray

$BadArray += 1
$BadArray += 2
$BadArray += 3

Write-Host "BadArray: $BadArray"

It should be noted that the line "[Array] $BadArray" does not declare a variable of type Array but instead casts a variable.

The previous code executes without an error and it is assumed the += operator will append the values of 1, 2, and 3 to be elements of the array. The output of this script should be an array with elements 1, 2, 3 but instead is the scalar value of 6:


Clearly, the variable $BadArray was treated as a scalar integer as 1 + 2 + 3 = 6.

The correct way to declare an array is to assign the array to an empty array using $() as is the case with variable $GoodArray below:

$GoodArray = @()

$GoodArray += 1
$GoodArray += 2
$GoodArray += 3

Write-Host "GoodArray: $GoodArray"

The output generated is as expected, an array containing elements 1, 2, and 3:


To make things interesting, an array of two elements is exported to an XML file using cmdlet Export-Clixml and then re-imported as an array using cmdlet Import-Clixml. After the array is de-serialized an additional element is appended to the end of the array ($BadFromDiskArray += 3):


$ToDiskArray = @()
$ToDiskArray += 1
$ToDiskArray += 2
$SerializationFile = 'D:\Blog\SerializedData.xml'

$ToDiskArray | Export-Clixml $SerializationFile
$BadFromDiskArray = Import-Clixml $SerializationFile
$BadFromDiskArray += 3
Write-Host "BadFromDiskArray: $BadFromDiskArray"

The output from the previous script shows the array being serialized and de-serialized correctly. The reason this works is because the array that was serialized has more than one element when it was serialized:


The previous example behaved correctly. The twist occurs when the serialized array contains one element. The below snippet shows an array with one element being serialized and de-serialized. Once the array is de-serialized two elements are appended to the array with the += operator (+= 2 and +=3):
$SerializationFile = 'D:\Blog\SerializedData.xml'

$ToDiskArray = @()
$ToDiskArray += 1
$ToDiskArray | Export-Clixml $SerializationFile
$BadFromDiskArray = Import-Clixml $SerializationFile
$BadFromDiskArray += 2
$BadFromDiskArray += 3
Write-Host "BadFromDiskArray: $BadFromDiskArray"

When the previous script is executed the de-serialized array is converted to a scalar because the array has one element:

This is the worst kind of developer nightmare – the code works correctly sometimes but at other times does not work. The solution is not to assign arrays directly from the return value from a cmdlet. The following code is not correct:

$BadFromDiskArray = Import-Clixml $SerializationFile

The correct way to handle arrays is to always append the results from the function to the array using the += operator. When the left-hand side is an array and the right-hand side is a scalar the += appends the scalar to the array on the left-hand side. When the left-hand side is an array and the right-hand side is an array the += appends the array to the right to the end of the array on the left.

The following snippet shows a single-element array being serialized and de-serialized. The de-serialized value may be an array or may be a scalar. The += operator highlighted below with boldface appends the value or values returned by Import-Clixml to the array on the left:

$ToDikArray = @()
$ToDiskArray += 1
$SerializationFile = 'D:\Blog\SerializedData.xml'
$ToDiskArray | Export-Clixml $SerializationFile

$GoodFromDiskArray = @()
$GoodFromDiskArray += Import-Clixml $SerializationFile
$GoodFromDiskArray += 2
$GoodFromDiskArray += 3
Write-Host "GoodFromDiskArray: $GoodFromDiskArray"

The results of this script demonstrate the array behaving as an array by the following screenshot displaying all the elements of the array and not behaving like a scalar:


Using += applies to both cmdlets and functions. Consider the following function that returns an array of elements based on the input parameter $numberOfElements:

function CreateAnArray($numberOfElements)
{
    $ReturnValue = @()
    for ($i = 0 $i -lt $numberOfElements $i++)
    {
        $ReturnValue += $i + 1
    }
    
    return $ReturnValue
}   

The previous function behaves correctly. The array is created as an empty array correctly ($ReturnValue = @()) and each element is appended to the array correctly using operator += ($ReturnValue += $i + 1).

The following code would exhibit incorrect behavior where an array, $EvilFromFunctionArray,  is assigned to the return value of the function:

$EvilFromFunctionArray = CreateAnArray(1)
$EvilFromFunctionArray += 2
$EvilFromFunctionArray += 3
Write-Host "EvilFromFunctionArray: $EvilFromFunctionArray"

The previous code will display a value of 6 because the alleged array $EvilFromFunctionArray is a scalar due to assignment.

The following code would exhibit correct behavior where the array is created as an empty array and the return value to the function is appended to the existing array variable $GoodFromFunctionArray:

$GoodFromFunctionArray = @()
$GoodFromFunctionArray += CreateAnArray(1)
$GoodFromFunctionArray += 2
$GoodFromFunctionArray += 3
Write-Host "GoodFromFunctionArray: $GoodFromFunctionArray"

The previous code will display a value of 1, 2, 3 because the return value of the CreateAnArray function is appended to the array variable $GoodFromFunctionArray.

The lesson learned is with arrays, append, and don't assign.

Thursday, October 10, 2013

Visual Studio Online (cloud-hosted TFS) for non-Visual Studio Developers

Update (September 18, 2014): the link to Team Explorer for Microsoft Visual Studio 2013 RC in this post was updated to reference the production release of this product Team Explorer for Microsoft Visual Studio 2013.

I was approached by a team of firmware engineers who had heard my pontificating on Microsoft's Visual Studio Online (Signing up for Microsoft Hosted Team Foundation Server (TFS) ). The firmware team was using SVN which gets high praise for how it integrates with Windows Explorer using various free open source clients. The question the firmware team asked me was, "Did they need to purchase Visual Studio to access Visual Studio Online?"

Team Explorer is the stand-alone client for accessing Visual Studio Online.  It just so happens that Visual Studio Online's Team Explorer is free from Microsoft so there are no barriers to using it with Team Foundation Server (TFS) run on an intranet or Visual Studio Online. Team Explorer is actually integrated with Visual Studio but it can be run stand-alone. When run stand-alone, Team Explorer is actually a one trick version of Visual Studio. The one trick it can perform is access to a TFS instance or Visual Studio Online.

The push to Visual Studio Online  is not meant to be a criticism of SVN. I respect SVN and have enjoyed using it. I have enjoyed using it in an environment with a strong IT department to manage SVN and insure it is backed up properly and maintained in a secure manner. Microsoft's Visual Studio Online is backed up and secured by Microsoft and Visual Studio is free for up to five users with source code access and an unlimited number of "stack holder" users with bug/task tracking access (Visual Studio Online - Stakeholder License).

To download Microsoft's Team Explorer at no charge access any of the following sites:

To download there is no need to log in or have an MSDN account. The Visual Studio 2013 download site is as follows:



When you click on download, you are prompted to download the executable or CD/DVD format (ISO):


Check the version to download and click on Next:


Obviously if the download does not start, you should pay attention to the prompt, "If your download has not start after 30 seconds, Click here".