‘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
   
[Chorus]  
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
Vanity
full of sound and fury
whistling past your weathered epitaph
   
[Bridge]  
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…

Before
After

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
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
#>

# PREP SCRIPT:
param(
  $IP = (Get-wmiObject Win32_networkAdapterConfiguration |where-object{$_.IPEnabled -and $_.DefaultIPGateway}).DefaultIPGateway[0],
  $PortNum = 443, # or 8443 depending on controller version
  $Username,
  $Password
)
# tweaks:
trap { $_; exit 1 }	# force RMM to treat unhandled runtime errors as ERROR!
#widen host buffer for better output on old PS versions:
$pswindow=(Get-Host).UI.RawUI
$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()

if(!$Password){
	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"
}

# CONNECT TO CONTROLLER
[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
[Net.ServicePointManager]::ServerCertificateValidationCallback = { $True }
#$LoginURI
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"
}



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

# LOOP THROUGH SITES
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
		}catch{
			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" }
		#https://ubntwiki.com/products/software/unifi-controller/api:
		$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"}

		# LOOP THROUGH DEVICES FOR SITE
		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
					}

					#PORTS:
					#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
		}catch{
			$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
			} 
		}

	}
	
}


if($rptDevices){
	$report += "$rptDevices `r`n"
}
if($rptAlarms){
	$report += "$rptAlarms `r`n"
}


# REPORT PASS/FAIL
if($exitcode -gt 0){
	write-host "FAIL - problems found:"
}else{
	write-host "OK - no problems found!"
}
$report


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


write-host 
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
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"


# WRAP UP:
write-host 
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!

Lift A Finger?

I’ve mentioned before that I have pet peeves around driving.  And I recently saw a bumper sticker that reminded me that I’m not alone:
“Forget About World Peace / Visualize Using Your Turn Signals”

Actually, I saw it again, but in a new way   At a glance it’s just snarky, and I’m all about snark.  But bad driving begets traffic jams, and time to reflect on the bumper stickers in front of you…

Everyone’s an armchair general of world politics, and these days everyone has a soapbox for that too (yay Facebook).  But I only see 1/3 of Cincinnati drivers use their indicators to signal their turns or lane changes.  (And I think 1/3 is generous).  It’s surely the easiest effort in driving.

Literally, only 1/3rd of the world will LIFT A FINGER for safer driving.

I found this realization depressing for a few days, but I’ve decided it should be a Jeremiad, or a harsh reminder to do better:
The little stuff matters.   Before asking everyone else for a better world, Lift A Finger to start making it happen.  

 

Ketchup

I mean catch-up.
Too much work for too long meant many accrued life complications, so I’m on a purge…

Anthem

Breaking news: Identity theft is a bad thing

One target is paper: The last 3 weekends have included many hours of sorting through paper files for shred, toss, or reuse as scrap.  (Yes, I caught my mother’s frugality, so our family prints on the blank sides of old stuff, which is fun when you discover weird personal history on the flip side years later.)

In the shred category: I award special recognition to Anthem, Discover, and US Bank for taking an extra decade to notice any news about that new-fangled “identity theft”.  (It took them until ~2006 to start removing complete SSNs and account numbers from monthly statements)

The other is Digital: Today I turned to my blog feeds.  15 years had “collected” roughly 450 feed subscriptions in my reader, which I’m still reading daily.  …Well, I knew some of those 450 had gone dark, but managing them has been a recurring pain (browsing feeds by name isn’t easy in Feedly – how about some basic alphabetical sorting?).

Awesome

Awesome

So I decided to clean house on my feeds.  +A couple hours = a couple realizations:

  1. It’s messed up that I can get sentimental about an RSS Feed.  WebMonkey, I still miss your irreverent teaching methods, and I probably owe you my career.   But in culture of obscene plenty, I gotta start dropping some burdens.
  2. Blogs are Dead!  At least half of those feeds are now offline or haven’t been updated in 5-10 years.  Now I know why the huge feed count was only netting a few dozen posts per day.
    But why have bloggers given up?   Facebook and its ilk are obvious.  Long-form takes too long, and “Sharing” is now a grunt-button (yes, a grunt is how much value you’re sharing with those things) .   With grunt-buttons over at the HealthyViralConservatives page (that’s probably a thing), we smart people are all now stealing our own thunder.  But minimal effort = minimal value, so those with nothing to share are sharing the most, and discourse is dead.

