Thursday, February 28, 2013

net send for windows vista/7/8

Remember back in the day of NT/2000/XP, where you could type
net send computername some message here?

If you tried to do a net send with any version of windows since xp (vista/7/8), you've probably noticed that Microsoft removed net send entirely (with xp sp2, they disabled the service, but you could easily re-enable it).

Microsoft probably did this for security/anti-spam.  Back in the days when I was in college, I would often be getting net send spam.

You can use msg.exe which will send a message to a terminal server (has to be a server vision of windows), or to display a popup on your local computer.  If we combine that with psexec we have a way to replicate the functionality,

psexec \\remotecomputer msg.exe * /server:remotecomputer some message here

However this doesn't work very well if you have many computers (say a whole office?) that you need to send a message to.
So here's a script to make it easier if you have multiple computers:

rem --------beginning of netsend7.bat-------------------------

@echo off

rem this is for sending messages to computers using psexec and msg.exe

rem instead of net send. as net send doesn't exist in windows after xp

rem NEEDS PSEXEC.EXE in the the path or same folder.

if "%~1" == "" goto error

rem need to convert the list of computers

rem from comma to space delimited

for /f "tokens=*" %%c in ('echo %~1') do set comps=%%c

echo the computers are %comps%

rem extract the message from the command line

for /f "tokens=1,* delims= " %%p in ('echo %*') do set msg=%%q

echo the message is: %msg%

rem call the subroutine for each message.

for %%c in (%comps%) do call :submsg %%c

goto end


set subcomp=%1

rem echo messaging %subcomp%, with message %msg%

psexec \\%subcomp% msg.exe * /server:%subcomp% %msg%

exit /b


echo make sure to include quotes at the beginning and

echo end of the list of computers, but not the message,

echo usage "comp1,comp2,comp3,etc..." some message to the computers

rem check for psexec

where /q "$path:psexec.exe"

if %errorlevel% == 0 goto end

echo .

if not exist psexec.exe echo you need to have psexec.exe somewhere in the path.


rem --------end of netsend7.bat-------------------------

If you want to accomplish the same thing without psexec, there is a guy who figured out a method using vbscript and setting a remoteRPC key in the registry on every computer you're messaging to:

Wednesday, February 27, 2013

synchronizing cross platform

If you've been in the computer field at all for the past few years, you've heard of the cloud, amazon s3, ec2, dropbox, windows live, carbonite, google docs, etc....

What if you don't want to store everything in the cloud, either it's too private, or don't want to run afoul of some data privacy laws (hippa?), or it would just cost too much to store all of the hours of baby videos you took.

Now you could use robocopy, or rsync, but these are both one direction.  If you have a laptop that you edit information on along with a desktop (or another laptop?), you probably want to sync your information between the two not just do a one direction backup.

Unison is the program I've been using to keep various repositories of information in sync.   It's cross platform, bi-directional, and doesn't involve the cloud, you control where everything is.

my usage is:
unison -batch profile.prf

the -batch option automates the synchronization process, without it, unison will ask about each and every file that it's copying, should it copy, delete, overwrite one, etc..., so you should probably run it just the first time without the -batch option (if at all).

profile.prf is the name of the configuration file (in the .unison folder if you don't specify a path to it), it can be any name though (pro.prf, home-sync.prf, etc...).

it'll also run over ssh like rsync does, or run a server also like rsync.

a unique feature of unison which I enable is for it to store previous versions of files into a separate folder (or you can store them in a hidden folder in the listing of folders being synchronized).

one of my .prf files, this is for windows, but unison on linux works just as well, just change the folders.

#######------start of prf file--------------

root = //server1/share/synced-folder1
root = //server2/share/synced-folder2

path = subfolder1
path = subfolder2
path = subfolder3

#as this is for windows, don't use fastcheck for unix usually
fastcheck = true
backup = Name *
#ignore any hidden folders, and cd images
ignore = Name {,.}*{.iso}
#where unison stores it's previous versions
backupdir = c:\Users\user1\unison-bak
#where to store the logs
logfile = c:\Users\user1\unison-logs\info-db
#the maximum number of previous versions
maxbackups = 10
#######------end of prf file--------------

Tuesday, February 26, 2013

sysinternals tools hanging due to license

You probably have come across (either in this blog or on other sites), various tools from sysinternals (psexec, psinfo, pskill, etc...).

While these are great tools, for the sysadmin, especially when it comes to automating and scripting, you may have noticed that they been absorbed my microsoft.  On it's own, being acquired by microsoft isn't necessarily a bad thing, however microsoft does now insist that you agree to a license the first time you use a sysinternals tool as a particular user on a particular machine.  This can be very problematic when running scripts on remote machines via psexec (the sysinternals tool will hang and not give you any indication that it's because you need to agree to a license).

One way to get around this is to put in registry keys onto the remote computer that you already accepted the eula,
reg.exe ADD HKCU\Software\Sysinternals\PsKill /v EulaAccepted /t REG_DWORD /d 1 /f
reg.exe ADD HKCU\Software\Sysinternals\PsList /v EulaAccepted /t REG_DWORD /d 1 /f
reg.exe ADD HKCU\Software\Sysinternals\PsInfo /v EulaAccepted /t REG_DWORD /d 1 /f
reg.exe ADD HKCU\Software\Sysinternals\PSexec /v EulaAccepted /t REG_DWORD /d 1 /f
reg.exe ADD "HKCU\Software\Sysinternals\Process Explorer" /v EulaAccepted /t REG_DWORD /d 1 /f
reg.exe ADD "HKCU\Software\Sysinternals\Process Monitor" /v EulaAccepted /t REG_DWORD /d 1 /f
reg.exe ADD "HKCU\Software\Sysinternals\Autoruns" /v EulaAccepted /t REG_DWORD /d 1 /f
reg.exe ADD "HKCU\Software\Sysinternals\TCPView" /v EulaAccepted /t REG_DWORD /d 1 /f
reg.exe ADD "HKCU\Software\Sysinternals\RootkitRevealer" /v EulaAccepted /t REG_DWORD /d 1 /f

many thinks to  for the information, please go there for a more complete listing of registry entries for each of the sysinternals tools.  

Monday, February 25, 2013

Monitoring free space

Previously I described one unusual method to help clear out space on windows, details are here, If you want to make sure your windows server (or workstation), doesn't get too low on free space you can use some of the many monitoring tools out there which eat up system resources when you use them and/or cost an arm and a leg.  My solution is to have a script which goes out and checks the drives, and saves the information to a csv file so you can check for trends using any spreadsheet program.  It will also send out an e-mail if the space is too low.  I run this script from the windows task scheduler at 7am and 7pm, against all the different servers.

Usage:  drv-space.bat  servername

note: e-mail functionality requires blat.exe which you can get at, and you will have to set some variables in the script also.

rem -----begin script --------

@echo off
set tech=network.admin
set blatexe=c:\utils\blat.exe
set freespacenum=1000000000
rem shouldn't need to change any variable below here
rem usage drv-space.bat servername
set server=%1
echo processing server %server% at %date% %time%
for /f "tokens=2" %%W in ('date /t') do set dater=%%W
for /f "tokens=1,2 delims=:" %%t in ('echo %time%') do set timer=%%t:%%u
for /f "tokens=1-3 delims=/" %%d in ('echo %dater%') do set curdate=%%f%%d%%e
for /f "tokens=3 delims=/" %%y in ('echo %dater%') do set curyear=%%y
echo checking drive space
for /f "tokens=3" %%s in ('dir \\%server%\c$ ^|find "free"') do set drvct=%%s
for /f "tokens=3" %%s in ('dir \\%server%\d$ ^|find "free"') do set drvdt=%%s
for /f "tokens=3" %%s in ('dir \\%server%\e$ ^|find "free"') do set drvet=%%s
rem strip out the commas from the values
set drvc=%drvct:,=%
set drvd=%drvdt:,=%
set drve=%drvet:,=%
echo checking if we have at least a gig on drive c. 
if %drvc% LSS %freespacenum% goto emailwarning
goto savetocsv
echo on 
echo we got less then 1 gig
rem if we have less then one gig we need to send an e-mail, but only if we haven't already done so today.  
if exist %temp%\%server%-%curdate%-low-space-msg.txt goto savetocsv
echo apparently need to email about %server% at %time%, only %drvc% bytes free
echo drive c on %server% has only %drvct% bytes of free space on it as of %date% %time% > %temp%\%server%-%curdate%-low-space-msg.txt
%blatexe% %temp%\%server%-%curdate%-low-space-msg.txt -to %tech%@%techdom% -server %mailserver% -f %COMPUTERNAME%_drv-space-check@%machinednsdomain% -s "%server% low on free space"
if not exist %server%-free-space-%curyear%.csv echo date ,time ,drive c ,drive d ,drive e >> %server%-free-space-%curyear%.csv
echo saving to csv %time%
echo %date% ,%timer% ,%drvc% ,%drvd% ,%drve% >> %server%-free-space-%curyear%.csv

rem -----------------end of script----------------

Thursday, February 21, 2013

freeing space, move uninstall packs

Any modern version of windows has many, many, updates over the course of its lifetime (2000, xp, vista, 7, etc...).  While you probably knew this already, you may not know that every time you install the windows updates (which are vital to keeping your system secure, and hopefully more stable), there is a folder created which stores some files in case you need to uninstall them.  This folder is under the windows system directory (usually c:\windows), and looks like $NtUninstalllKB######$ where ###### is some 6 digit number (and it may become 7 digits some years from now).

On server 2003, if you keep it up to date these files now take up a little less then a gig worth of space.  For most desktops this isn't an issue especially in an office, unless the person is filling up their hard drive with huge multi-media files.  On our servers at work though, drive C (where we have windows), was for some strange reason set to only 12gigs, and as some of these servers are in remote locations (I support offices in 7 different cities across the state), I can't just re-size the partition, and as it's a 6 year old server still under a support contract, I can't just add a drive, so I have to move whatever I can off of the drive.  There's the usual items of course, uninstall programs you don't need, move unneeded files, clear out the temp directories, empty the recycle bin, etc...., but I needed to be more aggressive, as some things just had to be on drive C that took up a huge amount of space.

If you do some checking, various sites, and Microsoft say that you should be able to remove the $NtUninstalllKB######$ folders, but me being the overly cautious sort, didn't want to just delete them, so I decided I want to move them to a different drive, but also still have windows be able to use them via junctions.  A junction is like a hard link for a directory under linux.  You can have a folder on a drive and you can have multiple junctions that also point to that folder, but as far as any programs are concerned they don't realize it's a junction they went through it just looks like another copy of the folder.

My script will move the $NtUninstalllKB######$ folders from c:\windows to a folder on another ntfs drive on the local machine and then create identical junctions for each of the folders on c:\windows that point to the new location.

Once you've cleared out a good amount of space on your drive, check out my script to alert you before you run out of space.  

You will need the sysinternals tool junction.exe
about junctions:

about the $NTUninstallKB##### folders

rem ----------------------script starts here-------------

@echo off

rem this is meant to make room on drive c for older servers
rem that have drive c be too small, but other drives where
rem drive c files can be moved to.

set junexe=d:\mis\single-progs\junction.exe
if not exist %junexe% goto error
rem no trailing backslash
set dstloc=e:\windows
if not exist %dstlock% goto error

echo processing %computername% at %date% %time%

rem extract current month, year, date, etc...
for /f "tokens=2" %%W in ('date /t') do set dater=%%W
rem for /f "tokens=1,2 delims=:" %%t in ('echo %time%') do set timer=%%t:%%u
for /f "tokens=1-3 delims=/" %%d in ('echo %dater%') do set curdate=%%f%%d%%e
for /f "tokens=3 delims=/" %%y in ('echo %dater%') do set curyear=%%y
for /f "tokens=1-3 delims=/" %%d in ('echo %dater%') do set curmonth=%%d
for /f "tokens=1-3 delims=/" %%d in ('echo %dater%') do set DOMC=%%e
rem only if the current month is february or later do we compute the last month
rem and set the lastmonth variable to year.
if %curmonth% GTR 1 set /a lastmonth=%curmonth% - 1
if "%curmonth%" == 01 set lastmonth=year
rem if the lastmonth is before november, add a zero in front of it
if %lastmonth% LSS 10 set lastmonth=0%lastmonth%


rem uninstall packs, take up almost 1gb on the server when uncompressed (compression can only do so much).

if exist %temp%\ntupdateuninstalls.lst del %temp%\ntupdateuninstalls.lst
for /f "tokens=5" %%d in ('dir /a:d c:\windows\?NtUninstallKB* ^|find /v "JUNCTION" ^|find /v "%curyear%"') do echo %%d >> %temp%\ntupdateuninstalls.lst
if "%lastmonth%" == "year" goto copyandlink
rem if we're in january just do last years stuff.
rem if we're in a latter month and it's less then 10 days into the current month, we don't want to move
rem last month's items, otherwise we'll move everything except for this months.

if %curdate% LSS 10 for /f "tokens=5" %%d in ('dir /a:d c:\windows\?NtUninstallKB* ^|find /v "JUNCTION" ^|find /i "%curyear%" ^|find /v "%curmonth%" ^|find /v "%lastmonth%"') do echo %%d >> %temp%\ntupdateuninstalls.lst

if %curdate% GEQ 10 for /f "tokens=5" %%d in ('dir /a:d c:\windows\?NtUninstallKB* ^|find /v "JUNCTION" ^|find /i "%curyear%" ^|find /v "%curmonth%"') do echo %%d >> %temp%\ntupdateuninstalls.lst


for /f %%l in ('type %temp%\ntupdateuninstalls.lst') do robocopy c:\windows\%%l %dstloc%\%%l /e /z /move

for /f %%l in ('type %temp%\ntupdateuninstalls.lst') do %junexe% c:\windows\%%l %dstloc%\%%l

rem for /f %%l in ('type %temp%\ntupdateuninstalls.lst') do compact /c %dstloc%\%%1

del %temp%\ntupdateuninstalls.lst
echo finished at %time%
goto end

echo you need to have junction.exe from sysinternals, and set
echo the junexe variable to point to the file, currently it's %junexe%
if exist %dstloc% goto end
echo make sure that you create a destination folder (perferably on a different drive
echo on a separate drive from your windows install) and set the dstloc variable
echo to reflect that location, currently it's %dstloc%
echo make sure to not end with a backslash
set /p mkdstloc=should I try to create %dstloc% (y/n):
if /i "%mkdstloc%" == "y" mkdir %dstloc%


rem ----------------------script ends here-------------

Tuesday, February 19, 2013

remote desktop for non admins

Windows by default will allow all administrators (domain admins, local admins, etc...), but no one else.  To allow non admins you need to add them to the "Remote Desktop Users" group.  You can do this easily enough via control panel (if you can remote in as an admin on the machine), but if you have a hundred machines, the following becomes more friendly (and much quicker, if you use the up arrow to retrieve the last command in your command line history).  You will need psexec.

psexec -h \\remote-pc -u domain\administrator net localgroup "remote desktop users" domain\user1 /add

enable remote desktop

Windows remote desktop, so useful, especially in an office environment, where you just have to do some things with a mouse, but it's not enabled by default (probably a good thing for security reasons).
But what if you want to get into a remote windows machine, and it's over an hour away, talk the person through control panel?, or just go in yourself (especially when you have about a dozen computers to do this with)?.

The following changes a value in the registry which will then enable remote desktop, you could use regedit, and it's connect to network registry feature (though with windows 7 you have to enable the remote registry service for that to work), but I prefer the following:

reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t reg_dword /d 0 /f

some say that you have to reboot the machine after you do this, I personally didn't (maybe I was lucky?)

you can run the above command via psexec (the -h is required for windows vista/7 machines),
ie: psexec -h \\remote-pc -u domain\administrator reg add "HKLM ....

thanks to orielly and the for the registry edit, if you want the gui version check these sites:


Welcome to my blog, the scripting admin.  Why the scripting admin?, most windows network administrators are use to point and click, and using the mouse.  However there are plenty of scripts for windows, and command line interfaces so that you don't have to use a mouse, and that is what I prefer especially with my linux background, so much so, I've gained the reputation at work, and am sometimes asked to create custom scripts.  This is a journal of my scripting/command line usage, and while it's mostly windows, I will be throwing in some linux also.

ps.  While there is he is a different person.