Hands on with the Lenovo Thinkpad X230t

One of the fortunate things of working in the SCCM space is you sometimes get first shot at a new piece of hardware when it comes in.  In this case, it was the Lenovo Thinkpad X230t, a convertible laptop.

The tablet has become a disruptive technology since the iPad really burst onto the scene and one of the outcomes of this is the convertible laptop, a device that can be used as a table but still managed as a native Windows device and have the benefit of whatever Windows software you have available.

The X230t is the first Thinkpad I’ve managed to use in a serious way and having heard about the legendary quality when they were made by IBM, it seems that has carried over with Lenovo.  The construction feels good, not tacky or cheap.  The only point of physical design I wasn’t overly comfortable about was the swivel point to convert between laptop and tablet modes.  The swivel can only twist one way and seems to be betting to be twisted the wrong way and broken by a user.  The only other sore point I had with the physical design was the location of the 3G card slot – it’s located under the battery, requiring you to take out the battery to access it.

In operation, the machines I used were quite fast thanks to the SSD in them.  They come with a stylus for using the touch screen and there’s a nice little slot to put the stylus when not in use. The screen seems to have a matt coating of some sort, possibly to prevent scratches/damage from the touch use.  Using the 3G slot was good, as the device appears as another wireless style connection, meaning you don’t have to deploy/install the proprietry application your 3G provider has you use.

The last point to note is Lenovo has come to the party with SCCM support and added driver packs similar to what HP and Dell are doing.  This made adding the X230t to the existing SCCM setup quite easy.

Office 2010 products MIA in SCCM 2007 reporting

One of the curious things about SCCM 2007 is the number of hot fixes it has to fix what are (in my experience) relatively common problems.  One of these came up when I wanted to do a report of how many Office 2010 installations there were versus other versions and reconcile those against the installed base of Windows 7 machines the RAC had.  The idea was to see how many machines were out of MOE compliance and start remediating them.

I got a bit of a shock when I started doing reporting and no numbers, not even entries, would appear for Office 2010 products, including Visio and Project.  Some of the more recent server products also weren’t listed (although this was a secondary concern at the time).

I soon found out there is not just one hot fix for this, but at least 3 have been issued, going back as far as November 2010 at least.  Following a change request, I got the latest version of the hot fix in and the reporting started working correctly.

Voting keypads and bluescreens

One of the more interesting problems I was given at RAC is the issue of Turning Point voting keypads causing computers to blue screen.

For those who don’t know, the keypads allow things like voting by an audience using little keypads.  The signal is sent wirelessly to a USB receiver plugged into a computer.  Following the roll-out of RAC’s new Managed Operating Environment (MOE), plugging in one of the receivers would cause the computer to blue screen.  I was tasked with fixing it.

The initial route I followed was to examine the blue screen dump files using the Windows Debugging tools.  Doing so pointed to the drivers for the receiver being the cause and after googling a bit, there did seem to be some supporting evidence that these style of devices didn’t play well on Windows 7.

The change in troubleshooting approach came from the fact that, if the device was plugged into a freshly un-boxed HP machine which hadn’t been re-imaged yet (that is, it was running the manufacturer image and drivers), it would work.  There was a date difference between the drivers, with the ones in the MOE being slightly older.

Going on the theory that one of the older drivers in the MOE was causing the blue screens in some way, I downloaded the latest drivers from HP and applied them one at a time, testing the receiver each time.  Eventually I hit a point where the blue screens stopped and the culprit was the fingerprint scanner’s driver.

I reproduced the fix on a few other machines with success, so there must’ve been some incompatibility between the MOE’s finger print scanner driver and the keypad receiver.

Windows 7 Remote Assist Wrapper Script

One of the functionality changes in Windows 7 was to Remote Assistance. In XP, you got a nice GUI to input the machine name or IP address of the target machine. In Windows 7, this was changed in a way where it was difficult to do this. You could do it via the command line. As an academic exercise I wanted to create a graphical wrapper for this that duplicated the XP Remote Assistance experience for service desk.

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

#endregion

#region Post-Constructor Custom Code

#endregion

