diff --git a/go/vendor/github.com/StackExchange/wmi/wmi.go b/go/vendor/github.com/StackExchange/wmi/wmi.go
new file mode 100644
index 0000000..a951b12
--- /dev/null
+++ b/go/vendor/github.com/StackExchange/wmi/wmi.go
@@ -0,0 +1,486 @@
+// +build windows
+
+/*
+Package wmi provides a WQL interface for WMI on Windows.
+
+Example code to print names of running processes:
+
+	type Win32_Process struct {
+		Name string
+	}
+
+	func main() {
+		var dst []Win32_Process
+		q := wmi.CreateQuery(&dst, "")
+		err := wmi.Query(q, &dst)
+		if err != nil {
+			log.Fatal(err)
+		}
+		for i, v := range dst {
+			println(i, v.Name)
+		}
+	}
+
+*/
+package wmi
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"log"
+	"os"
+	"reflect"
+	"runtime"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-ole/go-ole"
+	"github.com/go-ole/go-ole/oleutil"
+)
+
+var l = log.New(os.Stdout, "", log.LstdFlags)
+
+var (
+	ErrInvalidEntityType = errors.New("wmi: invalid entity type")
+	// ErrNilCreateObject is the error returned if CreateObject returns nil even
+	// if the error was nil.
+	ErrNilCreateObject = errors.New("wmi: create object returned nil")
+	lock               sync.Mutex
+)
+
+// S_FALSE is returned by CoInitializeEx if it was already called on this thread.
+const S_FALSE = 0x00000001
+
+// QueryNamespace invokes Query with the given namespace on the local machine.
+func QueryNamespace(query string, dst interface{}, namespace string) error {
+	return Query(query, dst, nil, namespace)
+}
+
+// Query runs the WQL query and appends the values to dst.
+//
+// dst must have type *[]S or *[]*S, for some struct type S. Fields selected in
+// the query must have the same name in dst. Supported types are all signed and
+// unsigned integers, time.Time, string, bool, or a pointer to one of those.
+// Array types are not supported.
+//
+// By default, the local machine and default namespace are used. These can be
+// changed using connectServerArgs. See
+// http://msdn.microsoft.com/en-us/library/aa393720.aspx for details.
+//
+// Query is a wrapper around DefaultClient.Query.
+func Query(query string, dst interface{}, connectServerArgs ...interface{}) error {
+	if DefaultClient.SWbemServicesClient == nil {
+		return DefaultClient.Query(query, dst, connectServerArgs...)
+	}
+	return DefaultClient.SWbemServicesClient.Query(query, dst, connectServerArgs...)
+}
+
+// A Client is an WMI query client.
+//
+// Its zero value (DefaultClient) is a usable client.
+type Client struct {
+	// NonePtrZero specifies if nil values for fields which aren't pointers
+	// should be returned as the field types zero value.
+	//
+	// Setting this to true allows stucts without pointer fields to be used
+	// without the risk failure should a nil value returned from WMI.
+	NonePtrZero bool
+
+	// PtrNil specifies if nil values for pointer fields should be returned
+	// as nil.
+	//
+	// Setting this to true will set pointer fields to nil where WMI
+	// returned nil, otherwise the types zero value will be returned.
+	PtrNil bool
+
+	// AllowMissingFields specifies that struct fields not present in the
+	// query result should not result in an error.
+	//
+	// Setting this to true allows custom queries to be used with full
+	// struct definitions instead of having to define multiple structs.
+	AllowMissingFields bool
+
+	// SWbemServiceClient is an optional SWbemServices object that can be
+	// initialized and then reused across multiple queries. If it is null
+	// then the method will initialize a new temporary client each time.
+	SWbemServicesClient *SWbemServices
+}
+
+// DefaultClient is the default Client and is used by Query, QueryNamespace
+var DefaultClient = &Client{}
+
+// Query runs the WQL query and appends the values to dst.
+//
+// dst must have type *[]S or *[]*S, for some struct type S. Fields selected in
+// the query must have the same name in dst. Supported types are all signed and
+// unsigned integers, time.Time, string, bool, or a pointer to one of those.
+// Array types are not supported.
+//
+// By default, the local machine and default namespace are used. These can be
+// changed using connectServerArgs. See
+// http://msdn.microsoft.com/en-us/library/aa393720.aspx for details.
+func (c *Client) Query(query string, dst interface{}, connectServerArgs ...interface{}) error {
+	dv := reflect.ValueOf(dst)
+	if dv.Kind() != reflect.Ptr || dv.IsNil() {
+		return ErrInvalidEntityType
+	}
+	dv = dv.Elem()
+	mat, elemType := checkMultiArg(dv)
+	if mat == multiArgTypeInvalid {
+		return ErrInvalidEntityType
+	}
+
+	lock.Lock()
+	defer lock.Unlock()
+	runtime.LockOSThread()
+	defer runtime.UnlockOSThread()
+
+	err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED)
+	if err != nil {
+		oleCode := err.(*ole.OleError).Code()
+		if oleCode != ole.S_OK && oleCode != S_FALSE {
+			return err
+		}
+	}
+	defer ole.CoUninitialize()
+
+	unknown, err := oleutil.CreateObject("WbemScripting.SWbemLocator")
+	if err != nil {
+		return err
+	} else if unknown == nil {
+		return ErrNilCreateObject
+	}
+	defer unknown.Release()
+
+	wmi, err := unknown.QueryInterface(ole.IID_IDispatch)
+	if err != nil {
+		return err
+	}
+	defer wmi.Release()
+
+	// service is a SWbemServices
+	serviceRaw, err := oleutil.CallMethod(wmi, "ConnectServer", connectServerArgs...)
+	if err != nil {
+		return err
+	}
+	service := serviceRaw.ToIDispatch()
+	defer serviceRaw.Clear()
+
+	// result is a SWBemObjectSet
+	resultRaw, err := oleutil.CallMethod(service, "ExecQuery", query)
+	if err != nil {
+		return err
+	}
+	result := resultRaw.ToIDispatch()
+	defer resultRaw.Clear()
+
+	count, err := oleInt64(result, "Count")
+	if err != nil {
+		return err
+	}
+
+	enumProperty, err := result.GetProperty("_NewEnum")
+	if err != nil {
+		return err
+	}
+	defer enumProperty.Clear()
+
+	enum, err := enumProperty.ToIUnknown().IEnumVARIANT(ole.IID_IEnumVariant)
+	if err != nil {
+		return err
+	}
+	if enum == nil {
+		return fmt.Errorf("can't get IEnumVARIANT, enum is nil")
+	}
+	defer enum.Release()
+
+	// Initialize a slice with Count capacity
+	dv.Set(reflect.MakeSlice(dv.Type(), 0, int(count)))
+
+	var errFieldMismatch error
+	for itemRaw, length, err := enum.Next(1); length > 0; itemRaw, length, err = enum.Next(1) {
+		if err != nil {
+			return err
+		}
+
+		err := func() error {
+			// item is a SWbemObject, but really a Win32_Process
+			item := itemRaw.ToIDispatch()
+			defer item.Release()
+
+			ev := reflect.New(elemType)
+			if err = c.loadEntity(ev.Interface(), item); err != nil {
+				if _, ok := err.(*ErrFieldMismatch); ok {
+					// We continue loading entities even in the face of field mismatch errors.
+					// If we encounter any other error, that other error is returned. Otherwise,
+					// an ErrFieldMismatch is returned.
+					errFieldMismatch = err
+				} else {
+					return err
+				}
+			}
+			if mat != multiArgTypeStructPtr {
+				ev = ev.Elem()
+			}
+			dv.Set(reflect.Append(dv, ev))
+			return nil
+		}()
+		if err != nil {
+			return err
+		}
+	}
+	return errFieldMismatch
+}
+
+// ErrFieldMismatch is returned when a field is to be loaded into a different
+// type than the one it was stored from, or when a field is missing or
+// unexported in the destination struct.
+// StructType is the type of the struct pointed to by the destination argument.
+type ErrFieldMismatch struct {
+	StructType reflect.Type
+	FieldName  string
+	Reason     string
+}
+
+func (e *ErrFieldMismatch) Error() string {
+	return fmt.Sprintf("wmi: cannot load field %q into a %q: %s",
+		e.FieldName, e.StructType, e.Reason)
+}
+
+var timeType = reflect.TypeOf(time.Time{})
+
+// loadEntity loads a SWbemObject into a struct pointer.
+func (c *Client) loadEntity(dst interface{}, src *ole.IDispatch) (errFieldMismatch error) {
+	v := reflect.ValueOf(dst).Elem()
+	for i := 0; i < v.NumField(); i++ {
+		f := v.Field(i)
+		of := f
+		isPtr := f.Kind() == reflect.Ptr
+		if isPtr {
+			ptr := reflect.New(f.Type().Elem())
+			f.Set(ptr)
+			f = f.Elem()
+		}
+		n := v.Type().Field(i).Name
+		if !f.CanSet() {
+			return &ErrFieldMismatch{
+				StructType: of.Type(),
+				FieldName:  n,
+				Reason:     "CanSet() is false",
+			}
+		}
+		prop, err := oleutil.GetProperty(src, n)
+		if err != nil {
+			if !c.AllowMissingFields {
+				errFieldMismatch = &ErrFieldMismatch{
+					StructType: of.Type(),
+					FieldName:  n,
+					Reason:     "no such struct field",
+				}
+			}
+			continue
+		}
+		defer prop.Clear()
+
+		switch val := prop.Value().(type) {
+		case int8, int16, int32, int64, int:
+			v := reflect.ValueOf(val).Int()
+			switch f.Kind() {
+			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+				f.SetInt(v)
+			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+				f.SetUint(uint64(v))
+			default:
+				return &ErrFieldMismatch{
+					StructType: of.Type(),
+					FieldName:  n,
+					Reason:     "not an integer class",
+				}
+			}
+		case uint8, uint16, uint32, uint64:
+			v := reflect.ValueOf(val).Uint()
+			switch f.Kind() {
+			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+				f.SetInt(int64(v))
+			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+				f.SetUint(v)
+			default:
+				return &ErrFieldMismatch{
+					StructType: of.Type(),
+					FieldName:  n,
+					Reason:     "not an integer class",
+				}
+			}
+		case string:
+			switch f.Kind() {
+			case reflect.String:
+				f.SetString(val)
+			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+				iv, err := strconv.ParseInt(val, 10, 64)
+				if err != nil {
+					return err
+				}
+				f.SetInt(iv)
+			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+				uv, err := strconv.ParseUint(val, 10, 64)
+				if err != nil {
+					return err
+				}
+				f.SetUint(uv)
+			case reflect.Struct:
+				switch f.Type() {
+				case timeType:
+					if len(val) == 25 {
+						mins, err := strconv.Atoi(val[22:])
+						if err != nil {
+							return err
+						}
+						val = val[:22] + fmt.Sprintf("%02d%02d", mins/60, mins%60)
+					}
+					t, err := time.Parse("20060102150405.000000-0700", val)
+					if err != nil {
+						return err
+					}
+					f.Set(reflect.ValueOf(t))
+				}
+			}
+		case bool:
+			switch f.Kind() {
+			case reflect.Bool:
+				f.SetBool(val)
+			default:
+				return &ErrFieldMismatch{
+					StructType: of.Type(),
+					FieldName:  n,
+					Reason:     "not a bool",
+				}
+			}
+		case float32:
+			switch f.Kind() {
+			case reflect.Float32:
+				f.SetFloat(float64(val))
+			default:
+				return &ErrFieldMismatch{
+					StructType: of.Type(),
+					FieldName:  n,
+					Reason:     "not a Float32",
+				}
+			}
+		default:
+			if f.Kind() == reflect.Slice {
+				switch f.Type().Elem().Kind() {
+				case reflect.String:
+					safeArray := prop.ToArray()
+					if safeArray != nil {
+						arr := safeArray.ToValueArray()
+						fArr := reflect.MakeSlice(f.Type(), len(arr), len(arr))
+						for i, v := range arr {
+							s := fArr.Index(i)
+							s.SetString(v.(string))
+						}
+						f.Set(fArr)
+					}
+				case reflect.Uint8:
+					safeArray := prop.ToArray()
+					if safeArray != nil {
+						arr := safeArray.ToValueArray()
+						fArr := reflect.MakeSlice(f.Type(), len(arr), len(arr))
+						for i, v := range arr {
+							s := fArr.Index(i)
+							s.SetUint(reflect.ValueOf(v).Uint())
+						}
+						f.Set(fArr)
+					}
+				default:
+					return &ErrFieldMismatch{
+						StructType: of.Type(),
+						FieldName:  n,
+						Reason:     fmt.Sprintf("unsupported slice type (%T)", val),
+					}
+				}
+			} else {
+				typeof := reflect.TypeOf(val)
+				if typeof == nil && (isPtr || c.NonePtrZero) {
+					if (isPtr && c.PtrNil) || (!isPtr && c.NonePtrZero) {
+						of.Set(reflect.Zero(of.Type()))
+					}
+					break
+				}
+				return &ErrFieldMismatch{
+					StructType: of.Type(),
+					FieldName:  n,
+					Reason:     fmt.Sprintf("unsupported type (%T)", val),
+				}
+			}
+		}
+	}
+	return errFieldMismatch
+}
+
+type multiArgType int
+
+const (
+	multiArgTypeInvalid multiArgType = iota
+	multiArgTypeStruct
+	multiArgTypeStructPtr
+)
+
+// checkMultiArg checks that v has type []S, []*S for some struct type S.
+//
+// It returns what category the slice's elements are, and the reflect.Type
+// that represents S.
+func checkMultiArg(v reflect.Value) (m multiArgType, elemType reflect.Type) {
+	if v.Kind() != reflect.Slice {
+		return multiArgTypeInvalid, nil
+	}
+	elemType = v.Type().Elem()
+	switch elemType.Kind() {
+	case reflect.Struct:
+		return multiArgTypeStruct, elemType
+	case reflect.Ptr:
+		elemType = elemType.Elem()
+		if elemType.Kind() == reflect.Struct {
+			return multiArgTypeStructPtr, elemType
+		}
+	}
+	return multiArgTypeInvalid, nil
+}
+
+func oleInt64(item *ole.IDispatch, prop string) (int64, error) {
+	v, err := oleutil.GetProperty(item, prop)
+	if err != nil {
+		return 0, err
+	}
+	defer v.Clear()
+
+	i := int64(v.Val)
+	return i, nil
+}
+
+// CreateQuery returns a WQL query string that queries all columns of src. where
+// is an optional string that is appended to the query, to be used with WHERE
+// clauses. In such a case, the "WHERE" string should appear at the beginning.
+func CreateQuery(src interface{}, where string) string {
+	var b bytes.Buffer
+	b.WriteString("SELECT ")
+	s := reflect.Indirect(reflect.ValueOf(src))
+	t := s.Type()
+	if s.Kind() == reflect.Slice {
+		t = t.Elem()
+	}
+	if t.Kind() != reflect.Struct {
+		return ""
+	}
+	var fields []string
+	for i := 0; i < t.NumField(); i++ {
+		fields = append(fields, t.Field(i).Name)
+	}
+	b.WriteString(strings.Join(fields, ", "))
+	b.WriteString(" FROM ")
+	b.WriteString(t.Name())
+	b.WriteString(" " + where)
+	return b.String()
+}
