WPKG with winexe

From WPKG | Open Source Software Deployment and Distribution
Jump to: navigation, search

You can use Samba's preexec directive to launch a script when a PC connects to Samba. To launch WPKG on a Windows machine which connects to Samba, we will use the below script and winexe.

Features[edit]

  • Will run software installation on Windows PCs (except XP Home, which does not support remote administration) without any additional client-side configuration - note the following requirements:
    • Workstation and Server services must be enabled
    • File and Printer Sharing must be enabled
    • Remote IPC and Remote Admin shares must be enabled (i.e. "Use simple file sharing" must be disabled - this is found in: Control Panel\Folder Options\View\Use simple file sharing). To check that these shares are available, execute the "net share" command in a command window. "ADMIN$" and "IPC$" should then be displayed in the results.
    • A local Windows user account with both administrative privileges and a non-empty password

Installation[edit]

  • Copy/paste/save the below script on your Samba server. Note: the script should have UNIX end-of-line characters. If you use Windows, make sure your editor saves the script with UNIX end-of-line characters; if it's saved with Windows end-of-line characters, it will not work.
  • Edit these variables:
    • WINUSER, PASSWORD - user which will start software installation (must have admin privileges),
    • LOGPATH - where to store our logs,
    • WINEXE - winexe binary,
    • TIMEOUT - winexe 0.90 has some bug which prevents it from exiting in some circumstances. Makes sure it's killed if it ever happens for you.
    • IGNOREIPS - don't try to start software installation on these IP addresses
  • down in the script, correct \\\\branchdc\\unattended paths to point to your server and software/wpkg share
  • Create a LOGPATH directory (default: /var/log/wpkg)
  • to smb.conf, add this to the [global] section:
root preexec = /root/scripts/wpkg-preexec.sh %I %m %S &
  • That's it!

Testing[edit]

In your server terminal/shell, start:

/root/scripts/wpkg-preexec.sh 192.168.145.150 pc-name-test netlogon

Meaning of command line arguments:

  • "192.168.145.150" - start software deployment on 192.168.145.150
  • "pc-name-test.log" - everything will be logged to /var/log/pc-name-test.log
  • "netlogon" - when a PC connects to this share, we deploy software on this PC


In a different terminal on that server, cd to /var/log/wpkg and see the logfiles (pc-name-test.log and wpkg.log).


Some more info[edit]

  • prevents from starting multiple WPKG instances on a single Windows PC
  • new software deployment is started by Samba in two cases:
    • PC connects to [netlogon] share (happens automatically for domain PCs which are turned on; nobody has to log in)
    • if /var/log/wpkg/<workstation>.log is not present, or is older than 24 hours
  • security: the script has admin username/password, so make sure to keep it in a directory which is accessible by root only
  • security: winexe will present username/password in ps output. If it's a concern for you (i.e. unprivileged users can view process list on that server), you have to modify the script to use --authentication-file with winexe
  • if you have WPKG Client running, but would rather disable it from this script, you can add these lines just before "net use \\\\branchdc\..." in the script:
taskkill /F /IM wpkgsrv.exe
sc config wpkgservice start= disabled

Script source[edit]

#!/bin/bash

# Launches wpkg.js on a remote Windows machine
# Author: Tomasz Chmielewski (tch .at. wpkg .dot. org)

HOST_IP=$1
HOST_NAME=$2
SHARE=$3

WINUSER='DOMAIN\Administrator'
PASSWORD='secretpass'
LOGPATH=/var/log/wpkg
WINEXE=/opt/winexe

TIMEOUT=3600	# winexe seem to hang sometimes - kill it after 1 hour if it's still there

IGNOREIPS="192.168.111. 127.0.0.1 192.168.128.10"


# No need to change anything below
if [ "x$HOST_IP" == "x" -o "x$HOST_NAME" == "x" ] ; then
cat <<EOF
This script launches WPKG on a specified machine.

Usage:

    $0 <host_ip> <host_name>

EOF
exit 0
fi

# We don't want to execute winexe on nagios, PDC etc.
IGNORE=0
for IGNOREIP in $IGNOREIPS; do
    echo $HOST_IP | grep -q $IGNOREIP
    if [ $? -eq 0 ] ; then
	IGNORE=1
    fi
done

if [ $IGNORE -eq 1 ] ; then
    exit 0
fi


