Month calendar with verical outlined weeks

VBscript is still boo, boo but some things are really simple to build in VBscript. Here is a calendar program with vertical outlined weeks, week numbers and even consideration for leap years (until the year 2100).


 C:\Scripts\> cscript //nologo calendar.vbs MM-YYYY

--- 8< ---------------------------------------------

Function Print(s)
 if len(s)=1 then
  wscript.stdout.write " " & s & "  "
  wscript.stdout.write s & "  "
 end if
end Function 

Datum = wscript.arguments(0)
dayOfTheWeek = DatePart("w",datum)
weekNumber   = DatePart("ww",datum, vbSunday ,vbFirstFourDays)
ArrayStart      = dayOfTheWeek - ((dayOfTheWeek -1) * 2)
monthNumber     = Month(Datum)
WeekDays        = Array("Su","Mo","Tu","We","Th","Fr","Sa")
DaysInMonth   = Array(31,28,31,30,31,30,31,31,30,31,30,31)
monthNames      = Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec")

'--- Calculate 5 or 6 weeks in this month...
if DaysInMonth(monthNumber-1) + (dayOfTheWeek-1) > 35 then NuOfWeeks = 6 else NuOfWeeks = 5

wscript.echo vbCrLf & "Calendar of: " & monthNames(monthNumber-1) & "-" & year(Datum) & vbCrLf
'--- Print weeknumbers
Print " "
for w = 0 to (NuOfWeeks-1) : Print (weekNumber + w) : next  
wscript.echo ""

for w = 0 to (NuOfWeeks) : Print "--" : next
wscript.echo ""

'--- Print calendar...
Column = 0
for i = ArrayStart to ArrayStart + 6
 Print Weekdays(Column)
 Column = Column + 1
 for j = 0 to 5
   dayNumber = i + (j * 7)
   if (dayNumber >= 1) and (dayNumber <= DaysInMonth(monthNumber-1)) then
     Print dayNumber
     Print "  "
   end if
 wscript.echo ""


Automatic emailing of your scanned documents

Some document scanners have the capability to send an email with the scanned document attached. Maybe your scanner can only store scanned files on a NAS, network share or in a folder on your computer. In that case, the next script will detect new scans and email them to you.

Yes, it is VBscript and that is boo, boo, as I mentioned before. However, the email method here, although deprecated, is also used by PowerShell users since it can deal with implicit SSL.

This post consists of two parts:
1. The script
2. A method to start the script automatically if the user is not logged on

The script

Copy & paste all the lines between the markers to Notepad or so and save the script as "MailScan.vbs". Then modify the Recipient with your email address. Modify the SMTP parameters. You might want to create a Gmail address specifically for sending scans. Finally, configure the folder where your scanner stores the scans.

--- 8< -------------------------------------
on error resume next

sub SendMail(Recipient, PDFfile)
    Dim objEmail
    Set objEmail        = CreateObject("CDO.Message")

    objEmail.From         = ""
    objEmail.To         = Recipient
    objEmail.Subject     = "Scanned document from scanner {scannername/location}"
    objEmail.Textbody     = now() & ", this email contains a scanned document from scanner {scannername/location}: " & PDFfile

'--- When you host your own mailserver, use this:   
    objEmail.Configuration.Fields.Item("")             = 2
    objEmail.Configuration.Fields.Item("")         = "" ' IP address of your emailserver
    objEmail.Configuration.Fields.Item("")         = 0
    objEmail.Configuration.Fields.Item("")     = 1
    objEmail.Configuration.Fields.Item("")        =""
    objEmail.Configuration.Fields.Item("")        ="{Password}"
    objEmail.Configuration.Fields.Item("")     = 25
'--- Or you can use Google's SMTP service:   
    REM objEmail.Configuration.Fields.Item("")        = aGoogleAccount
    REM objEmail.Configuration.Fields.Item("")        = theGooglePassword
    REM objEmail.Configuration.Fields.Item("")         = ""
    REM objEmail.Configuration.Fields.Item("")         = 1
    REM objEmail.Configuration.Fields.Item("")     = 1
    REM objEmail.Configuration.Fields.Item("")             = 2
    REM objEmail.Configuration.Fields.Item("")     = 465

    objEmail.AddAttachment PDFfile
end sub

'--- Main ----------------------------------------------------------------------------------------------------

const emailReceipient = ""
const intInterval = "5" 'check every 'intInterval' seconds for new file(s)...