#region Form Creation
#Warning: It is recommended that changes inside this region be handled using the ScriptForm Designer.
#When working with the ScriptForm designer this region and any changes within may be overwritten.
#~~< form1 >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$form1 = New-Object System.Windows.Forms.Form
$form1.Text = "ASG Remote Assistance"
#~~< btnStartRA >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$btnStartRA = New-Object System.Windows.Forms.Button
$btnStartRA.Location = New-Object System.Drawing.Point(13, 219)
$btnStartRA.Size = New-Object System.Drawing.Size(230, 23)
$btnStartRA.TabIndex = 4
$btnStartRA.Text = "Start Remote Assistance"
$btnStartRA.UseVisualStyleBackColor = $true
$btnStartRA.Enabled = $false
$btnStartRA.Add_Click({ StartRA })
#~~< lstCompInfo >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$lstCompInfo = New-Object System.Windows.Forms.ListBox
$lstCompInfo.FormattingEnabled = $true
$lstCompInfo.Location = New-Object System.Drawing.Point(13, 86)
$lstCompInfo.SelectedIndex = -1
$lstCompInfo.Size = New-Object System.Drawing.Size(259, 108)
$lstCompInfo.TabIndex = 3
#$lstCompInfo.Text = ""
#~~< btnConnect >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$btnConnect = New-Object System.Windows.Forms.Button
$btnConnect.Location = New-Object System.Drawing.Point(197, 37)
$btnConnect.Size = New-Object System.Drawing.Size(75, 23)
$btnConnect.TabIndex = 2
$btnConnect.Text = "Connect"
$btnConnect.UseVisualStyleBackColor = $true
#$btnConnect.Add_Click({ $lstCompInfo.Items.Add("This is a test") })
$btnConnect.Add_Click({ GetDetails })
#~~< txtCompName >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$txtCompName = New-Object System.Windows.Forms.TextBox
$txtCompName.Location = New-Object System.Drawing.Point(13, 39)
$txtCompName.Size = New-Object System.Drawing.Size(168, 20)
$txtCompName.TabIndex = 1
$txtCompName.Text = ""
#~~< Label1 >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$Label1 = New-Object System.Windows.Forms.Label
$Label1.Location = New-Object System.Drawing.Point(13, 13)
$Label1.Size = New-Object System.Drawing.Size(215, 23)
$Label1.TabIndex = 0
$Label1.Text = "Enter Computer Name or IP Address:"
$form1.Controls.Add($btnStartRA)
$form1.Controls.Add($lstCompInfo)
$form1.Controls.Add($btnConnect)
$form1.Controls.Add($txtCompName)
$form1.Controls.Add($Label1)

#endregion

#region Custom Code

#endregion

#region Event Loop

function Main{
[System.Windows.Forms.Application]::EnableVisualStyles()
[System.Windows.Forms.Application]::Run($form1)
}

function GetDetails
{
$strComputer = $txtCompName.Text
$strConnStatus = test-connection -computername $strComputer -quiet

if ($strConnStatus -eq $true)
{
# connection worked, continue script
$lstCompInfo.Items.Add("Connection successful...")
$objUsername = gwmi -computer $strComputer Win32_ComputerSystem | select username, model
$strUserName = $objUsername.Username
$strModelName = $objUsername.Model
$lstCompInfo.Items.Add("Current User is $strUserName")
$lstCompInfo.Items.Add("The target computer is a $strModelName")
$btnStartRA.Enabled = $true
$btnStartRA.Text = "Start Remote Assistance for $strComputer"

}
else
{
# connection failed
#Write-Host "Connection failed with status "
$lstCompInfo.Items.Add("Connection failed.")
$btnStartRA.Enabled = $false
#$strConnStatus | select *
}

}
function StartRA
{
$RAconName = $txtCompName.Text
$lstCompInfo.Items.Add("Attempting to connect to $RAconName" )
cmd /c msra /offerRA $RAconName
}

#endregion

#endregion

#region Event Handlers

Main #This call must remain below all other event functions

#endregion

Some of the lines are note are:

  • Line 24 – The Add_Click will call the function that performs the Remote Assistance connection
  • Line 76 – The script performs a test to see if the system name is responding
  • Line 87 – As part of the IF…THEN statement, if the connection status is true, the connect button is enabled by this line.
  • Line 106 – This line performs the command line version of the Remote Assistance connection, using the supplied computer name in the command

Windows 7 SOE – Reset Computer Groups Script

The application deployment setup in SCCM 2007 means you have to tend towards application deployment based on a user’s computer rather than the user’s account. One method of doing this is to have the computer in security groups that relate to collections to deploy the applications. For example, you may have a security group called “SCCM_Viso2010” to deploy Visio 2010. Where this becomes an issue is when you reimage the machine, you need a method of resetting the machine back to a default state so it doesn’t recieve those extra apps again. The script below was designed to achieve this.

add-pssnapin quest.activeroles.admanagement

write-host "Getting SID, GUID and DN for $env:computername"
$strComputer = get-qadcomputer $env:computername | select sid,guid,dn

write-host "Getting groups for $env:computername"
$strComputerGroups = get-qadmemberof $strComputer.SID

foreach ($obj in $strComputerGroups) {
if ($obj.Name -eq "Domain Computers")
{
write-host "This is the default group, do nothing"
}
else
{
write-host "The group $obj is a non-standard group"
remove-qadgroupmember -identity $obj -member $strComputer.SID
}
}

# Removing Quest AD snapin
remove-pssnapin quest.activeroles.admanagement

The behaviour of the script is to remove any group that isn’t the default group of “Domain Computers”. Like the OU move script, it utilises the Quest AD cmdlets.

Windows 7 SOE – Set Computer OU Script

