fortune for Windows Powershell

Distress, n.:
	A disease incurred by exposure to the prosperity of a friend.
		-- Ambrose Bierce, "The Devil's Dictionary"

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/.