dim fso
set fso=CreateObject("scripting.FileSystemObject")

'--- Split up the drive and the scan folder. Needed for WMI...
strDrive     = "M:"
strFolder    = "\\ProgramData\\MailScan\\"

wscript.echo "Scanning folder for files to arrive: " & replace(strDrive,"\\","\") & replace(strFolder,"\\","\")

'--- Set up event WMI handler...
Set objWMIService = GetObject( "winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2" )
strQuery =  _
    "Select * From __InstanceOperationEvent"                             _
    & " Within "                                     & intInterval         _
    & " Where Targetinstance Isa 'CIM_DataFile'"                         _
    & " And TargetInstance.Drive='"                 & strDrive &  "'"    _
    & " And TargetInstance.Path='"                     & strFolder & "'"
Set colEvents = objWMIService. ExecNotificationQuery (strQuery)

'--- Loop endless with an interval of 'intInterval'...
    Set objEvent = colEvents.NextEvent()
    Set objTargetInst = objEvent.TargetInstance

    Select Case objEvent.Path_.Class
        Case "__InstanceCreationEvent"
            WScript.Echo "*** New file received: " & f
            wscript.echo "*** emailReceipient : " & emailReceipient
            wscript.echo "*** Filename: " & f
            '--- Check for PDF file and email that...
            if Instr(lcase(f),".pdf") > 0 then
                call SendMail(emailReceipient,f)
                wscript.echo "*** Emailing of PDF file done"
                if Err <> 0 then wscript.echo "*** Error sending mail. Errormessage: 0x" & hex(Err) & " - " & Err.Description
            end if   
            '--- You can delete the PDF file after emailing. Uncomment the next lines...
            'fso.DeleteFile f,true
            'wscript.echo "File deleted: " & f
    End Select

--- 8< -------------------------------------

Testing the script

To test if everything works fine we manually start the script:

  c:\Scripts> cscript //nologo MailScan.vbs

Make a scan, or just copy a PDF file in the scanfolder, and check the output on the screen. If all goes well you see:

Scanning folder for files to arrive: M:\ProgramData\MailScan\
*** New file received: m:\programdata\mailscan\manual_en - copy (2) - copy - copy - copy.pdf
*** emailTo :
*** Filename: m:\programdata\mailscan\manual_en - copy (2) - copy - copy - copy.pdf
*** Emailing of PDF file ready

If there is an error sending the PDF you will see:

Scanning folder for files to arrive: M:\ProgramData\MailScan\
*** New file received: m:\programdata\mailscan\manual_en - copy (5).pdf
*** emailTo :
*** Filename: m:\programdata\mailscan\manual_en - copy (5).pdf
*** Emailing of PDF file done
*** Error sending mail. Errormessage: 80040211 - The message could not be sent to the SMTP server. The transport error code was 0x80040217. The server response
was not available

The Windows Service


You want to have this service 24x7 available, even when you are not logged on to your computer. When we use script in a Windows Service we can run the script automatically in the background. We need a utility to configure this for you: the Non-Sucking Service Manager. Download NSSM here.

Start NSSM and configure the scan service:

  C:\Scripts> nssm install MailScan

Configure the next two tabs. Configure in "Arguments" the folder where the script is stored.

When all is entered correctly press the "Install Service" button. We can start the service:

  C:\Scripts> net start MailScan

Now make a scan and check your mailbox!


Powershell ROCA test

This Powershell script tests a TPM based Public Key for the ROCA vulenerability (CVE-2017-15361).

Based on:

- Bouncy Castle crypto DLL (
- Windows 8, 8.1 or 10 OS (e.g. a USB stick with Windows to Go)

The comments below explains how to create a TPM based Public Key file.

--- 8< --------------------
    Date:             5-Nov-2017
    Description:     This script tests if a Public Key is vulnerable for ROCA
                    Use a TPM based CSR or CRT, extract the Public Key and test
    Prerequisite:    Bouncy Castle DLL (
>>> Create and extract a Public Key on Windows 8, 8.1 and 10 through a CSR:
(if a PC runs W7 or older or does note even have a hard disk, use Windows-to-Go from USB)

1. Create TPMCSR.inf
    --- 8< -----------------------
    Subject = "E=IFXTPMVSC"
    KeyLength = 2048
    Exportable = FALSE
    UserProtected = FALSE
    MachineKeySet = FALSE
    Providername = "Microsoft Platform Crypto Provider"
    ProviderType = 1
    RequestType = PKCS10
    KeyUsage = 0x80
    --- 8< -----------------------
2. Create CSR:
    C:\> certreq -new -f TPMVSC.inf TPMCSR.csr >nul

3. Extract Public Key with OpenSSL:
    openssl.exe req -in TPMCSR.csr -noout -pubkey -out TPMCSR.csr-pubk.pem   
4. Configure the filename in this script and run the script
    c:\scripts> powershell -file testROCA.ps1 TPMCSR.csr-pubk.pem   
    Vulnerable: True
>>> Using a TPM based certificate:
1. Extract the Public Key with OpenSSL:
    openssl.exe x509 -in TPMCSR.crt -noout -pubkey -out TPMCSR-pubk.pem   
2. Configure the filename in this script and run the script
    c:\scripts>powershell -file testROCA.ps1
    Vulnerable: True
>>> Example Public Keys:
Vulnerable Pubk:
    -----BEGIN PUBLIC KEY-----
    -----END PUBLIC KEY-----

NOT vulnerable Pubk:
    -----BEGIN PUBLIC KEY-----
    -----END PUBLIC KEY-----

if ($args.count -ne 1) {
    write-host "*** Usage: powershell -file testROCA.ps1 {public key file}"
$pubKfile = $args[0]
if (-not (Test-Path $pubKfile)) {
    write-host "*** File not found."
add-type -path ".\BouncyCastle.Crypto.dll"

[Org.BouncyCastle.Math.BigInteger[]] $markers = @(

[Org.BouncyCastle.Math.BigInteger[]] $primes = @( 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167 )

[System.IO.TextReader] $reader = [System.IO.File]::OpenText($pubKfile)

[Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters] $rsaKeyParameters = [Org.BouncyCastle.OpenSsl.PemReader]::new($reader).ReadObject()

$isVulnerable = $true
for ($i=0; $i -lt $primes.length;$i++)
    if ([Org.BouncyCastle.Math.BigInteger]::One.ShiftLeft($rsaKeyParameters.Modulus.Remainder($primes[$i]).IntValue).And($markers[$i]).Equals([Org.BouncyCastle.Math.BigInteger]::Zero))

write-host "Vulnerable (
$pubKfile):" $isVulnerable


BMW R1200RT, van model Sahara naar model Touring

De BMW R1200RT modellenreeks 2010-2014 zijn fantastische motoren met slechts een paar ontwerp foutjes. Een probleem, die opgelost is in de R1200 LC, is de hoge temperatuur in de kuip. Dit wordt veroorzaakt door de oliekoeler die onder de koplamp gemonteerd is. Door de onderdruk in de kuip wordt als het ware de (warme) lucht die uit de oliekoeler komt de kuip in gezogen (zeker met het grote Wunderlich scherm). Hierdoor is de temperatuur daar 6 a 7 graden hoger. 

Ik had al eens aan de deskundigen van de BMW RT Forum gevraagd hoe dat op te lossen. Na uitgebreide feedback heb ik besloten om de koeler naar beneden te verplaatsen. Na het zien van de oliekoeler van de R1200R heb ik de stoute schoenen aangetrokken en ben ik op onderdelenjacht gegaan. Op eBay stond een tweedehands R1200R koeler + slangen te koop. 

R1200R koeler + slangen
 Het "pikkie" bovenop de koeler valt in een uitsparing in de kap die voor de aandrijfriem van de dynamo zit.
Kap R1200R (links, met uitsparing voor de koeler) en R1200RT
De beugel wordt op de drie onderste bevestigingspunten van de kap gemonteerd. Op de beugel wordt de koeler geschroefd.

Oliekoeler bevestigingsbeugel

 Gemonteerd ziet het er dan zo uit:
Vervang de bestaande olieleidingen voor die van R1200R. Je kan gebruik maken van bestaande montage punten op het motorblok.
R1200R olieleiding rechts

R1200R olieleiding links
Een van de uitdagingen was de beugel waarop de zijpanelen bevestigd wordt. Die zit in de weg en ik heb daar een beugel voor gemaakt.
Nadeel is dat de panelen ongeveer 3cm meer naar "buiten" staan. Ook moeten er beugeltjes gemaakt worden om het positie verschil op te vangen.
Het past nu allemaal we maar het is niet een geweldig mooie oplossing. In de herfst ga ik de twee bevestigings beugels inkorten zodat de panelen weer op hun originele plek zitten.

  • Oliekoeler + slangen (eBay): $258 (EUR235)
  • Oliekoeler beugel: EUR23
  • Deksel: EUR40 
  • Lekkere koele lucht: onbetaalbaaar
Totaal: ongeveer EUR400.

Maar nu eerst de bergen in! Alle passen in Zwitserland en Oostenrijk zijn open!

UPDATE: Bij de Hornbach zag ik deze beugels liggen:
Verend en met een moer voor de beugel. Precies wat ik nodig heb!

Ik heb de twee bestaande "uithouders" voor de bevestiging van de fairing van de beugel geslepen, de beugel geschuurd en geschilderd en d.m.v. twee van die Hornbach beugels de fairing weer op de originele plaats gemonteerd.

Geheel gemonteerd ziet het er zo uit:


Een stofjas voor een oude baas

Veel mensen houden van muziek. Veel smartphones hebben voldoende geheugen om je hele muziek collectie op te slaan en af te spelen maar je kan ook genieten van on-line muziek. Hedendaagse muziek wordt digitaal opgeslagen en verstuurd en pas op je smartphone wordt de digitale informatie weer omgezet naar geluid.

Je kon vroeger natuurlijk muziek op de radio luisteren maar het was natuurlijk fijner als je zelf het tijdstip van je muziekkeuze kan bepalen. In de vorige eeuw is de platenspeler uit gevonden. De muziek wordt analoog (!) op een vinyl schijf van 30 cm/12 inch geperst. De analoge informatie wordt door middel van een naald afgetast en met versterker weer hoorbaar gemaakt.

Platenspeler (boven) en versterker (beneden)
Ik heb nog, ook vanuit nostalgische redenen, een prachtige platenspeler staan. Onlangs geheel gerestaureerd, voorzien van een nieuwe naald en opnieuw gekalibreerd. Dit baasje is ongeveer 35 jaar oud en werkt nog als nieuw. Bedenk eens een ding in je leven wat zo lang mee gaat en nog goed werkt...

Nu gebruik ik de platenspeler niet dagelijks en staat 'ie dus "stof te happen".  Platen en stof zijn vijanden. Daarom heeft mijn vriendinnetje met kunst en vlijt een mooie stofhoes gemaakt.
Platenspeler hoes
Als detail nog een muzikaal borduurtje toegevoegd.

Nu kan de platenspeler nog tijden mee en als ik nog eens een plaat afspeel komen de zoete herinneringen terug. Zoals de vader van Raymond (Everybody loves Raymond) al zei (tijdens het luisteren naar een krakerige jazzplaat):"Now that's music!"


Telemarketeer afkletser

Deze blog post legt uit hoe je een Fritz!Box instelt om telemarketeers en andere vervelende bellers te blokkeren.

We worden vaak gebeld door bedrijven op tijden dat het niet uitkomt met aanbiedingen waar we geen behoefte aan hebben. Deze bedrijven bellen zonder nummerherkenning (zodat je niet kan zien wie er belt) of met een "bedrijfsnummer". Deze nummers beginnen met 085, 087 of 088.

Bij het blokkeren van ongewenste bellers hebben we twee keuzes:
  1. Het gesprek wordt geblokkeerd. De telefoon wordt niet opgenomen;
  2. Er wordt een bericht afgespeeld. Hierin kan je aangeven waarom de telefoon niet opgenomen wordt en hoe men eventueel wel in contact kan komen.
In dit voorbeeld krijgen ongewenste bellers een bericht te horen (keuze 2). We moeten dus twee dingen instellen op de Fritz!Box:
  1. Het bericht die ongewenste bellers te horen krijgen. Dit gaat via de telefoonbeantwoorder van de Fritz!Box;
  2. De ongewenste telefoonnummers

Aanmaak telefoonbeantwoorder en een bericht opnemen

Maak een "antwoord apparaat" aan op Fritz!Box met deze instellingen (Telephony > Answering Machine):

Het antwoordapparaat kan een audiobestand importeren. Maak een opname (bijvoorbeeld met Audacity), sla dat op in een MP3 bestand. Klik op "Change greeting" bij "Greeting Only" en upload je zojuist opgenomen MP3 bestand. Als dat allemaal gelukt is zie je dit scherm:

Instellen van ongewenste nummers


Bellers zonder nummerherkenning

Voor bellers zonder nummerherkenning stel je deFritz!Box zo in (Telephony > Call Handling > Call Diversion):


De 085, 087 en 088 nummers worden ook op de "Call Diversion" pagina geconfigureerd. Bijvoorbeeld voor nummers die beginnen met 088 stel je zo in (Telephony > Call Handling > Call Diversion):

Als je dus alles heb ingesteld zie je dit scherm (Telephony > Call Handling):

Vanaf nu zullen alle bellers uit deze lijst je bericht te horen krijgen en wordt jij met rust gelaten. 


Tips voor het bericht wat ongewenste bellers te horen krijgen:
  1. Vertel waarom ze het bericht horen en geef eventuele andere mogelijkheden aan om in contact te komen (bijv.:"bel met nummerherkenning of met een mobiele telefoon" of "stuur een email");
  2. Doe alsof er een echte beller aan de lijn is:"Hallo met Jan.....(paar seconde wachten).. uuuh, wat was je naam en voor welk bedrijf bel je? ....(paar seconde wachten).... OK, hoe kom je aan m'n telefoonnummer?..." enz., enz.
  3. "Al onze medewerkers zijn bezet, een ogenblik alstublieft...(laat muziek horen)...nog een ogenblik geduld aub...(laat muziek horen)..." enz., enz.

Ongewenste bellers met een "gewoon" telefoonummer

Tegen bellers met een "gewoon" telefoonummer (bijv.: 0202159006) is preventief niet zo veel te doen. Je kan individuele nummers blokkeren. Dit is een voorbeeld hoe nummers meteen geblokkeerd worden (Telephony > Call Handling > Call Blocks):


Print PDF email attachements with hMailserver and Sumatra PDF

There are situations that you send an email with one purpose only and that is to print a PDF attachment.

In this case we have created a hMailserver script that:
- Checks for a specific email address ("");
- Checks a specific Subject field ("[pdfprint]");
- Checks for PDF attachment and if there is one, extract and print it.

To print the PDF, you need to have an app that renders PDFs and prints them. We are using Sumatra PDF, which has a command line interface that exactly does the job.

  1. Create a new hMailserver user that will be used as a stub to receive the PDF print emails. Enter a long random password and forget it;
  2. Install Sumatra PDF. Take care of the location of the x86 or x64 version;
  3. Modify Eventhandler.vbs of hMailserver with the code below.
  • Emails to "" will be discarded (not stored). You will see:
    "APPLICATION"    2284    "2016-08-28 08:48:37.699"    "SMTPDeliverer - Message 119900: Message deleted. Action was taken by script subscribing to OnDeliveryStart."
    " in the hMailserver eventlog;
  • You can address multiple printers (e.g. 2-side, b/w, color)) by adding additional Subject field markers and catch those in the script. Read the Samatra PDF documentation how to connect to specific printers;
  • You can add other attachment extensions (e.g. PNG, BMP, JPG, TXT, DOCX etc.) but then you need an app with a command line interface that is able to print the (extracted) file;
  • You can set a rule to forward your emails that have the PDF print Subject marker ("[pdfprint]"). The email will stay in your email box while the PDF attachments are printed anyway
  • Now you can use even your tablet (Android, iPad) or Smartphone (BB, WP8, WP10, Android, iPhone) to print PDF right from your email app;
  • You can have much more checks like attachment size and filename , sender's email domain, etc. Let your fantasy flow!
   Sub OnDeliveryStart(oMessage)
        dim wsh, fso, i
        dim AttachmentName, AttachmentType, tempAttachementName, tempFolder, objAttachement
        set wsh=CreateObject("")
        set fso=CreateObject("scripting.filesystemobject")

        if oMessage.Attachments.Count > 0 then

            For i = 0 To oMessage.Attachments.Count-1

                set objAttachement = oMessage.Attachments(i)

                AttachmentName=tempFolder & "\" & objAttachement.Filename
                Select Case lcase(AttachmentType)
                Case "pdf"
                    Call WriteLogfile("Processing PDF attachment: " & AttachmentName)
                    if lcase(oMessage.To)    =    ""         and _
                        Instr(lcase(oMessage.Subject),"[pdfprint]") > 0      then                       
                        Call WriteLogFile("Printing PDF file for: " & oMessage.From & ", PDF file:'" & AttachmentName)
                        s="""C:\Program Files\SumatraPDF\SumatraPDF.exe"" -print-to-default " & chr(34) & AttachmentName & chr(34) & " -silent -exit-when-done"
                        Call WriteLogfile("PDF print message processed.")                      
                    end if
                    fso.DeleteFile AttachmentName ,true
                End Select  
        end if

End Sub
Real Time Web Analytics