…But wait, isn’t this Rob’s like, yearly blog post?  Yeah, I’m not done yet — that’s another comeback in the works.

Not Awesome

Not Awesome

But what direction?  Journaling is a great exercise and enjoyable, but what do I have that interests folks?
Comments would be a great measure, but I’ve never been popular enough for much of them, and folks have even LESS time for comments in the grunt-jab era, so they’re out. But …Akismet brags it’s outright blocked 18,279 spam comments just since I switched to WordPress 2 years ago.  And I get regular notices of spam comments quarantined for review (and that’s easy.  The last blog move was good to me, and I’d like to heartily thank the whole WordPress community.  Posting is way more likely when I’m not just cleaning up.)
So, without bothering on analytics, maybe the spammers know something.  They LOVE two ancient posts in particular:  my write-up on Royal TS (RIP), and another about line-breaks in VBScript.  (Was 2005 special?  It was arguably the golden age of blogging, but I’ve no idea how that could still echo now.)

So I’m gonna go with the topics: “meta-throbs” journally junk like this doesn’t enthrall, but every geek loves good Tools and Tips.  And I’ve always got tons of those, so I’ll try to get back to sharing them here soon.

I’d love requests too, but certainly won’t get my hopes up.  After all, there’s probably a heart-warming new LiberalCatVideo with a grunt-button.

Trans Cat

Secret to skip DHCP check in SBS2011 CTIW

I’ve sat on this far too long.  In 2013 I was setting up SBS 2011 (rebuilding it for a Slingshot client, actually), and hit the classic gotcha where the Connect To Internet Wizard insists on being the DHCP server.  My workaround was usually to temporarily disable the router’s DHCP, finish the wizard, then re-enable the router’s DHCP.

Unfortunately, this time I was working remotely after hours, and had no access to their router or its admin to do anything about it, so I was at risk of losing the night’s work and the client finding their stuff still down the next day.

Fortunately, I already had Microsoft support on the line for other matters.  They knew a workaround for this — when I asked about it, this is the registry screenshot I got:
secret to skip DHCP check in SBS2011 CTIW

For the record, that’s HKLM\SOFTWARE\Microsoft\SmallBusinessServer\Networking and a DWORD of SkipDHCPConfig = 1

I asked if this was public knowledge, and the answer was no.  I’ve saved this for a while, but with SBS 2011 now abandoned I think the knowledge should benefit others.  So I hope this helps someone else!   (I actually just needed that info myself, for a similar situation 🙂

 

How To Not Get Extorted By Ransomware

(Following is some material that Slingshot recently wrote up to help guide our customers through securing their IT systems against Ransomware.  It’s too good to not share with the world, though, so here ya go.  BTW, we pair this with a personalized recommendation — just holler if your organization would like a Slingshot consultation!)

 

Introduction

CryptoWall, CryptoLocker, and a variety of other names – they’re all Ransomware, one of the newer and most dangerous types of malicious software (Malware) threatening anyone who uses computers.  Once a computer is infected, these threats can lock your users out of their computers or encrypt your data irreversibly, including data on your servers.

Once the computers and/or data are compromised, users are told they can pay a “ransom” to recover their system and data access, often for thousands of dollars.  Since the culprits are often overseas, they reach over and hide behind the Internet in ways that regular law enforcement can’t help you.  This is extortion, and you just don’t want to be there!

Instead, we want to help you stay safe, so we’ve written this document to do two things:

  • Outline your options to Avoid, Block, Catch, Limit and Recover From Ransomware.
  • Recommend your best options to quickly and thoroughly secure your organization.

Options

Fortunately, there are plenty of ways to avoid paying your way out of Ransomware!

1) Avoid It with User Training:

Some technologies can reduce your risks, but the most important part of the puzzle is training users.  Besides Ransomware, training can help you avoid other threats, such as:

  • Phishing: Masquerading as a trustworthy entity to acquire sensitive information such as usernames, passwords, and credit card details, and sometimes money.
  • Whaling: Phishing that specifically targets organizations’ empowered decision makers.  Targeting details are harvested through Internet searches and/or social engineering attempts.  Hackers will sometimes register a very similar-looking domain, and then email decision makers from what appears to be their bosses, directing them to transfer money to offshore accounts.
  • Pharming: Malware is secretly planted in your computer to hijack your web browser.  When you type in the address of a legitimate Web site, you’re redirected to a fake copy of the site without realizing it, where the attackers can harvest your sensitive information.
  • Vishing: Phishing via telephone, this relies on social engineering techniques to trick you into providing sensitive information.

