SyncDir

Logon script examples

On this page we will assume that you have read the article "Setting up logon scripts" and have setup your logon scripts. These examples assume that you put the content in the prelogon.fsh script file that executes before the explorer starts. You could put all or some of the content in your PostLogon.fsh file, but then it would be executed after the users' explorer process starts.

This page will present some practical examples for logon script content. Learn how to determine location, connect printers and shares and more.

This page will not go through running backups and automated installations through logon scripts, as these have separate pages. Please have a look at this page for information on running backups at logon and this page for automated installations through logon scripts.

Simple logon script

Let's take a look at an extremely simple logon script that could be the logon script for a small single office company, just to get the basic understanding. The complete prelogon.fsh could look like this:

''==== SHOW WELCOME SCREEN ====

Splash Welcome to ACME Corporation,[UserFullName]

 

''==== CONNECT SHARES ====

ConnectShare J:,\\AcmeServer\CommonShare

ConnectShare [UserHomeDrive],[UserHomeDir]

If UserIsMemberOf SalesStaff Then ConnectShare J:,\\AcmeServer\SalesShare

 

''==== CONNECT PRINTERS ====

ConnectPrinter \\AcmePrintServer\AcmePrt001

ConnectPrinter \\AcmePrintServer\AcmePrt002

 

''==== SET CLIENT TIME ====

SetTimeFromServer

With these few script lines we have:
- Displayed a nice welcome screen. Optionally, we could have provided a corporate logo as a third parameter.
- Connected a common share, the user's personal share and a common sales personnel share.
- Connected the two printers at the office.
- Synchronized the computers' time.

For most companies this is obviously not enough functionality for a logon script. In the next sections, we will look at, how we can add more complex functionality.

Connection based on groups

If we look at a company that is slightly bigger, multiple locations will exist and we will need more logic to determine what printers to connect. For example, if the company's office building has multiple floors, printers must be connected at the correct floor. A logical way to determine which printers to connect would be to put computers or users in groups based on their physical location. As the users may roam around the floors and borrow other users' computers from time to time, we will connect printers based on the computers' group memberships and shares based on users' memberships. So we could expand our above logon script with something like this to connect more shares and connect printers based on the computer's group memberships:

''========= USER-BASED CONNECTIONS =========

If UserIsMemberOf Management Then ConnectShare L:,\\AcmeGlobal\Management

 

If UserIsMemberOf SalesStaff Then

  ConnectShare J:,\\AcmeGlobal\SalesShare

  ConnectShare K:,\\AcmeGlobal\SalesExt

End If

 

''========= MACHINE-BASED CONNECTIONS =========

If ComputerIsMemberOf HoustonPCs Then

  ConnectPrinter \\AcmeSrvHouston\AcmePrt002

  ConnectPrinter \\AcmeSrvHouston\AcmePrt008

  ConnectPrinter \\AcmeSrvHouston\AcmePrt018

  SetPrinterDefault \\AcmeSrvHouston\AcmePrt018

End If

 

If ComputerIsMemberOf SeattlePCs Then

  ConnectPrinter \\AcmeSrvSeattle\AcmePrt019

  ConnectPrinter \\AcmeSrvSeattle\AcmePrt021

  SetPrinterDefault \\AcmeSrvSeattle\AcmePrt021

End If

 

If ComputerIsMemberOf LosAngelesPCs Then

  ConnectPrinter \\AcmeSrvLosAngeles\AcmePrt024

  ConnectPrinter \\AcmeSrvLosAngeles\AcmePrt026

  ConnectPrinter \\AcmeSrvLosAngeles\AcmePrt027

  SetPrinterDefault \\AcmeSrvLosAngeles\AcmePrt024

End If

For a practical example of connecting printers based on groups, please refer to this case study, where a consultancy company also creates a corporate Microsoft Outlook signature and installs standard applications through a logon script.

Connection based on groups and included script files

If this company was much bigger, the above script will be extremely long, and thus not very scalable. We use of Active Directory groups to connect certain shares for certain people, but it is not too easy to get a clear picture of what is actually connected for whom. A more scalable approach is to use the Active Directory group information to run scripts instead. Consider this example:

Loop Group,[UserGroups]

 IF FileExists GroupScripts\[Var Group].fsh Then Include GroupScripts\[Var Group].fsh

