function Write-BottlesOfBeer {
    param(
        [int]$bottles = 99
    )
    $b='bottles of beer'
    $w='on the wall'
    $n='no more'

    $bottles..1 | %{  
        "$_ $b $w, $_ $b.`r".Replace('bottles',"bottle$(if($_ -gt 1){'s'})")
        "Take one down and pass it around, $(if(($_-1) -ge 1){$_-1} else {$n}) $b $w.`r".Replace('bottles',"bottle$(if($_ -ne 2){'s'})")
        if ($_ -eq 1) {
            "No more $b $w, $n $b. `r"
            "Go to the store and buy some more, 99 $b $w."
        }
    }
}

I thought I'd have a go at a PowerShell version of 99 Bottles of Beer, to make something slightly nicer for 99-bottles-of-beer.net.

Slightly lazy code-golf-esque approach, but I think it's a little nicer than the version currently up for PowerShell.

I also wrote Pester testing for it, for the heck of it, as I've been feeling bad about how badly I wrote some tests for a recent technical evaluation. Sigh.

. ($PSCommandPath -replace '\.tests\.ps1$', '.ps1')

$lyrics = (Invoke-WebRequest 'http://www.99-bottles-of-beer.net/lyrics.html').ParsedHtml.getElementById('main').OuterText.Split("`n") | Select-Object -Skip 1

Describe 'Write-BottlesOfBeer' {
  Context 'Running without arguments'   {
    It 'runs without errors' {
      { Write-BottlesOfBeer } | Should Not Throw
    }
    It 'gets it right' {
        $i = 0
        Write-BottlesOfBeer | %{
            $_ | Should Be $lyrics[$i]
            $i++
        }
    }
  }
}

Passing Tests after the last silly non-compliance