Author: mw

PowerShell Logging Made Easy (thinking RAII)

Just a quick something I want to share :-)!
Make your life easier using a scope-based action approach when writing PowerShell.
The idea is simple: group tasks together in blocks that are passed into a function which logs start and end time of that block, as well as doing some logging and error reporting if something goes wrong during exection.

Let’s elaborate:

$start = Get-Date
Do-Something
Do-SomethingElse
$end = Get-Date
$duration = $end-$start
Write-FancyLog $duration "Done something"

This code doesn’t look nice. If you need to measure execution time of different blocks, do logging based on results, catch and evaluate errors, it would be much cleaner to do something like this:

FancyLog -Description "Do Something" {
  Do-Something
  Do-SomethingElse
}

Yes, that looks much better and is easier to grasp.

Without further detours, here’s a basic ‘logging monitor’ that nicely integrates into any PowerShell environment 🙂

function Monitor {
param(
  [Parameter(Mandatory = $True, ValueFromPipeline = $True)]
  [scriptblock]$scriptblk,
  [Parameter(Mandatory = $True)]
  [string]$Description,
  [Parameter(Mandatory = $False)]
  [scriptblock]$ResultReceiver,
  [Parameter(Mandatory = $False)]
  [switch]$CanFail
)
  $_start = Get-Date
  $_ex = $null
  $_res = 0
  try {
    & $scriptblk
    $res = $lastexitcode
  }
  catch {
    $_ex = $_
    $res = $lastexitcode
  }
  finally {
    $_resobj = @{
      Exception   = $_ex
      Result      = $_res
      Description = $Description
      Duration    = ($(Get-Date) - $_start)
		}
		if ($ResultReceiver) {
			$ResultReceiver.Invoke($_resobj)
		}
    if (-Not $CanFail -And $_ex) {
      throw $_ex
    }
  }
}

Sample usage with dummy-logging:

function PseudoLog {
param(
  [Parameter(Mandatory = $True)]
  [PSCustomObject]$logobj
)
	Write-Host "> $($logobj.Description)"
	Write-Host $($logobj | ConvertTo-Json)
}

The following code continnues after reporting and errror:

Monitor -Description 'This block errs but continues!' -ResultReceiver $function:PseudoLog -CanFail {
	.\filesdoesnotexist
}

The following code breaks on the exception that is thrown, logs correctly and then rethrows the exception:

Monitor -Description 'This block will probably fail!' -ResultReceiver $function:PseudoLog {
	echo 'hello'
	throw 'foobar'
	echo 'cruel world'
}

Hope you enjoy this snippet, happy hacking!

Autumn In Austria – With My New Camera

Yup, I’ve finally put up the money to buy a brand new Nikon D810 – and I totally love it! The detail you get from that 36MP sensor just makes my trusty D3s look old and ‘dusty’.

I’ve started taking a couple of landscape shots with the 14-24 Nikkor lens I bought last year – a combination that is worth having.

Looking forward to as many as possibly ‘golden’, rainy and colorful autumn days in the next couple of months.

Komberg - Fields

Styrian Sunset

Back From Vacation

I’ve just returned from my 3-weeks vacation to the Azores – so there hasn’t been much going on here in the meantime 🙂
If you ever have the chance – the Azores are just an amazing place to see! We’ve traveled the islands Sao Miguel, Terceira, Pico as well as Faial, and all of them have at least those things in common:

  • beautiful landscape
  • great food
  • welcoming people

Here’s some pictures:

In the next couple of weeks I’ll be focusing on SoftwareAutomation and Invoke-Remote as much as possible, hopefully I’ll have time to put together post on this asap.

Grazer Linuxtage 2017