End Loop

These three lines will make life much easier for you. Create a directory called "GroupScripts". For each user that logs in, it will execute all the scripts that have the same name as one of his or her groups. Each file would then contain a "ConnectShare" script line, but you can do more, like synchronizing document templates to the user's documents template folder, or whatever you want done for users in a specific group.

If we want to connect printers based on computer groups, we could simply have two loops, one for the user groups and one for the computer groups:

''========= USER-BASED CONNECTIONS =========

Loop Group,[UserGroups]

 If FileExists UserScripts\[Var Group].fsh Then Include UserScripts\[Var Group].fsh

End Loop

 

''========= MACHINE-BASED CONNECTIONS =========

Loop Group,[ComputerGroups]

 If FileExists ComputerScripts\[Var Group].fsh Then Include ComputerScripts\[Var Group].fsh

End Loop

And then the printer connection script lines would go into the per-machine group scripts. You can also modify the above examples to do the same based on Organizational Units using the "ComputerIsInOU" and "UserIsInOU" conditions.

Determining location

If we scale up one more time and look at a really big company, a new problem arises. Lots of people have laptops and they roam on different locations. This would not be a problem for a single location company, because the laptop would typically be docked at a fixed location, while at the office. But for larger companies, laptop users may roam on different locations and only have a fixed location at the "home" location.

So while the Active Directory will tell us where a person or computer is supposed to be, it doesn't help in this scenario. There is only one thing that will tell us where a computer is at, when the logon script executes and that is the IP address. So if a share is to be connected only when users are at a certain location (ip address scope), the InIpScope condition or the IPAddressPart function can be used like this:

If InIpScope 172.18.0.0,172.18.255.255 Then ConnectShare H:,\\AcmeHouston\CommonShare


Prompting the user for printers

If you only want to automate share connections and not printer connections, there is a much simpler approach to connect printers: Simply ask the user. Suppose we had this at the bottom of prelogon.fsh:

''==== SHOW MENU ====

SetMenuDefault [RegistryValue HKCU\Software\Acme Corp\CurrentPrinters]

Set Printers=[Menu Select printers,Printer|1. Floor left,Printer|1. Floor right,Printer|2. Floor left,Printer|2. Floor right,Printer|Reception]

 

''==== REMEMBER SELECTION ====

If Not VarIsEmpty Printers Then WriteRegistry HKCU\Software\Acme Corp\CurrentPrinters,[Var Printers]

 

''==== EXECUTE CONNECTION ====

Switch [Var Printers]

  Case 1. Floor left

    ConnectPrinter \\AcmePrtSvr\AcmePrt022

    ConnectPrinter \\AcmePrtSvr\AcmePrt024

  Case 1. Floor right

    ConnectPrinter \\AcmePrtSvr\AcmePrt031

    ConnectPrinter \\AcmePrtSvr\AcmePrt033

  Case 2. Floor left

    ConnectPrinter \\AcmePrtSvr\AcmePrt004

    ConnectPrinter \\AcmePrtSvr\AcmePrt058

  Case 2. Floor right

    ConnectPrinter \\AcmePrtSvr\AcmePrt011

    ConnectPrinter \\AcmePrtSvr\AcmePrt015

  Case Reception

    ConnectPrinter \\AcmePrtSvr\AcmePrt001

End Switch

...then the user would see this at every logon:

Printer selection menu

Observe how the selected choice is stored in the registry and is then fed to the "SetMenuDefault" command, so the user could effectively just press return to keep the current printers. There are two versions of all menus, one that forces the user to select and one that allows cancel. In case of cancel, the returned value is blank.

If the list was longer, it may be a better idea to use the ListMenu function instead of the Menu function. To show forced input, the ListMenuForced function is used here:

Graphical list with FastTrack Scripting Host

Now while this is nice and simple, the user might find it a bit annoying to be asked at every logon. So we could alternatively not ask them and place an icon on their desktop that starts the menu on demand instead. If we instead placed the above script snippet in a new file called PrinterMenu.fsh and placed that in the same directory as prelogon.fsh on the netlogon share, then we could just place this line in the prelogon.fsh to install the desktop icon at logon:

CreateShortCut [UserDesktopDir],Select Printers,[FastTrackPath]\PrinterMenu.fsh

