Shutting down Windows from Linux

I had to do some research on how to remotely shut down a Windows computer from a Linux host and decided to share :-)

My test environment:

  • Gentoo linux running on my laptop
  • Windows XP SP3 running in a VirtualBox guest

The command (you need Samba installed on your Linux machine):

net rpc shutdown -t 10 -f -C "Remote shutdown initiated" -I -U Erik

Broken down, that becomes:

  • -t 10 to give users 10 seconds to hit Ctrl-S
  • -f to force applications to quit without asking the user to save (so they can't get in the way of the shutdown)
  • -C "Remote shutdown initiated" is the message that should be displayed to any logged-in users
  • -I the IP address at which the machine to shut down is located. In my case, the host-only network adapter
  • -U Erik is my username on the Windows machine. Works also as \ (don't forget to escape the backslash if your shell requires it!) or as \
  • If you like, you can add -r to reboot the machine instead of shutting it down.

If you don't want to be asked for your password, append it to your username with a % sign, like so: -U %

Of course, with Windows being involved, this doesn't work right out of the box ;-) In my case, after being asked for the password the net rpc command reported "Shutdown of remote machine succeeded". The Windows XP machine didn't shut down. It didn't even show me a message. A little Wireshark magic ended up revealing the error code "WERR_ACCESS_DENIED" being sent across the wire. (note to self: maybe a newer version of samba will actually do something with this error?)

Long story short: the solution is to have file sharing enabled, but to disable simple file sharing. To do so, open Explorer, go to Tools -> Folder options -> View (yes, it's the most logical place to put this ) and uncheck "Use simple file sharing" (all the way at the bottom of the list).

Comparing two directories

Sometimes it's useful to check whether two directories contain the same files, and whether the files that match are exactly the same.

Assume you have two directories: dir1 and dir2

First, compare the listing of files in the dirs:

find dir1 |sort > contents_dir1.txt
find dir2 |sort > contents_dir2.txt

(I'm sure there are ways to exclude certain patterns, but I can't be bothered because I don't need it at this point.)

Next, compare the two listings using diff ( piping it to colordiff gives pretty colours, using less enables you to actually see what is different if the list is very long).

diff -u contents_dir1.txt contents_dir2.txt |colordiff |less

If you see files here for which you don't care about whether they are identical, remove them. Sed is your friend if there are many of them.

sed -i '//d' contents_dir1.txt
sed -i '//d' contents_dir2.txt

Now make md5sums of all files listed in contents_dir1.txt and contents_dir2.txt. Redirecting stderr to /dev/null suppresses " is a directory" warnings from the md5sum command

cat contents_dir1.txt |xargs md5sum > md5sums_dir1.txt 2> /dev/null
cat contents_dir2.txt |xargs md5sum > md5sums_dir2.txt 2> /dev/null

And once again, use diff to compare the md5sums. From here, it's up to you to decide what to do with files that are different :-)

diff -u md5sums_dir1.txt md5sums_dir2.txt |colordiff |less