#!/usr/bin/env python
# vsphere-nt-frob --- do various things in MICROS~1 VMs

# Author: Noah Friedman <friedman@splode.com>
# Created: 2018-08-20
# Public domain

# $Id: vsphere-nt-frob,v 1.9 2018/10/04 15:51:05 friedman Exp $

# Commentary:

# WIP

# Features to add:
#	change passwords
#	enable/disable/create accounts  (with specific SID if possible)
#	enable/disable firewalls
#	enable/disable remote desktop
#	enable/disable remote administration

# Code:

from   __future__ import print_function
import vspherelib     as vsl

import os
import sys

# wmic useraccount where name="noahf" get sid
# reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\%sid%" /v ProfileImagePath

# reg_keys_list('HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\DataStore', match='^0$', recursive=True)
# reg_value_get('HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\DataStore\\{sid}\\0', 'szTargetName')
# reg_value_get('HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\{sid}', 'ProfileImagePath' )
# 'HKEY_USERS\\{sid}\\Volatile Environment'

cmd_slmgr          = '@cscript //nologo slmgr.vbs '
cmd_shutdown       = '@shutdown /f /t {} '
cmd_shutdown_delay = 5  # default

cmd_template = { 'rename' : ( '@wmic computersystem where caption="%COMPUTERNAME%"'
                              ' call rename name="{}"' ),

                 'reboot'    : cmd_shutdown + '/r',
                 'halt'      : cmd_shutdown + '/s',
                 'hibernate' : cmd_shutdown + '/h',
                 'poweroff'  : cmd_shutdown + '/p',

                 'activate'  : cmd_slmgr + '/ato', }

def get_args():
    p = vsl.ArgumentParser( loadrc=True )
    p.add( '-U', '--guest-username', required=True )
    p.add( '-P', '--guest-password', required=True )
    p.add( '-v', '--verbose', default=False,  action='store_true' )
    p.add( 'vm',      nargs=1 )
    p.add( 'actions', nargs='+' )
    return p.parse()

def output_fixup( s ):
    # Some windows commands (e.g. wmic) output utf16.
    # Unfortunately this can be mixed with ascii,
    # so we can't convert the entire output using a proper codec.
    fixups = [ ('\ufeff', ''),
               ('\0',     ''),
               ('\r\n',   '\n'), ]
    for f in fixups:
        s = s.replace( *f )
    return s

def main():
    args = get_args()
    vsi  = vsl.vmomiConnect( args )
    vm   = vsi.find_vm( args.vm )[0]
    vop  = vsi.vmguest_ops( vm,
                            username=args.guest_username,
                            password=args.guest_password )

    actions = args.actions
    script = []
    while actions:
        cmd = actions.pop(0)
        if cmd in ('rename'):
            newname = actions.pop(0)
            script.append ( cmd_template[ cmd ].format( newname ) )
        elif cmd in ('activate'):
            script.append( cmd_template[ cmd ] )
        elif cmd in ('reboot', 'halt', 'hibernate', 'poweroff'):
            if actions: # not at end of list
                try:
                    # Try converting first so that we don't pop element if
                    # this causes an exception.
                    delay = int( actions[ 1 ])
                    actions.pop(0)
                except ValueError:
                    delay = cmd_shutdown_delay
            else:
                delay = cmd_shutdown_delay
            script.append( cmd_template[ cmd ].format( str( delay )))
        else:
            vsl.printerr( cmd, 'Undefined action' )
            sys.exit( 1 )
    script = str.join( '\n', script ) + '\n'

    res = vop.run( script=script ).result
    print( output_fixup( res.output ) )
    if args.verbose:
        print( '[Exit {}]'.format( str( res.exit )), file=sys.stderr )
        print( 'Started:', res.startTime, file=sys.stderr )
        print( 'Ended:  ', res.endTime,   file=sys.stderr )
    sys.exit( res.exit )


if __name__ == '__main__':
    main()

# eof
