Amazon Banner

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. 

Monday, March 18, 2013

Cacheberry Pi

As an avid Geocacher, when I was thinking of what to do with my Raspberry Pi, I couldn't help but wonder what geocaching related devices I could make.  I considered building a geocache that had some kind of electronics, controlled by the Pi, but decided that powering the Pi long term would be an issue.  I searched for other ideas online, and came across a video of the Cacheberry Pi project, by Jeff Clement.  The perfect mix of geocaching, electronics, and programming, I had found my first project!

The Cacheberry Pi is designed to be used in the car.  Place the small box on the dashboard, connect it to power, and while you're driving, the Raspberry Pi will search a pre-loaded database of geocaches for the nearest cache in the direction you're travelling.  This is different from most GPS receivers or applications because it searches only a narrow area ahead, and will not return caches that you've already passed by.

I've spent the last few weeks getting it working.  I used some slightly different hardware from the original, so it wasn't quite as simple as dropping his image onto my Pi and running it.  Here's what I used:
The Cacheberry-Pi displays a dashboard screen when no
nearby caches are found.
Getting the Raspberry Pi up and running was easy.  Getting the other hardware working right took a little bit of time.  The LCD that I used didn't work with the lcdproc driver included in the original version of the Cacheberry Pi.  I struggled for a while to get the lcd working right.  For more info on that, and to download the modified driver if you need it, see my previous post on the subject here.

The GPS module I used doesn't connect via USB, but instead connects directly to the GPIO pins on the Raspberry Pi and communicates via serial.  By default, the serial port on the Raspberry Pi is set up as a serial console, which must be disabled before it can be used by the GPS.  This can be done by making small changes in 2 files.

In /etc/inittab scroll to the end of the document, where you should add a # sign before this line:
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
Next, edit /boot/cmdline.txt - This file is just one long line of text.  Find and remove the following from that line:
console=ttyAMA0,115200 kgdboc=ttyAMA0,115200

GPSD must also be reconfigured for the serial port instead of the USB. To do this, run:
sudo dpkg-reconfigure gpsd
This will start a wizard to configure settings for gpsd.  Set gpsd to run automatically at startup, then accept the default settings on each screen until prompted for the port that the gps unit is connected to.  Enter the following in the port field:
I've added an extra LED to my cacheberry pi, which is connected directly to the LED pin on the +Adafruit GPS unit.  This makes it easy to tell whether the GPS has a signal lock yet.  The other LED is controlled by the python code and activates based on the cache search pattern and distance.

I've also forked the Cacheberry Pi project on github and made a few changes to the code.  I added some missing steps to the instructions in the readme, to make it easier for others to reproduce the project. I've added configuration settings to display measurements in Metric or Imperial units, localize the time displayed on screen, adjust the scroll speed of geocache data on screen, changed what information about a geocache is displayed on the screen and how it's formatted, and made a few other small changes.  I hope these changes can be of help to someone else who is inspired by Mr Clement's project and wants to give it a try.

The updated code with these changes can be found here github.

Still on my to-do list for this project:

  • Adjust the behavior and triggers for the software controlled LED
  • Add a push button or keypad to allow simple interaction with the Cacheberry-Pi
  • Add a method for initiating a safe shutdown of the OS
  • Add some kind of backup power system which will kick in when the vehicle power is turned off, triggering a safe shutdown of the Pi's OS and powering the Pi long enough for that shutdown to complete. 
  • ???

Saturday, February 2, 2013

Using a 16x2 LCD with i2c on the Raspberry Pi

I got a Raspberry Pi for Christmas, and have been playing with it ever since. For one project, I needed to display a couple of lines of text. I ordered a 16 Character x 2 Line LCD display based on an hd44780 compatible controller. From what I had read, I wanted one with an i2c i/o expander. By using i2c, the lcd can be controlled using just 4 GPIO pins from the Raspberry Pi instead of 8. I ended up ordering the SainSmart IIC LCD1602 Display from amazon for just $12.

When I received the LCD, I hooked it up to my Pi and tried using it with a tutorial I found on the raspberry pi blog. The tutorial I was following mentioned that some of the i2c expansion 'backpack' boards connected the i2c chip's pins to the lcd's pins in a different way than others, and that the code has to be modified to use it with other versions.  When I couldn't get it working, I looked through the 'documentation' sainsmart offered for download on their website and in the product description on amazon. Unfortunately, the documentation was basically just some sample code for arduino. (As it turns out, the sample arduino code didn't even work.  It was written for an old, pre 1.0 version of the arduino IDE.) I contacted sainsmart support to ask for any further documentation available and a schematic of the i2c expander board, but the best they could do is point me to a post on someone's blog about using an i2c controlled lcd with the Raspberry Pi. After examining the path of traces on the backpack board, I was able to map out which pins of the i/o expander chip were connected to which pins of the lcd:

