Author Topic: A simple logon script for Windows clients logging into an eBox PDC  (Read 20544 times)

tbg58

  • Zen Apprentice
  • *
  • Posts: 9
  • Karma: +0/-0
    • View Profile
I'm sure there are many folks on the forum who are vastly more sophisticated than this, but for the sake of my fellow neophyte users of the eBox platform, here's a very simple logon script which can be used by Windows clients for mapping private, public, and group shares on the eBox platform.  The logon script is a VBScript file, launched by a batch file that processes the script using the CScript processor built into the Windows client.
The files are as follows:
logon.bat
logon.vbs
Both are to be placed in the /home/samba/netlogon directory on the eBox PDC running the Office service.

Here's the launcher batch file, logon.bat
Code: [Select]
cscript \\yourservername\netlogon\logon.vbs

This launches the script itself - I've tried to include enough comments to show how it works and I think it should be simple enough for just about anyone to implement.
Code: [Select]

'First make sure all variables are dimensioned.
'This isn't necessary for functionality; it's for coding discipline only.
Option Explicit
'dimension all our variables
dim objNetwork
dim strDriveLetter, strRemotePath, strUser, strGrp
dim strGroupADSPath, strUserADSPath, grp

'This script will use the MapNetworkDrive method
'for each network drive mapped.

'We'll be using the Wscript.Network Object to enumerate the user as well as to map drives.
'We only need to instantiate it once at the beginning.
Set objNetwork = Wscript.CreateObject("Wscript.Network")

'First let's get the user name since we'll use it for mapping the home directory
'as well as checking group memberships. 
strUser = objNetwork.UserName

'In just about every network at least two drives are mapped:
'One for the user's home directory, and one for an organizational public share.
'We'll map those first since they don't depend on group memberships.

'User Drive to U:
strDriveLetter = "U:"
strRemotePath = "\\yourservername"
objNetwork.MapNetworkDrive strDriveLetter, strRemotePath & "\" & strUser

'PublicShare Drive to P:
strDriveLetter = "P:"
strRemotePath = "\\yourservername\public"
objNetwork.MapNetworkDrive strDriveLetter, strRemotePath


'next we'll enumerate groups and map drives for specific departmental memberships
'The code to check for memberships and map the drives is in a subroutine called IsMember.
'All we have to do is copy the same block over again for each group membership we want to check.
'The block only needs to set the string values for the group name, the desired drive letter, and the share path.
'Then it calls the IsMember subroutine down below.

'Q: for members of groupq
strGrp="groupq"
strDriveLetter = "q:"
strRemotePath = "\\yourservername\groupqpvt"
IsMember

'R: for members of groupr
strGrp="groupr"
strDriveLetter = "R:"
strRemotePath = "\\yourservername\grouprpvt"
IsMember

'Repeat for as many private groups and their respective enumerated shares as you wish.

'We're done with the login script.
'Let's tidy up variables first to make sure we're not leaving anything behind.
objNetwork = ""
strDriveLetter = ""
strRemotePath = ""
strUser = ""
strGrp = ""
strGroupADSPath = ""
strUserADSPath = ""
grp = ""
'That's all.  Close the script processor.
wscript.quit


sub IsMember
'set the directory service path to enumerate the group
strGroupADSPath = "WinNT://yourdomain/" & strGrp & ",group"
'poll the PDC for the group
set grp = GetObject(strGroupADSPath)
'set the user directory service path to enumerate the user
strUserADSPath = "WinNT://yourdomain/" & strUser
'Check membership in the group. 
If (grp.IsMember(strUserADSPath)) Then
'map the drive
objNetwork.MapNetworkDrive strDriveLetter, strRemotePath
End If
'clean up variables for next group check.
strGrp = ""
strDriveLetter = ""
strRemotePath = ""
'Rinse, lather and repeat this code as many times as needed.
End sub


As much as I hate to use weasel words, this code is released freely into the public domain, with no implicit or explicit warranty.  Use it at your own risk.  If you have problems or corrections - post them here.  That's what the community is for.
Note that the logon script only works with Windows clients - it has been tested only on Windows XP using eBox 1.2, where it seems to work well.

I hope this is helpful for my fellow new users of eBox - I put it up here in the hope that doing so will save others the time it took me to cobble together a logon script. It's been several years since I scripted for the WinNT provider; my work has been mostly in AD, but I am certainly very impressed by the work done by the eBox team and the community.  Please be encouraged that your work is bearing fruit.  This little message is my very small and humble attempt to help.
Kind regards,
Rob in Memphis

J. A. Calvo

  • Zentyal Staff
  • Zen Hero
  • *****
  • Posts: 1986
  • Karma: +67/-3
    • View Profile
    • http://blogs.zentyal.org/jacalvo
Re: A simple logon script for Windows clients logging into an eBox PDC
« Reply #1 on: October 13, 2009, 04:20:47 pm »
Thank you for the contribution!!

Regards,

J. A. Calvo
Zentyal Server Lead Developer

adrian

  • Zen Apprentice
  • *
  • Posts: 5
  • Karma: +0/-0
    • View Profile
Re: A simple logon script for Windows clients logging into an eBox PDC
« Reply #2 on: October 14, 2009, 12:50:59 pm »
Hi tbg58

Your script looks like what I have been looking for.

I have 20 windows xp pro users and 5 ubuntu users.

I saved the following code: cscript \\myserver\netlogon\logon.vbs into logon.bat and copied your vbs script above into logon.vbs and saved them both into /home/samba/netlogon directory.

logon.vbs:
Code: [Select]
'First make sure all variables are dimensioned.
'This isn't necessary for functionality; it's for coding discipline only.
Option Explicit
'dimension all our variables
dim objNetwork
dim strDriveLetter, strRemotePath, strUser, strGrp
dim strGroupADSPath, strUserADSPath, grp

'This script will use the MapNetworkDrive method
'for each network drive mapped.

'We'll be using the Wscript.Network Object to enumerate the user as well as to map drives.
'We only need to instantiate it once at the beginning.
Set objNetwork = Wscript.CreateObject("Wscript.Network")

'First let's get the user name since we'll use it for mapping the home directory
'as well as checking group memberships. 
strUser = objNetwork.UserName

'In just about every network at least two drives are mapped:
'One for the user's home directory, and one for an organizational public share.
'We'll map those first since they don't depend on group memberships.

'User Drive to H:
strDriveLetter = "H:"
strRemotePath = "\\nebula"
objNetwork.MapNetworkDrive strDriveLetter, strRemotePath & "\" & strUser

'PublicShare Drive to P:
strDriveLetter = "P:"
strRemotePath = "\\nebula\public"
objNetwork.MapNetworkDrive strDriveLetter, strRemotePath

'next we'll enumerate groups and map drives for specific departmental memberships
'The code to check for memberships and map the drives is in a subroutine called IsMember.
'All we have to do is copy the same block over again for each group membership we want to check.
'The block only needs to set the string values for the group name, the desired drive letter, and the share path.
'Then it calls the IsMember subroutine down below.

'I: for members of Accounts
strGrp="Accounts"
strDriveLetter = "i:"
strRemotePath = "\\nebula\Accounts"
IsMember

'J: for members of SYSBackup
strGrp="SYSBackup"
strDriveLetter = "j:"
strRemotePath = "\\nebula\SYSBackup"
IsMember

'K: for members of GCAdmin
strGrp="GCAdmin"
strDriveLetter = "k:"
strRemotePath = "\\nebula\GCAdmin"
IsMember

'L: for members of GCSat
strGrp="GCSat"
strDriveLetter = "l:"
strRemotePath = "\\nebula\GCSat"
IsMember

'M: for members of Webmaster
strGrp="Webmaster"
strDriveLetter = "m:"
strRemotePath = "\\nebula\Webmaster"
IsMember

'N: for members of Ngami
strGrp="Ngami"
strDriveLetter = "n:"
strRemotePath = "\\nebula\Ngami"
IsMember

'O: for members of Okavango
strGrp="Okavango"
strDriveLetter = "o:"
strRemotePath = "\\nebula\Okavango"
IsMember

'R: for members of groupr
'strGrp="groupr"
'strDriveLetter = "R:"
'strRemotePath = "\\yourservername\grouprpvt"
'IsMember

'Repeat for as many private groups and their respective enumerated shares as you wish.

'We're done with the login script.
'Let's tidy up variables first to make sure we're not leaving anything behind.
objNetwork = ""
strDriveLetter = ""
strRemotePath = ""
strUser = ""
strGrp = ""
strGroupADSPath = ""
strUserADSPath = ""
grp = ""
'That's all.  Close the script processor.
wscript.quit

sub IsMember
'set the directory service path to enumerate the group
strGroupADSPath = "WinNT://oeb/" & strGrp & ",group"
'poll the PDC for the group
set grp = GetObject(strGroupADSPath)
'set the user directory service path to enumerate the user
strUserADSPath = "WinNT://oeb/" & strUser
'Check membership in the group. 
If (grp.IsMember(strUserADSPath)) Then
'map the drive
objNetwork.MapNetworkDrive strDriveLetter, strRemotePath
End If
'clean up variables for next group check.
strGrp = ""
strDriveLetter = ""
strRemotePath = ""
'Rinse, lather and repeat this code as many times as needed.
End sub

smb.conf file is set with "logon script = logon.bat"

Now, the logon.vbs does not seem to be loading. Is there anything else I can try, to get this working.

Thanks again

vitaliysh

  • Zen Apprentice
  • *
  • Posts: 13
  • Karma: +0/-0
    • View Profile
Re: A simple logon script for Windows clients logging into an eBox PDC
« Reply #3 on: October 14, 2009, 04:05:59 pm »
Hey thanks for the script! =)

Quick question, is there any way to run certain script once?

For example:
After adding new user to the PDC, I want to run a script to install default applications. Is there any way to do it?

Cheers

tbg58

  • Zen Apprentice
  • *
  • Posts: 9
  • Karma: +0/-0
    • View Profile
Re: A simple logon script for Windows clients logging into an eBox PDC
« Reply #4 on: October 14, 2009, 05:36:01 pm »

Now, the logon.vbs does not seem to be loading. Is there anything else I can try, to get this working.

Thanks again

Be systematic.  Use this debugging method:
1.  Copy the script and batch file into a local directory on one of your XP boxes.
2.  For troubleshooting purposes make a cleanup file.  If your script maps drives j:, k:, l:, and m: create a cleanup.bat file which has these contents.
Code: [Select]
net use j: /d
net use k: /d
net use l: /d
net use m: /d
This will unmap the drives for debugging purposes.
3.  Next, try manually running the script.  On one of your XP boxes, go out to a command prompt.  CD to the directory where you put the local copy of the script and the launcher bat file.
4.  Run the vbscript file manually.  Don't double-click it; at a command prompt run cscript logon.vbs from the directory where you have the local copy.  Troubleshoot the vbs code first.
5.  After you get the vbs code working, then create your launcher batch file to contain the cscript command.
6.  If you have trouble getting the code to run at all, check your antivirus software, firewall, and local security policy on the XP boxes.  Any one of these may have a rule that prevents VBscript from running.  You should create an exception (hopefully a granular exception just to allow this specific vbs file, not a blunt instrument that allows all vbs to run)
7.  Once you get the script running on the local box, then copy it up to the netlogon share.  Again, make sure the files are world-readable.
8.  Try running the script manually at a command prompt on an XP box.  First run cscript locally with the path to the logon script as your argument, e.g. cscript \\eboxservername\netlogon\logon.vbs.
9.  After you can run the vbscript manually using the local cscript command, troubleshoot the launcher batch file.

If you go through these steps you should be able to get it working.  Start local, start simple.

Without trying to give a full WSH course, here are some pointers:
Apostrophe (unshifted character just to the left of the Enter key) can be used to comment out a line in the vbscript.  Comment out lines to make your script simpler while you're debugging.
For each procedure you are executing, insert a command like this one to help the troubleshooting process:
Code: [Select]
wscript.echo "the script got this far."
This will give you some screen output to let you know how far the script got - be a bit more descriptive in your prompts.

While debugging insert this command at the top after Option Explicit (you can comment out the option explicit command as well)
Code: [Select]
on error resume next
this will allow the script to keep running even after errors, though if there is a compilation error the script still will not run.

Also make sure you have the latest version of the script processor loaded.  At a command prompt enter cscript with no arguments.  The logo will be the first part of the response - current version is 5.7, generally what is installed with XP is 5.6.  You can get 5.7 here:
http://www.microsoft.com/downloads/details.aspx?FamilyID=47809025-D896-482E-A0D6-524E7E844D81&displaylang=en

Those are general troubleshooting and debugging guidelines.  Good luck!
Rob


tbg58

  • Zen Apprentice
  • *
  • Posts: 9
  • Karma: +0/-0
    • View Profile
Re: A simple logon script for Windows clients logging into an eBox PDC
« Reply #5 on: October 14, 2009, 06:22:31 pm »
Hey thanks for the script! =)

Quick question, is there any way to run certain script once?

For example:
After adding new user to the PDC, I want to run a script to install default applications. Is there any way to do it?

Cheers

Yes, there are several ways to run a script once.
You can create a flag file several ways.  In a batch file you could, for example do this:
Code: [Select]
echo "this is some text">>c:\filename.txt

Then you use the "if exists" method in a batch file to check whether the flag file exists or not.
Check here:  http://support.microsoft.com/kb/65994
If it exists, you know that your procedure has run at least once.

VBScript can also check for the existence of a file.
Here's one article:
http://www.tek-tips.com/viewthread.cfm?qid=1267900&page=5

Or you can go to the big kahuna scripting guide which teaches you all these things.  Microsoft has the entire book online here.
http://www.microsoft.com/technet/scriptcenter/guide/default.mspx?mfr=true

Now to your second question:
Yes, it's possible to install software using a logon script, though you will want to exercise some finesse which is beyond the scope of a board post.  You will want to check for the existence of the software, and you will then want to have a scripted silent install for your application.
The complexity of the automated install is proportional to the complexity of the app you want to deploy.  The success of automated, scripted deployment will depend on how well your script anticipates contingencies, and the success rate will also depend on how standardized your desktops are.

On an Active Directory domain (eBox is not Active Directory; perhaps one day when Samba 4 is ready for primetime it will be) you can use a Group Policy Object to deploy software that uses an .msi installer.

Otherwise, all I can say for certain is that yes, it is possible to do automated application deployment using scripts however doing so requires a great deal of effort and sophistication to pull off, and even then you will probably not achieve a 100% success rate because there are so many variables.
Kind regards,
Rob

vitaliysh

  • Zen Apprentice
  • *
  • Posts: 13
  • Karma: +0/-0
    • View Profile
Re: A simple logon script for Windows clients logging into an eBox PDC
« Reply #6 on: October 14, 2009, 06:46:28 pm »
wow, Rob, BIG THANKS, your answer is EXACTLY what I was looking for =). The only software that is needed to install are Office, Firefox and bunch of other stuff. I already made unattended install scripts for most of them, now it is time for some extended testing.

tbg58

  • Zen Apprentice
  • *
  • Posts: 9
  • Karma: +0/-0
    • View Profile
Re: A simple logon script for Windows clients logging into an eBox PDC
« Reply #7 on: October 14, 2009, 08:56:50 pm »
wow, Rob, BIG THANKS, your answer is EXACTLY what I was looking for =). The only software that is needed to install are Office, Firefox and bunch of other stuff. I already made unattended install scripts for most of them, now it is time for some extended testing.

You are quite welcome.

I'm in the same boat as a lot of others here - I've been a Windows sysadmin for a very long time (pre-WinNT4) and have used Linux (mostly Ubuntu) for several years, but I'm a neophyte with eBox.  But a file server is a file server, and a logon script is a logon script, and there's a lot you can do with scripting.  VBscript is not nearly as strong with regular expressions as something like Perl, but it's a great language for your Windows clients because it's well documented and well integrated with the OS.

Good luck with your deployment.

Kind regards,
Rob
 

tbg58

  • Zen Apprentice
  • *
  • Posts: 9
  • Karma: +0/-0
    • View Profile
Re: A simple logon script for Windows clients logging into an eBox PDC
« Reply #8 on: October 14, 2009, 08:58:50 pm »
wow, Rob, BIG THANKS, your answer is EXACTLY what I was looking for =). The only software that is needed to install are Office, Firefox and bunch of other stuff. I already made unattended install scripts for most of them, now it is time for some extended testing.

Vitaly, takzhe ne mog ne zamyetit' vashe imya i zakhotelos' peredat' privet na russkom.  Vsego vam nailuchego.

Rob

vitaliysh

  • Zen Apprentice
  • *
  • Posts: 13
  • Karma: +0/-0
    • View Profile
Re: A simple logon script for Windows clients logging into an eBox PDC
« Reply #9 on: October 15, 2009, 09:38:59 am »

Vitaly, takzhe ne mog ne zamyetit' vashe imya i zakhotelos' peredat' privet na russkom.  Vsego vam nailuchego.

Rob

WOW =) Bolshoe Spasibo! I vam vsego samogo-samogo!

vitaliysh

  • Zen Apprentice
  • *
  • Posts: 13
  • Karma: +0/-0
    • View Profile
Re: A simple logon script for Windows clients logging into an eBox PDC
« Reply #10 on: October 20, 2009, 09:59:39 am »
I've been improving my logon script (based on tbg58 ;D script) for a while now, and I have a question.

What is the best way to check if software is installed? So far I found only 1 way - check if file exists in default location, but this leads to a lot of IF statements in the code.
Basically I will have to check for every single software I'm trying to install if it is already on PC. I think this is not a way to go.

Example:
Code: [Select]
'----------Silent Install of Firefox-------------'

WScript.echo "Firefox install"
'PFPATH is program files path defined in the beginning of the script
If (fso.FileExists(PFPATH+"Mozilla Firefox\firefox.exe") = False) Then
WScript.echo "Firefox is not installed, proceeding with install"
strCommandText = "msiexec /i "+SERVERPATH"+\NETLOGON\Software\Firefox-3.5.3-en-GB.msi /quiet"
objShell.run strCommandText,1,True
strCommandText =""
Else
WScript.Echo "Firefox is already installed"
WScript.Echo "-----------------------------------------------------------------------------"
End If

'----------End of Silent Install of Firefox-------'

In addition if I have x64 machine I will have to check for special MSI as well...not practical as far as I see.

What I came up with is to separate Software folder on logon server in 2 parts x86 and x64, then make a script that will go through all files in folder and install them.

Example:
Code: [Select]
OsType = objShell.RegRead("HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\PROCESSOR_ARCHITECTURE")
WScript.Echo "Os Type: "+OsType
WScript.Echo "-----------------------------------------------------------------------------"


folderPath = SERVERPATH+"netlogon\software\"+OsType+"\"
Set folder = fso.GetFolder(folderPath)
Set files = folder.Files
WScript.Echo "-----------------------------------------------------------------------------"
WScript.Echo "                      Installing software for "+OsType+" OS                  "
WScript.Echo "-----------------------------------------------------------------------------"
For each folderIdx In files
WScript.Echo "Installing "+folderIdx.Name
strCommandText = "msiexec /i "+SERVERPATH+"\NETLOGON\Software\"+OsType+"\"+folderIdx.Name+" /quiet"
WScript.Echo strCommandText
objShell.run strCommandText,1,True
strCommandText =""
Next

Problem in this code - there is no way to check if software is installed or not.
Maybe there is install switch to check if software is installed? Or get software name from MSI and check against registry of the target machine?

vitaliysh

  • Zen Apprentice
  • *
  • Posts: 13
  • Karma: +0/-0
    • View Profile
Re: A simple logon script for Windows clients logging into an eBox PDC
« Reply #11 on: October 20, 2009, 02:02:23 pm »
Ok another thing, is there any way to list all available shares on the ebox server via vbs? (my google-fu fails =()

tbg58

  • Zen Apprentice
  • *
  • Posts: 9
  • Karma: +0/-0
    • View Profile
Re: A simple logon script for Windows clients logging into an eBox PDC
« Reply #12 on: October 21, 2009, 01:19:26 am »
Privetstvuyu, Vitaly.  Nadeyus', chto vse khorosho u vas.  U vas mnogo voprosov!

Hi Vitaly - hope all is going well with you.  You have plenty of questions to ask!

Question 1:  Is there a way to use vbscript to check whether the Windows OS is 32 or 64 Bit.
Answer:  Yes.  Here's a code segment you can use to check the OS is 32 or 64 bit using Windows Management Interface (WMI).

Code: [Select]
On Error Resume Next

Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20


Set objWMIService = GetObject("winmgmts:\\" & "." & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT AddressWidth FROM Win32_Processor", "WQL", _
wbemFlagReturnImmediately + wbemFlagForwardOnly)

For Each objItem In colItems
wScript.Echo "AddressWidth: " & objItem.AddressWidth

Next

Disclaimer - I know it works on a 32 bit OS running on 64 bit hardware.  I am at the office, and don't have any Win64 software running here; all my 64bit software is Linux of some flavor.  I can try the script at home when I get there - my wife's desktop has Win 7 x64 running on it.


Question 2:  Is there a way to enumerate installed applications?

There are several ways to enumerate installed software (just as there are several ways to do just about anything).  Here's one that uses the Windows Management Interface or WMI to enumerate all the apps.  It's echoing the results out, but you could as easily add each line to a text file, then parse the text file to match strings for a specific app, or you can take the final if statement and use it to parse for a known app value.

Code: [Select]
strHost = "."
Const HKLM = &H80000002
Set objReg = GetObject("winmgmts://" & strHost & _
    "/root/default:StdRegProv")
Const strBaseKey = _
    "Software\Microsoft\Windows\CurrentVersion\Uninstall\"
objReg.EnumKey HKLM, strBaseKey, arrSubKeys
 
For Each strSubKey In arrSubKeys
    intRet = objReg.GetStringValue(HKLM, strBaseKey & strSubKey, _
        "DisplayName", strValue)
    If intRet <> 0 Then
        intRet = objReg.GetStringValue(HKLM, strBaseKey & strSubKey, _
        "QuietDisplayName", strValue)
    End If
    If (strValue <> "") and (intRet = 0) Then
        WScript.Echo strValue
    End If
Next

This will give you results - how to parse the text to match or find what you're looking for is a whole area of study in and of itself.  VBscript can do a lot with parsing text (or regular expressions) but it is not the most powerful tool for doing so.

As I said in an earlier post, you can use a logon script to do application deployments but it requires a great deal of sophistication in your coding to pull it off.   What you might think of as a single app might enumerate as several - for instance MS Office enumerates as several apps - the ones you already know plus several support apps you might not know.  It takes some savvy parsing of text to query the results effectively.

If you can come up with a script that can check for prior installations and deploy apps, then you will have really achieved an impressive task.


Question 3:  Is is possible to enumerate the shares on an eBox from a Windows client using vbscript?

Answer:  Yes, but it's a bit tricky. 

You'll find plenty of examples of how to do it using the Windows Management Interface (WMI), but that doesn't work with Samba shares - WMI is a supply-side query which says, "Hey, server, here are my credentials.  Tell me what shares you have."  WMI isn't implemented in Samba however; an eBox will not respond to a WMI query because you're speaking a language to the eBox it can't understand.  More precisely, it won't answer because it doesn't even have ears that can listen for WMI queries, but enough with imperfect analogies.

To query eBox shares from a Windows host, we have to use a demand-side method here, a way to ask the local Windows box, "Hey, look out on the network and tell me what shares you see on host (servername)."  Since the command is executed locally there is no credential problem.  VBscript as I said is tricky, however you can enumerate the shares with a DOS command you can batch script:

Code: [Select]
net view \\(servername)

This works fine on Samba boxes because it queries the local browser service (don't confuse with a web browser, which is a completely different thing).  This will enumerate all file and printer shares on an eBox.  There isn't a vbscript object to do this, AFAIK.  But to use the net view command in a vbscript, you can use the wscript.shell object to execute the command and output results into a string.  Then you can use your own vbscript to parse the result.  Here's a very simplified example, not including the parsing:

Code: [Select]
Set objShell = CreateObject("WScript.Shell")
' Get list of shares
strServer = "yourservername"
strCommand = "net view \\" & strServer
strResults=""
Set objExecObject = objShell.Exec(strCommand)
Do
WScript.Sleep 60
Loop Until objExecObject.Status <> 0
strResults = objExecObject.StdOut.ReadAll()
wscript.echo strResults

Dumayu chto dostatochno dlya odnogo soobshcheniya.
Nadeyus' chto ehto polezno dlya vas.

By this time you are getting more sophisticated in your scripting - please keep posting your results, as they will be helpful for this community plus others.

A sleduyushchij raz tol'ko odin vopros - zadavaete voprosy kak iz pulemeta!   Skazano s ulybkoj ;-)

Rob

tbg58

  • Zen Apprentice
  • *
  • Posts: 9
  • Karma: +0/-0
    • View Profile
Re: A simple logon script for Windows clients logging into an eBox PDC
« Reply #13 on: October 21, 2009, 01:21:50 am »
Maybe we need to fork this thread over to a new subject line - "What was once a simple logon script..." ;-)

vitaliysh

  • Zen Apprentice
  • *
  • Posts: 13
  • Karma: +0/-0
    • View Profile
Re: A simple logon script for Windows clients logging into an eBox PDC
« Reply #14 on: October 22, 2009, 03:38:56 pm »
Приветствую! =)
Hello! =)

Ok, so far only thing I've done is parsing all available shares on the server and mapping them to the local client, everything seems to work fine. Did it via net view as suggested and then fetching all share names from net view output.

Here how parsing was done (quick-explanation):
Net View output:
Code: [Select]
Shared resources at \\liberty

vitaly Server

Share name             Type  Used as  Comment

-------------------------------------------------------------------------------
cip_pub                Disk  E:       cip share directory
Dev                    Disk  F:       Dev share directory
ebox-internal-backups  Disk
ebox-quarantine        Disk  G:
mng                    Disk           Mng share directory
Public                 Disk  H:       Public folder
vitaly           Disk  I:       Home Directories
www                    Disk  J:       Web Server
The command completed successfully.
From the output of the net view we can see that the first share name starts from new line after '-' character and if you look at the output in ascii '-' char followed by CarriageReturn and LineFeed ascii codes.
Thus function (fetchShares(string)) first looks for '-' char followed by CR and LF. As soon as it finds 3 consecutive characters it starts adding all next characters to the buffer until whitespace character is reached (AFAIK you can't have whitespaces in share name).
If whitespace character is reached move contents of buffer to the Shares array and continue with traversing of the string until next LF ascii code found.
As soon as we get next LF we can start parsing next share. Do until end of file. In the end of the function, remove last 3 elements of array, because they are parts of the last line from the output The command completed successfully.
Result of this function will be array of shares:
Code: [Select]
cip_pub
Dev
ebox-internal-backups
ebox-quarantine
mng
Public
vitaly
www

Whats left is just going through array and mapping all shares to the user  ;D

Tested on Vista/XP

Code: [Select]
Option Explicit

Dim objNetwork, objFileSys, objShell, objSystemDrives, objExecObject
Dim arrShares
Dim strShare, strDriveLetter, strCommandText, strResults,strRemotePath

Const SERVERPATH = "\\liberty\"

Set objNetwork = Wscript.CreateObject("Wscript.Network")
Set objFileSys = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("Wscript.Shell")
Set objSystemDrives = objFileSys.Drives

strCommandText = "net view " & SERVERPATH
strResults=""

Set objExecObject = objShell.Exec(strCommandText)
strCommandText =""

Do
WScript.Sleep 60
Loop Until objExecObject.Status <> 0

strResults = objExecObject.StdOut.ReadAll()
arrShares = fetchShares(strResults)

For Each strShare In arrShares
Call MapDrive(strShare)
Next

wscript.quit

Function MapDrive(strShare)

'Find next available drive letter
'TO-DO What if all drive letters are already taken? Add guard to prevent further mapping

strDriveLetter = Asc("c") 'Convert CHAR C to ASCII code
While objFileSys.DriveExists(Chr(strDriveLetter)+":") 'Increase ASCII code index by 1 until free letter is found
strDriveLetter = strDriveLetter+1
Wend

strDriveLetter = Chr(strDriveLetter) + ":" 'Convert ASCII code back to character and concatenate : to it
Wscript.Echo "The next available drive letter is "+strDriveLetter
strRemotePath = SERVERPATH&CStr(strShare)
strRemotePath = CStr(strRemotePath)

If(objFileSys.FolderExists(strRemotePath)) Then
objNetwork.MapNetworkDrive strDriveLetter, strRemotePath 'map the drive
Else
WScript.Echo " is memeber of the group, but no folder found"
End If

End Function

Function fetchShares(str)
    Dim i 'current position in string
    Dim asciiChar 'current string character converted to ascii
    Dim startFound, parse 'bool
    Dim strShare 'share name
    Dim arrayPosition 'position in array of shares
    Dim Shares() 'shares array
    
    'init default values
    arrayPosition = 0
    parse = False
    startFound = False
    
    For i = 1 To Len(str)
    
     If (startFound=False) Then
     asciiChar = CStr(Asc(Mid(str, i, 1)))+CStr(Asc(Mid(str, i+1, 1)))+CStr(Asc(Mid(str, i+2, 1)))
        Else  
         asciiChar = CStr(Asc(Mid(str, i, 1)))
        End If

        If (asciiChar = "451310") Then 'match char '-' Line Feed and Carriage Return -> at this stage next char will be first letter of our share name
         parse = True ' allow parsing
         startFound = True 'start of share list found set flag to true
         i=i+3 'increase i by 3 to skip - LF CR
        ElseIf ((asciiChar = "10") And (startFound)) Then 'if current character in Line Feed and we already found start -> start parsing
         parse = True
         i=i+1
        End If

If ((parse)) Then
While((asciiChar <> "32")) 'While character is not ' ' parse chars to out strShare buffer
If(i=Len(str)) Then 'safeguard if we reach end of file
asciiChar="32"
Else
asciiChar = CStr(Asc(Mid(str, i, 1)))
If (asciiChar <> "32") Then 'If character is not whitespace add it
strShare=strShare+ Mid(str, i, 1)
End if
i = i+1
End if
Wend
ReDim Preserve Shares(arrayPosition) 'increase array size
Shares(arrayPosition)= strShare 'add new share to array
arrayPosition = arrayPosition+1
parse=False
End If
strShare =""
    Next
    
    ReDim Preserve Shares(arrayPosition-3) 'remove 3 last items of array -> it is rubbish I had no time to tune parser, will do later, works fine anyways
    fetchShares = Shares    
End Function

Next -> application installation. Will update tomorrow or day after.

PS If this is not efficient parsing in VBs - sorry, this is my first week with VBs and I had no time to go through documentation in details  ::)
PPS Only one question so far - where is decent VBs documentation and is there any intellisense editor on for VBs =)
« Last Edit: October 22, 2009, 03:43:40 pm by vitaliysh »