Saving yourself from Sender’s Remorse with Outlook

tl;dr summary: Create an Outlook rule to “delay outgoing mail by <5> minutes”, “unless body contains: е”, where the character used for the body exclusion comes from typing ALT+1077.

“When it comes to email, it seems that I always do my best proof reading immediately after I press the Send button.”

Perhaps you’ve been in the situation before, where you immediately regret sending an email in anger. Or realize after a few more moments of reflection that the email you just sent was well and truly wrong. Or you accidentally hit the “Send” button, and now have an incomplete thought floating around in everybody’s mailbox.

Fortunately, you’re not the first to run into this issue. And if you’re using Outlook, there’s a simple way to prevent it.

The first time somebody told me how they solved the problem, they pointed out that Outlook Rules Wizard lets you set the following condition on all outgoing mail:


In that, they select “Delay sending by 5 minutes”. The next screen in that wizard is the “Except when” conditions, where they said, “Unless sent with high importance”:


That sounds really handy: high-importance mail goes out immediately, while all the rest is delayed for 5 minutes. And it seemed to work – I never noticed hasty / incomplete mails from him, but he did seem like kind of a rager because you’d sometimes get mails marked urgent for totally non-urgent things.

Unfortunately, the issue with that system was that mails are sometimes time sensitive but not urgent. If you take a look at the other exclusion alternatives, nothing seems reasonable. Message size? Subject? (Who wants to tag subjects with things like: “FAST: “).

In search of a solution, I found another useful feature: configuring Outlook to send and receive every 10 minutes, even when connected to a fast network. That way, your mails wait for 5 minutes on average before leaving your outbox. You still get your incoming mail immediately, so it seems like it’s the best of all worlds.

Unfortunately, there were plenty of situations where I went to fish a mail out of my Outbox, only to find it missing.

The issue with this solution is that 5 minutes is only an average. 10% of your mails will leave your Outbox in less than a minute. 5% will vanish in less than 30 seconds. And then of course there’s the 5-10% of mails that feel like they take an entire working day to leave – so basically you’re unhappy about 20% of your outgoing mail :)

After some more fiddling, I finally landed on a pretty useful solution, and have been using it ever since. This one goes back to the “Delay sending by 5 minutes” approach, but with one twist. Since the main issue with exclusions in the subject / body of your mail is that externalizes your rules onto your readers, what if they didn’t notice?

Fortunately, there are a handful of characters that look like spaces, but aren’t. To type a special character in Windows, you hold down the ALT key, type the character code on the number pad of your keyboard (not the numbers on the top row of your keyboard), and then let go of the ALT key.

The one I use is ALT+1077. It is еasy to remеmbеr and rеminds me of my BBS days. It rеprеsеnts the Cyrillic letter ‘e’. I used it 10 times in the previous sentence :)

You have two main options here:

"Except if the subject contains specific words"


When you click on "specific words", press ALT+255, and now every mail you send with this in the subject goes out immediately. This looks like a blank space.

"Except if the body contains specific words"

This is the best – you can replace an ‘e’ with ALT+1077 (е) pretty much anywhere in the content of the mail, and nobody will know.


If you use ALT+255 in that dialog (like with the subject), the rule doesn’t seem to work. It works fine for plain-text mails, but HTML mails don’t seem to pick this up properly. I think that perhaps Outlook auto-correct replaces it with a space.

So instead, ALT+1077 is a good substitute for an ‘e’.


All in all, I only have two minor gripes with these techniques for Sender’s Remorse:

  1. (In the ‘Body’ case): ALT+1077 doesn’t work on a laptop that has no number pad. If this is a big issue, you can copy and paste it from another mail, a "snippets" file, or add an international keyboard that lets you do this without the number pad.
  2. (In the ‘Subject’ case): If you use this technique when responding to an existing mail thread, the subject line change makes Outlook treat your mail as a fork of the thread. This is why I prefer the ‘Body’ approach.
  3. Outgoing mail rules are applied when you press ‘Send’ the first time. If you decide that a mail is time-sensitive after sending it, you can’t add ALT+1077 to the content to make it leave your outbox any quicker. If you decide that your mail is time sensitive after pressing send, you need to create a new mail. You can take all the content from the one in your Outbox so it’s not a huge problem, just a slight annoyance.