Just like almost every year, my friend Martin and I attended the “Grazer Linuxtage”, a free conference that annually takes place at FH Joanneum Graz. (#glt17)

We’ve more or less set-up the track for single board computers, consisting of a workshop on Friday, as well as an info-stand and a talk on Saturday.

Thanks to the 200+ people that visited our talk, hope you enjoyed it!

Our slides are available for download, feel free to contact us if you’ve got any questions concerning the discussed topics! [talk at Linuxtage website]

I’m building a PhotoBox

Finally I put up some time and started building a “PhotoBox” / “PhotoBooth”. Many thanks to my brother-in-law who’s skilled enough in handcraft to make this project possible without falling apart right away 🙂

The main goal of this project is to come up with an actual use case for one of my old Nikon D2x-cameras, that otherwise wouldn’t leave the shelf at all. Everything is build around the amazing SLR Booth android app – I’ve added a little Raspberry Pi spice (people using the booth should be able to download their pictures to their mobile phones for ~ 5 minutes after they’ve taken a picture).

Once I’m done with it and everything works as I expect it to, I’ll be sharing building instructions and the source-code for the RPi extension 🙂

What is the PhotoBox made of?

  • Wood
  • Screws
  • Metal Coupler Pieces
  • Nikon D2x
  • Pixel C
  • Raspberry Pi
  • Canon Selphy Printer
  • Cables

Merging XML with XSLT and PowerShell? – OK!

Combining XMl files from PowerShell – well, that’s pretty easy once you figured out how to work with


, but doing a correct & automatic merge turns out to be a quite challenging task.

Luckily there’s this: merge.xslt by (LGPL) by Oliver Becker – a XSL transformation ready accomplish this task in no time!

Let’s assume we’ve got two XML files.

FileA.xml:

<?xml version="1.0" encoding="utf-8"?>
<dict>
	<awesome id="21">Saxon</awesome>
	<awesome id="42">Chocolatey</awesome>

	<someweirdtag>
		I want candy.
	</someweirdtag>
</dict>
FileB.xml:

<?xml version="1.0" encoding="utf-8"?>
<dict>
	<awesome id="21">Coffee</awesome>
	<awesome id="42">Chocolatey</awesome>

	<someweirdtag>
		I'm afraid of catfish.
	</someweirdtag>
	<IhaveNoMemoryOfThisPlace/>
</dict>

What we want to accomplish is a merge of these two files – and there are several different possible outcomes:
If we just combine the two files, we’d want a result like this:

<?xml version="1.0" encoding="utf-8"?><dict>
	<awesome id="21">SaxonCoffee</awesome>
	<awesome id="42">Chocolatey</awesome>

	<someweirdtag>
		I want candy.
		I'm afraid of catfish.
	</someweirdtag>
	<IhaveNoMemoryOfThisPlace/>
</dict>

In the scenario I’ve been facing I needed to combine two files, favoring the second one – so all existing elements from FileA would be overridden by the elements of FileB.

<?xml version="1.0" encoding="utf-8"?><dict>
	<awesome id="21">Coffee</awesome>
	<awesome id="42">Chocolatey</awesome>

	<someweirdtag>
		I'm afraid of catfish.
	</someweirdtag>
	<IhaveNoMemoryOfThisPlace/>
</dict>

Adding the missing PowerShell script:

param(
[Parameter(Mandatory = $True)][string]$file1,
[Parameter(Mandatory = $True)][string]$file2,
[Parameter(Mandatory = $True)][string]$path
)

# using only abs paths .. just to be safe
$file1 = Join-Path $(Get-Location) $file1
$file2 = Join-Path $(Get-Location) $file2
$path = Join-Path $(Get-Location) $path

# awesome xsl stylesheet from Oliver Becker
# http://web.archive.org/web/20160502194427/http://www2.informatik.hu-berlin.de/~obecker/XSLT/merge/merge.xslt
$xsltfile = Join-Path $(Get-Location) "merge.xslt"

$XsltSettings = New-Object System.Xml.Xsl.XsltSettings
$XsltSettings.EnableDocumentFunction = 1

$xslt = New-Object System.Xml.Xsl.XslCompiledTransform;
$xslt.Load($xsltfile , $XsltSettings, $(New-Object System.Xml.XmlUrlResolver))

[System.Xml.Xsl.XsltArgumentList]$al = [System.Xml.Xsl.XsltArgumentList]::new()
$al.AddParam("with", "", $file2)
$al.AddParam("replace", "", "true")

[System.Xml.XmlWriter]$xmlwriter = [System.Xml.XmlWriter]::Create($path)
$xslt.Transform($file1, $al, $xmlwriter)

The eagle-eyed viewer spotted a caveat: yes, this does not run on Linux, there’s no

System.Xml.Xsl

in DotNetCore/PowerShell so far, but hopefully this will change!
– this seems to no longer be true, thank’s Brian!

If you don’t have System.Xml.Xsl or PowerShell for any reason, just swap the .NETish XSL code with our all-time-favorite Saxon!

java -jar saxon9he.jar .\FileA.xml .\merge.xslt with=FileB.xml replace=true

~ happy hacking!

Links:

Update: replaced $args in Code because of PowerShell 5.1 (thanks https://outofmemoryexception.wordpress.com/2016/08/05/powershell-5-1-14393/ )

Longterm Internet Connection Speedtest In Linux … With PowerShell ??

Something weird just happened: I’ve actually created the first PowerShell script that now regularly runs on my main Linux machine … the start of something new? …

I’ve been using PowerShell, well, A LOT at work lately – and the syntax is just so easy and straight forward – you gotta love it, even as a dedicated Linux user 😉

Script Speedtest.ps1

$outfile = "speedtest.csv"

[regex]$regexDl="Download\:\s(?'speed'\d+\.\d+)\s"
[regex]$regexUl="Upload\:\s(?'speed'\d+\.\d+)\s"

"Date;Time;Download;Upload;" | Out-File $outfile -Encoding utf8

while (1 -eq 1) {
    Write-Host -ForegroundColor Green "doing speedtest..."
    $meas = $(speedtest)
    $meas
    $download = $regexDl.Match($meas).Groups[1].Value.Replace(".",",")
    $upload = $regexUl.Match($meas).Groups[1].Value.Replace(".",",")

    "$(Get-Date -Format "yyyy-mm-dd;HH:mm:ss");$download;$upload;" | Out-File $outfile -Encoding utf8 -Append
    Start-Sleep -Seconds 300
}

The results will be shared in a couple of days when I’ve collected a significant amount of data!

Update: first results – upload speed pretty constant, download unstable!

Raspberry Pi Zero Wireless

So that happened … Can’t say that I was looking forward to a replacement of the “old” Rapsberry Pi Zero, as it really was a neat device for what it cost, but hey, WiFi + Bluetooth will make it even a better IoT device!

I’ve just placed an order for both, a(nother) old Pi Zero as well as the new version from https://www.kiwi-electronics.nl – as they seem to be the only place that  still has the old version in stock at a reasonable price. (go fast if you want one!)

My first projects with the “Pi Zero Wireless” will probably be home-automation related … maybe a little weather station or room-temperature regulation – something like that 🙂

If you’re interested in that area, my friend Martin has a great collection of sample projects and materials over at his site http://strohmayers.com – in addition to that, we’re going to do a workshop at Grazer Linuxtage where you can get hands-on RPi tinkering and programming!

my pre-holiday Schdraggel #1

I’ve just been looking on what to do and where to go this summer on the Azores … and it seems that 18 days on the islands won’t be enough to visit all the awesome places on this atlantic archipel! 🙁