If the user then deletes the desktop icon, then it's simply created again at next logon. You may be wondering why the path to the script file is prefixed with the "FastTrackPath" function. We could have created a shortcut to the netlogon location, but the FastTrackPath function will give us the location of the executing fsh.exe and as FastTrack Logon has synchronized the needed netlogon files locally to preserve bandwidth, we might as well use the local copy. As fsh.exe, prelogon.fsh and our PrinterMenu.fsh script are in the same directory on netlogon, they will also be in the same directory in the client cache and thus the FastTrackPath function will give us the directory of the local copy of the PrinterMenu.fsh file.

Further down this page there is an extended version of this script. Be warned though that that example is very advanced and very hard to understand, if you are new to FastTrack Scripting Host.

FastTrack Inventory

If you don't have a management system, you don't know what is installed on what computers, who has what computer or what hardware is in which computer. FastTrack Scripting Host 7.1 comes with a cloud-based inventory system that has no setup steps. Simply issue this one command in your logon script:

UploadInventory

With this one command in your logon script, you will have full hardware and software inventory of your computers. FastTrack Inventory has no additional cost; it just requires your clients to be licensed and within maintenance period. Refer to this page for more information on FastTrack Inventory.

Logon script summary

The rest of this article contains very advanced logon script functionality that is relevant only to very large companies. If you intend to use some of the material presented further down this page, it is still highly recommended to start by setting up a simpler logon script, based on the above information, to be sure that the basic setup is in order and working. In either case, the below video is highly recommended as a sum-up of the material above. Press play below to watch Senior Technical Writer Steve Dodson from Binary Research International walk you through the material above.



Advanced location determination - using IP tables

Let's go back to one of the previous sections, where we determined location based on IP address. In this section we will go through an advanced version of that, where we use information in an xml-based ip table file instead of using hard-coded ip addresses in the scripts, which is a better solution for companies with lots of IP scopes.

A common setup is to have the same share with the same common data and maybe some programs replicated to a server on each location. To find out which one is closest, you can of course write more if-statements, but if you have more than a couple of locations, this is not a smart solution. Instead, create an XML file and put it in your logon script folder with the information you need, like this:
<?xml version="1.0"?>
<Acme>
  <Locations>
    <Scope_172.18 Name="Houston" Server="HoustonServer" />
    <Scope_172.19 Name="Dallas" Server="DallasServer" />
    <Scope_172.20 Name="Los Angeles" Server="LAServer" />
    <Scope_172.21 Name="San Fransisco" Server="SFServer" />
    <Scope_172.22 Name="Seattle" Server="SeattleServer" />
  </Locations>
</Acme>
In the logon script you can use this information to determine the location. So the first few lines of your logon script could look something like this:

''==== DETERMINE LOCATION ====

SetVar LocationName,[XMLAttribute Locations.xml,Acme/Locations/Scope_[IPAddressPart 2],Name]

SetVar ServerName,[XMLAttribute Locations.xml,Acme/Locations/Scope_[IPAddressPart 2],Server]

 

''==== SHOW WELCOME SCREEN ====

Splash Welcome to ACME [Var LocationName],[UserFullName]

 

''==== CONNECT THE LOCAL SHARE ====

ConnectShare O:,\\[var ServerName]\Data

 

''==== WRITE LOCATION BASED INFORMATION, SO OTHER APPLICATIONS CAN GET IT ====

WriteRegistry HKCU\Software\Acme\Location\Name,[Var LocationName]

WriteRegistry HKCU\Software\Acme\Location\Server,[Var ServerName]

This will display for instance "Welcome to ACME Los Angeles" and will then connect the Los Angeles server share, if that's where the user is. You could extend the attributes with more information about the location in the XML file as needed, with just one extra script line being required to get each.

Automatic location based printer connection

So we have established where the user is. But people at opposite ends of a fairly large building are not going to want to use the same printers, so we need a little help from the user, but we will only trouble them once per location or if they want to change printers within the location.

The best way to do this requires more complex scripting. However, this is probably the most complex script you will ever need. Firstly, we need to create a repository that contains printer information and for this we will simply expand the XML file like as follows (the last three locations would, of course, also have printers):
<?xml version="1.0"?>
<Acme>
  <Locations>
    <Scope_172.18 Name="Houston" Server="HoustonServer" />
    <Scope_172.19 Name="Dallas" Server="DallasServer" />
    <Scope_172.20 Name="Los Angeles" Server="LAServer" />
    <Scope_172.21 Name="San Fransisco" Server="SFServer" />
    <Scope_172.22 Name="Seattle" Server="SeattleServer" />
  </Locations>
  <Printers>
    <Houston>
      <PrinterSite Name="Houston Building 1. Floor" Printers="\\HoustonServer\Printer01,\\HoustonServer\Printer02"/>
      <PrinterSite Name="Houston Building 2. Floor" Printers="\\HoustonServer\Printer03,\\HoustonServer\Printer04"/>
    </Houston>
    <Dallas>
      <PrinterSite Name="Dallas Building Reception" Printers="\\DallasServer\Printer01,\\DallasServer\Printer02"/>
      <PrinterSite Name="Dallas Building 1. Floor" Printers="\\DallasServer\Printer03,\\DallasServer\Printer04"/>
    </Dallas>
  </Printers>
</Acme>
But be careful! A malformed XML file will cause runtime errors, so be careful when modifying the file. This simplest way to test if it is malformed or not is simply to logoff and logon again on a workstation and check that is still shows the location in the splash.

We have now defined sub-locations for each site. We now want to accomplish this:
- The first time users logs on at each location, they should be asked which printers they want.
- The user must have a shortcut in order to get the menu again and to re-select printers.
- If we change the printers in the list, we want such changes to be enforced automatically on all clients.

This is achieved in three steps; one for each of the above. The first step is to detect when a user enters a location for the first time. If they have logged in on that location before, the changes need to be enforced. So, in the logon script, we do this:

If [RegistryValue HKCU\Software\Acme\Sites\[Var LocationName]\PrinterSite]=[Blank] Then

  RemoveSplash

  Include PrinterConnect.fsh

Else

  Include PrinterReconnect.fsh

End If

If UserOnce PrinterShortcut Then

  CreateShortcut "[UserStartMenuDir]","Select Printers",[FastTrackPath]\PrinterConnect.fsh

End If

The first time the user logs on to the site, PrinterConnect.fsh is executed because the registry key is unique for each location. A menu of choices will be displayed. For every user on the network we create a shortcut to reconnect the printers that point to PrinterConnect.fsh, which will contain these four script lines:

SetVar LocationName,[XMLAttribute Locations.xml,Acme/Locations/Scope_[IPAddressPart 2],Name]

SetVar XmlLocations,[XMLMultiAttributes Locations.xml,Acme/Printers/[var LocationName]/PrinterSite,Name]

SetVar SelectedPrinters,[ListMenuWithoutCancel Select location,[Var XmlLocations]]

WriteRegistry HKCU\Software\Acme\Sites\[Var LocationName]\PrinterSite,[Var SelectedPrinters]

Include Reconnect.fsh

Observe that we read the locations off the registry. This is because you don't have the variable if you start this script from a shortcut. The last part is the actual connection of printers. It is the same script that reconnects and connects. It is a bit tricky to get the actual information we need (partly from the registry and partly from our xml file), so the script is a little complex:

SetVar LocationName,[XMLAttribute Locations.xml,Acme/Locations/Scope_[IPAddressPart 2],Name]

SetVar PrinterSet,"[RegistryValue HKCU\Software\Acme\Sites\[Var LocationName]\PrinterSite]"

SetVar XmlPath,Acme/Printers/[Var LocationName]/PrinterSite

SetVar PrinterList,"[XMLPairAttribute Locations.xml,[Var XmlPath],Name,[Var PrinterSet],Printers]"

SetVar DefaultPrinter,Yes

Loop Printer,[Split [Var PrinterList]]

  ConnectPrinter [Var Printer]

  IF [Var DefaultPrinter]=Yes Then SetPrinterDefault [Var Printer]

  SetVar DefaultPrinter,No

End Loop

DisconnectNonConnectedPrinters

The first printer in the list will be connected as the default printer. Running ConnectPrinter does nothing if the printer is already connected, so we don't need to test if it is already connected. The last line will delete all network printers that have not been through the ConnectPrinter command in this script context, removing all printers from other sites or previous XML settings.

If we put a bit more data in the xml file, the user will see the following when prompted for printer location:



Advanced logon script

Putting it all together, a complete Acme Corporation logon script could now look something like this:

