Get Programs and Features script

I was trying to find a good method/script to (remotely) get all the installed programs from a Windows 7 client. I didn’t want to use Remote Desktop or similar however, so it had to be a method that was unnoticeable for the user. I know that SCCM has its own software inventory, but I wanted a fast(er) way to check if version XXX of Office is installed on a client. The reason for this was mainly because there are (unfortunately) soooo many different Office installations throughout the whole University. (Also, it’s nice to have some clues about the client before SCCM starts using its magic). The script lists more than (Office) installations however, including other useful information as well. It is based on

and It basically queries the registry of a remote client and returns the installed software. Cheers to the author Anthony Howell!

This modified version also lists:

  • Colored headings 🙂
  • OS Name
  • OS Version
  • System Model
  • Total Physical Memory
  • Original Install Date
  • Uptime/System Boot Time
  • Current logged on user

Usage: .\get_programs_and_features.ps1 computername.

Here’s a screenshot with example output:


Fig 1. get_programs_and_features.ps1


The text in the screenshot is in Swedish, but it should be quite self explanatory 🙂

If you want to have a go yourself, the script looks like this (download link at the bottom):

        [string[]]$Name = $env:COMPUTERNAME
        $LMkeys = “Software\Microsoft\Windows\CurrentVersion\Uninstall”,”SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall”
        $LMtype = [Microsoft.Win32.RegistryHive]::LocalMachine
        $CUkeys = “Software\Microsoft\Windows\CurrentVersion\Uninstall”
        $CUtype = [Microsoft.Win32.RegistryHive]::CurrentUser
        ForEach($Computer in $Name)
            write-host “Information om datorn: ” $Computer -foreground “magenta”
            $datastring= systeminfo /s $Computer
            $datastring | find “OS Name”
            $datastring | find “OS Version”
            $datastring | find “System Model”           
            $datastring | find “Total Physical Memory”
            $datastring | find “Original Install Date”           
            $datastring | find “System Boot Time”
            write-host “Inloggad person för tillfället (console): ” -foreground “magenta”
            qwinsta /server:$Computer
            $MasterKeys = @()
            If(!(Test-Connection -ComputerName $Computer -count 1 -quiet))
                Write-Error -Message “Unable to contact $Computer. Please verify its network connectivity and try again.” -Category ObjectNotFound -TargetObject $Computer
            $CURegKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($CUtype,$computer)
            $LMRegKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($LMtype,$computer)
            ForEach($Key in $LMkeys)
                $RegKey = $LMRegKey.OpenSubkey($key)
                If($RegKey -ne $null)
                    ForEach($subName in $RegKey.getsubkeynames())
                        foreach($sub in $RegKey.opensubkey($subName))
                            $MasterKeys += (New-Object PSObject -Property @{
                            “ComputerName” = $Computer
                            “Name” = $sub.getvalue(“displayname”)
                            “SystemComponent” = $sub.getvalue(“systemcomponent”)
                            “ParentKeyName” = $sub.getvalue(“parentkeyname”)
                            “Version” = $sub.getvalue(“DisplayVersion”)
                            “UninstallCommand” = $sub.getvalue(“UninstallString”)
            ForEach($Key in $CUKeys)
                $RegKey = $CURegKey.OpenSubkey($Key)
                If($RegKey -ne $null)
                    ForEach($subName in $RegKey.getsubkeynames())
                        foreach($sub in $RegKey.opensubkey($subName))
                            $MasterKeys += (New-Object PSObject -Property @{
                            “ComputerName” = $Computer
                            “Name” = $sub.getvalue(“displayname”)
                            “SystemComponent” = $sub.getvalue(“systemcomponent”)
                            “ParentKeyName” = $sub.getvalue(“parentkeyname”)
                            “Version” = $sub.getvalue(“DisplayVersion”)
                            “UninstallCommand” = $sub.getvalue(“UninstallString”)
            $MasterKeys = ($MasterKeys | Where {$_.Name -ne $Null -AND $_.SystemComponent -ne “1” -AND $_.ParentKeyName -eq $Null} | select Name,Version | sort Name)
            write-host “Har följande program installerade:” -foreground “magenta”


Downloadable version (translated to English):

Data Deduplication in Windows 8.1

I got a hot tip from my friend regarding the Data Deduplication feature available (only) in Windows Server 2012 (R2) (Thanks Mats 🙂 ). With some small tricks you’re now able to use this cool feature in Windows 8/8.1. I’m currently using a lot of disk space for virtual machines and iso-files, so for me this is (was) the best thing ever. With deduplication enabled, I’m now able to free up a lot of my precious disk space. Yes A LOT. You’ll love it on your small SSD. So, what is Data Deduplication you may ask. Here’s a short answer to that:


“Data deduplication involves finding and removing duplication within data without compromising its fidelity or integrity. The goal is to store more data in less space by segmenting files into small variable-sized chunks (32–128 KB), identifying duplicate chunks, and maintaining a single copy of each chunk. Redundant copies of the chunk are replaced by a reference to the single copy. The chunks are compressed and then organized into special container files in the System Volume Information folder.



And while you’re at it, also have a look at



I have to say that after finding out that Deduplication was doable on windows 8.1, it wasn’t that hard finding information on HOW to do it. I’ll start by linking to the original source as usual, thanks to the author for the guide!

Well, not much to say really. I followed the guide (for Win 8.1) and it worked 🙂 Here are some screenshots of the process:


Fig 1. Adding Deduplication packages and enabling the Deduplication feature.



Fig 2. Enabling and starting Deduplication job on the D: –drive. Also checking the status with Get-DedupJob (currently at 0% because the process just started).


My D: –drive consist of 2 x Western Digital Black 2TB 7200 RPM drives configured in software raid-0 (stripe). The Deduplication job ran forever the first time (4.5h), but it was well worth the wait – check the before and after screenshots below;


Fig 3. Before Deduplication (1.54TB free on D: –drive).



  Fig 4. After Deduplication (2.77TB free on D: –drive 🙂 )


and the same thing checked with Get-DedupStatus:


Fig 5. Get-DedupStatus


As you can see, the space savings are HUGE (1.25TB saved space). All I can say is that I’d recommend Deduplication for everyone. Now the same procedure is waiting for my E: –drive (a 512GB SSD) 🙂 And remember folks, do NOT run/use Data Deduplication on your system drive! You have been warned.

For some more Deduplication PowerShell commands, have a look at:

For information about Deduplication and backups, have a look at:


…and the BAD

Well, all of this seemed too good to be true. And for me, apparently it was. I didn’t notice any slowdowns in normal usage, but when I started playing around with my virtual machines things started getting slow. It took FOREVER to load a virtual machine from a suspended state for example. My guess is that Microsoft’s version of Deduplication is best suited for Hyper-V, NOT VMware. (They even have an option for it in the Hyper-V settings). What a shame. For now, it’s not usable and I decided to disable it altogether. Luckily this was an easy (but slooooow) process. It took me about 7-8h to De-Deduplicate my 4TB Raid-0 striped volume. Steps for reversing the deduplication process:

In PowerShell:

Start DedupJob -Type Unoptimization -Volume D:

That’s it. No other command was needed (even though I found some articles saying that I should also disable deduplication and clean up the garbage collection after unoptimization). This was however unnecessary/impossible;

PS C:\> Start-DedupJob -Volume D: -Type GarbageCollection
Start-DedupJob : MSFT_DedupVolume.Volume=’D:’ – HRESULT 0x80565323, The specified volume is not enabled for deduplication.
At line:1 char:1
+ Start-DedupJob -Volume D: -Type GarbageCollection
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (MSFT_DedupJob:ROOT/Microsoft/…n/MSFT_DedupJob) [Start-DedupJob], CimException
+ FullyQualifiedErrorId : HRESULT 0x80565323,Start-DedupJob


PS C:\> Disable-DedupVolume D:
Disable-DedupVolume : MSFT_DedupVolume.Volume=’D:’ – HRESULT 0x80565323, The specified volume is not enabled for deduplication.
At line:1 char:1
+ Disable-DedupVolume D:
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo         : NotSpecified: (MSFT_DedupVolume:ROOT/Microsoft/…SFT_DedupVolume) [Disable-DedupVolume], CimException
+ FullyQualifiedErrorId : HRESULT 0x80565323,Disable-DedupVolume


Finally I also removed the Deduplication (and File Server) feature from Windows Features (in “Turn Windows features on or off”). After a test run I can confirm that my virtual machines now start and resume more rapidly again.



Final words

Unfortunately, luck wasn’t completely on my side with Deduplication 😦

However, I’d still recommend deduplication for people running low on disk space (using non-disk intensive stuff). A good place for deduplication would probably be your non-system stash-disk filled with music, photos, videos and so on.

That said, happy deduplication after all 🙂

Converting a Windows 8.1 BIOS installation to UEFI

I got my hands on a Sony Vaio Pro 13” Ultrabook (very nice laptop btw) which originally came equipped with the basic version of Windows 8. It was going to be used as a work computer however, so I decided to install our Windows 8.1 Enterprise image on it. That said, I noticed that the current Windows installation was an UEFI installation of Windows 8. Our own image doesn’t include the needed partitions for UEFI, so it isn’t deployable as an UEFI installation (without MDT or partition modifications). MDT 2012 and newer are able to deploy both BIOS and UEFI versions from the same image but I didn’t test that stuff just yet. I don’t have a spare workstation with UEFI to test on either 😦 Update: I was able to test UEFI in combination with MDT 2013 and WDS in VMware workstation, more info later in the document. Update 2: I have now also tested a “real life” computer (HP Compaq Elite 8300 workstation) with UEFI PXE enabled in the bios. I can confirm that the WDS-server indeed HAS to be version 2012 (R2). I tried with the old Windows Server 2008 R2 and the boot image was NOT found. This statement can of course be untrue with other computer brands. I also enabled fast boot in the bios on the Elite 8300 after successful deployment, but I can’t really tell if it boots faster than before. At least it works, but it’s probably more noticeable on laptops.

Some info about UEFI in MDT:

“By default, MDT creates the appropriate partitions to support computers running UEFI. MDT supports UEFI versions from 2.0 up to 2.3.1. UEFI 2.3.1 is a newer version of UEFI that will be used on Windows 8 logo–compliant computers.
For more information about UEFI support in MDT, see the section, “Deploy to Computers with UEFI”, in the MDT document Using the Microsoft Deployment Toolkit.”

I saw different requirements for the WDS server also; some say that UEFI pxe-booting works with Windows Server 2008 R2, and some say it requires Windows Server 2012. I can confirm that it works with Server 2008 R2 for 64-bit clients at least. Some links:

Sony isn’t our main brand so it was unnecessary to add a bunch of drivers for it in MDT. UEFI isn’t in use on many of our computers either so I’ll put the whole UEFI with MDT on hold for a while. Now it’s time for some old school manual labor with a Boot CD and ImageX + diskpart 🙂

Here’s the process:

  • Entered the bios on the Sony and changed boot device from UEFI to Legacy. I also changed the boot order so it would boot from CD/DVD as first boot device.
  • Booted from a WinPE 5.0 CD (Windows 8.1 install DVD is also fine).
  • Ran diskpart with the commands “list disk”, “select disk 0”, “clean”. This cleans the whole disk and partitions
  • Created a new primary partition, “create partition primary”. I could have created more partitions NOW and not later, this way I would have had the computer UEFI-ready instantly. See the Conversion to UEFI step. It did work fine this way also, just more (unnecessary) steps…
  • Made it active with the command “active”.
  • Formatted the partition, format fs=ntfs label=”Windows 8” quick
  • Assigned drive letter, “assign letter=c”
  • Exited diskpart with “exit”
  • Applied the image (from a usb hard drive) with ImageX (integrated on my WinPE CD).
  • Imagex.exe /apply path-to-Windows81.wim 1 c:
  • bcdboot c:\Windows
  • Exit. Wait. Done.
  • I now have a regular mbr/ntfs image applied and running.


Conversion to UEFI

With the laptop still running in “normal bios/legacy mode”, I did the following:

  • Installed EaseUS Partition Master Free ( in Windows.
  • Created an unallocated chunk of disk space “to the left” of the Windows partition. Mine was 350MB. If you already have a 300+ MB system partition you can skip this step. I didn’t have one though as I didn’t create one in the steps above. MDT creates this system partition for you automatically if you deploy with that and not manually.
  • Formatted the partition and gave it a drive letter. Doesn’t matter which drive letter you give it as it’s going to be partitioned (and formatted) again real soon. I could have left it unformatted/unallocated also.
  • Downloaded gptgen ( This is needed to convert the whole disk to GPT (GUID Partition Table). GPT is needed for UEFI, and in turn UEFI is needed for Secure Boot (if you choose to enable it).
  • Ran gptgen.exe –w \\.\physicaldrive0 from an administrative command prompt. (You get the drive number from Windows Disk Management, usually 0). After this, the computer won’t/can’t boot with normal legacy mode anymore so you MUST boot the computer with the WinPE or Windows installation disk.
  • Restarted the computer and booted with the WinPE CD
  • Time for diskpart again:
  • diskpart
  • list disk
  • select disk 0
  • list partition
  • Showed me two partitions, Partition 1 which was the newly created one (350MB) and the other which was my Windows installation (120GB)
  • I selected the the 350MB’s partition and deleted it, “select partition 1”, “delete partition”
  • Created new partitions for EFI and system:
  • create partition EFI size=100 offset=1
  • format fs=fat32 label=”System” quick (EFI partition should be fat32)
  • assign letter=S
  • create partition msr size=128 offset=103424
  • Listed the partitions again, “list partition”
  • Partition ###  Type              Size     Offset
           ————-  —————-  ——-  ——-
           Partition 1    System             100 MB  1024 KB
           Partition 2    Reserved         128 MB   101 MB
           Partition 3    Primary            120 GB   229 MB

  • Partition 3 is my Windows partition
  • list volume
  • select volume 3 (my Windows 8 Volume, not same as Partition, just happen to be “3” in both cases)
  • assign letter=c
  • exit diskpart
  • bcdboot c:\Windows /s s: /f UEFI
  • restarted computer and enabled UEFI in bios.
  • Worked! Enjoy!


Configure UEFI/GPT-Based Hard Drive Partitions:

P.S. This has to be the fastest (Windows 8.1) computer I’ve ever tested. Bootup and restart only takes a couple of seconds due to UEFI and Windows 8 Fast Boot feature.


Bonus: UEFI PXE-Windows 8 Deployment in VMware Workstation 9

This was actually quite an easy task. It also answered some of my earlier questions regarding the PXE/WDS server version. I had an old virtual machine named “miffo” which was my old test deployment client. It had Windows 8 running at the moment (not that it matters). I opened up up the configuration file for the vm, namely miffo.vmx. I added an extra line into the file: “firmware=”efi”.


Now I could boot the virtual machine with an UEFI-enabled “bios” (Fig 1). EFI-boot from hard drive should be unsuccessful due to the fact that the current installation is using bios/mbr and UEFI can’t boot from mbr.


Fig 1. EFI boot.

Just as with “normal” pxe-boot, the client contacted the pxe server (Fig 2). NOTE: The LiteTouchPE boot image HAS to be 64bit. If you boot with x86 architecture it will fail (vm will eventually shut itself down). As far as I know, this should be fixed in WDS for Windows Server 2012 (better support for UEFI and x86). I’m using Windows Server 2008 R2 WDS/PXE in my test environment so I wouldn’t know…


Fig 2. PXE booting

After this everything was running as normal. You choose your task sequence and sit back and enjoy the show. I did not change anything in the task sequence regarding “Format and Partition Disk”, but MDT was smart enough to partition the disk correctly despite that (Fig 3).


Fig 3. Gpt + UEFI partitions created automatically

Same thing checked after successful deployment (Fig 4):


Fig 4. Gpt + UEFI partitions again

And just to make sure we’re running UEFI (Fig 5):


Fig 5. System Information (msinfo32.exe)


This little test shows that UEFI deployments can be rather pain-free. Hopefully the same goes for production environments. Fingers crossed.

Some more links regarding UEFI and fast boot: (especially the fast boot video)

It would be nice to have the Windows 8 Fast Boot feature on a workstation also, but that requires UEFI GOP support from the graphics card. This isn’t probably a big deal if you have an integrated graphics card on the motherboard, but for people with an (older) add-on graphics cards there can be problems. My own workstation graphics card (Nvidia Quadro NVS 450, non-integrated) won’t support UEFI GOP for example 😦 This is yet to be tested on another workstation (even though this feature is much more desirable on laptops).

Making Windows 8.1 look like Windows 8.0 (with a touch of Windows 7)

Change is good they say. I partially agree. With the release of Windows 8 there were also a bunch of third party start menu programs released. This is a good thing in my opinion, because I wouldn’t use Windows 8.x without some sort of modified start menu either. Now with the release of Windows 8.1 (I got the msdnaa version), there’s a “start button” present by default. The negative side of this is that it’s useless. When you click it, It just takes you to the metro interface. Why is this solution better than the one in Windows 8.0? I don’t get it.

The good thing is that everything is also customizable in Windows 8.1. You can have the Windows 7 start menu and also the default desktop theme from Windows 8.0. I happen to think that the default theme in Windows 8.1 is rather ugly (Fig 1) and I prefer the one from Windows 8.0. Call me old school if you want…


Fig 1. Default theme/look in Windows 8.1.


So, how do we get the Windows 8.0 look in Windows 8.1?

  • Update: Just download the Official Windows 8.0 flower wallpaper from and put it as your desktop background. Problem solved 🙂
  • Old method that also works: Save your current theme (right-click, Save theme for sharing) from a Windows 8.0 installation (Fig 2).


Fig 2. Save old theme

  • Copy and apply the saved theme from your Windows 8.0 installation to Windows 8.1 (Fig 3 and Fig 4).


Fig 3. Saved theme


Fig 4. Theme applied. Enjoy the Windows 8.0 theme in Windows 8.1 🙂


As I previously mentioned, I also prefer a modified start menu/button. My favorite (free) choice is Classic Shell (with the SevenVG skin).


Fig 5. Classic Shell with SevenVG skin in action


Another “new feature” of Windows 8.1 is integrating the Library folders into My Computer or “This PC” as it’s called in Windows 8.1 (Fig 6). Again, call me old school if you want but I do NOT like this either.


Fig 6. This PC with integrated Libraries

Luckily there’s also a  solution for this dilemma. You can get the old Windows 7/Windows 8.0 look back to Windows Explorer by removing some registry entries. I won’t “steal” that information so here’s a link for the solution: Note the reply at the end.

Below is a screenshot with the registry entries removed (Fig 7). I’ve also enabled libraries by right clicking somewhere on an empty space on the left side and choose Show libraries ( Finally I renamed “This PC “ to “Computer”. (The “+” in front of the folders is also a modification I’ve been using for many years, called Classic Explorer. It’s part of Classic Shell).

There you go, transformation complete 🙂


Fig 7. Integrated Libraries removed and old school libraries enabled.