ScanSnap ix500 Handwriting Recognition

I got a question today about the handwriting recognition capabilities of my ScanSnap ix500. I’m still madly in love with the ScanSnap for paperwork and automatic document filing, but handwriting isn’t its strong point. Here’s an example document I scanned:


Here’s what was recognized:

e//o vjon ‘anreo/ia//po/n/
0 V/or d reqw ar 3a
eilo yor,
c 0 Worio
/C Ol2
“po/yi //e[[o is/oMiiaftc chsel Hello regularcbhcl
iiellc W(^rU ^Ic^iYcksel //e//o wr/c/^m/ec///ey
reouiar lex

Here is the actual PDF: 2015_04_09_19_03_15

Adding custom confirmation to commands

We recently had a customer question where they were concerned that some commands might be typed accidentally and end up causing significant disruption. In general, commands that fit that classification include a confirmation message to warn you, but sometimes you just don’t agree with what the cmdlet author thought was a high-impact action. While Restart-Computer might be a day-to-day operation for some servers, it might be certain doom for others.

So let’s pretend you want to make Stop-Process prompt you whenever you run it.

In PowerShell V3, the solution is amazing with PSDefaultParameterValues. In this case, it will opt in to the ‘WhatIf’ behaviour by default, which you can override if you want:

4 [C:\]
>> $PSDefaultParameterValues["Stop-Process:WhatIf"] = $true

5 [C:\]
>> Stop-Process -name notepad
What if: Performing the operation "Stop-Process" on target "notepad (5936)".

6 [C:\]
>> Stop-Process -name notepad -WhatIf:$false

(Notepad stops)                                                                                                                                                         

In PowerShell V2, the solution is still pretty handy. You can use PowerShell’s proxy function APIs insert your own logic into a cmdlet. In this case, we can have it confirm:

19 [C:\]
>> Set-HighImpactCommand Stop-Process

20 [C:\]
>> Stop-Process -Name Notepad

Invoke Stop-Process?
Stop-Process has high impact. Invoke?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"): N
Invocation of Stop-Process was discontinued.
At line:25 char:106
+ ... -Process?')) { throw 'Invocation of Stop-Process was discontinued.' }
+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (Invocation of S...s discontinued.:String) [], RuntimeException
    + FullyQualifiedErrorId : Invocation of Stop-Process was discontinued.

21 [C:\]
>> Stop-Process -Name Notepad

Invoke Stop-Process?
Stop-Process has high impact. Invoke?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"): Y

22 [C:\]                                                                                                                                                        

And the function that does the magic?












function Set-HighImpactCommand




    $MetaData = New-Object System.Management.Automation.CommandMetaData (Get-Command $CommandName -CommandType Cmdlet)

    $functionContent = ([System.Management.Automation.ProxyCommand]::Create($MetaData))

    $updatedFunction = $functionContent -replace "begin`r`n{",

        "begin`r`n{`r`n if(-not `$PSCmdlet.ShouldContinue(‘$CommandName has high impact. Invoke?’, ‘Invoke ${CommandName}?’)) { throw ‘Invocation of $CommandName was discontinued.’ }`r`n"

    Set-Item function:\GLOBAL:$CommandName $updatedFunction


The Wonderful World of PowerShell Filtering and Globbing

If you’ve been using PowerShell for long, you are probably familiar with the concept of wildcards. At the very least, you’ve done something like this:

PS C:\temp> dir *.txt

    Directory: C:\temp

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         1/21/2015  10:01 AM        664 test.txt                                                                                                                                                   

Or perhaps you’ve taken a lap or two around about_wildcards and now type things like this in your sleep:

PS C:\temp> dir C:\win*\*.N[a-f]?\F*\v2*\csc.exe

    Directory: C:\Windows\Microsoft.NET\Framework\v2.0.50727

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         5/26/2014   9:39 PM      77960 csc.exe

    Directory: C:\Windows\Microsoft.NET\Framework64\v2.0.50727

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         5/26/2014   9:39 PM      88712 csc.exe                                                                                                                                                    

While wildcarding in the Path parameter is both powerful and useful, you might have seen another parameter: Filter.

In the PowerShell documentation, we describe the –Filter parameter in Get-ChildItem as:


Specifies a filter in the provider’s format or language. The value of this parameter qualifies the Path parameter. The syntax of the filter, including the use of wildcards, depends on the provider. Filters are more efficient than other parameters, because the provider applies them when retrieving the objects, rather than having Windows PowerShell filter the objects after they are retrieved.

In a SQL provider, the –Filter parameter might offer SQL syntax (like: –Filter “WHERE Name LIKE %pattern%”). Or, the AD provider might offer LDAP syntax. In the FileSystem provider, PowerShell’s wildcard syntax (dir *.txt) is very similar to the NTFS “format or language” which also looks like: *.txt. In the Filesystem Provider’s case, the Win32 API (FindFirstFile) takes a pattern parameter that is then processed by the API itself.

When you use wildcards in cmd.exe, file resolution and wildcarding is done directly by this Win32 API.

What’s the difference?

Now you might wonder about Filesystem: if both wildcards and filters are so similar, why does PowerShell need its own? Why not just call the Win32 API like cmd.exe does?

The primary distinction is around power. As about_wildcards mentions, PowerShell offers the character and character range operators. The native Win32 API does not.

Wildcard Description        Example  Match             No match

——– —————— ——– —————– ——–

*        Matches zero or    a*       A, ag, Apple      banana

         more characters

?        Matches exactly    ?n       an, in, on        ran

         one character in

         the specified


[ ]      Matches a range    [a-l]ook book, cook, look  took

         of characters

[ ]      Matches specified  [bc]ook  book, cook        hook


There’s also a surprising distinction around correctness. Try these examples in your System32 directory.

Should return all files with three-letter extensions:

$r1 = dir *.???

$r2 = dir –Filter *.???

Compare-Object $r1 $r2 –Property FullName

(Oops! –Filter returns directories, as well as files with 1 or 2 letter extensions!)

Should return all files with “2” in the name

$r1 = dir *2*

$r2 = dir –Filter *2*

Compare-Object $r1 $r2 –Property FullName

(Oops! –Filter returns a ton of stuff without “2” in the name.)

For the last example, this is because native wildcard filters ALSO work against the 8.3 filename representation!

PS C:\windows\system32> cmd /c dir /x *2* | sls SqlServerSpatial.dll

04/03/2010  10:57 AM           459,104 SQLSER~2.DLL SqlServerSpatial.dll                                                                                                                                

But what about performance?

Native Filesystem filters are unquestionably faster than PowerShell doing all of the wildcard matching on its own. However, PowerShell doesn’t do all of the matching on its own. In Version 2, we added support for partial filtering to the Filesystem provider (and of course, to any other provider that wants to implement it). When the Filesystem provider applies this partial filtering, it offloads as much of the filtering work as it can to the raw Win32 APIs – and then does more powerful (and correct) wildcard matching on the smaller set of results.

So now you know – when it comes to the Filesystem provider, you probably don’t want or need the –Filter parameter!


If you want to know more about wildcarding in the Filesystem provider, this is covered in Recipe 20.6 in the PowerShell Cookbook, which you can preview for free here: Find Files that Match a Pattern.

Extracting Tables from PowerShell’s Invoke-WebRequest

If you’ve ever wanted to extract tables from a web page in PowerShell, the Invoke-WebRequest cmdlet is exactly what the doctor ordered.

Once you’ve invoked the cmdlet, the ‘ParsedHtml’ property gives you access to the Internet Explorer DOM of that page. From there, you can get elements by tag name (“TABLE”), ID, and more.

One neat application of this technique is to automatically parse data out of tables on the web page. I recently needed to do this, and the PowerShell script really wasn’t that complicated. In true PowerShell style, each row of the table is output as an object – that way, you can access the data as you would with any other PowerShell cmdlet. Even better – if the table uses the TH tag (“Table Heading”), it uses those headings as property names for the output objects.

Here’s an example of it in action:

1 [C:\Users\leeholm]
>> $url = ''

2 [C:\Users\leeholm]
>> $r = Invoke-WebRequest $url

3 [C:\Users\leeholm]
>> Get-WebRequestTable.ps1 $r -TableNumber 0 | Format-Table -Auto

P1              P2         P3                   P4
--              --         --                   --
Gardiner Number Hieroglyph Description of Glyph Details
Q1                         Seat                 Phono. st, ws, . In st ?seat, place,? wsir ?Osiris,? ?tm ?perish.?
Q2                         Portable seat        Phono. ws. In wsir ?Osiris.?
Q3                         Stool                Phono. p.
Q4                         Headrest             Det. in wrs ?headrest.?
Q5                         Chest                Det. in hn ?box,? ?fdt ?chest.?
Q6                         Coffin               Det. or Ideo. in qrs ?bury,? krsw ?coffin.?
Q7                         Brazier with flame   Det. of fire. In ?t ?fire,? s?t ?flame,? srf ?temperature.?

4 [C:\Users\leeholm]                                                                                                    

And the script:


















































    [Parameter(Mandatory = $true)]

    [Microsoft.PowerShell.Commands.HtmlWebResponseObject] $WebRequest,


    [Parameter(Mandatory = $true)]

    [int] $TableNumber


## Extract the tables out of the web request

$tables = @($WebRequest.ParsedHtml.getElementsByTagName("TABLE"))

$table = $tables[$TableNumber]

$titles = @()

$rows = @($table.Rows)

## Go through all of the rows in the table

foreach($row in $rows)


    $cells = @($row.Cells)


    ## If we’ve found a table header, remember its titles

    if($cells[0].tagName -eq "TH")


        $titles = @($cells | % { ("" + $_.InnerText).Trim() })



    ## If we haven’t found any table headers, make up names "P1", "P2", etc.

    if(-not $titles)


        $titles = @(1..($cells.Count + 2) | % { "P$_" })


    ## Now go through the cells in the the row. For each, try to find the

    ## title that represents that column and create a hashtable mapping those

    ## titles to content

    $resultObject = [Ordered] @{}

    for($counter = 0; $counter -lt $cells.Count; $counter++)


        $title = $titles[$counter]

        if(-not $title) { continue }


        $resultObject[$title] = ("" + $cells[$counter].InnerText).Trim()


    ## And finally cast that hashtable to a PSCustomObject

    [PSCustomObject] $resultObject


Maslow’s Hierarchy of Security Controls

You’ve probably heard of Maslow’s Hierarchy of Needs. It’s a useful way to think about human needs and the priority in which we tend to fulfill them. Somebody dealing with a physiological crisis such as lack of food and water is unlikely to improve their situation much by focusing on self-actualization issues like finding opportunities for their artistic expression.

When thinking about an organization’s security stance or security controls, I find that there is a very close parallel to Maslow’s Hierarchy of Needs. I call it Maslow’s Hierarchy of Security Controls. If an organization is struggling to contain known viruses exploiting patched vulnerabilities, they are unlikely to improve their situation much by trying to address zero-day attacks that operate in a “forensically clean” stealth mode.




When it comes to system defenses and security controls, there are many controls and mitigations you can employ:

  • Antivirus
  • AppLocker in “Deny” Mode (or another technology that does Application Blacklisting)
  • AppLocker in “Allow” Mode (or another technology that does Application Whitelisting)
  • Auditing (especially of implemented security controls)
  • Forensic capture and analysis of host-based artifacts (filesystem, network, registry, etc.)
  • Forensic capture and analysis of memory-only artifacts

Each control depends on the protection of those below it in the hierarchy of security controls. If you only add security controls near the top of the hierarchy, attacks can trivially avoid those controls by exploiting weaknesses lower in the hierarchy.

Here’s a deeper look at these controls, and how they build on each other:



Impact Without Control


Antivirus / Antimalware

Can limit the execution of malware known to the AV industry.

Attacker can write and run any code, custom C++ applications, internet tools, etc.

Can be disabled by administrators. AV signatures can be evaded if the attacker is capable of recompiling or modifying an application.

Applocker in Deny Mode

Can limit the execution of malware known to your organization.

Attacker can write and run any code, custom C++ applications, etc., as long as they aren’t well known attack tools or exploits.

Can be disabled by administrators. Only blocks known evil / undesirable malware, can be bypassed with only minor application changes.

Applocker in Allow Mode

Can prevent the execution of unknown / unapproved applications.

Attacker can write arbitrary custom applicatons, as long as they are not detected by AV or Applocker Deny rules.

Can be disabled by administrators. Attacker can still leverage in-box tools like VBScript, Office macros, HTA applications, local web pages, PowerShell, etc.

Auditing of protections (AppLocker registry keys, AV settings, etc.)

By implementing and watching for registry / filesystem audit events generated when an attacker disables protections like AppLocker, attackers become more visible.

Attacker can disable most built-in controls, and then compromise a system without being impacted by that control.

Auditing is a reactive technology, not a preventative technology. An attack might still be successful, but proper audit monitoring can help you detect it.

Forensic capture / examination of host-based artifacts

Can help detect attacks based on in-box applications that modify the system in some way (such as putting a .VBS / .HTA file on disk).

Attacks that leverage in-box tools may not be detected.

Requires significant expertise and custom tooling to capture and forward all “interesting” forensic artifacts. Can be avoided by in-box components (such as Internet Explorer, VBScript “stagers”, PowerShell, and debuggers) that have the ability to invoke in-memory commands.

Memory forensics / application-specific logging

Can detect forensic artifacts that do not touch disk.

Memory-only attacks may go undetected.

Not all components that have the ability to invoke in-memory commands expose application-specific logging. Memory-only forensics require significant expertise and custom tooling.


So if you find yourself or an organization considering mitigations or security controls at a high level in Maslow’s Hierarchy of Security Controls, be sure that you’ve covered your bases at the lower levels, too. Otherwise, your return on investment will be exceedingly low.

(Link to this in PPTX format: Maslow’s Hierarchy of Security Controls)

Saving yourself from Sender’s Remorse with Outlook

Please see the update here:

Repairing a NatureBright SunTouch Plus


I recently had the misfortune of having my relatively unused NatureBright SunTouch Plus break down:




It’s a "Light Therapy" box that is very popular on Amazon, but a recurring problem among the disappointed reviews seems to be that it turns on, but then just immediately clicks and then turns off again. My lamp was out of warranty, so I decided to look into whether it was possible to fix it myself. One thing I noticed was that holding the "On" button would make it repeatedly turn on and turn off – but after a while, you could see that at least all of the bulbs were working. So it wasn’t the bulbs.

Opening up, it’s really a simple device electrically:


Power comes into the box in the middle right of the picture via the grey power cord. It gets split into two parts:

  1. Power for the bulbs, fed into (and fed by) the large grey box on the left.
  2. Into the transformer on the middle right, which brings the 120V down to 12V to feed the circuit at the bottom right.

With the power unplugged, there is nothing to be scared of inside (unlike TVs or cameras that have huge capacitors that can hurt you unless you discharge them properly).

Taking a close look at the circuit board, it was pretty simple. The board was marked "RG1100E", but there was nothing on the internet talking about it.


It has a power button ("K2"), a button to switch the countdown timer ("K1"), and a button to enable the ionizer. My initial hypothesis was that the timer circuit was somehow broken, but that was just a guess. I tested the fuse ("F1") at the bottom left with a multimeter, and it was fine. It showed no resistance – whereas if it was blown, it would show infinite resistance.

One component was very suspicious. Capacitor C1 (missing in the picture above) looked like it had blown / leaked – one of the legs was pretty dirty, and there was slight white residue on the top and bottom. I asked both my daughter and my wife for their opinion of which part might be bad (without telling them my opinion), and they both thought it was the capacitor, too. So I desoldered it to replace it.

Soldering and desoldering takes a soldering iron, solder, and little bit of skill. If you’ve got these already, this was a pretty simple process. The solder pads were large, and the existing solder wasn’t the high-temperature stuff that takes industrial soldering irons to melt. If you don’t have this stuff already, soldering irons are pretty cheap – and soldering doesn’t take much practice to learn. Starting with this $9.99 solder practice kit (which includes the soldering iron!) should let you build all the skill you need.

Here’s how the suspicious capacitor looked after removing it:


This capacitor is 470uf, and rated for 16V. RadioShack had it for $1.49. The primary thing that you have to pay attention to when replacing a capacitor is the polarity (making sure the + and – leads go where they did before). This board had the polarity labeled nicely, so that wasn’t a concern. The C1 capacitor was mounted on its side, so you also need to make sure to leave enough wire below the bottom of the capacitor that you can bend it over as well. Otherwise, the board won’t mount correctly when you go to attach it again. If you bend the capacitor to its side before soldering it, you don’t have to worry about leaving enough room.

Evidently, capacitor issues are a fairly common problem in electronics. The RadioShack reviews have people talking about repairing their SlingBox Solo with new capacitors. When I was doing research, there’s even – a site dedicated to capacitor repair in motherboards / etc. – including identifying bad capacitors, and instructions on "recapping".

If replacing the capacitor didn’t work, my intention was to just bypass the board entirely. The circuit board is really just a fancy way of controlling power delivery to the lights – with an on / off switch, timer, etc. If something more fundamental about the board was broken, it should be possible to just bypass it all with a simple switch rated for 12 volts, and then try to mount that nicely.

However, after replacing the capacitor, it worked! $1.49 to save $100 of electronics.


Absolute Positioning in Autodesk 123D Design

If you’re looking for a way to position an object in an exact spot in Autodesk 123D Design, you might have stumbled on forum topics like:







The last meaningful response was:



It doesn’t appear to have been added yet. Or it has been newly added, and the usability leaves something to be desired. In any case, it’s not as easy as you might think, but here’s a technique that works in version 1.6.41:

1) Click on the Ruler tool under the "Adjust" menu



