File extension for Windows Language Packs

For some reason I have a mental block and can’t seem to remember this, but instead of using dism to install language packs on Windows 7 or above, like this…

dism /online /add-package /packagepath:<path to language pack .cab file>

…you can also simply rename the .cab language pack file to have the .mlc file extension and double-click it.

There’s yet another way too, and that’s to run the lpksetup.exe utility and point it at your .cab file I think. Haven’t tried that though as I think the .mlc method is easier.

Long startup and logon delays with a shared Windows 7 desktop

I’m writing with reference to a colleague’s blog post where he has found a very useful fix for a very annoying start up and log-on delay issue in Windows 7 SP1. Here’s his post, worth a read:

We were finding that computers in shared areas which had been logged on by many users (i.e. 50+ user profiles) were experiencing massive delays starting up and logging on. Until he found the fix the only solution was to leave the computers on all the time, or get them to start up really early in the morning.

One fix we tried was removing all the user profiles from the computers, and this only worked some of the time. Then my colleague found the right hot-fix and all of a sudden our startup and logon times dropped back to a few minutes. Big relief!

Here’s the relevant hotfix:

See the blog entry (linked above) for a detailed explanation.

A way to run a 64-bit process from a 32-bit script (like add a registry key)

Say you have a need to add a registry key into the 64-bit registry hive but you’re stuck with doing it from a vbscript running in a 32-bit process. For example SCCM always runs vbscript in a 32-bit process, even on a 64-bit Windows machine! If you try this normally Windows 7 64-bit will redirect the key to the virtual 32-bit hive. So running in a 32-bit process if we want to add a key to HKLM\Software\ you will find it will always end up in HKLM\Software\Wow6432Node\ no matter what you do.

I couldn’t find a way to do it directly using vbscript in the short time I spent looking into it, but I did find a sneaky indirect way. My method is to execute a command to add a scheduled task into Windows that will do it for you!

I’ve written a bit of vbscript which will create a run-once self-deleting scheduled task that can be used to run a command such as REG ADD which will be running as a 64-bit process, assuming you use it on Windows x64. The only thing you need to have is admin rights, the rest will happen automatically.

You could use it for all sorts of things, like getting access to an area of the OS that needs LOCAL SYSTEM rights for example. You must remember though it’s just for firing off a command that you don’t need a response from. You need to test whatever you fire-off because you can’t check what you’ve done from within the script!

Click here to see my function on pastebin

To use the vbscript function you need to call the CreateJob() function and pass it the command that you want to run. For example if we call the following…

CreateJob("REG ADD HKLM\Software\64BitKey /v 64BitValue /d 64BitData /f")

…then my function will create a scheduled task that runs the command between the quotes 1 minute after it is created. Once the task completes it will then delete itself automatically, whether it succeeds or fails. The command in my example will create a registry key HKLM\Software\64BitKey with a new REG_SZ value 64BitValue which has the string data 64BitData.

I’ve commented the code as best I can. Basically the scheduled task that is created will have a unique name every time due the use of a guid string for the name. The task will work on XP, Vista and Windows 7, and on 32-bit or 64-bit, but it will always be in ‘XP mode’ so that it will delete itself after it is executed.

Here’s a slightly generic example of use:

Adding a registry key HKLM\Software\RegKey with KeyName that has a DWORD value of 000000FF:
CreateJob("REG ADD HKLM\Software\RegKey /v KeyName /t REG_DWORD /d 0xFF /f")
Notice here the use of 0xFF to specify the hex value, and the /f switch to force the key to add. If we don’t use /f and the value is already there then the command will perpetually wait for a response.

Here are some screenshots proving it works…

1. running the script in an Admin CMD prompt running in 32-bit mode on a 64-bit machine

2. proving the script is running as a 32-bit process

3. showing the scheduled task about to run

4. and finally the registry key after it has been created, definitely in the 64-bit hive!

For more info about the REG ADD command either go here, try typing reg add /? in the command-line, or you could Google it.

The right way to do my precise example is use WMI as mentioned here but my way is more flexible because you can do other stuff like run apps in a 64-bit process as well…

Anyway, here’s my function. Have fun with it, and don’t forget, you’re running as the SYSTEM account when you use this, so please be careful!

