Monday, June 25, 2012

Cleanly replace links with jQuery UI Dialogs.

This but of code along with a bit of link decoration will automatically open all specified links in dialog popup windows instead of in new browser windows.  It benefit here is that this code is quite small, clean, and automatically applied to all matched elements on the page without having to write custom code or hooks for each link.

First of all make sure that you are including jQuery, jQuery UI and a jQuery UI Stylesheet.

<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="http://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
<link href="http://code.jquery.com/ui/1.8.21/themes/base/jquery-ui.css" rel="stylesheet"></link>

Next add the following code to a external javascript file that is included on this page or into the page code itself. Not that this needs to be included/executed after the above scripts are included.


ConfigureDialogPopups.js
// make sure the page is fully loaded.
$(document).ready(function() {
  // For each link makred up with the popup attribute change the link to open the contents in a jquery dialog instead.
  $("a[popup]").each(function() {
    $(this).click(function() {
      dest = $(this).attr("popup");
      // Get the page contents with a background ajax query.
      $.get($(this).attr("href"), function(data) {
        // Push the results into a div tag with a custom id to spit out the script and style elements.
        $("<div id='"+dest+"' class='"+dest+"'>" + data + "</div>").each(function() {
          if($(this).is("div")) {
            // Add the div to the page as a popup.
            $(this).dialog({
              close: function() {
              $(this).remove();
              },
              modal: true,
              resizable: false
            });
            // Move the first p to the dialog title. 
            $("#"+dest).dialog( "option", "title", $("#"+dest+">p").first().html() );
            $("#"+dest+">p").first().remove();

            // Update the style of the header.
            $("span.ui-dialog-title").addClass("subhead14");
          } else {
            // Add all other elements to the body directly.
            $(this).appendTo("body");
          }
        });
      });
      // Return false so the link isn't clicked.
      return false;
    }); 
  });
});

The final step is to go through the page and decorate and links you want to open in dialog popups with the popup attribute. This should be added directly to the A link that will trigger the popup and the href will be be the location to retrieve and place into the popup. The value of the popup attribute needs to be assigned a unique id that will be assigned to the resulting dialog object.

 For example the following link can be make up as so to change it from a normal page link to a popup dialog.
<a href="page2.hmtl">View Page 2</a>
<a popup="page2dialog" href="page2.hmtl">View Page 2 (Popup)</a>

Furthermore the dialog can be accessed and manipulated as needed with the following jQuery selector.
$("#page2dialog")

Monday, December 12, 2011

Connecting OTRS into Active Directory.

I was testing out OTRS for work and got it to connect to and integrate with out Active Directory server.  All the Customers and Agents are pulled in from AD, bassed on group membership, along with their contact information.  This took quite a bit of trial and error but here is the config file I ended up with.  Note that this isn't the full file but rather goes into the load method where indicated.

How to retain a users default printer in Citrix when using Session Printers.

Update: 2/27/2011
Rewrote the scripts as they didnt work is some situations and caused some very strange errors.
Aslo to remove some potential errors with client session printers a network printer shuold now be set in the policies though this will get changed by the scripts.


I just covered how to push down Session Printers in Citrix based on Active Directory membership in my last post.  This method does however have one problem and that is that the users Default Printer preference will be discarded upon logout.  To get around that the with some scripts can be set up in the users login script to restore the previous default printer.  Also the free Defset utility will also need to be added as a published application for the users to use to change their default printer instead of the normal way.

You will need to download and save theDefSet utility onto each citrix server available form http://www.ctrl-alt-del.com.au/CAD_Utils.htm.  In my case I just saved it to %windir%.

Once downloaded you will need to add a plublished application for the user to run this tool and set their default printer.  It should use the following command line to execute.
%windir%\defset.exe /PA

Also save the following  VBScript onto your Citrix servers where you put DefSet. The Adobe PDF printer is a default that will be used if no preference is set of if there is some error in the proccess though it can be changed here.

SetDefault.vbs
On Error Resume Next
Err.Clear
Set WSHNetwork = CreateObject("WScript.Network")
Set ArgObj = WScript.Arguments
if ArgObj(0) = "Document" then
WSHNetwork.SetDefaultPrinter "Adobe PDF"
Else
WSHNetwork.SetDefaultPrinter ArgObj(0)
End if
if Err.Number <> 0 then
WSHNetwork.SetDefaultPrinter "Adobe PDF"
End if


After that you will need to create a Group Policy that will apply to all the Citrix users.  In this policy you will need to add the following login scripts.

SetPrinterDefault.bat
rem @echo off
echo Waiting for network printers to appear.
timeout 15
echo Setting user default printer.
FOR /F "eol=; tokens=3 delims=\" %%i in (%userprofile%\Windows\defset.ini) do (
cscript.exe %windir%\SetPrinterDefault.vbs "%%i"
)

 This will in essence work now but any client side printers published to the session will not save properly.  To fix this add the following Citrix Policy to the Group Policy we already created.
Policy: Client printer names
Value: Legacy printer names


We also need to set a default printer in the policy so that client side printers not cause errors durring startup.  Specificly what will happen is that if one of them gets assigned as a default durring the normal winodws logon proccess then the utilities will not work properly.  To get around this we will set a server side default printer and then the login script will change it.  This printer will need to be a session printer shared out to all the citrix users, though the default will just be changed so they won't really be printing to it.  We just use our support printer but you could jsut as easily use a fake printer. Add the following Citrix Policy to the Group Policy we already created.
Policy: Default Printer
Value: \\PrintServer\GlobalSharedPrinter


Please note that changing the default printer must be done with the DefSet tool and changing the printer in Windows will still be ignored on logoff.

