‘X Out’ – From One Extreme To A Brother

A favorite band of mine is Extreme. They go back, but a refresher is their 90s radio hits More Than Words, Hole Hearted, Get The Funk Out, or more recently having Play With Me featured on Netflix’ Stranger Things.

Good favorites have a Why – an article I definitely plan to write about …many years ago.
Until then, I’ll just placehold it for Extreme: world-class musicianship, affecting song-writing, and lyrical content that’s evocative and meaningful. But that’s not what I’m on about right now.

Their new album “Six” is half good, half great.  And that includes one song I can’t quit called “X Out”.  It’s all there: great playing and affective execution (with a stimulating Tribe of Judah vibe). It’s pretty intense – listen while you read:

The song is also lyrically just PACKED with references, mostly from the Bible.  And Shakespeare.  (Yes, “Shakespeare-or-the-Bible” quizzes are fun, but this article is just a reference job.)

And in 2023, I expected surely some enterprising nerd had tagged all those references, but no!

So guess who’s the nerd now? 🪞
(Of course some dudes have already interpreted the lyrics, but I say just go read the sources, and interpret from there! : )

Hope someone finds this useful!

[Verse 1]  
Forgive me Father In Catholic Sacrament of Reconciliation, Confession starts with this line
show me your unfailing love Psalm 17:7-8 Show me your unfailing love in wonderful ways. By your mighty power you rescue those who seek refuge from their enemies.
There is no other Deuteronomy 4:39 the Lord Himself is God in heaven above and on the earth beneath; there is no other. (Also: 1 Samuel 21:9, 1 Kings 8:60, 9× in Isaiah, Daniel 2:11, Daniel 3:29, Joel 2:27, Mark 12:31, Mark 12:32, Acts 4:12, 1 Corinthians 8:4)
have Mercy on your wayward son Luke 15:11-32 The Parable of the Prodigal Son
From grace I fell Galatians 5:4 You have become estranged from Christ, you who attempt to be justified by law; you have fallen from grace.
opened up my eyes in hell Luke 16:19-31 Parable of The Rich Man and Lazarus
brimstone burning, crying out in agony
Father send someone
quench the fire from my tongue
where the worm’s eternal Mark 9:44-48 Their worm does not die And the fire is not quenched.
and, I’m crying out in agony
Sun burns out and it fades to black Joel 3:15 The sun and moon will grow dark, and the stars will cease their shining. (Also: Joel 2:31, Matthew 24:29, Revelation 6:12)
there’s no way I’m gonna make it back Luke 16:19-31 Parable of The Rich Man and Lazarus
out of time and I’m running out of light
X Out X Out, Faith 1 Corinthians 13:13 Now these three remain: faith, hope, and love. But the greatest of these is love. (Also: 1 Thessalonians 1:3, 1 Thessalonians 5:8)
X Out X Out, Hope
X Out X Out, Love
[Verse 2]  
Behold a flower Psalm 103:14-16 As for man, his days are like grass — he blooms like a flower of the field; when the wind passes over it, it vanishes, and its place is no longer known.
flourishing then falls away
Know not the hour Matthew 24:36-44 The Day and Hour Unknown
number of or length of days Psalm 90:12-17 teach us to number our days, that we may gain a heart of wisdom
Save your breath MacBeth Act 5 Scene 5 Life’s but a walking shadow, a poor player, That struts and frets his hour upon the stage, And then is heard no more. It is a tale Told by an idiot, full of sound and fury, Signifying nothing.
on a stage a strutter frets
just another tale being told by an idiot
full of sound and fury
whistling past your weathered epitaph
Rich man blessed in purple thread Luke 16:19-31 Parable of The Rich Man and Lazarus
Poor man begging for a crust of bread
like the poor the rich are born to die
One man suffering forever damned
the other in the bosom of Abraham
looking on beyond the great divide
Darkness drapes both sun and moon Ecclesiastes 12:1-2 Remember your Creator in the days of your youth, … before the sun and the light and the moon and the stars grow dark, and the clouds return after the rain; (Also: Joel 3:15Joel 2:31, Matthew 24:29, Revelation 6:12)
after the rain storm clouds return
Strong men bow
and the housekeepers quake
Ecclesiastes 12:3 when the keepers of the house tremble, and the strong men stoop, (Also: Matthew 27:54?)
Severed is the silver chord (cord) Ecclesiastes 12:6-7 before the silver cord is snapped, and the gold bowl is broken, and the jar is shattered at the spring, and the wheel is broken into the well; and the dust returns to the earth as it once was, and the spirit returns to God who gave it. (Also: Silver Cord metaphysical term)
broken like the golden gourd
dust returns to death
from whence it came
Source: LyricFind
Songwriters: Eric Warfield / Gary Cherone / Jordan Ferreira / Nuno Bettencourt
X Out lyrics © Calhoun Enterprises LLC, Kobalt Music Publishing Ltd.