Function CreateJob(strCommand)
    Const SHELL_WAIT = True
    Const SHELL_HIDE = 0
    CreateJob = False
    ' Get date & time 1 minute in advance
    ' And it must be at least 1 minute
    ' Source: w3schools, & mikeblas on
    Dim strDateTime : strDateTime = DateAdd("n", 1, Now())
    Dim strDate     : strDate = LEFT(strDateTime, InStr(strDateTime, " ")-1)
    Dim strTime     : strTime = MID(strDateTime, InStr(strDateTime, " ")+1)

    ' define the command we will run to create the once-only scheduled task
    ' uses a new guid for the name each time so it will be a unique task
    Dim strJobCmd   : strJobCmd = "schtasks.exe /Create /TN " & _
        getGuid & " /RU SYSTEM /ST " & _
        strTime & " /SD " & _
        strDate & " /SC ONCE /TR """ & _
        strCommand & """"
        ' on Vista/Win7 must create task as XP-readable type using /V1
        ' this is so it will delete itself propely (bug in schtasks) using /Z
        If onVistaWin7 Then strJobCmd = strJobCmd & " /Z /V1"
    WScript.echo strJobCmd
    Dim oJobShell : Set oJobShell = CreateObject("WScript.Shell")
    Dim jobRet : jobRet = oJobShell.Run(strJobCmd, SHELL_HIDE, SHELL_WAIT)
    If jobRet = 0 Then CreateJob = True
    ' here we tried to make the task and get the result to a variable
    ' if the return is non-zero then the creation of the task errored
    Set oJobShell = Nothing
End Function

Function getGuid
    ' this functions gets a unique guid and returns it as a string
    Dim TypeLib : Set TypeLib = CreateObject("Scriptlet.TypeLib")
    getGuid = Left(CStr(TypeLib.Guid),38)
    ' above line also removes some strageness at the end
    Set TypeLib = Nothing
End Function

Function onVistaWin7
    ' this function returns true on Vista or above (incl. Srv2008)
    Dim colOSver, objOSver
    onVistaWin7 = False
    Set colOSver = GetObject("WinMgmts:root\cimv2").ExecQuery _
        ("Select Version from Win32_OperatingSystem")
    For Each objOSver In colOSver
        If Left(objOSver.Version,1) >= 6 Then onVistaWin7 = True
    Set colOSver = Nothing
End Function

Orca 5 – msi editing tool for Windows 7

I finally realised where to get hold of version 5 of Orca – the one most suitable for Windows 7 able to validate .msi files for Windows Installer 5. It was of course in the Windows SDK for Windows 7 and .NET Framework 4. Unfortunately there’s no mini-download for the msi sdk like with version 4.5, so for simplicity I’ve acquired the .msi for orca and put it online for download…

Orca 5.0.7693.0 (2.1MB)

If you would rather download the official version from Microsoft you need to install the debugging tools from the Windows SDK, then go in to Program Files\Windows SDK\7.1\Bin and orca.msi will be in there.

[Update 2012-09-08: there’s now a slightly newer version available here]

Windows Biometric Service stops preventing fingerprint logon

Recently I setup one of my work laptops to allow me to login using my fingerprint without the need for any client software other than a driver. A handy new feature built-in to Windows 7, and it works fabulously well. One finger on each hand for different things, one for admin, one for my normal user. Love it!

However I have been finding occasionally that when I switch the laptop on (usually after being in hibernation or standby) that I can’t login with a fingerprint and have to resort to legacy means (typing!).

I think that this is because the “Windows Biometric Service” service has stopped. There are events notifying that it’s happened but no explanation why. I made sure the service was set to automatic (it was) and I’ve added recovery options to the service telling it to restart if it stops. Seems that hasn’t fixed it because the problem cropped up immediately afterwards when I tested it. I’m not quite sure what else to do yet…

Just thought I’d blog this in case someone else runs into it.

How to download individual updates when using Vista or Windows 7

If you want to get hold of updates for Windows 7 or Vista when you’re running Vista or Win 7 already, you can get the updates via the updates catalog (catalogue): (the pages require IE of course).

I actually had to run up my virtual xp machine to get hold of that link! I simply couldn’t remember the word “catalog”. Heh.

What inspired this blog entry was that I thought I’d have a go at making a fully up to date disc of Win7 before I put it on my wife’s PC, i.e. mount the wim with imagex, and use dism with the latest updates. Thought that would be fun, but then I couldn’t get hold of the updates of course. Sorted.

Exchange 2007 SP2 has been released

And so to the insignificant clash of tiny mouse sized symbols Exchange 2007 Service Pack 2 has finally been released:;=4c4bd2a3-5e50-42b0-8bbb-2cc9afe3216a

According to a little very sketchy investigation I’ve done there’s a schema change and support for PowerShell 2 – in fact they are recommending it! According to this blog post (link) PowerShell 2 is already in Windows 7 and Server 2008 R2, and sure enough if you run powershell and type $psversiontable and that proves it 🙂
[yes i’ve been running Win7 Enterprise x64 RTM for the last 2 weeks, hehe]