''==== TERMINATE TERMINAL SERVER SESSIONS ====

IF TerminalServer Then

  ShowMessage "You are not allowed to logon through Remote Desktop Services, please contact HelpDesk","Error"

  Logoff

End If

 

''==== DETERMINE LOCATION ====

SetVar LocationName,[XMLAttribute Locations.xml,Acme/Locations/Scope_[IPAddressPart 2],Name]

SetVar ServerName,[XMLAttribute Locations.xml,Acme/Locations/Scope_[IPAddressPart 2],Server]

 

''==== SHOW WELCOME SCREEN ====

Splash Welcome to ACME [Var LocationName],[UserFullName]

 

''==== CONNECT THE LOCAL SHARE ====

ConnectShare O:,\\[Var ServerName]\Data

 

''==== WRITE LOCATION BASED INFORMATION, SO OTHER APPLICATIONS CAN GET IT ====

WriteRegistry HKCU\Software\Acme\Location\Name,[var LocationName]

WriteRegistry HKCU\Software\Acme\Location\Server,[var ServerName]

 

''==== CONNECT SHARES ====

ConnectShare J:,\\AcmeServer\CommonShare

ConnectShare O:,\\[Var ServerName]\Data

ConnectShare [UserHomeDrive],[UserHomeDir]

 

''==== RUN GROUP SCRIPTS ====

Loop Group,[UserGroups]

 IF FileExists GroupScripts\[Var Group].fsh Then Include GroupScripts\[Var Group].fsh

End Loop

 

''==== SHOW LOW DISK ERROR ====

IF [FreeDiskSpace]<5 Then ShowMessage "Please contact HelpDesk, you are running out of disk space","Warning"

 

''==== ENSURE MINIMUM SCREEN RES ====

IF [ScreenWidth]<1024 Then SetScreenRes 1024,768

 

''==== BACKUP USERDATA ON PORTABLES ====

IF UserOnceAWeek Then

  IF Portable Then

    Splash Backing up documents, please wait...

    SyncDir [UserDocumentsDir],[UserHomeDir]\DocumentsBackup\ [Computername]

  End If

End If

 

''==== CLEANUP ====

IF UserOnceAWeek Then DeleteDirPreserved [TempDir]

IF UserOnceAMonth Then DeleteDirPreserved [UserInternetCacheDir]

 

''==== SYNC COMMON ACME ICONS ====

SyncDir O:\CommonIcons,[UserStartMenuDir]\Acme

 

''==== SET CLIENT TIME ====

SetTimeFromServer

 

''==== RUN USER SETTINGS ONCE PER APPLICATION PER USER ====

Loop Application,[ApplicationsInstalled]

  IF FileExists UserDataScript\[Var Application].fsh Then

    IF UserSettingsOnce [Var Application] Then Include UserDataScript\[Var Application].fsh

  End If

End Loop

 

''==== CONNECT PRINTERS ====

If [RegistryValue HKCU\Software\Acme\Sites\[Var LocationName]\PrinterSite]=[Blank] Then

  RemoveSplash

  Include PrinterConnect.fsh

Else

  Include PrinterReconnect.fsh

End If

If UserOnce PrinterShortcut Then

  CreateShortcut [UserStartMenuDir],"Select Printers",[FastTrackPath]\PrinterConnect.fsh

End If

 

''==== UPLOAD INVENTORY ====

UploadInventory

If you disregard the blank lines and the comments, you will see that there are very few actual script lines, but we have:
- Ensured that no one logs on through Remote Desktop Services.
- Determined where the user is.
- Shown a nice welcome splash screen.
- Connected a common share, the user's home share and a location-based share.
- Written registry information for other applications about the current location.
- For every group the user is a member of, we looked for a script file and include it.
- Asked the user to contact the HelpDesk if he is running out of disk space.
- Ensured that no one runs at a resolution lower than 1024x768.
- Backed up the user's personal folder on portable computers once a week.
- Once a week, cleaned up temp.
- Once a month, cleaned up temporary internet file folders.
- Synchronized the company's common icons to the user's profile.
- Applied all needed user settings based on what the user has installed.
- Synchronized the computers' time.
- Applied user settings once per user for every scripted application.
- Automatically handled connection of the user's printers.
- Uploaded inventory to the cloud-based FastTrack Inventory