Granting users Session Printers bassed on Active Directory Membership with Citrix.

I have been setting up the new Citrix environment where I work on one of the biggest problems we have run into is that of printing.  In the end I set the system up to use Citrix Group Policies to configure Session Printers at login time.  Furthermore I have it configured to discard the printers at log off.  The primary benefit to this approach is a one to one relationship between the printers a user has access to and the group membership in Active Directory.  There is one group for each printer in AD those groups are granted to user/department groups as needed. 

The Active Directory groups are named to match the printer names.
Printer - PNT001, Printer - PNT002-Color, Etc.

The Citrix Policies can be configured in the GPO or the Citrix Delivery Services Console as User Policies, one entry per printer. and look like so.
Name: Printer - PNT001
Setting: Session Printers   \\print01\PNT001
Filter:  Allow when user is in DOMIAN\Printer - PNT001 


When the user logs in the Citrix policy is applied.  It has one session printer line for each printer that is only applied if the user is a member of that printers security group.  As a result when adding or removing printers in AD any changes will be reflected when the users log in again.  This does not set or force down a default printer and any default set by the user will be lost on log out as the printers are discarded.  Please see the next post for dealing with allowing users to set and store their default printer preference.

Friday, September 16, 2011

Using a single Windows 7 install with Boot Camp and VMware Fusion

09/17/2011- Update: Updated the power on-vm-custom script to add /persistent:yes.  Without this extra parameter the drive mapping immediately disconnects when the login scripts finish which is not what we are looking for.

I recently put a SSD drive into my iMac running OSX Lion. When I did this I also decided to create a single Windows 7 install for use in Boot camp and VMware Fusion. Below is a brief overview of the process and the decisions I made along the way.


I started out by using the Boot Camp Assistant to create a 20 GB(Probably should have been closer to 30GB) partition on the SSD drive(120 GB) I installed. I will only be using this partition for the operating system and drivers and have a 700GB external Firewire drive for all other data.

I installed Windows 7 64bit on this volume and loaded it with the proper Windows 7 Boot camp drivers and all the Windows Updates.

Next I installed VMware Fusion 3 created a new Virtual Machine with the Boot Camp partition.  This is only a pointer to the partition and not a copy and as such the VM itself is only a few megabytes.  After this was done I booted up the VM and configured the VMware tools.

I now have a single operating system that can be used in the VM or as a native OS.  To simplify the switching between the two Operating Systems I also installed BootCamp.

Next I configured Windows to automatically log in when booting to speed the startup/reboot times.  To do this open Window, press Command-R, and enter control userpassword2. not uncheck the option to require users to login and enter the username and password you want to automatically log in with.


Setting up shared access to a NTFS partition from both Boot Camp and VMware Fusion.

Next up is tackling the problem of the second hard drive.  I could have just created one large partition and been done now but the SSD eliminates the option.  Also I can't directly attach the external firewire drive to Windows XP become there is another partition on is for use in OSX.  As a result I am limited to make a few modifications to make it usable.  First off I configured the drive with two large partitions with Disk Utility(The first is a HFS+ volume with my OSX home directory and documents).  Then I Booted into Boot Camp and formatted the second column as NTFS for use in windows.  This drive will now automatically connet when booting in Boot Camp as E:\.

This was only half the battle though as previously mentioned when booting in VMware this column isn't accessible.  The solution to this is to enable Sharing in the Virtual Machine settings.  Now click Add, select the proper volume, and make sure it is set to Read & Write.  Note that you definitely want to leave Mirrored folders off here or you will have problems when booting back to Boot Camp.  You can also add other folders to share here like tour home folder or other external volumes.

Now you may have noticed that this volume is Read Only.  This is a limitation of OSX but there is a NTFS-3G Driver that will enable write access to the drive.  When installing be sure to chose the Cache option as the performance is needed and on a power failure only the programs will be vulnerable, not the OS itself.  Once installed you don't need to reboot, just click the X at the last screen then un mount the column and user Disk Utility to re-mount it.  You can now write to the NTFS volume all be it as a slightly reduced speed.

Upon booting VMware we not get a Z:\ shared folder with this external drive listed within it.  This will not work though as the applications will not be installed in the same location in both modes.  To fix this we need to create a login and logout scrip in VMware.  Open up C:\Program Files\VMware\VMware Tools  and make copies of the poweron-vm-default and poweroff-vm-default scripts.  Now open up My Computer, Z:\, and the shared external volume.  Copy the full path from the address bar at the top of the window.

Edit the poweron-vm-copy script and add the following line where DRIVE is the drive letter expected in windows and PATH is the path copied previously.
net use DRIVE: "PATH" /persistent:yes
Edit the poweroff-vm-copy script and add the following line where DRIVE is the same drive letter again.
net use DRIVE: /delete


For example here are mine:
net use e: "\\vmware-host\Shared Folders\Windows HD" /persistent:yes
net use e: /delete

Finally open up VMware tools and change the Shut Down Guest and Power On Guest scripts to point to the appropriate files we just created.  Now reboot and enjoy seamless reboots and convenience.


Other notes:
  • With this setup and the SSD I can switch back and forth between anteing and emulated environments in less them a minute.  
  • I also have both operating systems configured to load the majority of their applications and data onto the external drive and hold only the OS and working files on the SSD.  The only real exceptions to this are in OSX where most applications are acutely on the SSD as in both OS's the user profiles are still on the SSD.  I all detail my OSX setup in a future post.
  • You will notice that you can't use BootChamp to reboot when the VM is running.  You need to shut down Windows first before you can reboot to Boot Camp.  VMware does not acutely need to be exited and I tend to leave the application running and the VM set to auto start so that earn I boot back to OSX the VM automatically starts back up.