An argument against out of hours system maintenance

Late night again...
Late night again…

“You have no problem with out of hours work, right?”

It’s that question during the interview that causes a knot in your stomach. You hope, even pray, that what they mean is the occasional bit of emergency response work or a crunch period at a critical part of a project, both of which you have no issue with. But after you accept that job you find out that the work is routine system maintenance.

I’m going to put forward the argument that in this, dare I say it, golden age of automation, continuous deployment, commodity hardware, virtualisation, micro-services and other cloud-related fluff that there is very few situations why this work needs to be done out of hours. If anything using this model incurs additional risk.

(To any prospective employers out there, don’t take this as my refusal to do such work, this piece is simply about thinking about the issue differently)

Read more

CeBIT Australia 2015 Experience

This year was the first time I had attended CeBIT, with a primary motivator being the Cloud Conference component, with that component being of interest personally and professionally, as well as the fact that events of this size are rarely held in Perth.  The speakers for the Cloud Conference covered private enterprise and government, giving a broad view of how cloud was making IT work better.

The first speaker was Chris C Kemp, former CTO at NASA and co-founder of OpenStack.  He spoke about the concepts of anti-scarcity, where a thing can be made more valuable by making it more freely available and accessible because more parties are involved and invested in the item.  This concept applies strongly with open source software and OpenStack in particular, which because as an internal project at NASA.  By allowing it to be available to all, OpenStack now has support and investment from large IT vendors such as HP, IBM and Cisco.

David Boyle from NAB opened his presentation by stating he wouldn’t use the “c word” (cloud).  He managed to stick with his promise, and talked about the concepts of traditional “horse and cart” IT, the model we’ve used in the past of physical infrastructure, lengthy release cycles and waterfall development.  This was contrasted with “Ferrari” IT, which uses virtualisation, frequent release models, continuous deployment, automation and dev ops.  A key concept he outlined was “fail fast” – having a deployment framework that can be run rapidly so success or failure can be determined quickly and subsequent deployments attempted once problems have been fixed.

Read more

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.

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.

Powershell Task of the Day – Move Mailbox for all users in an Organisational Unit (part 2, Bulk move)

A follow on from the previous script was to move a larger number of users in a list of OUs. To make the task easier, I decided to automate it a bit:

$miglist = import-csv c:scriptsmigration.csv

foreach ($item in $miglist)
{
$strTargetmbx = "EXCH02" + $item.tiernumber + "-east" + $item.tiernumber + "-east"
$strReportFile = "c:scripts" + $item.name + ".xml"
Get-Mailbox -server "EXCH01" -OrganizationalUnit $item.ouname | `
Move-Mailbox -Confirm:$False -TargetDatabase $strTargetmbx -SourceMailboxCleanupOptions DeleteSourceMailbox -ReportFile $strReportFile
}

In the first line, I’m importing the contents of a CSV file that listed the OUs, a friendly name for the OU and the “tier” database those users were to go in. Iterating through the $miglist, I construct the target mailbox database name ($strTargetmbx) and report filename ($strReportFile). The Move-Mailbox command uses the -Confirm:$False switch to suppress confirmation. If this switch isn’t used, you will be prompted for confirmation at each step. The rest of the move command is pretty simple, specifying where to move to and a report filename.