# The main "launch wpkg" function
launch_wpkg()
{
$WINEXE --debug-stderr --system -U "$WINUSER%$PASSWORD" //$HOST_IP \
cmd.exe <<EOF &>"$LOGPATH/$HOST_NAME.log"
net use \\\\branchdc\\unattended /user:$WINUSER $PASSWORD
cscript \\\\branchdc\\unattended\\packages\\wpkg\\wpkg.js /synchronize /nonotify /debug
net use /delete \\\\branchdc\\unattended
echo wpkg_run_is_done
exit 0
EOF
if [ $? -eq 0 ] ; then
    echo "$(date) $HOST_NAME (IP: $HOST_IP, PID: $$) WPKG execution finished" >>$LOGPATH/wpkg.log
elif [ $? -eq 1 ] ; then
    echo "$(date) $HOST_NAME (IP: $HOST_IP, PID: $$) cscript was already running" >>$LOGPATH/wpkg.log
else
    echo "$(date) $HOST_NAME (IP: $HOST_IP, PID: $$) unspecified error code" >>$LOGPATH/wpkg.log
fi
echo "$(date) $HOST_NAME (IP: $HOST_IP, PID: $$) processing done" >>$LOGPATH/wpkg.log
}

echo "$(date) $HOST_NAME (IP: $HOST_IP, PID: $$) starting processing (share hit: $SHARE)" >>$LOGPATH/wpkg.log

UPDATE=0
if [ "$SHARE" == "netlogon" ] ; then
    UPDATE=1
else
    grep -q "wpkg_run_is_done" $LOGPATH/$HOST_NAME.log
    if [ $? -ne 0 ] ; then
	UPDATE=1
    else
	STAMP=$(find $LOGPATH -mtime +0 -name $HOST_NAME.log)
	if [ "x$STAMP" != x ] ; then
	    UPDATE=1
	fi
    fi
fi

# Check if the host was updated in the past 24 hours
if [ $UPDATE -eq 1 ] ; then
    ps aux | grep winexe | grep -q $HOST_IP
    if [ $? -ne 0 ] ; then
	if [ "$SHARE" == "netlogon" ] ; then
            echo "$(date) $HOST_NAME (IP: $HOST_IP, PID: $$) netlogon share hit - starting WPKG" >>$LOGPATH/wpkg.log
	else
            echo "$(date) $HOST_NAME (IP: $HOST_IP, PID: $$) not updated during the last 24 h - starting WPKG" >>$LOGPATH/wpkg.log
	fi
        launch_wpkg &
	WINEXEPID=$!
	while [ $TIMEOUT -gt 0 ] ; do
	    sleep 10
	    ps -C winexe | grep -q $WINEXEPID
	    if [ $? -gt 0 ] ; then
		echo "$(date) $HOST_NAME (IP: $HOST_IP, PID: $$) process finished - winexe ended" >>$LOGPATH/wpkg.log
		exit
	    else
		TIMEOUT=$((TIMEOUT-10))
	    fi
	    if [ $TIMEOUT -le 0 ] ; then
		kill $WINEXEPID
		echo "$(date) $HOST_NAME (IP: $HOST_IP, PID: $$) killed winexe after inactivity timeout" >>$LOGPATH/wpkg.log
	    fi
	done
    else
        echo "$(date) $HOST_NAME (IP: $HOST_IP, PID: $$) winexe already running" >>$LOGPATH/wpkg.log
        echo "$(date) $HOST_NAME (IP: $HOST_IP, PID: $$) processing done" >>$LOGPATH/wpkg.log
    fi
else
    echo "$(date) $HOST_NAME (IP: $HOST_IP, PID: $$) updated during the past 24 hours - skipping an update" >>$LOGPATH/wpkg.log
    echo "$(date) $HOST_NAME (IP: $HOST_IP, PID: $$) processing done" >>$LOGPATH/wpkg.log
fi

Alternative solution for the winexe hang problem[edit]

If the script stated by winexe exits ASAP, than it seems to solve the problem (at least it solved for me). You must make two script.

wpkg-runner.cmd

@echo off
start /b \\server\path\to\wpkg.cmd %1
exit

wpkg.cmd

@echo off
cscript \\server\path\to\wpkg.js /synchronize /debug /nonotify > \\server\path\to\logs\%1.txt
exit

In your shell script start wpkg-runner.cmd like this:

winexe ... "cmd /c start \\\\install\\wpkg\\wpkg-runner.cmd $REMOTE_ADDR"