WPKG with winexe
From WPKG | Open Source Software Deployment and Distribution
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.
Contents
Features
- 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
- 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 &
- follow this guide on how to download and compile winexe: https://sites.google.com/site/balihb/winexe
- That's it!
Testing
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
- 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
#!/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
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"