Amazon Banner

Monday, July 6, 2015

Convert Windows 10 Pro ISO to Enterprise

For recent builds of the Windows 10 Technical Preview, when Microsoft has released ISO images of a build they have elected not to release ISO's of Enterprise Edition.  The most recent Enterprise edition ISO available is for build 10074.  While it is possible to download and install that build, then upgrade to the more recent builds using windows update, having install media for the current version would make things much easier.

The good news is, all of the bits for Enterprise edition are included in the ISO of Windows 10 Pro Technical Preview, and with a few simple commands it's possible to change from Pro to Enterprise edition.

To get started, download the latest Windows 10 Pro Technical Preview ISO.  As of the time of this writing, the image currently available is build 10162.  Extract the contents of the iso into a temporary directory.  In my example, I use D:\10162\.

From a command prompt, Create an empty directory to mount the wim file in, and mount the image:


Check the current edition and available targets that the mounted image can be upgraded to:



As shown in the output above, my image is currently Professional edition, and can be upgraded to either Enterprise or Education editions.  I'll upgrade to Enterprise using the /set-edition parameter of dism, then run dism again with the /get-currentedition parameter to confirm the change was successful:



Since the Enterprise edition requires a different product key than the Professional edition, the product key used in the image must also be updated:


Lastly, unmount the wim image, committing the changes that were made:

D:\10162 now contains the install files for Enterprise edition.  Run setup from there, or copy the files to bootable media to install a clean version of the latest Windows 10 Enterprise Technical Preview.

For reference, the commands used in the screenshots above are listed in order below:
md d:\mount
dism /mount-wim /wimfile:d:\10162\sources\install.wim /mountdir:D:\mount /index:1
dism /image:d:\mount /get-currentedition
dism /image:d:\mount /get-targeteditions
dism /image:d:\mount /set-edition:Enterprise
dism /image:d:\mount /get-currentedition
dism /image:d:\mount /set-productkey:CKFK9-QNGF2-D34FM-99QX2-8XC4K
dism /unmount-wim /mountdir:d:\mount /commit

I hope this information is helpful.  While it was written and tested with Windows 10 Technical preview, it should also work with Windows 8, 8.1, Server 2012 and 2012R2 (with minor changes), and most likely with the RTM version of Windows 10 when it is released.  More information about the DISM parameters used can be found on technet.

Tuesday, June 16, 2015

ISP DNS Hijacking breaks DirectAccess connectivity

Edit: Thanks to Richard Hicks for commenting on this post. It seems that my understanding of exactly why things broke the way they did may have been flawed. I leave the post here for reference however, since it does describe the symptoms and the solution that worked in this particular situation. Understand however that the explanation of why the solution worked may not be correct. We recently began piloting Microsoft's DirectAccess (DA) for use connecting remote/mobile computers to our internal network over the internet.  Yesterday I received a call from a user who had been using DirectAccess for several weeks without issue, but suddenly was not able to access internal resources.  I'm documenting the issue here in hopes that it will help others experiencing similar issues with DirectAccess connections.

The first thing I tried was to remote control the computer using SCCM.  When this connected successfully, I knew that the DA connection had at least established the tunnel and was working, even if it reported that it wasn't.  After a bit of testing to identify what was working and what wasn't, I determined that when the computer tried to connect to the network location server it was able to resolve the host name to an IP address, but couldn't verify the identity of the server at the IP address given.

The network location server is used by DA  to determine whether the computer is connected to the internal network, and thus whether DA needs to create a tunnel for corporate connectivity.  DA attempts to establish an SSL connection to a web server on a host that can only be accessed internally.  If the computer is on the internal network, the connection is successful and DA verifies the remote server's identity based on the SSL certificate.  If the computer is connected to the public internet, the internal host name should not be resolved by DNS, and DA will then attempt to establish a secure tunnel to the internal network.  An entry in the client's Name Resolution Policy Table (NRPT) prevents the client from connecting to that internal host over an established DA connection.

When the user's computer tried to resolve the internal host name of the NLS, instead of responding with "Non-existent domain" as it should, the ISP's DNS server returned an IP address of 198.105.254.63.  The client then tried unsuccessfully to open an SSL connection to the server at that address to verify that it was on the internal network and did not need to establish a DA tunnel. At this point, even though DA was able to successfully open a connection to the internal network, it showed on the client side that corporate connectivity was not working, and the user was not able to connect to some internal resources.