2) Place the ruler on the origin



3) Select your object

You can now see lots of measurements about it, including how far it is from the origin.



4) Click on a Manipulator (thick arrow)



5) Enter your position in the measurement box that appears


Playing with Classes in PowerShell v5 Preview

One of the features we’re working on in the latest version of PowerShell is the ability to define custom classes.

If you’ve ever used a PSCustomObject or a Hashtable in a script for storing related data, you’ll probably find classes to be a useful addition to your scripting toolkit.


$point = @{ X = 0; Y = 0 }
$point.X = 10
$point.Y = 20


While PSCustomObjects and Hashtables let you group related data, what if you want to perform actions on that data? For example:

$point = @{ X = 0; Y = 0 }
$point.Move(10, 20)


This is the kind of scenario that classes really excel at. You use classes for holding “buckets” of related data, and operations on that date.

While the release notes in the V5 Preview (and of course, upcoming actual documentation) give an overview of how to define a class in PowerShell, here’s what they end up looking like:

class Point
    ## Define two properties, using PowerShell’s regular
    ## variable syntax. You can limit variables to a type
    ## using regular type contraints, toos:
    ## [type] $VarName = initialValue
    $X = 0
    $Y = 0

    ## Define a method (that returns void), and takes
    ## two parameters. You can limit the types on these
    ## parameters, of course.
    [void] Move($xOffset, $yOffset)
        $X += $xOffset
        $Y += $yOffset

## Create a point and use it
$point = [Point]::new()
$point.Move(10, 20)


And in use:

PS C:\temp> c:\temp\point.ps1 | Format-Table -Auto

 X  Y
 -  -
10 20


Now, if you wanted to extend this concept far further than you would ever want to, you might get this :)



And Show-BoxDemo in all of its glory. TAB switches between objects, and there are a few other hotkeys in the source.

And if you’re curious: