Showing posts with label ActiveDirectory. Show all posts
Showing posts with label ActiveDirectory. Show all posts

Thursday, December 20, 2007

[Visual BASIC 6] BOOST (v2)

I revisited BOOST this week. A friend had pointed out to me some time back that /P: and /L: were a bit of a pain when one wanted to speed something up quickly, or kill it quickly. So this version changes the command line handling.

This version also demonstrates how to kill a process. In fact it kills every process of the same name. I wish I'd had this a couple of years ago when I was doing stuff with Excel -- I'd end up with multiple Excel sessions which I would then have to kill off one-by-one through the Task Manager. (I eventually ended up installing Cygwin so that I could script the process.)

If you remember the original VBScript of BOOST and the first VB6 version, you'll see some similarities.

I've given up on using
setsubsys in favour of using VBAdvance (which is now freeware) to handle the compile-to-console-app process. I'm still compressing the app using UPX.

First a few constants and the declarations, found on
vb.mvps.org, for doing console I/O.



Next, a few supporting functions. First off the rank, is an invocation syntax display. Notice that priority can now be specified either by a number (0 to kill, 1-6 for low to realtime) or by name (kill, low, belownormal, normal, abovenormal, high, realtime).



Second, the command line parser. This splits on space and tab and is based on code found at
microsoft.public.vb.winapi



Third, the two routines which wrap the WMI functions to set priority and to kill process. The latter was found at
tek-tips. If I remember correctly, the places in each routine where it says
sComputer = "."
could, in fact, have some other computer's name. If you had sufficient privilege you could be tweaking or killing a process on someone else's machine.



Finally, the Main subroutine. Notice the additions to the priorities collection. Note also the change in the way the command line is handled.

Because there's no .Exists method on Collections, the .Item call is wrapped in an 'On Error' so that a non-existent item situation is caught appropriately.



What's next with this thing? I suppose one could explore the possibility of influencing the lives of applications on other computers:
BOOST Skype.exe kill /C:GUEST_01
There's also the fact that the commandline parser doesn't properly handle double-quoted names. If an .exe had a space it its name, you wouldn't be able use BOOST on it.

Finally, here's a short batch file (killall.bat) I use for killing applications en masse. It was originally designed to get around the 'typing the /P and /L' issue, but I'm so used to using it now ...



An example invocation:
killall excel.exe outlook.exe


© Copyright Bruce M. Axtens, 2007

Sunday, April 09, 2006

[VBScript] When did I log on/off?

The Australian federal government has brought in new laws which seem to require a return to the old days of clocking in at the beginning of the working day and clocking out at the end. As a contractor I don't think I'm going to notice a big difference ... if I want to get paid for the hours I work, then I fill out my timesheet appropriately.

If you aren't in the habit of keeping this kind of information, don't worry too much: Windows keeps a track of your login and logout in one of its Event Logs. Getting that information is fairly easy, if you know what you're looking for. Otherwise its like the proverbial needle in the haystack.

The script outputs into an Excel spreadsheet, the date of each logon in a separate column containing time of logon and logoff. Please note that the script was designed to query someone else's machine, and will likely need modification if you are trying to get your own data out of your own event log.

Here's the code.

As is often the case in my scripts, the preamble loads external code libraries. The former is a the standard library and the latter (see the end of the posting) a symbol table class, based on the Scripting.Dictionary object.
Next comes code to split up the event log's timestamp, followed by the routine to store logon date and logon and logoff times into spreadsheet cells.
Next comes the variable declarations. In retrospect the variables sComputer and sUser could have been Const rather than Dim. For that matter they could have been taken from the command line. Note the double backslash in the uUser variable: this is needed for where it occurs in the WMI call.
This is the core of the script: pointing WMI at sComputer and executing an SQL query against Win32_NTLogEvent. It asks for everything from the 'Security' Logfile where the EventCode matches a logon or a logoff and where the User matches sUser.
Then the script starts to do things with the list of events now stored in cEvents. First a Dictionary is loaded with logons as (zero, comma, TimeSplit of datestamp) and logoffs as (one, comma, TimeSplit of datestamp). The reason for this is that there may be more than one logon and logoff event for a given user during a working day. By storing the logon and logoff times in this way, the first "0" reference can be assumed to be the first logon off the day, and the last "1" can be assumed to be the last logoff of the day.
From the Dictionary wrapper class the keys are extracted. A check is put in here to make sure that there are records to be reported.
Next comes the Excel interactions. The ExcelStart and ExcelNewSheet macros are listed at the bottom of this posting.
What follows is the guts of the Excel reporting. Despite the possibility of incorrect recording, the assumption is that the report will contain the first logon and the last logoff. If a logon occurs after the last logoff, it is discarded. The script is unable to cope with the situation where someone logs on today and logs off tomorrow.

Note that a check is made not to report more dates than MAX_INSTANCE, a limit that has not yet been encountered. AMax and AMin are listed at the bottom of the posting.
Excel is left running with the results of the report. It's up to the user to save it, print it or whatever. To finish, the macros ExcelStart, ExcelNewSheet, AMax and AMin, and the ClassSymTab class as promised.

Friday, January 27, 2006

[VBScript] Where else have I logged in on this network?

It's not so much a question for me -- I remotely log into many pcs daily as part my job, and try to leave as few tracks as possible. However, today a customer rang saying she'd lost a few important Favourites and had no backup. The best way I could think of helping her, was to locate all the machines she's logged into and see if any of the Favourites could be found.

I did find what she was looking for. Here's the code I used.

First the standard header implementing the synthetic include (derived from
Rube Goldberg Memorial Scripting Page)
StandardLibrary.vbs is getting big. 1500+ lines of code.

Next a little function for a right fill. Having needed this only once, I haven't included it in the StandardLibrary.
Now the main body of the script.

1. Check commandline to see if a username is specified.
1.1 If nothing specified, throw a fit.
2. Get an array of all the computers currently online.
2.1 No error checking here but there ought to be
3. Tell everyone what's going on.
4. Loop through the names of the online machines
4.1 Trim off the leading \\ put on by NET VIEW
4.2 Write out the name, right filled with dots
4.3 Get an array of the login profiles for the computer
4.4 Scan the array to see if contains the the username (case insensitive search)
4.4.1 If found say so with a CRLF
4.4.2 otherwise issue a CR

The calls to BeginsWith are commented out. They apply only to my situation where a company edict ensures that all desktop pc names start with PC and all laptops with LP.
The supporting library rountines are below, First GetOnLineComputers with its supporting routines, GetNetView, CaptureDOS and ReadFile
Next, BeginsWith (included for completeness sake)
Then GetLoginProfiles, plus support routine AAdd
And, finally, StrInArray.
Unfortunately, this does not run quickly. It can take ages to get through the entire list and sometimes hangs inexplicably. Your mileage may vary.

If anyone comes up with a faster way of doing this I'd be very interested.

Tuesday, January 10, 2006

[VBScript] Threads ... thin ones

The following is an attempt at threads in VBScript. The code owes a lot to Greg Chapman of MouseTrax Computing Solutions. There are two scripts, the first calling the second (in many instances). The means for communicating between the two is via the Volatile environment. When the script runs, Outlook flickers (don't know why).

There are comments, but the basic idea is to keep a watch over how many instances of cscript.exe there are running and while there's only so many, add more. Use the Volatile environment for semaphores and make sure there's enough delay in there to get stuff to and from Volatile (which is actually in Registry and not blazingly fast).

First the controller.
Then the controlled. There are quite a few extra useful routines in all that code, including an AADD(), and assorted WMI related routines.

I'm in the process of putting the thread functionality inside a Class so that I can change how things are done without causing drastic rewrites of the original VBScripts. I'm not entirely pleased with the Volatile environment and may end up playing with something else that can be used as a shared storage area between many programs ... like subdirectory structures.


Monday, December 19, 2005

[VBScript] Deriving user name from computer name

I found a brilliant bit of code for deriving the username from the computer name. It's found inside Matt Williams's "ManagePC v1.31" HTA. His description of the routine is as follows
This bit of code is "cheating" slightly in that all it's doing is getting the owner of the explorer.exe process. Seeing as explorer.exe only runs if a user is logged on it is a reliable (but sneaky) way of getting the logged-on user. It does, however, mean that even if a user is logged on locally or the account is a generic account, it will retrieve the correct values (WMI cannot do this).
-- Matthew Williams, ManagePC
Below is my routine, combining his code with some extra housekeeping. Of course, if no one is logged in, you get nothing. My own take on Matt's routine adds in a check to see if the computer is actually running, using ResolveIP() below: