Tag: PowerShell

preparing for WinOps London 2019

I’ve just finished the presentation for my talk at WinOps in about 3 weeks from now, this is going to be fun! I will be talking about (among others)
  • golden images
  • drifting state
  • PowerShell
  • the risks of relying on the cloud
  • Chocolatey & Boxstarter
  • package internalization
  • monitoring, alerting & statistics
It would be awesome to meet and have a chat at the event, looking forward to meeting you soon!

psconf.eu 2019

This year was the first time I’ve attended psconf.eu – and it was an amazing experience! To be honest, I wasn’t in the best mood when I arrived late night on Monday before the event. This was mainly due to my connection flight being cancelled from Frankfurt to Hannover, and being forced to take a 4 hour train ride, without a chance to get a seat in a overfilled ICE train. This alone wouldn’t have been too bad, I’ve got a bar table at the on-board restaurant and was able to do some coding, but then also my luggage went missing at the airport – which got me quite grumpy (but you can’t really blame anyone for bad weather.. right?)
Luckily I’ve been able to fetch some essentials at the airport duty-free shopping and pauby was so nice to deposit a new Chocolatey T-Shirt at the hotel desk, so I’d be covered for the first day of the conference.

psconf.eu

psconf.eu“, the powershell conference Europe, is an annual event taking place in Hannover, Germany.This year, about 350 delegates from over 30 different countries had the chance to visit more than 50(++) talks on different topics (generally everything about PowerShell and system automation).

the sessions

The sessions are not available on YouTube yet, but watch out for them on psconf.eu’s channel. Supplemental material can be found on GitHub.
The following is the list of the talks I’ve been attending.

Tuesday

  • State of the Shell 2019 (Keynote)
  • Improving Performance by Reducing Memory Allocations
  • Pester internals and concepts
  • “RegEx 4.0”

Wednesday

  • Tracking Activity and Abuse of PowerShell
  • Test infrastructure as code?
  • Building a better command line experience: Windows Terminal and WSL2
  • Lean on me: Managing dependencies in PowerShell
  • Generating Azure PowerShell (and more) cmdlets via AutoRest
  • Attack Surface Reductions for Adventurous Admins

Thursday

  • Learn Classes with Class{}
  • Don’t do that, do this instead: PowerShell worst practices
  • PowerShell Remoting Internals
  • Automating the Software Deployment Lifecycle with Chocolatey, Jenkins and PowerShell
  • Visual Studio Code: deep dive into debugging your PowerShell scripts

Friday

  • A better way to do WPF in PowerShell 5+
  • Lessons learned from a large scale infrastructure as code project
  • Click-free application deployment using the magic of PS and Chocolatey
I’m not going to get into detail what I liked most or what I didn’t like, every single one of the talks at least gave me one new idea or something to think about concerning my current workflow, which I consider highly valuable. Just know that I am looking forward to the other talks being available on YouTube, and I’m pretty sure I will also be re-watching some of the talks I went to.

the people

Anyone who’s attending conferences like this one probably has a similar mindset about it, IT’S ALL ABOUT THE PEOPLE. Getting to know the real person behind that avatar in Slack or GitHub, who’s been talking to you or that you’ve been angry about because he or she closed off your pull requests, really put the value into the conference (at least for me it did). The conference offered a great mix of quality content and “networking possibilities”, especially the many coffee-breaks and the evening event at the zoo.

my takeaway

I’ve had a lot of fun and interesting discussion with experts that excel at what they’re doing in the field of Windows automation. It was very helpful to discuss certain problems, do’s and dont’s in system administration and automation. Getting some insight, in how other people and companies approach tasks that are similar to what I’m (trying) to do will definitely influence my future work.
In the end, a cancelled flight and lost luggage (my bag actually went missing again on my trip home!!) wasn’t all that bad. I’ve been able to pick up a lot of great ideas, meet nice people and even make some new friends.

WinOps 2018 Recap

I’ve had the chance to re-visit WinOps London this year, meet a couple of old friends and make new ones – after all, a great event!  I really enjoyed all of the talks and workshops I attended, but following topics somehow really stood out for me. (I am honestly looking forward for the videos being available on YouTube, so I can watch those talks for second time!)

SRE with Steven Murawski and Trond Hindenes

Negating releases is not a solution to face site reliability issues / incidents.

Steven Murawski
If it’s scary. You are not doing it right. Build robust systems: TRUST but VERIFY.

Trond Hindenes
Systems Reliability Engineering” really did feel like a “hipster buzzword” to me (sorry) .. UNTIL I attended those two talks, one from Steven Murawski and one from Trond Hindenes. Steven really gave some important insights in the why, Trond into the how of their experience with SRE in 2017/2018 and they presented some incredible results and numbers (achieved uptime, basically).

Docker with Elton Stoneman

Tearing down monolithic applications does not imply we have to do code changes. Elton Stoneman
To be honest, I never really thought about the possibility of splitting a monilithic app into pieces without having to modify the existing code base. Although I think nobody will ever be on par with Elton in concern of “containerization speed / efficiency”, seeing how a DotNet 3.5 app is split up into a bunch of containers whilist no code changes are being carried out really is an experience. 

Chocolatey with Rob Reynolds

You can’t spell system automation without package management. Rob Reynolds
In the last two years I’ve been lucky enough  see a couple of Rob’s talks and watch how Chocolatey matured and grew both as a tool, and as a company. The fluffy boss unicorn and dancing coworkers in Robs presentations have just been beat by the CCM (Chocolatey Central Management) live demo this time. I can’t wait for this feature to get out of it’s beta phase.

PowerShell with Chris Gardner

Pester is your friend. Chris Gardner
Watching Chris talk about how you should be developing your PowerShell modules really reminded me of a couple of things I tend to forget when I’m down coding.
  • when you’ve got a bug, write testcase for that bug
  • AFTERWARDS, fix that bug!
  • create docs for each public, preferably also for each private function
  • make the docs available!

So that’s my writeup for WinOps LDN 2018. Despite revisiting some topics I kind of forgot about I was lucky enough to get some insights in how folks at other companies tackle problems I’m still facing in my daily work – got a couple of ideas for improvements too, so I’d say – a win 🙂

“Killing Golden Images” at ChocolateyFest

After my wife and I [visited Hawaii], we took a short detour to San Francisco, where I was given the opportunity to give a talk at ChocolateyFest. After attending WinOps conf in London last year, I was really looking forward to this event, being able to exchange my thoughts on Windows infrastructure automation with experts and other folks working in this area. (Every single talk at ChocoFest was somehow related to the work I’ve been doing for the last two years or so.) “Killing Golden Images In Your Infrastructure Setups”
Being my first international talk, I must admit that I’ve been quite nervous, and you can definitely see this in the first 3-5 minutes watching the recording of the talk. I’ve prepared supporting material for the talk on my GitHub page (you can also grab my slides there) I really enjoyed listening to awesome, informative talks at the event, the evening workshops and coffee-break-chats with Dan, Stefan, Paul, Gary, … and of course, Willi Wonka himself 🙂
Rob Reynolds as Willi Wonka after the event
Looking forward to meeting a lot of you folks at WinOps London 2018 in less than 3 weeks from now!

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
    }
  }
}
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!

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!