One of the nice things about a Windows 7 SOE is it opens up the use of Powershell during the second phase of the OS installation.  Part of the SOE design for I worked on required some manipuation of items in Active Directory.  Doing this in VBScript is something I’ve found difficult, while it can be very easy in Powershell, especially if using the Quest AD cmdlets.

In this situation, the requirement was to move the computer account from the default location for the machine account creation (the Computers container) to an custom OU so the computer would fall under the influence of numerous group policies.  The script is detailed below:

add-pssnapin quest.activeroles.admanagement
$strComputer = $env:computername
$currDate = get-date -format g
add-content -path c:windowstempASGMoveComputertoCorrectOU.log -value "$currDate --- Starting OU Check"

$strGetComputer = get-qadcomputer $strComputer | select sid,GUID
$strGetComputerSID = $strGetComputer.sid

$strParentDN = get-qadobject -identity $strComputer -type computer | select parentcontainerdn
$currDate = get-date -format g
add-content -path c:windowstempASGMoveComputertoCorrectOU.log -value "$currDate --- Current OU is $strParentDN"
if ($strParentDN.ParentContainerDN -eq "OU=Windows7SOETesting,OU=SCCM Managed PCs,DC=asggroup,DC=com,DC=au" )
{
$currDate = get-date -format g
add-content -path c:windowstempASGMoveComputertoCorrectOU.log -value "$currDate --- This computer is in the correct OU"
}
else
{
$currDate = get-date -format g
add-content -path c:windowstempASGMoveComputertoCorrectOU.log -value "$currDate --- This computer is not in the correct OU"
add-content -path c:windowstempASGMoveComputertoCorrectOU.log -value "$currDate --- Attempting to move this computer with SID $strGetComputerSID to the correct OU...."
move-qadobject -identity $strGetComputersid -NewParentContainer 'OU=Windows7SOETesting,OU=SCCM_Devices,DC=contoso,DC=com'
add-content -path c:windowstempASGMoveComputertoCorrectOU.log -value "$currDate --- Move operation completed."
}
remove-pssnapin quest.activeroles.admanagement

A lot of the code is taken up with various setup code, but the key line is 22, which moves the machine account to the Windows 7 SOE OU.

Windows 7 SOE – Computer Naming and Space Characters

One of the frustrating road blocks I’ve run into with this Windows 7 SOE was related to the machine name.  Under the Windows XP SOE task sequence, there was a simple script that extracted the asset tag field from the BIOS and used that as the basis for the computer name.  One would think this would work without issue for Windows 7.  As it turns out, I was wrong.

After much hair pulling, I decided to check for non-visible characters by checking the length of the string.  Normally there is 9 characters.  When performing this check under the Windows 7 SOE, it returned 10 characters.  It seems the Windows 7 installer doesn’t like having a space in the machine name.  Once I added some code to remove these sort of characters, the problem went away.

[cc lang=”powershell” line_numbers=”true”]
strAssetTagNew = trim(strAssetTagNew)
[/cc]

Windows 7 SOE Design Outline

I’ve been working on a Windows 7 SOE for ASG for a couple of months now.  One of the things driving how the SOE is structured is to address issues with the old Windows XP SOE.  The XP SOE used what I call a “monolithic” process, by using a captured reference image that included all the SOE applications.  This is similar to how Ghost works and I don’t really like it as it doesn’t offer flexibility.  The Windows 7 SOE will use a modular approach where the task seequence will have several discreet tasks:

  • OS Deployment
  • SOE Application Deployment
  • Driver Installation

The rationale behind this is, should the need arise, these individual modules can be updated independently without having  an effect on other modules.

Upgrades and how they can change

The “old” PC I have was upgraded to Windows 7 but it just couldn’t cut it. The poor thing was a dual-core Athlon X2 with only 2gigs of RAM and a 3-drive RAID 5 array. I have since found out that the support for the chipset on the board from nVidia is basically non-existant and there is no support for running Windows 7 on that platform. Add to that the woeful performance and I decided to upgrade… Halfway through doing the hardware upgrade I decided to put Windows 2008 R2 on instead and setup the machine as a second virtualisation system, as the primary is now getting overloaded. I’ll be fleshing out the details on the home network page over time.

Upgrading to Windows 7

My new PC has been running Vista up until now. With the release of Windows 7 and the following positive praise for it, I decided to take the plunge. The sealing commentary came from some friends who had nothing but priase for Windows 7, while in the past they had complained constantly about Vista.

So I did all the right things, I ran the upgrade advisor tool. All my hardware was compatible. Only one application was not compatible – iTunes. The upgrade process itself was smooth and fast. The actual use of Windows 7 is pretty nice so far. The UI is very responsive.

I’ve completed three different install methods with Windows 7, just to see how they all work – the traditional installing from a CD/DVD, installing off a USB hard disk and installing via network using Windows Deployment Services (WDS). I think the WDS method ended up being the fastest, followed by the USB hard disk.