P0       RS
P1       RW
P2       EN
P3       BL
P4       D4
P5       D5
P6       D6
P7       D7
Armed with this information, I was able to get assistance from the lcdproc help to modify the hd44780-i2c driver used by lcdproc.  Since I had seen many posts from others with the same problem, I wanted to share the solution.  Here is the patch code code that I used to modify the hd44780 driver:

Index: server/drivers/hd44780-i2c.c =================================================================== RCS file: /cvsroot/lcdproc/lcdproc/server/drivers/hd44780-i2c.c,v retrieving revision 1.14 diff -u -r1.14 hd44780-i2c.c --- server/drivers/hd44780-i2c.c 30 Oct 2010 18:04:21 -0000 1.14 +++ server/drivers/hd44780-i2c.c 27 Jan 2013 14:39:31 -0000 @@ -76,10 +85,10 @@ void i2c_HD44780_backlight(PrivateData *p, unsigned char state); void i2c_HD44780_close(PrivateData *p); -#define RS 0x10 -#define RW 0x20 -#define EN 0x40 -#define BL 0x80 +#define RS 0x01 +#define RW 0x02 +#define EN 0x04 +#define BL 0x08 // note that the above bits are all meant for the data port of PCF8574 #define I2C_ADDR_MASK 0x7f @@ -168,43 +214,43 @@ // powerup the lcd now /* We'll now send 0x03 a couple of times, * which is in fact (FUNCSET | IF_8BIT) >> 4 */ - i2c_out(p, 0x03); + i2c_out(p, 0x30); if (p->delayBus) hd44780_functions->uPause(p, 1); - i2c_out(p, enableLines | 0x03); + i2c_out(p, enableLines | 0x30); if (p->delayBus) hd44780_functions->uPause(p, 1); - i2c_out(p, 0x03); + i2c_out(p, 0x30); hd44780_functions->uPause(p, 15000); - i2c_out(p, enableLines | 0x03); + i2c_out(p, enableLines | 0x30); if (p->delayBus) hd44780_functions->uPause(p, 1); - i2c_out(p, 0x03); + i2c_out(p, 0x30); hd44780_functions->uPause(p, 5000); - i2c_out(p, enableLines | 0x03); + i2c_out(p, enableLines | 0x30); if (p->delayBus) hd44780_functions->uPause(p, 1); - i2c_out(p, 0x03); + i2c_out(p, 0x30); hd44780_functions->uPause(p, 100); - i2c_out(p, enableLines | 0x03); + i2c_out(p, enableLines | 0x30); if (p->delayBus) hd44780_functions->uPause(p, 1); - i2c_out(p, 0x03); + i2c_out(p, 0x30); hd44780_functions->uPause(p, 100); // now in 8-bit mode... set 4-bit mode - i2c_out(p, 0x02); + i2c_out(p, 0x20); if (p->delayBus) hd44780_functions->uPause(p, 1); - i2c_out(p, enableLines | 0x02); + i2c_out(p, enableLines | 0x20); if (p->delayBus) hd44780_functions->uPause(p, 1); - i2c_out(p, 0x02); + i2c_out(p, 0x20); hd44780_functions->uPause(p, 100); // Set up two-line, small character (5x8) mode @@ -240,8 +284,8 @@ i2c_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch) { unsigned char enableLines = 0, portControl = 0; - unsigned char h = (ch >> 4) & 0x0f; // high and low nibbles - unsigned char l = ch & 0x0f; + unsigned char h = ch & 0xf0; // high and low nibbles + unsigned char l = (ch << 4) & 0xf0; if (flags == RS_INSTR) portControl = 0; @@ -277,7 +321,7 @@ */ void i2c_HD44780_backlight(PrivateData *p, unsigned char state) { - p->backlight_bit = ((!p->have_backlight||state) ? 0 : BL); + p->backlight_bit = ((p->have_backlight && state) ? BL : 0); i2c_out(p, p->backlight_bit); }

A copy of the modified source code and a compiled, ready to use, copy of the driver file can be downloaded here.

The sainsmart backpack board seems to be a clone of a similar board made by DFROBOT and others, so if your i2c backpack matches the pinouts I listed above, give the modified driver for lcdproc a try.

I hope this post is able to save others from going through the trouble I did to get this LCD working.