Office – Check out our new look

Hey Microsoft QA, you might want to check out your new look:

animated GIF of Office's horrible new 'Check out our new look' popup

It looks less “modern, coherent and familiar”, and more “Unreadable” and “lost the Title Bar”.

This has popped up on many systems recently, so Consider it Checked out and extremely Not now.

Update 2022-02-25 It just popped up again where it was previously dismissed
(did they realize it was garbled and wanted another chance to persuade?)

Comparing key frames…


Their fixed comparison seems to offer :

  • LOSS of support for Windows’ Title Bar accent colors
  • LOSS of the Quick Access Toolbar from the Title Bar
    …and of those, add just “Undo” back to the Ribbon (Customize the Ribbon could already do this)
  • LOSS of usable vertical space to 15% increased Ribbon sprawl
  • LOSS of usable horizontal space, reducing Style choices from 4 to 3.

So “modern, coherent and familiar” means: form over function!, set the designers loose!, dumb it down!
…aka a typical “Fresh New Look”.

Now, you can do stuff without clicking buttons, ’cause they’re annoying!

RMM Check: Unifi Health

At Slingshot, we’ve moved our Managed clients over to Unifi networking systems, and I wanted to use our RMM to directly monitor the Unifi Controller. The API isn’t officially documented, but I did find other resources: the community’s API documentation, CyberDrain’s examples, and the Unifi API browser. Add tons of other research and trial/error, and I finally accomplished a Powershell RMM script that monitors Device connections, resources/ports, and Alerts, and reports on a ton more.

Enough with the intros. Here’s an instance currently alerting in Solarwinds RMM:

…and More Info gives the full report (looks better in console — I wish SWRMM preserved whitespace):

Before I forget, some quick notes:

  • Needs a local account (limited admin/readonly) on controller
  • For UDMPs with firmware 1.6 or greater, use port 443; For older controllers, use port 8443
  • It defaults the Controller IP to the detected Gateway IP (we do a lot of UDMPs).
  • Several of the Device Status codes are documented nowhere, so this script might have the only public record of them (for posterity, I’ve figured out 2=pending adoption, 9=inform error, and 11=isolated).

And finally the Powershell — (self-consciously) still in progress with plenty of debug stubs, BUT with lots of useful production miles already under its belt:

<#	checkHealth-UnifiController.ps1
Purpose: for all sites on a controller, checks device connections, resources, ports, alerts
Author: 	Slingshot Solutions, www.slingfive.com
Params:		$IP (or hostname) of controller (default: detected gateway), [int]$PortNum (default:443), Username, PASSWORD
* needs a local account (limited admin/readonly) on controller
* For UDMPs with firmware 1.6 or greater, use port 443;  For older controllers, use port 8443

  $IP = (Get-wmiObject Win32_networkAdapterConfiguration |where-object{$_.IPEnabled -and $_.DefaultIPGateway}).DefaultIPGateway[0],
  $PortNum = 443, # or 8443 depending on controller version