This user was working from home, using an internet connection from their cable company, Mediacom.  Like many big ISP's these days, Mediacom uses a form of deep packet inspection to return search results instead of a proper error when the address a user entered doesn't point to a valid web page.  They also configure their DNS servers to respond with the IP of their "Search Guide" servers so they can provide search results even when the user enters key words or other data that isn't a valid address at all.  By hijacking their users requests in this way, they can provide search results from their service instead of from the user's preferred search engine (or instead of returning a message that the page cannot be found.)  They present this as a feature, a service to their users, but of course in reality it is designed to take a cut of money that google and others make selling ads in search results, by redirecting users to Mediacom's search results and ads instead.

To resolve this issue, the user had to get to one of the Mediacom search results pages.  From a new browser window, I had the user attempt to browse to a web address that I knew didn't exist.  As expected, this returned a Mediacom branded page listing search results similar to the address she entered.  At the top right corner of this page was a Settings link, which opened a Preferences dialog with a single option inside labeled Search Guide Settings.


After turning off the Search Guide and saving changes, the user tried again to browse to a non-existant site and received a proper error message.  Next, we tried to resolve the name of the internal NLS server and received the "Non-existant domain" response that was expected, instead of the IP of Mediacom's search server.  By the time we were done testing these, the Direct Access Connectivity Assistant had already updated to show that corporate connectivity was working.  The user's mail client was connected successfully to the server, and the intranet page which initially indicated a problem when it wouldn't display was now loading successfully.

Now the user is fully connected again and enjoying the simplicity of using DA.  The only question that remains is why this DNS hijacking didn't affect this user previously, as Mediacom has been known for several years now to hijack DNS requests for non-existant domains and return the address of their search servers instead.

TL;DR:  If an ISP hijacks DNS requests for non-existant domains, this can cause problems for DirectAccess connections when attempting to determine the client's network location.

Tuesday, March 31, 2015

Windows Update doesn't work in Windows 10 Technical Preview build 10041 on a corporate network

After updating to the recently released build #10041 of the Windows 10 Techincal Preview, I found that Windows Update wasn't working for me.  The old style Windows Update was no longer available from the Control Panel.  The new Windows Update in the modern "Settings" app showed that I had no updates available, and last checked for updates on 2/2/2015.  If I clicked the Check Updates button, nothing seemed to happen, or occasionally the "last checked" date would flicker briefly, but not change.

This PC is a member of a domain, with an active System Center Configuration Manager 2012R2 server.  As such, it would normally get it's updates from the SCCM server (which in turn pulls them through the associated WSUS server.)  However, SCCM doesn't offer updates for the Technical Preview, so that isn't an option when running a preview build of Windows 10.

I found that to get Windows Update working, I had to change the policy setting which points my workstation to the configmgr server for updates.  The easiest way to do this in a one-off situation like this is to edit the local policy.

Open the start menu, and type "gpedit.msc" and press enter.  This should launch the Local Group Policy Editor.  In the left pane, expand "Computer Configuration\Administrative Templates\Windows Components" and select the "Windows Update" folder.  In the right pane, look for any settings with a State other than "Not configured".  The important one here is "Specify intranet Microsoft update service location".  If this setting is enabled, Windows will check the specified server for updates, instead of Microsoft's internet based update servers.  Double click on this setting, and change it to Disabled.  (This setting should automatically revert back to the previous setting after a period of time, but you may want to make a note of it before you make the change, just to be safe.)



After disabling this setting, apply the changes and click ok.  Wait a moment or two, then open the modern "Settings" app again.  Select "Update & Recovery", and click the "Check for Updates" button.  The "last checked" info should disappear, and be replaced with a message that it is checking for updates.  After a few minutes, some updates should be available.  (I believe to date there have been 4 windows updates released for build 10041.  In my case, I also had a few driver updates available which had been released in the past week or so.)

This change will also allow the computer to check for new builds of the Windows 10 Technical preview, including the just released build 10049.

Saturday, December 20, 2014

How to use import-gvhistory script to parse Google Voice data from Takeout and export it to a .csv file

I recently posted the import-gvhistory powershell script that I wrote, which parses the html files provided by Google Takeout when downloading data from a Google Voice account.  Below are step by step instructions on how to use the script.

Note: The link below to HTML Agility Pack goes to a codeplex page where you can download version 1.46.  There is a note at the top of the page that the latest version is available from NuGet.  Currently, the version on NuGet is 1.4.9.  Either of those versions will work, so for simplicity I recommend you just click the big purple download button and get v1.4.6 if you aren't already familiar with NuGet.


  1. Download your Google Voice data using Google Takeout.
  2. Extract the the zip file to c:\temp or another path of your choosing. 
  3. **Windows 7 Users** Download and install WMF4 to update Powershell to 4.0
  4. Download the HTML Agility Pack, unzip the file, open the NET45 folder inside, and copy HtmlAgilityPack.dll the same folder.  For example, I'll use c:\temp
  5. Open a new notepad window.  Copy the entire text of the script from this post, and save the file as c:\temp\import-gvhistory.ps1
  6. Open Powershell (It's probably in your start menu, under the name Windows Powershell )
  7. Type "cd \temp" (without the quotes)
  8. Type ". .\import-gvhistory.ps1" (without quotes.  Note that this begins with a period, a space, then another period, don't leave out that first period!)
  9. Type "import-gvhistory -path c:\temp\takeout\calls | export-csv c:\temp\GVHistory.csv"


That should take just a minute or two before the prompt comes back up.  Once you're back at the prompt, there will be a new file c:\temp\GVHistory.csv containing the details of all your google voice calls, texts, etc.  Those who are more comfortable working with powershell can leave off the export-csv part of the command and pipe the data to where-object or other tools to filter or otherwise manipulate the data as needed.

Tuesday, December 16, 2014

import-gvhistory: Export Google Voice SMS/Text Messages and Call logs to CSV using Powershell

Here is a script I wrote to parse the thousands of HTML files produced by Google Takeout when exporting Google Voice data.  This script parses the html files to gather the Contact Name, Number, time, type (Placed/received etc), duration, and (text/voicemail) message contents for every phone call and text message, and outputs them as a powershell object which can be further filtered or manipulated and then exported into a csv or other format as needed.

Basic examples of how to use this script are included in the script comments.  If you download the script and have trouble, or if it works perfectly, please leave a comment and let me know.

**Update 12/20/2014** I've just posted step by step instructions for how to use the script..

Thursday, October 24, 2013

Deploying Installshield package via SCCM fails, Return Code -3

I recently ran into an issue installing the driver package for some new Interlink "Epad" signature pads we got in at work.  The instructions from the readme file for unattended installs matched the typical method for InstallShield packages:
  1. Run the installer with additional parameters to record the install and create a response file.  Example: "setup.exe /r /f1c:\temp\setup.iss"
  2. Copy the setup.exe and setup.iss files to the computer where the software needs to be installed.  
  3. On the target computer, run "setup.exe /s /f1setup.iss /v/qn"
In theory, this should silently run the installer, using the same responses provided when creating the response file in step 1.  In my case, this worked perfectly.  As long as I was manually running the command in step3 from an administrative command prompt.  When I tried deploying this as an application from system center, using the same command line and the same response file, the installation failed with a return code of "-3". 

Since the command works fine when I run it manually, I decided it had to be a problem of the different context in which configmgr was running the installer.  Configmgr was running the package as system, not as a user.  

When the InstallShield package executes, the first thing it does is extract files into a temporary location.  If I run it manually, those files are placed in c:\users\\appdata\local\temp\ - but it can't use the same path when running in the system context.  I was able to work around this by adding a "/b" parameter, in which is the directory where I want the setup files extracted to.  The final command line used for the application in SCCM looked like this:
"setup.exe" /s /f1setup.iss /bc:\swsetup\ /v/qn
Using that syntax, the application installed successfully from ConfigMgr.  Hopefully this information will be useful to others who might run into the same error. 

Tuesday, July 2, 2013

SCCM 2012 OSD Refresh Error: "FAILURE (5456): Unable to determine Destination Disk, Partition, and/or Drive."

I recently modified our SCCM (MDT Integrated) OSD task sequence so that we could also use the refresh deployment type.  One of the requirements for our refresh was that the hard drives be re-partitioned and formatted, just as they would if it were a "New Computer" deployment type.  To accomplish this, I copied the "Format Disk" group from the "New Computer Only" section of the task sequence into the "Refresh Only" section.  

When testing the refresh deployment, the process started off smoothly, but eventually the task sequence restarted the computer.  When the computer tried to boot back up, there was no OS on the drive. The only clue as to the cause was found in the bdd.log file: 

FAILURE (5456): Unable to determine Destination Disk, Partition, and/or Drive.


The task sequence attempts to back up the original drive to an image before re-installing the OS.  Since I had added the format steps under "Refresh Only" (which is above "Backup" in the task sequence), the drive was already wiped before the backup step tried to run.  In my case, I don't want a full backup of the computer anyway, so disabling the backup step resolved the issue.  If you do want a full backup before the drive is wiped, moving the "backup" step up into or above the "refresh only" group would probably solve this issue.