XML Driven Logon Script
What is a XML Driven Logon Script you ask? It is a VBScript based logon script which behaviour (like mapping network drives, installing printers) is controlled from an xml file. This makes it easy for the none-programmer to build and manage logon scripts within his or hers organisation, since no knowledge of VBScript is needed.
Here is a rundown of the main features of the XML Driven Logon Script:
- Separation of code and rules. The script file (Logon.vbs) contains all the functions and objects that performs the actions defined in an xml file (logonrules.xml). Unless a new feature is needed, a change to the behaviour of the logon script is done completely in the xml file.
- Control behaviour of the logon script by defining filters and actions in xml file(s). Build action sets that are selected based on one or more filter, filter by Active Directory security groups, usernames, computer names and more. Actions include ability to map network drives, add network printers, copy files and more. See the documentation for more details on available filters and actions.
- Logging direct to the executing computers Event Log. All information gathered by the script and all executed actions are logged to an entry in the Event Log on the computer running the script, making it easy to debug and find errors.
- Friendly Internet Explorer window used to display messages to users. Among other things, the logon script will display a friendly message about each action performed during execution and tell the user how long until his or hers password expire.
The script itself was just recently reorganized to make it more versatile, so there might be a minor bug here and there, but the tests I have performed so far looks very good.
Go to the download section to get the latest version of the script, and take a look at the documentation section for a more in-depth examination of the features and configuration options in the script.
Please post any comments, suggestions, etc., in the comments on this page.
February 16th, 2008 at 13:18
hi, is it possible to contact you directly? If have some questions.
would be great to talk to you.
your script rocks
February 16th, 2008 at 15:00
Thanks Tony.
I just send you a mail, looking forward to hearing from you.
April 7th, 2008 at 16:05
Hi
Sorry for spamming you website today, but i’ve got every thin working now i only have one question
is it possible to call a logon.htm page insted of the html inside the .vbs – i would like to ad a logo on the top, and maby put in som tables so i can create a proper layout or is it possible from within the vbs, im sorry but im not used to work with vbs or xml .. Thanks
Kenneth
April 9th, 2008 at 9:44
Hi
i also have a few questions, that i would like to ask, can i also contact you directly?
Thanks Kennneth
April 13th, 2008 at 13:41
Hi Kenneth
I’ve been away with exams, sorry for not getting back to you. I would have to make an extra method that would read the content of a .html file and have the IE object print it out, so in a way it is certainly possible to attach a header.html file or similar.
I am a bit overworked the next days, but I will look into making it possible to attach a html file.
April 14th, 2008 at 13:03
HI
actually no need, I’ve managed to get what I wanted using .WriteLN (“link to logo”)
- I do however have another question – or 2 ..
1. Using CopyFile, is I possible to just check if a file exist, and no whether or not it has been changed? – it’s for Navision, and it contains Server information, but users personal changes will also be written in this file, and theses settings have to be saved. But I would still like to check if the file is there.
Also is it possible to use the variable %logonserver% like this (we have 4 servers in 4 different locations) I haven’t been able to get this to work
But i must say it is really nice your script
April 14th, 2008 at 13:48
Hi Kenneth
Thanks for the feedback. I like the idea of allowing a separate .html file to be inserted at the top of the Internet Explorer window. It should also make it much easier to style the content.
In regards to the %logonserver% wildcard, yes, I have been planning to add it and a few others, since the script gathers the information anyway.
However, if you need to point to the \\your-dc\netlogon share, you can simply use the DFS share that is automatically set up, e.g. \\your-fully-qualified-domain-name\netlogon
Either way, I will add more wildcards as soon as I have a free half hour
In regards to the CopyFile action. If the destination file does not exist, a new one is copied. But I suspect you know that and want a CopyFileIfExists action, which will only copy a file if it exists at the source. Is that what you are looking for?
April 14th, 2008 at 15:22
cool I’ll use the FQDN.
about the copying, im rather looking for a CopyFileIfNotExists action.
here’s challenge today (source and destinations “last modified” file-attribute is different.)
The file i’m copying is being used to decide screen res. last logon etc. etc.
so the atributes is changed, and a new file is being copied at next logon
i hope im making sense?
Feel free to email me – also in danish if you prefer
Thanks
Kenneth
May 8th, 2008 at 12:44
When ever an error comes up the following message comes up
“There where one or more error’s during execution.”
the ‘where’ is without h.
May 8th, 2008 at 13:04
doh, thanks Casper. Weird that nobody have caught that, including myself, before. Been using that sentence for about 2-3 years now
May 9th, 2008 at 9:07
Talking about “spellingerror” or just a spacebar that didn’t work…
There’s missing a space in the following:” The difference between when the password was last setand today is 43 days”
’setand’ = ’set and’
Is there a setting in version 4 that makes it possible for the logonscript to ignore the ‘error” – ‘Error: Unable to map x: to \\server\netlogon’.
I get alot of errors when I’m mapping drives eventhough the map is still mapped. Even from PC’es that have been fully shutdown and have no open files on that serverdrive.
As you can imagine that equals loads of calls to the IT department for no apparent reason
May 9th, 2008 at 10:20
haha Casper. I see a pattern emerging
I could definitely add a constant at the top of the script that would cause all errors to be suppressed, but I am more interested in figuring out why you are getting the errors. My best guess is that it is when the MapDrive function tries to unmap an existing connection. Have you tried running the script on a computer with no previously mapped drives?
Update: I just uploaded version 4.00k, try that out and see if it works better Casper.
May 23rd, 2008 at 11:23
So far it seems to work succesfully.
Was wondering if there’s an option not to show the loginscreen at all?
We’ve already set the time of which the logonscreen disapears down to 5 sec instead of 10.
May 23rd, 2008 at 11:35
Good to hear Casper. Regarding running the script silent, call the script with the /silent switch, then it will not display a internet explorer window at all. It will still log all execution to the event log on the computer.
Have a look in the Script settings & command line parameters for more command line parameters.
June 12th, 2008 at 13:31
Really good work, I’ll definitely have a deeper glance. Keep it up.
June 12th, 2008 at 14:38
Hi Sidar
Thanks, please post any feedback you might have.
September 23rd, 2008 at 12:40
I have the following code from KIX32 I’d like to convert to your script but I cannot find the description for this.
Use S: “\\SERVER\SHARE” /user:SERVER\USERNAME /password:PASSWORD
I know I have to use something like this:
But cannot find a description about an option to put a username and password with mapDrive.
September 24th, 2008 at 8:45
Hi Casper
There is no way to specify a user name and password. And you should never do that in a plain text file like the XML rules file, especially since that file is most likely placed in a rather public share like \\Domain\NETLOGON – which renders the point of having a user name and password irrelevant.
The script assumes the user logging onto computer is part of a domain, which means you can also assign access rights through NTFS ACLs on the shared folder directly, and thus do not need to specify a user name and password. That is by far the recommend way of doing things.
If the share is on a none Windows server, where you can not authenticate against the domain, and you need the data to be secure, I would look in to setting up a automated copy/move process of the data to a server that can be protected with NTFS security. That way only the copy/move process needs to know the security credentials to the original share.
Hope this helps, Egil.
October 9th, 2008 at 21:06
Hi Egil,
I was researching in order to write an XML+VBScript based logon script for may company when I run into yours. After a few minutes i decided to adopt yours as it’s already doing most of what I wanted it to.
Now, I have made a few changes to it and it’s only fair that I offer them back to you.
The changes I made are:
1) added a variable for the sitename (so we can use it when specifiying servers) as we are geografically distributed company and we map stuff to the local servers.
2) Re designed a litle the HTML to add our company logo and put the user information in a table instead of plai text.
3) modified the group selection in order to pull the group information from multiple domains, and not just the current one.
4) created a simple XLS to show the current values in a more understandable way.
If you think that the changes and you think that someone else might like them, let me know (you should have my email in this post) and i’ll send them to you.
October 10th, 2008 at 8:47
Hi marianok
That is very cool. I always like it when someone build upon then script. You should get a mail from me soon, would love to discuss the additions you have made.
January 8th, 2009 at 17:53
Hi,
I try to map a drive, but have this error:
Line 463
Char 9
Error: This key is already associated with an element of this colletion
Thanks,
January 8th, 2009 at 17:56
I have vbscript error on try the map a drive: line 463, char 9, error: This key is already associated with an element of this collection.
Thanks,
January 8th, 2009 at 17:57
Need help, but Duplicate comment detected; it looks as though you’ve already said that!
January 8th, 2009 at 17:58
Map drive : error line 463 char 9 This key is already associated with an element of this collection
January 8th, 2009 at 18:22
Sorry about this spam, maybe cache problems
January 9th, 2009 at 11:37
Hi Leao:
The line you are getting the error in, has nothing to do with the mapping of a drive.
The line of code adds each active directory security group to a dictionary for lookup later, it looks like you have two security groups with the exact same name, something I have never come across before.
Try testing with a new user, who is not a member of any security groups besides the default Domain Users.
January 12th, 2009 at 12:11
Hi,
It’s true, isn’t not a map drive. I have active the debug mode and make a various tests, and the error occurs when the script try get the distribution group (doesn’t detect distribution group) from a standby dc (not a master dc)… But I have make a restart on all dcs and now it’s work. (estrange)
How I can use the distribution group to make a filterset? There are exist registry filterset or action?
Thanks,
January 12th, 2009 at 13:18
You would have to add some code to the GetGroupMembership sub, that would get a list of distribution groups the user is a member of and possibly create a new filter. There is not any existing filter that you can apply I am afraid.
Alternatively, you can upgrade your distribution groups to security groups. To do that, I am pretty sure you have to have a domain that’s running in 2003 native mode on the forest level.
Hopo this helps, Egil.
March 9th, 2009 at 23:46
Hello Egil,
Great work on this script! I had been considering splitting our logon script code from the functions and rules for a while.
I noticed a couple of minor issues in the ‘ReplaceWildCards’ function and thought you would like to know about it:
1. %Fonts% is being set twice
2. %PrintHood% is not set at all
Also, one other thing: In our environment we have a need to set IPC connections and also to map drives using alternate credentials. I have reworked your ‘MapDrive’ class a bit to accommodate these requirements. If you would like to see the updated code just let me know.
Best regards,
Ken
March 10th, 2009 at 11:22
Hi Ken
Thanks for the feedback. I will drop you a mail later today, would love to see your code. I hope to get a chance to actually update the script with some of the feedback I have been getting from various people the last year.
June 3rd, 2009 at 17:15
Dear Egil
I must admit, your logonscript is one of the best I have seen so far. Is it still under active development ?
If so could you please add the following features ?
- %userprofilepath% = Users Profile Path
- %userhomedirpath% = Users Home-Directory Path
- %userhomedrive% = Users Home-Directory Drive (e.g. H:)
Actions:
RemoveNetworkPrinter = Would remove a specific network printer
RemoveAllNetworkPrinters = Would remove all network Printers
Maybe an additional option for AddPrinter would be nice as well (removebeforeadd = true¦false)
Would it be possible to extend teh TestFilter (for Computers) in a way you could test the OU name a computer object is stored in ? I need this for printer assignment. All PCs in the same OU (Room OU) get a specific Printer assigned.
Kind regards,
Oliver
June 3rd, 2009 at 18:21
Dear Oliver
Thank you for the input. I would be pushing the term “active development” if I said that it was. I have received some great input from a few others as well and would love to write an updated version of the script. With a bit of luck I might get to it during the summer, but no guarantees
If you decide to extend the script yourself with some of the functionality you talk about, please send me a copy of what you figure out.
Regards, Egil.
June 4th, 2009 at 16:45
Dear Egil
I have implemented most of the stuff I mentioned above
%userhomedirectory%
%userhomedrive%
%userprofilepath%
New Actions:
Modified Filters:
They now can check against the OU where an object (user, group) is stored in.
“name” can now handle DNs as well. Example
It auto-detects if it is a real name or a DN and compares accordingly.
Added internal variables for
Computer Objects OU
Users OU
I had to slightly change the DTD of the XML file.
Can you send me your email so I can send you back the code ?
Especially the DTD definition of the “ou” attribute is special. As I am not a XML DOM crack
I would like to know what a real crack has to say about this implementation and if it could
be solved easier or cleaner.
Regards,
Oliver
June 4th, 2009 at 16:49
Upppsss…. There has been a lot more text but the blog cut it out because I used XML syntax…..
So send me your email address and I send you the text and code.
Regards,
Oliver
June 4th, 2009 at 19:10
Dear Oliver, you should receive a mail shortly, thanks for the work.
July 1st, 2009 at 13:32
Dear Egil
Your script incl. my modifications works fine so far…
But I would be interested in the changes from:
- Ken Knicker (March 9th 200) : http://www.egil.dk/xml-driven-logon-script/#comment-275
- marianok (October 9th) : http://www.egil.dk/xml-driven-logon-script/#comment-218
Can you send them to me ?
Regards,
Oliver
July 2nd, 2009 at 6:13
Hi All
I am trying this out and it works great. I am trying to create dtd file for the xml file, but strugling a big load on this, is there an dtd file out there for this xml file?
Thanks all
July 2nd, 2009 at 10:07
Oliver:
I am working on an updated version that will include the updates Ken, Marianok and you provided, hopefully I will be done with it over the weekend.
If you can wait a little bit, I will have something for you then.
Jacob:
There is a DTD included in the XML file right now (at the very top), are you trying to put the DTD in a separate file?
July 6th, 2009 at 2:52
Hi Egil
Thanks for the reply, found it, stupid me…
July 21st, 2009 at 21:30
Hello Egil,
Very nice script,
Is there a way to see if a computer is part of a group not the user?
TIA
James
July 22nd, 2009 at 13:36
Hi James
Thanks!
No, there is not a filter that will look at a computers security group.
A work around is to assign the script to the computers using group policy, and then use filters when applying group policies.
July 30th, 2009 at 6:39
Hello Egil,
Saw your comment re: working on an updated version via RSS feed for this thread and thought I would check in and ask how development is going and post a few updates re: our implementation of your script (based on the current version, 4.00k)
I’ve recently added code to check the domain membership of the workstation. We needed this because we have multiple domains and ran into situations where a workstation is in one domain and the user is in another.
Another is an update to the routine used to populate the dictionary object with user’s group membership information. It now checks to confirm the entry is not already in dictionary object prior to adding it. I’m pretty certain this is the same thing that Leao Bras described in this post: http://www.egil.dk/xml-driven-logon-script/comment-page-1/#comment-248.
In our situation, we saw the error on users that are members of a domain which is being replaced. As part of that project, user objects and groups from the original domain were copied to the new domain. Because the new domain is visible to the script, during the AD interrogation step performed by “GetGroupMembership”, the script would report “This key is already associated with an element of this collection.”
I believe we could have handled this by requiring user and group names to be fully qualified (i.e.: Instead of “myusername”, make it “mydomain\myusername” or “myusername@mydomain.com”). Another option was to include an “On Error Resume Next” just prior to the loop that populates the dictionary object but that’s really not my style
.
Other updates we’ve made include:
- Forcing silent mode for all Citrix sessions
- Obtaining home drive info to support users logging in via VPN
- Addition of a “Warning” category for success/fail results. This allows special formatting of events posted to the IE status window but doesn’t prevent the IE window from closing.
- Ability to handle situations where an attempt to map a drive that is already assigned to a local system drive letter (these are flagged as a “Warning” instead of “Error”). This was done primarily to accommodate logging on to servers via Remote Desktop.
We’ve begun deploying to users across the enterprise as a replacement for the various logon scripts developed by separate IT groups at different locations — sort of a “one script to rule them all” idea. Things are going well overall.
Something I’m interested in now is identifying any unused bits, redundancies, and general optimization. Would you be interested in having a look at our latest efforts?
Thanks,
Ken
July 30th, 2009 at 9:20
Hi Ken
It sounds very cool what you are doing.
I am still working on my new version, it is a total rewrite, based mainly on jscript. Basically I am trying my best to make the new version very modular, so you only include the parts you need. If you for example don’t need to map a network drive, you do not include the code to do that, nor the code to parse the map drive xml.
The added bonus is that it makes it very easy to add new actions, without touching the core logic of the script.
If you have the time, please post your version of the script on your blog, I will gladly link to it on this page, so people can get their hands on a more updates version than the one currently on this site.
September 30th, 2009 at 8:44
We’re now running a Multi-language version of Windows XP (with DK layout) which shouldn’t have any connection to the problem though the problem didn’t exist on our old DK installation.
The problem only occurse when the logon script is run with the /silent parameter it seems and what’s worse. It’s only very few machines that gets an error.
The error message is: “The procedure entry point GetProcessImageFileNameW could not be located in the dynamic link library PSAPI.DLL”
I’ve tried to google it and the problem exists in a number of applications. I have reason to believe it’s our new IE7 installation that gave us the problem since its one the applications that gives this problem. I just don’t understand why this only happens when I use the “/silent” parametre with your logon script and even why its only on a handfull of PCs?