Hacking Windows, PSTools, Scripting...
In the last day or so, I've done some very interesting things with Windows XP. It started with my tinkering with a software collection called PSTools by Mark Russinovich. The most useful of these tools is "psexec" which allows me to execute commands from the "Command Prompt" across the network. One of the more significant problems with using these tools is the lack of worthwhile documentation.
I started with editing my environment to include the %PATH% to location where I store the PSTools binaries. This is done by maneuvering to
You continue with configuring the terminals that the tool will be used on. First, these tools will only work across the network on Windows XP Professional computers. (You can, of course, use them directly on Windows XP Home machines.) You have to re-enable the "Classic" "Network Sharing and Security Model" to allow password access to the machine (
In my case, I created a new account on the target machines and added a password to it. (It is worth noting for later, that this account has a space in the "User Name".) I also took some pains to make the account disappear from the Windows XP "Welcome Screen". For those that don't know how to do so, you first need to open the "Registry Editor". Then maneuver down:
With this being done, you can now use:
However, this wasn't good enough for me because I may have to manipulate several dozen machines at a time. So now, I need to manipulate this command to allow that. Fortunately, the author of the tool anticipated that and he allows you to import a list of computers from a file. The problem, again, is lack of documentation for that file. I can't say that I took a lot of time working with it but my initial attempts failed and I gave up and went to find some other way.
That is when I found the following in a post on SysInternals Fora by Karlchen:
e.g.
Fortunately, I wasn't without options and after a bit of hacking I came up with a derivation of the following code.
pstools.cmd
There are other minor changes that I've made to this file. The first change includes another token in the source file which is not currently being used. Next you can see that the path to the source has been made more relative with the inclusion of
NOTE: I'm sure that you've noticed by now, that the
The next step in this journey was to make the batch files available just like the original applications were. Rather than add yet another entry to my
MacroFile.cmd
As I'm sure that you've already deduced that even this was not good enough. I want these macros to be launched every time that I open the "Command Prompt". So I get to go back and edit the registry again:
This environment file contains just a few commands:
environment.cmd
psexec.cmd
After all this editing, I think that it is about time to recap what is actually happening with what I've done.
I started with editing my environment to include the %PATH% to location where I store the PSTools binaries. This is done by maneuvering to
Control Panel -> System; Advanced -> Environmental Variables. I just appended the new path to the end with %ProgramFiles%\SysInternals\PSTools; and it was done (Note: the ; on the PATH).You continue with configuring the terminals that the tool will be used on. First, these tools will only work across the network on Windows XP Professional computers. (You can, of course, use them directly on Windows XP Home machines.) You have to re-enable the "Classic" "Network Sharing and Security Model" to allow password access to the machine (
Control Panel -> Administrative Tools -> Local Security Policy). You have to make certain that "File and Printer Sharing for Microsoft Networks" is enabled on your network device (Control Panel -> Network Connections). You also have to modify the SP2, or other, firewall to allow in traffic on port 135 (i.e. MSRPC Port) but you will want to limit the scope of the "hole" to your local subnet. Finally, you have to have an administrative account that has a password on it (without the password Windows won't allow the connection).In my case, I created a new account on the target machines and added a password to it. (It is worth noting for later, that this account has a space in the "User Name".) I also took some pains to make the account disappear from the Windows XP "Welcome Screen". For those that don't know how to do so, you first need to open the "Registry Editor". Then maneuver down:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\Current Version\Winlogon\SpecialAccounts\UserListIn this key, you need to make a new "DWORD Value" and give it the name of the account you want to hide (e.g. "User Name"). Now you will notice that it is not on the "Welcome Screen" but if you press CTRL+ALT+DELETE you can still access this "hidden" account.
With this being done, you can now use:
psexec \\somecomputer -u "User Name" -p "Some Password" chkdsk /rHowever, this wasn't good enough for me because I may have to manipulate several dozen machines at a time. So now, I need to manipulate this command to allow that. Fortunately, the author of the tool anticipated that and he allows you to import a list of computers from a file. The problem, again, is lack of documentation for that file. I can't say that I took a lot of time working with it but my initial attempts failed and I gave up and went to find some other way.
That is when I found the following in a post on SysInternals Fora by Karlchen:
@echo offThis script will parse every record of the provided text file and will replace
for /F "tokens=1,2,3*" %%a in ('type computerlist.txt') do (
echo Machine=%%a User=%%b PW=%%c Rest=%%d
REM This will be the resulting psexec command
psexec \\%%a -u %%b -p %%c [put in the remote command here]
)
%%a with the first field, %%b with the second field, and %%c with the final field.e.g.
somecomputer1 SomeUser1 SomePassword1The obvious problem is that this script will only allow the use of one command, which is particularly unpalatable for
somecomputer2 SomeUser2 SomePassword2
psexec \\somecomputer1 -u Someuser1 -p SomePassword1
psexec. The less obvious problem is due to the space delimited nature of the for command and the possibility of having spaces in "User Name" (remember the note above).Fortunately, I wasn't without options and after a bit of hacking I came up with a derivation of the following code.
pstools.cmd
setLocalThe two biggest differences are the inclusion of a
set PATH=%PATH%;%ProgramFiles%\SysInternals\PsTools
if %PSTools% EQU psloggedon (
for /F "tokens=1,2,3,4* delims=:" %%a in ('type "%USERPROFILE%\Desktop\computerlist.txt"') do (
echo -- Machine=%%a User="%%b" PW=%%c Spec=%%d COM=%* --
REM This will be the resulting psloggedon command
psloggedon.exe \\%%a %* 2> %TMP%\garbage.txt
echo.
)
) else (
for /F "tokens=1,2,3,4* delims=:" %%a in ('type "%USERPROFILE%\Desktop\computerlist.txt"') do (
echo -- Machine=%%a User="%%b" PW=%%c Spec=%%d COM=%* --
REM This will be the resulting pstools command
%PSTools%.exe \\%%a -u "%%b" -p %%c %* 2> %TMP%\garbage.txt
echo.
)
)
endLocal
: as a delimiter for the source file (i.e. computerlist.txt) and the inclusion of %* on the command. (Aside: The first change makes the source file look at lot like a Unix/Linux password file.) I chose a colon as the delimiter because it is not a valid character to use in a folder and, as I'm sure your aware, every user gets a folder with their user name under C:\Documents and Settings\ . The second change appends any additional commands to the end of the command. This gives you the ability to use the various switches on the individual PSTools applications.There are other minor changes that I've made to this file. The first change includes another token in the source file which is not currently being used. Next you can see that the path to the source has been made more relative with the inclusion of
%UserProfile% . Finally, I've redirected sterror to a "garbage" file in the directory referenced by %TMP%.NOTE: I'm sure that you've noticed by now, that the
if command is referencing an environmental variable in order to determine which tool to call. The reason for this will be obvious below. Also, in the original version of the above code, I had one file for each of PSTools applications (which made it very tedious to fix errors).The next step in this journey was to make the batch files available just like the original applications were. Rather than add yet another entry to my
%PATH%, I decided to utilize a series of doskey alias'. To make it more compact, I created a macro file which contains the following code:MacroFile.cmd
psexec="%ProgramFiles%\SysInternals\PsTools\Scripts\psexec.cmd" $*The final command
psfile="%ProgramFiles%\SysInternals\PsTools\Scripts\psfile.cmd" $*
psgetsid="%ProgramFiles%\SysInternals\PsTools\Scripts\psgetsid.cmd" $*
psinfo="%ProgramFiles%\SysInternals\PsTools\Scripts\psinfo.cmd" $*
pskill="%ProgramFiles%\SysInternals\PsTools\Scripts\pskill.cmd" $*
pslist="%ProgramFiles%\SysInternals\PsTools\Scripts\pslist.cmd" $*
psloggedon="%ProgramFiles%\SysInternals\PsTools\Scripts\psloggedon.cmd" $*
psloglist="%ProgramFiles%\SysInternals\PsTools\Scripts\psloglist.cmd" $*
pspasswd="%ProgramFiles%\SysInternals\PsTools\Scripts\pspasswd.cmd" $*
psservice="%ProgramFiles%\SysInternals\PsTools\Scripts\psservice.cmd" $*
psshutdown="%ProgramFiles%\SysInternals\PsTools\Scripts\psshutdown.cmd" $*
pssuspend="%ProgramFiles%\SysInternals\PsTools\Scripts\pssuspend.cmd" $*
$* on each line causes any additional bits after the command to be passed along to the batch file on the other end.As I'm sure that you've already deduced that even this was not good enough. I want these macros to be launched every time that I open the "Command Prompt". So I get to go back and edit the registry again:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command ProcessorOR
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Command ProcessorYou have a choice of keys you can edit to enable the autoloading functionality. The first choice edits all the accounts on the computer at once while the second one only changes your account. (FYI: If you use VMWare to run your Windows installation you might have a problem if you edit
HKLM.) You need to edit the value of AutoRun to point to a new batch script that will load the macros, in this case I pointed it to %UserProfile%\environment.cmd but you can point it to anywhere your computer can access.This environment file contains just a few commands:
environment.cmd
@echo offAt this point there is still one problem, I now have about a dozen batch files that I may need to edit in order to make any changes. (Aside: Behold my longing for symlinks in Windows XP.) Since versions of Windows prior to Vista don't really include symlinks, so that I can use path detection (i.e. %0), I have to come up with something else. My solution is another script. (I know, big surprise.)
doskey /macrofile="%UserProfile%\MacroFile.cmd"
@echo on
psexec.cmd
@echo offIn the above command, you notice that I'm setting an environmental variable
setLocal
set PSTools=psexec
call "%programfiles%\SysInternals\PsTools\Scripts\pstools.cmd" %*
endLocal
@echo on
%PSTools% and putting a value of psexec in it. Then I call another script pstools.cmd and append any additional bits onto that call.After all this editing, I think that it is about time to recap what is actually happening with what I've done.
- Login to computer and start Command Prompt.
- Registry key edit calls
environment.cmd doskeycommands are loaded.- I type
psexec chkdks /r - Macro is detected and calls the
psexec.cmd psexec.cmdsets environmental variable and callspstools.cmdpstools.cmdreads%PSTools%and processes it accordinglypstools.cmdreadscomputerlist.txtand loops the commandpstools.cmdreaches the end of the script and clears local environmental variablespsexec.cmdreaches the end of the script and clears%PSTools%environmental variable- Command finishes.