Informed users are the first line of defense against Internet security threats!  Slingshot can train your staff by several means: easy-to-read advisory documents, “lunch and learn” sessions with a hands-on visual component and Q&A, one-on-one training, or any combination of these.

2) Block It with Perimeter Defense:13604255104_b8cf62e8c0_m

The next defense is to block threats at a network level before they reach users (or vice versa).  Here are options and recommendations for each network threat:

  • Malicious File FilteringBlocks access to Malware and other known dangerous files.
    → We recommend Cyberoam firewalls paired with an Antivirus Filtering subscription for this.
  • Malicious Traffic Filtering – Blocks malicious traffic, like encryption keys used by Ransomware.
    → We recommend Cyberoam firewalls paired with an IPS subscription for this.
  • Geo BlockingBlocks all traffic from countries known for their criminal Internet reputation.
    → We recommend Cyberoam firewalls with Geo Blocking configured.
  • Web Filtering – Blocks access to websites classified as dangerous. Many firewalls can do this as a blanket solution, but most folks want something more sophisticated.
    → We recommend WebFilter (a Slingshot Managed Service), which we can also setup with per-user policies to also shield you from productivity and legal risks.
  • Email Filtering – Blocks spam, dangerous email content, and fraudulent emails. Some email servers can be setup to do some of this, but not very effectively.
    → We recommend MailControl (another Slingshot Managed Service), which we setup and keep tuned up, but which gives users easy self-management over their own filtering.

3) Catch It with Endpoint Protection2182760200_2825aac351_m

Should Ransomware or other malware still get past the user and firewall (e.g. by infected flash drive or using a work laptop outside the office network), additional protections are available:

  • Antivirus software – Installed software to detect and block malware. Windows 8+ has Defender built-in, which is free, but basic and unmanageable. → We recommend Slingshot’s Managed Antivirus (a Slingshot Managed Service) which uses the top-ranked BitDefender scanning engine, and which we setup, manage and monitor.
  • CryptoPreventA third party software application that installs on each computer and blocks many Ransomware infections. The commercial version costs around $100 for 50 licenses.
  • Malwarebytes Anti-RansomwareNew program (still in beta) that detects ransomware behavior and blocks the threads that are trying to encrypt files. Currently available for free.

4) Limit It with Secure Settings4250220079_b577b9b0c1_m

Even with a comprehensive protection plan in place, malware is constantly morphing to get around those measures.  If malware gets past the user, firewall, and malware detection, we want to limit its impact as much as possible.  There are two good ways to do this:

  • Software Restriction Policy (SRP) – A built-in Microsoft utility which can be configured to prevent executable files from running from directories that malware commonly tries to use. Basically, this keeps malware from having a foundation to work off.
  • Least User Privilege (LUA) – This is just a matter of using Standard User accounts for everyday work (rather than Administrator accounts). If a user account can only make changes to his areas, Ransomware running as that user has the same limitations.  (A best practice anyway, LUA also protects against staff accidentally taking down systems, as well as from snooping or malicious users tampering with things they shouldn’t.)
  • Network Share Security – Similar to LUA and “need to know” thinking, server network shares should have their access set to only allow the level of access that’s needed by each user or user group. This requires some thinking about an organization’s groups and who needs what.  (Also a best practice for the same reasons as LUA above).

5) Recover From It with BackupsStone-Rolled-Away1[1]

Finally, no matter what you do, bad things can still happen.  If worse comes to worst, there are options for data recovery without paying ransom.
→ Any properly configured server should follow the 3-2-1” Backup Rule:  3 backups, on 2 different media, and 1 offsite.

  • Volume Shadow Copy / Restore Previous Versions / System RestoreProperly configured Windows servers and workstations “snapshot” a backup of their files several times per day. In most cases, these previous versions can be easily restored over the encrypted versions.  Unfortunately, some malware knows how to also corrupt the previous file versions – LUA (above) helps prevent that.
  • Nightly Backups This is the second layer, usually a full-system (“bare metal”) Windows Backup to an external drive or NAS. Should Volume Shadow Copy have trouble, we can still restore files from this.
  • Offsite Backups – Finally, in the event of any catastrophe, you want a copy of your data offsite. We recommend CrashPlan or JungleDisk for this.