# tweaks:
trap { $_; exit 1 }	# force RMM to treat unhandled runtime errors as ERROR!
#widen host buffer for better output on old PS versions:
$newsize=$pswindow.BufferSize; if($newsize.width -lt 100){$newsize.width=100}; $pswindow.BufferSize=$newsize
$newsize=$pswindow.WindowSize; if($newsize.width -lt 100){$newsize.width=100;$newsize.height=20}; $pswindow.WindowSize=$newsize
function short([string]$str,[int]$size){if($str.length -gt $size){return ($str.substring(0,$size-3)+"...")}else{ return $str}}
# vars:
$exitcode = 0
$report = ""
$FullRpt = ""
$StopWatch = [system.diagnostics.stopwatch]::startNew()

	write-host "PARAMETERS:"
	foreach ( $key in ((Get-Command -Name $MyInvocation.InvocationName).Parameters).Keys ) {
		$val = ((Get-Variable $key -ea SilentlyContinue).Value) -join ", "
		Write-Host "  $($key): $val" 
	write-error "Hey dummy, set your params!"
	exit 1000

$Credential = @{  username="$Username"; password="$Password"; remember=$True; strict=$True; } |ConvertTo-Json
if($PortNum -eq 443){ # UnifiOS 1.6 or newer:
	$BaseURI = "https://$($IP):$($PortNum)/proxy/network"
	$LoginURI = "https://$($IP):$($PortNum)/api/auth/login"
}elseif($PortNum -eq 8443){ # EdgeOS 1.5 firmware or older:
  $BaseURI = "https://$($IP):$($PortNum)"
	$LoginURI = "https://$($IP):$($PortNum)/api/login"

[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
[Net.ServicePointManager]::ServerCertificateValidationCallback = { $True }
Try {
	$login = Invoke-RestMethod -uri $LoginURI -Method POST -Body $Credential -ContentType "application/json" -SessionVariable UniFiSession | out-null
}catch{	#wrong username/password = "The remote server returned an error: (400) Bad Request"
	write-error "* ERROR - Api Connection Error: $($_.Exception.Message)"    
	$exitcode = 1010
if($exitcode -eq 0){
	#write-host "CONNECTED`r`n"

if($exitcode -eq 0){
	try {
		$urlSites = "$($BaseURI)/api/stat/sites"
		$sites = Invoke-Restmethod -Uri $urlSites -Method GET -WebSession $UniFiSession
		#$report += "* ERROR - Sites Query Failed: $($_.Exception.Message)`r`n"
		write-error "* ERROR - Sites Query Failed: $($_.Exception.Message)`r`n"
		$exitcode = 1011

if($exitcode -eq 0){
	# DIRTY HACK: UDMPs lose their auth on the second call (Something ServerCertificateValidationCallback related), so just pound it back every time:
	Invoke-RestMethod -uri $LoginURI -Method POST -Body $Credential -ContentType "application/json" -SessionVariable UniFiSession | out-null

	$rptDevices = ""
	$rptAlarms = ""
	Foreach ($site in $sites.data){  # SITE
		try {
			$urlDevices = "$($BaseURI)/api/s/$($site.name)/stat/device/"
			$devices = Invoke-Restmethod -Uri $urlDevices -Method GET -ContentType "application/json" -Headers @{"Accept"="application/json"} -WebSession $UniFiSession
			write-error "* ERROR - Device Query Failed: $($_.Exception.Message)`r`n"
		$shortsitename = short $site.desc 7

		$FullRpt += "`r`nSITE '$($site.desc)' - $urlDevices :`r`n"

		$DeviceStateNames = @{0="disconnected"; 1="connected"; 2="pending adoption"; 3="3(?)"; 4="upgrading"; 5="provisioning"; 6="heartbeat missed"; 9="inform error"; 11="isolated" }
		$DeviceModelNames = @{"BZ2"="UniFi AP"; "BZ2LR"="UniFi AP-LR"; "U2HSR"="UniFi AP-Outdoor+"; "U2IW"="UniFi AP-In Wall"; "U2L48"="UniFi AP-LR"; "U2Lv2"="UniFi AP-LR v2"; "U2M"="UniFi AP-Mini"; "U2O"="UniFi AP-Outdoor"; "U2S48"="UniFi AP"; "U2Sv2"="UniFi AP v2"; "U5O"="UniFi AP-Outdoor 5G"; "U7E"="UniFi AP-AC"; "U7EDU"="UniFi AP-AC-EDU"; "U7Ev2"="UniFi AP-AC v2"; "U7HD"="UniFi AP-HD"; "U7SHD"="UniFi AP-SHD"; "U7NHD"="UniFi AP-nanoHD"; "UFLHD"="UniFi AP-Flex-HD"; "UHDIW"="UniFi AP-HD-In Wall"; "UCXG"="UniFi AP-XG"; "UXSDM"="UniFi AP-BaseStationXG"; "UCMSH"="UniFi AP-MeshXG"; "U7IW"="UniFi AP-AC-In Wall"; "U7IWP"="UniFi AP-AC-In Wall Pro"; "U7MP"="UniFi AP-AC-Mesh-Pro"; "U7LR"="UniFi AP-AC-LR"; "U7LT"="UniFi AP-AC-Lite"; "U7O"="UniFi AP-AC Outdoor"; "U7P"="UniFi AP-Pro"; "U7MSH"="UniFi AP-AC-Mesh"; "U7PG2"="UniFi AP-AC-Pro"; "p2N"="PicoStation M2"; "US48PRO"="UniFi Switch Pro 48"; "US8"="UniFi Switch 8"; "US8P60"="UniFi Switch 8 POE-60W"; "US8P150"="UniFi Switch 8 POE-150W"; "S28150"="UniFi Switch 8 AT-150W"; "USC8"="UniFi Switch 8"; "US16P150"="UniFi Switch 16 POE-150W"; "S216150"="UniFi Switch 16 AT-150W"; "US24"="UniFi Switch 24"; "US24P250"="UniFi Switch 24 POE-250W"; "US24PL2"="UniFi Switch 24 L2 POE"; "US24P500"="UniFi Switch 24 POE-500W"; "S224250"="UniFi Switch 24 AT-250W"; "S224500"="UniFi Switch 24 AT-500W"; "US48"="UniFi Switch 48"; "US48P500"="UniFi Switch 48 POE-500W"; "US48PL2"="UniFi Switch 48 L2 POE"; "US48P750"="UniFi Switch 48 POE-750W"; "S248500"="UniFi Switch 48 AT-500W"; "S248750"="UniFi Switch 48 AT-750W"; "US6XG150"="UniFi Switch 6XG POE-150W"; "USXG"="UniFi Switch 16XG"; "UGW3"="UniFi Security Gateway 3P"; "UGW4"="UniFi Security Gateway 4P"; "UGWHD4"="UniFi Security Gateway HD"; "UGWXG"="UniFi Security Gateway XG-8"; "UP4"="UniFi Phone-X"; "UP5"="UniFi Phone"; "UP5t"="UniFi Phone-Pro"; "UP7"="UniFi Phone-Executive"; "UP5c"="UniFi Phone"; "UP5tc"="UniFi Phone-Pro"; "UP7c"="UniFi Phone-Executive";
		"UDMPRO"="UniFi Dream Machine Pro"}

		Foreach ($device in ($devices.data)){
			$DeviceModelName = $DeviceModelNames[$($device.model)]
			$DeviceStateName = $DeviceStateNames[$device.state]

			if( $device.default -eq $True){	# PENDING ADOPTION:
				$vwireEnabled = ($device.vwireEnabled -eq $True)
				$discovered_via = $device.discovered_via	#scan or l2
				$FullRpt += "* $($device.type) $DeviceModelName, ip:$($device.ip), mac:$($device.mac), state:$DeviceStateName $($device.state), discovered_via:$discovered_via, wireless:$vwireEnabled`r`n"				
				$rptDevices += "* PENDING ADOPTION$(if($vwireEnabled){" (WIRELESS)"}): $shortsitename > ($DeviceModelName)`r`n"
				$exitcode = 1010

			}elseif ($device.adopted -eq $True){
				if($device.state -eq 0 -or $device.state -eq 9 -or $device.state -eq 11){	# DISCONNECTED, INFORM ERROR, ISOLATED:
					$FullRpt += "* '$($device.NAME)' - $($device.type) $DeviceModelName, ip:$($device.ip), mac:$($device.mac),`r`n    state:$($device.state) $DeviceStateName, adopted:$($device.adopted), disabled:$($device.disabled -eq $True)`r`n"				
					if($device.disabled -ne $True){	# don't care if it's disabled
						$rptDevices += "* $($DeviceStateName.toUpper()): $shortsitename > '$($device.name)'`r`n"
						$exitcode = 1011
				}else{	# OTHERWISE:					
					$uptime = new-TimeSpan -Seconds (0+ $device.'system-stats'.uptime)

					$FullRpt += "* '$($device.NAME)' - $($device.type) $DeviceModelName, ip:$($device.ip), mac:$($device.mac),`r`n    state:$($device.state) $DeviceStateName, uptime:$uptime, cpu:$([int]$device.'system-stats'.cpu)%, mem:$([int]$device.'system-stats'.mem)%, current:$(!$device.upgradable) (FW v$($device.version))`r`n"

					if( [math]::Round($device.'system-stats'.uptime) -lt "300") { 
						$rptDevices += "* $shortsitename > $($device.name) : Disconnected `r`n"
						$exitcode = 1010
					if( [math]::Round($device.'system-stats'.cpu) -gt "90.0") { 
						$rptDevices += "* $shortsitename > $($device.name) : CPU usage of $($device.'system-stats'.cpu)% `r`n"
						$exitcode = 1012
					if( [math]::Round($device.'system-stats'.mem) -gt "90.0") { 
						$rptDevices += "* $shortsitename > $($device.name) : Memory usage of $($device.'system-stats'.mem)% `r`n"
						$exitcode = 1013
					if( $device.upgradable -eq $true ) {
	#					$rptDevices += "* $shortsitename > $($device.name) : Firmware upgrade available <-- IGNORING til QA recovers`r`n"
	#					$exitcode = 1014

					#if($device.port_table.count -gt 0){	#don't need to see AP Pros' secondary ports
					if($device.type -eq 'usw'){
						$FullRpt += "  "+ ($device.port_table |ft port_idx,name,enable,up,is_uplink,port_poe,autoneg,speed,full_duplex,network_name -AutoSize |out-string).trim().replace("`n", "`n  ") +"`r`n"
					Foreach ($port in $device.port_table.data){
						if($port.stp_state -eq "discard"){
							$rptDevices += "* $shortsitename > $($device.desc) > PORT $($device.name) : blocked due to STP issues `r`n" 
							$exitcode = 1017


		Foreach ($device in $devices.data.wan1 |where-object {$_.name}){	#weirdly duplicates with blanks otherwise
			$FullRpt += "* FW WAN1 '$($device.name)' - is_uplink:$($device.is_uplink), up:$($device.up), ip:$($device.ip), netmask:$($device.netmask), gateway:$($device.gateway)  `r`n"
			if($device.is_uplink -and $device.up -ne $True) { 
				$rptDevices += "* $shortsitename > WAN1 $($device.name) : link down `r`n" 
				$exitcode = 1015
		Foreach ($device in $devices.data.wan2 |where-object {$_.name}){#weirdly duplicates with blanks otherwise
			$FullRpt += "* FW WAN2 '$($device.name)' - is_uplink:$($device.is_uplink), up:$($device.up), ip:$($device.ip), netmask:$($device.netmask), gateway:$($device.gateway)  `r`n"
			if($device.is_uplink -and $device.up -ne $True) { 
				$rptDevices += "* $shortsitename > WAN2 $($device.name) : link down`r`n" 
				$exitcode = 1016

		# DIRTY HACK: UDMPs lose their auth on the second call (Something ServerCertificateValidationCallback related), so just pound it back every time:
		Invoke-RestMethod -uri $LoginURI -Method POST -Body $Credential -ContentType "application/json" -SessionVariable UniFiSession | out-null

		try {
			$urlAlarms = "$($BaseURI)/api/s/$($site.name)/stat/alarm/"
			$alarms = Invoke-Restmethod -Uri $urlAlarms -Method GET -ContentType "application/json" -Headers @{"Accept"="application/json"} -WebSession $UniFiSession
			$report += "* ERROR - Alarm Query Failed: $($_.Exception.Message)"
			write-error "* ERROR - Alarm Query Failed: $($_.Exception.Message)"
		Foreach ($alarm in ($alarms.data)){
			if(! $($alarm.handled_time)) {	# ???
				$rptAlarms += "* ALERT: $shortsitename > '$($alarm.ap_name)' : $($alarm.msg) @$([datetime]$alarm.datetime -f "yyyy-MM-dd-Hmmss") `r`n" 
				$exitcode = 1018


	$report += "$rptDevices `r`n"
	$report += "$rptAlarms `r`n"

if($exitcode -gt 0){
	write-host "FAIL - problems found:"
	write-host "OK - no problems found!"

 write-host "CHECKED DATA:"
 write-host " "($FullRpt.replace("`n", "`n  ")).trim() #format

write-host "PARAMETERS:"
foreach ( $key in ((Get-Command -Name $MyInvocation.InvocationName).Parameters).Keys ) {
	$val = ((Get-Variable $key -ea SilentlyContinue).Value) -join ", "
	Write-Host "  $($key): $val" 
write-host "CONTEXT:"
write-host "  Script Path:" (get-item $MyInvocation.InvocationName)
write-host "  Script Last Updated:" (get-item $MyInvocation.InvocationName).LastWriteTime " (try -5hrs [SW saves as UTC])"
write-host "  Execution Time: Total $($elapsed_Total)sec"

write-host "exitcode: $exitcode" 
exit $exitcode

NOTE: updates since publishing this have so far added:
* proper detection of the “pending adoption” state
* awareness of the undocumented “adopting” state
* awareness of the undocumented UBB, USP and USW-Flex-Mini models
If anyone’s dying to see the latest version, let me know in the comments.

ExcelMicro.com RSS feeds

Are you an ExcelMicro partner who needs to stay in the loop on what they’re doing?  

They’ve got some great services and folks, but it sounds like they’re swamped with a lot of internal changes over the last couple years.  Unfortunately, that leaves them a bit weak on partner communication…

Their ONLY official way to not get surprised by changes is to manually/constantly check their support portal web pages.  After extended nagging for them to publish ANY info on Proofpoint releases, they did finally add that a few months ago.  But still no mailing lists, no RSS feeds, no carrier pigeons — just keep clicking refresh til something shows up…

So I took matters into my own hands: Using Feed43’s fantastic service, I wrote custom regular expressions to scrape EM’s content, which I’ve published into my own RSS feeds.  If you’re looking to stay in the ExcelMicro loop, feel free to subscribe to these feeds:

I expect EM will eventually get official feeds so these aren’t needed, but til then, enjoy!

Fool me 8 times, shame on me.

  1. Reader
  2. Postini
  3. Calendar sync
  4. iGoogle
  5. Gears
  6. Code Search
  7. Pack
  8. and now Voice XMPP integration

These are a few of my favorite things,
…that Google has yanked out from under my feet.

And let’s not forget Gmail’s Activesync. (That’s why I switched to Outlook.com, and happily).

Why are geeks still trusting Google? We should know better by now.

You can remember dozens of other loved ones in The Google Graveyard


Long Live Reading

With Google Reader now buried, and
my preferred reading app NewsRob with it, I figured I’d share how things shook out in my quest to keep reading…

My targets:

  • content-focused web app, keyboard navigable, and somehow able to theme it dark (y’know, light the content, not the room 🙂
  • responsive mobile app with good caching, plugin support, and also dark-skinnable

On the web service side, I tried and found:

  • Yoleo – ok, but strange UI, and no mobile app!
  • The Old Reader – UI similar to Reader, but much too basic and slow
  • CommaFeed – almost perfect clone of Reader’s UI, and great features (including custom theming), but somewhat slow
  • NewsBlur – fast UI, but focused on its own slickness, and bad keyboard accessibility
  • Feedly – (originally NO web client, but they made one for Reader fans!) – fast UI, but missing +/- to zoom text.

For mobile apps, I tried:

  • CommaFeed – too little/late. Alpha released 2 days before Reader buried, and didn’t even have caching.
  • Feedly – too dog slow to be at all usable.
  • GReader – very sophisticated (and better performance than my previous try a year ago)

My friend Sean McCabe (who really needs a blog!) enlightened me that GReader supported Feedly, and that Feedly also imported Reader’s Starred Items. I have 6 years of Starred Items that I didn’t want to use, so that sealed the deal: Feedly+GReader it is!

Feedly’s only cons: missing +/- zoom, and themes only cover navbar — I figured I can handle that… But I just remembered the Chrome extension Stylebot, which can inject your own custom CSS into any page. I’ve just used it to create a black AND zoomed theme for Feedly. Perfecto.

Keep on reading!

RIP Reader Google

Google is shutting down Reader.


6 years ago, I made a lengthy search and was happy to find it, and I happily use it daily for 454 feeds on various computers and devices.  So I’m not sure what comes next.  Everyone seems to be sharing lists or gimmicks of Reader alternatives, but they all look like steps back to me.

For now, I’ve left a flower for Reader at the The Google Graveyard.

Beyond that, my strongest next inclination is to stop trusting Google with my stuff.

Dear Acer: It’s your own fault

So Microsoft is about to sell its own hardware running Windows.    And Acer is unhappy, because Microsoft is effectively competing with its own partners.

Now, working for a Microsoft Partner, I can understand the feeling.  I have my beefs with Microsoft, like how they’ve just disenfranchised Small Business Specialists and cut down Small Business Server at the knees
(The 30-day discontinuation of SBS on SA is really throwing us for a loop now, since we relied on TechSoup to provide affordable solutions to non-profits, and Techsoup only has SA software, not OEM).

But consider this:

Acer and their ilk have been making Windows suck.

How so?   What do you think you should get to do after first powering up your brand-new computer?   Hours manually uninstalling paid Norton or McAfee trials, a dozen manufacturer addons, and a dozen more partner promotions?   Me either.    Here’s our experience:

  • Once upon a time, we manually removed the junk, as a labor of love. 
  • A few years ago we started using PC-Decrapifier to help automate the process, followed by CCleaner for the remnants.  Down to an hour or so…
  • Last year, we started wiping the (brand new) systems, and scratch installing from Microsoft’s own media.   It’s some upfront work, but actually faster, and the result is so much better.  (The only downside is tracking down weird laptop drivers).


Last week we bought an Acer netbook, and (for some crazy reason) gave their install a shot.   After powering up and doing some standard Windows configuration, Acer started their first-run customization process .   Now I’ve done this a LOT, and know this process should take about minute or two.  

Instead, it took 45 minutes, and crashed with a BSOD.

Then, after finally getting past “buy me” promos, it was sluggish.   Task Manager showed 35% CPU gone to a McAfee trial, and 67% RAM used overall, when I HAD RUN NO PROGRAMS YET.   Did we buy a pet to run for our amusement, and do nothing useful?


Dear Acer, I don’t like the idea of Microsoft taking their ball back either, but you dropped it, and someone’s gotta run the bases.  


P.S.  Also noteworthy about the Microsoft shift is that’s how Apple sells:  unified software AND hardware.  Other criticisms aside, Apple delivers a pretty tight package.