Things I wish I hadn't done while writing PowerShell stuff for work:
1. Wish I hadn't used absolute paths as much since it makes updating so painful.
2. Not using more common functions/variables/etc and pulling them from a central location.
3. Keeping the code so simple that it becomes complicated.
4. Not using code signing from the getgo. After setting up AD CS and getting a code signing cert, all you need to do is SignAndPush $File:

function SignAndPush {
        param ($file)
        $CodeSigningCert = (dir Cert:\CurrentUser\My -CodeSigningCert)[0]
        Set-AuthenticodeSignature $env:LocalScripts\$File -Certificate $CodeSigningCert
        copy $env:LocalScripts\$file $env:RemoteScripts
5. Not setting up my environment in the same way people use .bashrc to do. That, combined with the above means everything is nicely updatable with minimal effort across the board

American Nightmare - ST 2018:
Stop putting out bad records when you're a reunion band.

Hyper-V Cluster on a PowerVault MD3420 - Cluster Config:
1. Make sure all nodes are identical. Update all firmware; drivers; software; Windows Updates; etc.
2. Create a GPO which applies only to your cluster nodes which sets everything up required for the cluster to function.
3. Enable Cluster Aware Updating
4. Validate your cluster, create it, and configure your storage.

Hyper-V Cluster on a PowerVault MD3420 - SAN Config:
Install MDSM on your Hyper-V hosts, configure the basic settings, add licenses as required.
Create the hosts for each by only pluggine in on SAS cable from each of your nodes at a time so that you don't fuck up the mappings. Once you've configured a port for a host, unplug your SAS cable and move to the next HBA.
Reboot each of your hosts, and then configure MPIO by opening MPIO from the Start Menu, then click Discover Multi-Paths. If nothing shows up click Add support for SAS devices and try again.

Sophos UTM 9: Up2Date failed: Not enough free space:
Since the UTM partitioning is dumb, if you haven't installed updates in ages you won't be able to do a massive update. Rather than spending a billion years installing updates one at a time, create a symlink to somwhere that has more storage, either the log drive or storage drive:

mkdir /var/storage/up2date
chmod 700 /var/storage/up2date
mv /var/up2date/sys/* /var/storage/up2date
rmdir /var/up2date/sys
ln -s /var/storage/up2date/ /var/up2date/sys

Nginx 502 Bad Gateway after Ubuntu Upgrade:
When updating your php install, remember to update your paths in your web conf files.

It’s 2017 and ZFS STILL doesn’t have an API?!?:
Trying to sysadmin by parsing text files is annoying. Give me a proper interface to work with.

M83 - Junk:
M83 put out a new record, and called it Junk. I agree.

Grave Pleasures - Dreamcrash Review:
Beastmilk was a great band; too bad they only put out one good record.

On Bolt Thrower, Faith No More and the quasi-sexual response to music.:
I like Bolt Thrower, Faith No More, and a bunch of other bands enough to make my skin tingle.

2014 Music:
10. Death from Above 1979 - The Physical World
9. Victims - In Blood
8. Tove Lo - Queen of the Clouds
7. Run the Jewels - 2
6. Chelsea Wolfe - Pain is Beauty
5. Robyn and Royksopp - Do It Again
4. Eagulls - Eagulls
3. Kendrick Lamar - Good Kid, M.A.A.D City
2. No Problem - Already Dead
1. Beastmilk - Climax

Parse old archived event logs to audit permissions changes:
First, get the event log details:

$XPath = @'

$today = (get-date -format g).split()[0]
$DeletableLogs = @()
$logfile = "L:\Permissions Changes\$today.txt"
$DeleteList = "L:\DeletableLogs.txt"
try {
    $ParsedLogs = get-content $DeleteList -erroraction stop
catch [System.Management.Automation.ItemNotFoundException]{}
$AdminUsers = @(List,of,admin,users)

Function LogPermissionChange($PermChanges){
    ForEach($PermChange in $PermChanges){
        $Change = @{}
        $Change.ChangedBy = $[1].value.tostring()

        # Filter out normal non-admin users to prevent catching people
        # making their own files.
        if ($AdminUsers -notcontains $Change.ChangedBy){continue}
        $Change.FileChanged = $[6].value.tostring()
        #Ignore temporary files
        if ($Change.FileChanged.EndsWith(".tmp")){continue}
        elseif ($Change.FileChanged.EndsWith(".partial")){continue}

        $Change.MadeOn = $PermChange.TimeCreated.tostring()
        $Change.OriginalPermissions = $[8].value.tostring()
        $Change.NewPermissions = $[9].value.tostring()

        write-output "{" >> $logfile
        write-output ("Changed By           : "+ $Change.ChangedBy) >> $logfile
        write-output ("File Changed         : "+ $Change.FileChanged) >> $logfile
        write-output ("Change Made          : "+ $Change.MadeOn) >> $logfile
        write-output ("Original Permissions : "+ $Change.OriginalPermissions) >> $logfile
        write-output ("New Permissions      : "+ $Change.NewPermissions) >> $logfile
        write-output "}
" >> $logfile

GCI -include Archive-Security*.evtx -path L:\Security\ -recurse | ForEach-Object{
    $log = $_
    if ($ParsedLogs -contains $log){
        $PermChanges = Get-WinEvent -Path $_ -FilterXPath $XPath -ErrorAction Stop
    Catch [Exception]{
        if ($_.Exception -match "No events were found that match the specified selection criteria."){
        else {
                Throw $_
    $PermChanges = $Null
    $DeletableLogs += $_

foreach ($log in $DeletableLogs){
    $Timer = 0
        remove-item $log -ErrorAction Stop
    Catch [Exception]{
        write-output $log.FullName >> $DeleteList
Then, delete the old events logs:
$StillToDelete = @()
$DeleteList = "L:\DeletableLogs.txt"
$DeletableLogs = get-content $DeleteList

Function Close-LockedFile{
    $HandleApp = 'C:\sysinternals\Handle64.exe'
    If(!(Test-Path $HandleApp)){Write-Host "Handle.exe not found at $HandleApp`nPlease download it from and save it in the af$
    $HandleOut = Invoke-Expression ($HandleApp+' '+$Filename)
    $Locks = $HandleOut |?{$_ -match "(.+?)\s+pid: (\d+?)\s+type: File\s+(\w+?): (.+)\s*$"}|%{
            'AppName' = $Matches[1]
            'PID' = $Matches[2]
            'FileHandle' = $Matches[3]
            'FilePath' = $Matches[4]
    ForEach($Lock in $Locks){
        Invoke-Expression ($HandleApp + " -p " + $Lock.PID + " -c " + $Lock.FileHandle + " -y") | Out-Null
    If ( ! $LastexitCode ) { "Successfully closed " + $Lock.AppName + "'s lock on " + $Lock.FilePath}

foreach ($log in $DeletableLogs) {
    try {
        remove-item $log -ErrorAction stop
    catch [System.Management.Automation.ItemNotFoundException]{
    catch [system.IO.IOException]{
        try {
                Close-LockedFile $log
                remote-item $log -ErrorAction stop
        catch [exception]{
                $StillToDelete += $log

write-output $StillToDelete > $DeleteList

Scripts to automate ZFS NFS re-sharing:
On the client:

if grep -qs '/MOUNT/POINT' /proc/mounts; then

        ssh user@server touch /Public/unmounted.SHARE.SERVER
        filename=$(date +%Y-%m-%d-%H-%M-%S.%2N)
        echo "Touching local unmounted $filename"
        touch /scripts/results/unmounted-$filename
        sleep 30

while [ -e /scripts/results/unmounted-$filename ]
        echo mounting
        /bin/mount -a
        echo "checking if mounted"3
        if grep -qs '/Data/Final' /proc/mounts; then
                echo mounted
                rm /scripts/results/unmounted-$filename
On the server:
if [ -e "/Public/unmounted".* ]
                # Repeat for each NFS share you have.
                /sbin/zfs set sharenfs=OPTIONS ZFS/FILE/SYSTEM
                rm /Public/unmounted.*

Powershell Script to find service accounts across servers:

$servers = Get-AdComputer -LDAPFilter "(OperatingSystem=*Server*)"
foreach($server in $servers){$serverlist += $}

foreach($server in $serverlist){
        $services = Get-WmiObject -ComputerName $server win32_service
        foreach($service in $services){
                if ($service.startname -ne "LocalSystem" `
                -And $service.startname -ne "NT AUTHORITYLocalService" `
                -And $service.startname -ne "NT AuthorityNetworkService"){
                        $padserver = $server.padright(32)
                        $padservicename = $
                        write-host $padserver $padservicename $service.startname.padright(32)

Beastmilk - Climax Fuck off, buy it. It's so good, Misfits/Sisters of Mercy/early goth, post-punk, death rock, whatever.

Exchange 2013 Management tools on Windows 8.1 Add Windows features install IIS 6 Management Console and IIS Metabase and IIS 6 configuration compatibility, then go to shell and do Setup.exe /Role:ManagementTools /IAcceptExchangeServerLicenseTerms

Online fileserver archiveing use this script to move files to a different drive, verify the copy, then create a link to the file. Do: fsutil behavior set SymlinkEvaluation r2r:1 to make it work.

    [string]$Dir = "",
    [string]$ArchiveDrive = ""

if ($ArchiveDrive -eq ""){
    $hostname = hostname
    $ArchiveDrive = "\\Archives\"+$hostname+"\"+$Dir[0]+"\"

import-module PSCX
import-module new-symlink

$FileList = @()

$SourceDrive = $dir[0] + ":\"

$date = Get-Date -Format yyyy-MM-dd
$ErrLog = "C:\ErrorLog $date.txt"
$DelLog = "C:\DelLog $date.txt"
$PathWarning = "C:\_PROBLEMS DETECTED.txt" 

function BuildLists($dir){
    $FileList = @()
    $DirList = (dir $dir -recurse)
    foreach ($item in $DirList){
        if ( ((get-date).Subtract($item.LastWriteTime).Days-gt 1460) -eq $True) { 

            $FileList += $item
        #else {write-host "$item is modified recently"}
    return $FileList

function CheckPathLength($file){
    if ($File.FullName.Length -ge 220){
        copy $PathWarning $File.DirectoryName}

function ArchiveFile($SourceFile){
    $DestFile = ($SourceFile.fullname.replace($SourceDrive, $ArchiveDrive))
    $DestDir = ($SourceFile.DirectoryName.replace($SourceDrive, $ArchiveDrive))
    mkdir -Path $DestDir 2>$ErrLog
    copy $SourceFile.FullName $DestFile

function HashCheckFile($SourceFile){
    $DestFile = $SourceFile.FullName.replace($SourceDrive, $ArchiveDrive)
    $SourceHash = get-hash($SourceFile.fullname)
    $DestHash = get-hash("$DestFile")
    return $SourceHash.HashString -eq $DestHash.HashString

function DeleteFIle($File){
    del $file.fullname 

function LinkFile($Sourcefile){
    $SourceFilePath = $Sourcefile.fullname
    $DestFile = ($sourcefilepath.replace($SourceDrive, $ArchiveDrive))
    New-Symlink -path $DestFile $SourceFile.fullname -file 1>$errlog

function CheckPathLength($file){
    if ($File.FullName.Length -ge 220){
        copy $PathWarning $File.DirectoryName}

function ReplicateFile($file){
    if ($file.Attributes -eq "Directory"){continue}
    if (HashCheckFile($File)){

function Archive($FileList){
    foreach ($File in $FileList){

function RunArchiving($dir){
    $FileList = BuildLists($dir)


My favourite records in 2013:
10. Everything by APMD and Bars
9. Radkey - Devil Fruit
8. Boston Strangler - Primative
7. Destruction Unit - Deep Trip
6. Everything by Red Dons
5. Holy Terror - Terror and Submission
4. Radkey - Cat and Mouse
3. Turbonegro - Sexual Harrasment
2. Night Birds - Born to Die in Suburbia
1. Power Trip - Manifest Decimation

Frozen transport queues in Exchange 2013/2007 coexistence Remove antimalware scanning. If you can't do this, this script will restart the queues for you and notify you that it happened.

add-pssnapin Microsoft.Exchange.Management.PowerShell.*
$logfile = "~\Desktop\Transport Failure Log.txt"
$Today = Get-Date
$marker = "-------------
Script started on $Today
write-output "$marker" > $logfile

Function GetQueue(){
	$queue = Get-Queue Exch07\* | where {$_.nexthopdomain -eq "hub version 15"}
	return $queue}

Function EmailAlert($count){
	$mailServer = ""
	$email = new-object Net.Mail.SMTPClient($mailServer)
	$message = new-object Net.Mail.MailMessage

	$message.From = "whomever"
	$message.ReplyTo = "whomever"
	$message.subject = "There are $count messages waiting to be delivered."

	$message.body= "Email Text."

	start-sleep -s 120

Function CheckQueues($queue){
	$count = $queue.messagecount
	$queueID = $queue.Identity.RowID
	if($count -gt 10){
		$messages = get-message -queue Exch07\$queueID
		$messageZero = $messages[0].identity.internalID

		start-sleep -s 60
		$newQueue = GetQueue
		$newCount = $newQueue.messagecount
		$newQueueID = $newQueue.Identity.RowID

		if($newcount -lt $count){

		elseif($newQueueID -ne $queueID){

		$NewMessages = get-message -queue Exch07\$queueID
		$NewMessageZero = $NewMessages[0].identity.internalID
		elseif($NewMessageZero -ne $messageZero){

		elseif($newcount -eq $count){

		elseif($newcount -gt $count){
			$today = Get-Date
			write-output "------$Today-------- The service was restarted." >> $logfile

			$XportService = Get-Service -Name "MSExchangeTransport" -ComputerName "Exhc13"
			Restart-Service -InputObj $XportService
			$RestartCount = 0

			while($XportService.Status -ne "Running"){
				$today = Get-Date
				write-output "Exchange Transport failed to restart at $today." >> $logfile
				start-service -InputObj $XportService

Function DoWork(){
	start-sleep -s 300
	$count = GetQueue


Delete new myspace account myspace icon > Settings > Profile > Delete Account > Delete account > Delete my account. No confirmation for account closure, but it seems to work. doesn't do HTTPS for charts curl it to your server in cron, and serve it yourself:

curl -s > /local/path/to/file.gif

Full home in sync network audio playback Doing something fun since what's out there is too expensive. I'm using MPD and Python to make a crowd controlled radio station for full home playback via RaspberryPi. Check projects page for code.

Kvelertak - Meir More like Kvelertak - Merd

Demote a busted 2008 R2 DC If dcpromo fails with Failed to detect if Active Directory Domain Services binaries were installed. The error was: An error with no description has occurred is usually caused by improperly installed Windows updates. Use the SURT to figure out what's broken and fix it. Manually fix broken packages by redownloading and installing the standalone version via wusa /extract:path\to\extract\to file.msu and then rerun dcpromo.

Auto restart crashed MySQL with this.

   curl --silent -o /scripts/temp/index.txt -k
if diff /scripts/temp/index.txt /scripts/___NoDB.txt -q > /dev/null
   /usr/sbin/service mysql start
   /usr/sbin/service mysql restart
   date >> /var/log/sqlService.log
   cat /scripts/checkSQL.msg > /scripts/temp/checkSQL.msg
   date >> /scripts/temp/checkSQL.msg
   /usr/sbin/ssmtp MYEEMAILADDRESS < /scripts/temp/checkSQL.msg
rm /scripts/temp/index.txt
   rm /scripts/temp/checkSQL.msg
# Compare it to HTML file of down database:
   #<!DOCTYPE html>
   #<html xmlns="">
   #<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   #        <title>Database Error</title>
   #        <h1>Error establishing a database connection</h1>
# Email message:
   #To: "Robbie Crash" [email protected]
   #From: "Mentat Todd" [email protected]
   #Subject: "Subject"
   # Message text

Naughty By Nature Rules. Proof: 1 2 3 4 5

Rob Ford Sucks and since the crack video storycame out, I've been happy he's been in office. Not happy happy, but haha happy.

Nexus 4 Launch boondogle part 2 3 week shipping delays to almost all your customers? Seriously, pre-orders. WTF guys?

Nexus 4 Launch boondogle Sold out almost instantly? No notification for those that asked to be notified it was on sale until after it sold out? Did you think nobody would want a high end smart phone for less than $400 outright? Google fucked it up like nobody else could. Way to ruin what could've been an amazing customer experience.

Happyness is a private link Someone is linking to my articles from their internal helpdesk. :)

Set default font and template in Word/PowerPoint/Outlook 2010/20123 via GPO Setup Outlook options via File>Options>Mail>Signatures and Stationary. Setup Word styles how you want and save that as a Macro Enabled Word template (.dotm). Open PowerPoint and set up as desired and save as Macro Enabled PowerPoint Template (.potm). Copy .dotm and .potm to all users file share. Create a user based GPO to push those files to %appdata%\Microsoft\Templates\FILENAME. Make a new registry GPO under User Configuration> Preferences> Windows Settings> Registry to update HKCU\Software\Microsoft\Office\14.0\Word\Options with DWORD=1. Export your Outlook settings from HKCU\Software\Microsoft\Office\Office\14.0\Common\MailSettings and push thosee as a new registry entry as well. You'll also want to add template details to Word's Security stuff, as per here, and create template niceness as per here. Push the femplate files with the template as above.

Creating multiple PPTP VPNs on TomatoUSB Don't do this if you can avoid it, PPTP is broken and IPSec is not. Do this as a startup script:

/usr/sbin/pppd file /jffs/options.vpn
/usr/sbin/iptables --insert FORWARD --protocol tcp --tcp-flags SYN,RST SYN --jump TCPMSS --clamp-mss-to-pmtu
/usr/sbin/iptables --table nat --insert POSTROUTING --out-interface ppp1 --jump MASQUERADE

Set your VPN options file:

lcp-echo-failure 3
lcp-echo-interval 2
maxfail 0
pptp_server IPAddress_of_VPN_Server
idle 0
ip-up-script /jffs/ip-up
ip-down-script /jffs/ip-down
ipparam kelokepptpd
mtu 1450
mru 1450
user vpn_username
password password
unit 1

Setup routes and iptables rules in ifup, and tear them down in ifdown.

How to be your own CA (AKA how to kill your web traffic) Don't bother, nobody will visit your site anymore.

Installing protobuf on OI do pfexec pkg install header-math to fix google/protobuf/ math.h: No such file or directory

Generate a UCC/SAN cert with TomatoUSB and AD Make a SAN.conf file:

   [ req ]
   default_bits        = 2048
   default_keyfile     = privkey.pem
   distinguished_name  = req_distinguished_name
   req_extensions     = req_ext
   [ req_distinguished_name ]
   countryName           = CA # 2 letter country
   stateOrProvinceName   = ON # 2 letter state/province
   localityName          = Toronto # city name
   organizationName      = Crashcorp # company name
   commonName            = Robbie Crash # your name
   [ req_ext ]
   subjectAltName          = @alt_names
   DNS.1   =
   DNS.2   =
   DNS.3   =

Make the certificate request via CLI with OpenSSL:

openssl req -new -nodes -out /path/to/put/request.csr -config /path/to/SAN.conf
Go to https://yourca/certsrv and select a new advancedd certificate request, then select Web Server, download the DER encoded file and add it to your TomatoUSB router. If you have problems with it persisting use JFFS or CIFS to keep it.

Insecure Content Disqus didn't work properly with SSL, they fixed it right away.

Set PATH through GPO Set system wide PATH variables through Computer Configuration > Preferences > Windows Settings > Environment. Then New > Environment Variable, Create, System Variable, check Path and select Partial. Add directories separated by semicolons. For user based, do the same in User Configuration instead of Computer Configuration, and write Path as the value instead of picking it as a variable.

Compiling Mosh part 2 Did a bit more, gave up. Created an Ubuntu VM and installed Mosh on it, and run a persistent ssh from there to the OI box.

Compiling Mosh part 1 Did a bunch, can't get it to compile.

Satan - Court in the Act This rules, buy it or leave the hall, you worshiper of false metal!

Static IP on OI with NWAM
Run nwamcfg as root and specify you want static, not DHCP. Then fill out the rest of the options as required.

A letter to Vic Toews
C-30 is a bad bill, you should email your MP to tell them to oppose it. Go here to find out how.

NTFS Permissions: Deny
Permissions aren't that confusing. Deny permissions override allow, unless the deny is inherited and the allow is explicit.

Moving to OpenIndiana from Ubuntu
I like it, I'm happier about some things, other things are a pain in the ass. Customized bash shells, nothing big.

Snow Leopard, Lion, AFP with OI 151a and TimeMachine
Install netatalk, then configure /etc/netatalk/afpd.conf with:
# default:
- -tcp -noddp -uamlist,,, -nosavepassword

Set /etc/netatalk/AppleVolumes.default to:
:DEFAULT: cnidscheme:dbd options:upriv,usedots,acl perm=0744
/Path/To/Directory "Share Name"

Then connect the Mac and set it to use non-Apple TimeMachines:
defaults write TMShowUnsupportedNetworkVolumes 1
Then on Lion create a sparsebundle in the share:
hdiutil create-fs HFS+J -volname _.sparsebundle
Configure TimeMachine

Google analytics

Can't modify CIFS shares on OpenIndiana 151a
Set the permissions with /usr/bin/chmod instead of the default chmod. A 0700 mask recursive and inheritable would be:
/usr/bin/chmod user@host:full_set:fd:allow,user@host:read_set:fd:deny,user@host:read_set:fd:deny <DIRECTORY>

MSWinsock corrupted after root kit
Combofix out the rootkit, reboot to safe mode with networking, replace mswsock.dll with the one from DLLCache, reboot, run netsh int tcp reset and netsh reset winsock reboot again.
Fun with javascript, Google Feelin' Lucky queries and Motorhead/Slayer/Siouxsie and the Banshees and Weird Al.

DRAC5 on W2K8 and IE9
(run IE as admin): Add DRAC to trusted sites, install activeX, hit refresh when nothing happens, click install again, close IE and reopen.

Expensive routers are a pain in the ass to configure. Medium sized businesses can often get away with a consumer grade router and some open source software, like OpenWRT, Tomato; and to a lesser extent, DD-WRT

EXEs don't launch.
If programs don't open check that HKCR\.exe is set to "%1" %* WITH the quotes, then reboot.

Censorship should be left to the community by not allowing discourse they dislike to go unrebuked, not by authority figures doling out their own definition of justice.

Data redundancy.
I used to think my setup was overkill, now I use ZFS to stream music and store photos.

iTunes sucks