Many clever tricks are mentioned on my other pages, especially Solutions found on alt.msdos.batch
Every now and then a real "jewel" is sent to me by mail or otherwise.
A selection of these tricks will be displayed on this page.
Rob,
I feel your pain about finding a logged-on user... but there is hope from the most unlikely of places... using Netsh.
netsh diag show computer /v
Checkout near the bottom:UserName =
If there is no username, there is no logged-on user. Sweet!
Programmatically in Batch:
FOR /F "tokens=3" %%a IN ('netsh diag show computer /v ^| FIND /i "username"') DO ECHO %%a
Remotely using Batch via Psexec:
SET REMOTE_COMPUTER=%1
FOR /F "tokens=3" %%a IN ('PSEXEC.exe \\%REMOTE_COMPUTER% netsh diag show computer /v ^| FIND /i "username"') DO ECHO %%a
Note: this only gets you the locally logged-on user: Windows Server 2003 Terminal Services Users will not show up on this.
-r \\%REMOTE_COMPUTER%
switch should do the trick without the need for PSEXEC, but my own
tests using this switch failed.NETSH Diag Show Computer /V command,
there is a lot of valuable information available.SET /P to read the first line
of a file and store it in an environment variable.SET /P TestVar=<C:\boot.ini
SET TestVar
FOR /F "tokens=*" %%A IN (C:\boot.ini) DO SET TestVar=%%A
SET TestVarSET /P reads the first line,
whereas FOR /F reads the last line!Sometimes it is necessary to get a Driveletter from a mapping.Wow! Great!
Normally you will define a fixed Driveletter which you will map to your Remote path.
After you have done all things you will delete the drive mapping.
I found an simple solution for Windows Server 2003. Maybe it's also working in Windows 2000.
WithPUSHD \\Server\Share\[path]the system automatically creates a driveletter for you and jumps to it.
In the next step you can get the current Drive with %CD%.
When you usePOPDyou will jump back and the drivemapping is also deleted.
Attention: BecausePUSHDcan be nested you have to make sure that withPOPDyou don't delete your current directory!
In my scripts I will use the following lines to Map a remote path:
PUSHD \\Server\Share\path
SET rmt=%CD%
CALL %rmt%\script.cmd
PUSHD \\server\sharename
CD >> C:\pushdtest.log
POPD
CD >> C:\pushdtest.logX:\
C:\
X:\
C:\Under XP (And I assume NT/2000 as well) it is possible to create a group of commands from the command line (not a batch file). This is useful for, among other things, copy&pasting scripts off of the internet for testing without saving. To do this, just type "(" and hit enter, enter each command one by one (or paste a previously copied list of commands), then type ")" and hit enter.Thanks, Chris.
As well, it allows for groups of commands intended to be executed sequentially to be entered beforehand then allowed to run, useful if you are running external programs that you need to wait for and don't want to write a batch file for that specific job.
Output for every command may also be redirected at the end of the block, in the same manner as Tip 7 on the Clever Tricks page: ") > log.txt" instead of just ")"
C:\>(
More? cd
More? echo %windir%
More? echo This may be useful to someone wanting
More? echo to enter multiple commands in a row...
More? )
C:\
C:\WINDOWS
This may be useful to someone wanting
to enter multiple commands in a row...
C:\>
Well, now I just found something more useful: A way to increase readability.Thanks, Chris.
After thinking about why this works under NT/etc, I realized its because under windows, a physical linebreak is represented by 2 characters, and the escape character only escapes one of them, leaving the other there. My guess is that under OS/2, a linebreak is only a single character.
After some testing, I found that using just the second half of the linebreak, its possible to make it all neat and non-spaced out (the hex value is shown in notepad as a square, it won't provide a physical linebreak):
ECHO testˆ<hex 0A>
testˆ<0A>
testˆ<0A>
test
will result in:
test
test
test
test
To use in a SET command:
SET var=testˆˆˆ<0A><0A>ˆ<0A>
testˆˆˆ<0A><0A>ˆ<0A>
testˆˆˆ<0A><0A>ˆ<0A>
test
ECHO %var%
will result in:
test
test
test
test
The reason that the <0A> is repeated twice is that the first one is ignored, which would be interpreted asˆˆˆˆwhich is not what is wanted. Having a few control codes on the end instead of excessive linebreaks is much more readable, while providing the same behaviour. The only requirement is that you be able to enter the correct value.
I have [...] discovered that you can run 'Well, this sure is a nice simple replacement for my (now obsolete) SNDisk2.bat.egather2 -local' to output the native XML file rather than the .eg2 file.
You can also specify which information is output by egather2 by specify the probe name on the command line, eg:
You can get a list of probe names to specify by runningegather2 -local -probe SYSTEM_SUMMARYegather2 -listprobes
STRINGS -a EGATHER2.EXE | FINDSTR /R /B /I /C:"-[A-Z0-9][A-Z0-9]"
to find the following possible switches:
-Y2
-ht
-wB
-binaryfile
-xmlfile
-textfile
-asciifile
-dgmlfile
-vpd
-stdout
-local
-probe
-probes
-listprobes
-html
-filename
-level
-debug
-step
-nolimit
-silent
-batch
-help
-64OS
-zc
Try the
-help switch and you'll notice that most of
these switches are indeed undocumented.
EGATHER2 -html -batch
which I used in my new
SNDisk3.bat.
EGATHER2 -html -batch -filename\\remoteserver\remoteshare\%ComputerName%
(no space between
-filename and the actual file name; and no
extension, the -html switch will take care
of that)
REGSVR32 %systemroot%\apppatch\slayerui.dll
From that moment on you can choose to run any program
in Windows 95 or NT 4 compatibility mode.
ECHO Press Enter to continue . . .
SET /P =
Unlike PAUSE, which accepts any key, SET /P will only accept
the Enter key.
SET /P =Press Enter to continue . . .
DIR,
which is shorthand for:
DIR /A
Works only in COMMAND.COM (tested in Windows 2000).
:: bootdrv1.bat
@ECHO off
:: By Laurence Soucy
:: http://bigfoot.com/~batfiles/
::
:: To place drive letter into variable
ECHO %comspec%|choice.com/n/c%comspec% set bootdrv=>%temp%.\bootdrv$.bat
FOR %%c in (CALL DEL) do %%c %temp%.\bootdrv$.bat
ECHO "%bootdrv%"
The same trick could be used to determine the current drive letter:
@ECHO OFF
CD | CHOICE /N /C:ABCDEFGHIJKLMNOPQRSTUVWXYZ SET curdrive=>%temp%.\curdrv$.bat
FOR %%A IN (CALL DEL) DO %%A %temp%.\curdrv$.bat
ECHO "%curdrive%"
Tip (and the bootdrv* batch files
themselves) provided by
Laurence
Soucy
command1 > logfile.log
command2 >> logfile.log
command3 >> logfile.log
In Windows NT4/2000/XP command grouping can be used to simplify
the code:
(
command1
command2
command3
) > logfile.log
Tip provided by Dave Denholm
VER | NET USE * \\server\share [ /USER:domain\user ]
Note: this will skip the drive mapping and display an
error message if the user ID/password combination is
invalid (in other words: if you don't have the rights
you just won't get the drive mapping)
PING server | FIND "TTL=" >NUL
IF ERRORLEVEL 1 ECHO Error pinging server
In Windows 95/98/NT this will result in 4 tries from PING to
detect the presence of server.
PING server -n 1 | FIND "TTL=" >NUL
IF NOT ERRORLEVEL 1 GOTO Next
PING server -w 3000 | FIND "TTL=" >NUL
IF ERRORLEVEL 1 ECHO Error pinging server
:Next
Tip provided by Mark Johnson,
and improved (using "TTL=" instead of "TTL") by
Richard Parvass
RUNDLL USER.EXE,SwapMouseButton
RUNDLL32 USER32.DLL,SwapMouseButton
CONTROL MAIN.CPL
or:
RUNDLL32 SHELL32.DLL,Control_RunDLL MAIN.CPL,@0,1
START RUNDLL32 RNAUI.DLL,RnaDial exact name of dialer entry
TRACERT -h 1 -w 1
The RUNDLL command starts DUN, the TRACERT command
is supposed to actually start the dialing process.
Since I do not have access to any PC with DUN installed,
I could not test the TRACERT command's effect.
FOR /F "tokens=2 delims= " %%A IN ('PING -a %1 ˆ| FIND "[%1]"') DO ECHO.%%A
The HostName.bat
examples use this trick.FIND /V part if you expect host names
containing the (sub)string "TTL".
DEBUG < %0.BAT
GOTO Around
(do not skip this blank line)
(original DEBUG script goes here)
(do not skip this blank line)
:Around
Technique first seen at
McAfee's
siteThe win98 tasks scheduler creates .JOB files when you setup a program to run on a certain occasion.
These .JOB files contain information about some things like the path to the program that should be run and probably when it will run.
I've also seen that there's allways a character that indicates wether the .JOB file is active or not.
Checking if a certain task will be run or not could then be done in a batch file:
TYPE C:\Windows\Tasks\Thejobb.job | FIND "%character%" >NUL
IF NOT ERRORLEVEL 1 ECHO Job not active!
IF ERRORLEVEL 1 ECHO Job is active!
Where %character% is the one character that will disappear from the .JOB file when it's activated.
I've found that the ASCII 196 is a pretty safe bet, but you should scan the file you want to test, both when you have it activated and when it is inactive.
Then check if it's really this character that differs (I suggest looking at it in notepad, thats how I did it).
If you're really unlucky the active-or-not charcter could be found twice in the file, on its active-or-not position and some other place, this test will then not work.
Check also that your program's name does not contain the control character.
SET /A switch:SET /A.
SET /A 0XFF
and you should see the number 255 (the decimal value of the
hexadecimal number FF) on screen.
A final word of thanks to all who sent me their tips and tricks.