fortune for Windows Powershell

How doth the VAX's C compiler
Improve its object code.
And even as we speak does it
Increase the system load.

How patiently it seems to run
And spit out error flags,
While users, with frustration, all
Tear their clothes to rags.

Included in many Linux distributions is a fun little program called fortune that prints a random, often amusing message to the screen. If you've ever wanted the same functionality in Windows PowerShell, you've come to the right place!

Installation

  1. Download fortune.txt and save it in %USERPROFILE%\Documents\WindowsPowerShell\fortune.txt
  2. Place the following in your PowerShell profile. In PowerShell, type notepad $profile to edit your profile.
    function fortune {
    	[System.IO.File]::ReadAllText((Split-Path $profile)+'\fortune.txt') -replace "`r`n", "`n" -split "`n%`n" | Get-Random
    }
    
    # Remove the line below if you do not want fortune to run when PowerShell starts
    fortune; echo ''

Using .dat files

This version is much faster on large fortune files. Use this if have a corresponding .dat file for your fortune cookie file generated by strfile. Largely untested, only works properly on UTF-8 files.

function fortune($Path) {
	if(!(Test-Path $Path)) {
		throw "File not found: $path"
	}
	
	$datfile = "$Path.dat"
	if(Test-Path $datfile) {
		$dat = New-Object "System.IO.FileStream" $datfile, 'Open', 'Read', 'Read'
		[byte[]] $dat_bytes = New-Object byte[] 8
		$seek = (Get-Random -Minimum 7 -Maximum ([int]($dat.Length / 4))) * 4
		[void] $dat.Seek($seek, 'Begin')
		[void] $dat.Read($dat_bytes, 0, 8)
		[array]::Reverse($dat_bytes) # Swap endianness
		$start = [BitConverter]::ToInt32($dat_bytes, 4)
		$end = [BitConverter]::ToInt32($dat_bytes, 0)
		$len = $end - $start - 2
		$dat.Close()

		$cookie = New-Object "System.IO.FileStream" $Path, 'Open', 'Read', 'Read'
		[byte[]] $cookie_bytes = New-Object byte[] $len
		[void] $cookie.Seek($start, 'Begin')
		[void] $cookie.Read($cookie_bytes, 0, $len)
		# If you want multiple encodings you'll have to do it yourself
		[System.Text.Encoding]::UTF8.GetString($cookie_bytes)
		$cookie.Close()
	} else {
		[System.IO.File]::ReadAllText($Path) -replace "`r`n", "`n" -split "`n%`n" | Get-Random
    }
}

Credits

fortune.txt was generated from http://fortunes.cat-v.org/openbsd/.