Server 2008 R2 Read-Only disks in ESX Templates

During the build process of my Windows Server 2008 R2 VM templates, I had perplexing problem with my second virtual disk after sysprep completed. In my previous blog post I showed a PowerShell command that reassigned a drive letter. Worked great, but a noticed a problem. My “D” drive, which is a second PVSCSI disk, was being mounted as read-only. If I manually took the disk offline and brought it back online, magically it was read-write.

However, using a script to take the disk offline and bring it online did not remove the read-only attribute. After a bit more digging, I found a command that works like a charm. I had to change the disk attributes and clear the read-only flag.

The full PowerShell script, which I call from the c:Windowssetupscriptssetupcomplete.cmd file, is shown below.

$script = $Null

$script = @”

select disk 1

online disk noerr

attributes disk clear readonly

$scriptdisk += $script + “`n”

$scriptdisk diskpart

echo E: %{$a = mountvol $_ /l;mountvol $_ /d;$a = $a.Trim();mountvol Z: $a}

I don’t know if the read-only problem comes from sysprep, changing drive letters, a VMware thing, or what. Since the script is executed during the sysprep process, you never know what is going on behind the scenes. Drive letters get changed and the D drive is read-write, just as you’d expect.

Change a volume drive letter with Powershell

I ran across a useful command that instantly reassigns a drive to another letter, and another one liner that detects a CD-ROM and assigns it a particular letter. For additional details and a richer script, check out this blog post from The Admin Guy. The piece that I found most useful from his script was (replace ! with the pipe symbol):

(gwmi Win32_cdromdrive).drive ! %{$a = mountvol $_ /l;mountvol $_ /d;$a = $a.Trim();mountvol x: $a}

That one liner detects a CD-ROM drive and re-assigns it the letter X. Works great on systems with one CD-ROM. Taking this as an example, I slightly modified the command to take as an input a fixed drive letter and then re-assign it another letter. Here the drive changes from X to Y. Replace ! with the pipe symbol.

echo x: ! %{$a = mountvol $_ /l;mountvol $_ /d;$a = $a.Trim();mountvol y: $a}

One great thing about these commands is that the change happens immediately, unlike a VBS script I was trying to use earlier this week that just hacked the registry and required a reboot. I’m using these scripts in my Server 2008 R2 ESX template to re-assign various drive letters during the sysprep process.

Create 32-Bit system ODBC DSN with Powershell

This Powershell script creates a 32-bit system DSN on a 64-bit server. I got tired of manually creating DSNs for my VMware vCenter installations, so I automated the process. The only argument you need to pass to the script is the FQDN or IP address of your SQL server. If you don’t pass any arguments, the script will abort with an error message.

I apologize for the line wraps, but I think its fairly obvious where the breaks are. You can change the $DSNName to be any name that you wish. $DBName is the name of the database on the SQL server. The script assumes the SQL 2008 native client is installed. If you use a different client you will need to modify the script a bit.

## Creates a 32-bit System DSN on 64-bit OS.

$DSNName = “vCenter Server Update Manager”
$DBName = “vCenter Update Manager”

If($args[0] -eq $NULL) { echo “Must specify FQDN or IP of SQL server.”; Exit}



md $HKLMPath1 -ErrorAction silentlycontinue

set-itemproperty -path $HKLMPath1 -name Driver -value “C:WINDOWSSysWOW64sqlncli10.dll”

set-itemproperty -path $HKLMPath1 -name Description -value $DSNName
set-itemproperty -path $HKLMPath1 -name Server -value $args[0]
set-itemproperty -path $HKLMPath1 -name LastUser -value “”
set-itemproperty -path $HKLMPath1 -name Trusted_Connection -value “Yes”
set-itemproperty -path $HKLMPath1 -name Database -value $DBName

## This is required to allow the ODBC connection to show up in the ODBC Administrator application.

md $HKLMPath2 -ErrorAction silentlycontinue

set-itemproperty -path $HKLMPath2 -name “$DSNName” -value “SQL Server Native Client 10.0”