Monday, 26 September 2011

Enumerating user active directory attributes with Infopath and Sharepoint 2010 SP1


Sharepoint 2010 and Infopath are an extremely powerful team, from IT support request forms, staff leave request forms and the ability to enumerate values from SQL databases, the options are endless.

Recently we began working on a "Parent Portal" which will allow parents of our students to login and view school dates, student marks and timetables. Most of the data we want to pull is stored on our SQL 2008 R2 SP1 servers, so Sharepoint and Infopath are potentially a great match.



The Problem

We quickly realized that all of these external SQL databases didn't reference our users by their Active Directory samAccountName but instead by the students ID number. The solution we came up with was to populate an unused Active Directory attribute with the student ID.

So then when a user logs in, Sharepoint sees the samAccountName then can enumerate the AD attribute (we are using the Department attribute) and use that Student ID to do lookups in SQL.

So how do we enumerate AD attributes with Infopath? Easy!




The Solution


Prerequisites

1. Sharepoint 2010 (preferably with SP1 installed as it fixes a number of User Profile problems).
2. The User Profile Service application needs to be running and a Active Directory synchronization connector created. This AD synchronization connector needs to have completed a full synchronization before you can enumerate any attributes.
3. An AD attribute needs to be pre-populated.


The Process

1. Open Infopath Designer 2010 and create a new Blank form.

2. Click on the "Data" tab and select "Data Connections"

3. Select "Create a new connection to" and select "Recieve Data" then click next.

4. Select "SOAP Web Service" and click next.

5. Enter the URL of the User Profile Service. In my environment it is http://sharepoint.domain.internal/_vti_bin/userprofileservice.asmx

6. Select "GetUserPropertyByAccountName", press next.

7. Leave "tns:AccountName" as is, set the value of "tns:propertyName" to the name of the Active Directory attribute you want to enumerate.

It is best to use something standard like "Department" or else you need to mess around in Forefront Identity Manager and the Sharepoint User Profile Service and believe me its something you don't want to do. For this example I am using "Department" Active Directory attribute which I have pre populated, then click next.

8. Click next on the following screen.


9. You can give this connection a name that means something to you, I will call mine, "sharepointEnumerateDepartment", then click Finish.


10. Now for demonstration we will simply display this "Department" attribute on the screen as a proof of concept. Click on the Fields dialog on the far right hand side of the screen, select "myFields" then click "Add Field".


11. Name it "Test" and click OK.


12. Drag the "test" field onto the form and drop it. This will insert the test field into the form.


13. Right click the test box and select "Text Box Properties" then select the "Data" tab, and the "fX" symbol under the Default Value heading.


14. Select "Insert Field or Group".


15. Click the "Fields" drop down and select "sharepointEnumerateDepartment" or whatever you named this DataConnection in step 9.


16. Please select the "Value" item as in the image below.
myFields > dataFields > tns:GetUserPropertyByAccountNameResponse > GetUserPropertyByAccountNameResult > Values > ValueData > Value
Then click OK, OK, OK.


17. Now it is time to preview the form. Click on the "Home" tab and select "Preview".


If all has worked correctly, you will see the Active Directory attribute you want to enumerate displayed in the Test box above. My attribute is Department and I have set it to my example student ID of 20010.


Completion

Now that we have pulled this value from Active Directory we have so many more options. I can use this ID to pull student marks from our Accelerus database or student timetables from the timetable SQL database. You might want to pull a totally different attribute from AD and display custom SQL content to the end user, this same process can be modified and used to achieve that.






Things to check if its not working


  • The Sharepoint User Profile Service application. Ensure it is running and both the "Forefront Identity Manager Service" and "Forefront Identity Manager Synchronization Service" are running on the Sharepoint 2010 server. 

  • Ensure the Sharepoint User Profile Service application has done a full synchronization. You can check this in Sharepoint Central Administration > Manage Service Applications > User Profile Service. On the far right side of the page, there should be a number relating to your AD users in the "Number of User Profiles" field and a number relating to the number of Active Directory properties you are synchronizing in the "Number of User Properties" field.

If these are blank. you need to create a new Active Directory Synchronization connector and then start a full profile synchronization.


  • Of course ensure the "Department" attribute is populated in Active Directory.




 

Sharepoint User Profile Service application can be extremely difficult to configure correctly, if you have problems I have found the folks on the Sharepoint MSDN forums are extremely helpful.

Friday, 23 September 2011

SCOM CU4 - Manual agent installs not appearing in pending management

I work in fairly small server environment and due to the firewalls being up on clients, I have always installed the SCOM agents onto my target servers manually. After the agent is installed it appears under the "Pending Management" tab of the SCOM > Administration console and I simply have to approve it.



The Problem

After installing CU4 onto my SCOM management server I would no longer see these manual agent installs under the "Pending Management" tab.

After investigating the "Operations Manager" event logs on the SCOM management server I found an entry.

Source: OpsMgr SDK Service
Event ID: 26321

An agent was rejected. Current security settings do not allow the automatic insertion of agents.

Change either the security global settings, or the security settings for the specific management server.

Agent name: computer.domain.local
Management server name: SCOM001.domain.local

And on the client itself there was another corresponding event log entry.

Source: OpsMgr Connector
Event ID: 21016

OpsMgr was unable to set up a communications channel to SCOM001.domina.local and there are no failover hosts.  Communication will resume when SCOM001.domain.local is available and communication from this computer is allowed.


The Fix

The resolution was seriously simple.

1. On the SCOM management server open your SCOM Console.

2. Click on the Administration tab.

3. Select Settings.

4. Right click "Security" and select Properties"

5. Select "Review new manual agent installations in pending management". You can tick "Automatically approve new manually installed agents" but I would avoid it for security reasons.











6. Restart the SCOM agent on the client system. Voila, it appears in the "Pending Management" tab and I can then approve it.

Delivering custom Citrix settings based on Client Name or IP Address

In a school or even enterprise environment you might have the requirement the closest printers or even network drives based on a devices location. Citrix has included a great set of printer management tools with Xendesktop 5.5, very simply these work by mapping printers on the thin client itself and then passing them through to the virtual desktop. With different endpoints running different operating systems and different architectures this can be tricky, so we have opted for a different solution.


The "HKLM\Software\Citrix\ICA\Session" registry key

This registry key contains a number of extremely useful values including Client IP Address, Client Name and Client Version. These values can be used in any number of ways to tailor delivery of settings to the virtual desktop.

One example might be installing a printer onto thin clients sitting in a specific VLAN, you can target them with a group policy based login script by checking the "HKLM\Software\Citrix\ICA\Session","ClientAddress" REG_SZ value.



Mapping printers via Client Name

I prefer to target my printers via "ClientName". When I build a set of thin clients for a specific area, lets take the Library for example I name them VDIC-LIB01 LIB02 LIB03 (VDIC for VDI client and LIB to specify Library). Of course if you were doing a large number of clients it might be easier to put them in their own VLAN and target them by IP address with the "ClientAddress" value and forget about individually naming each client.

As I am using the Kixtart scripting language for my existing logon script I am going to leverage that for my virtual desktop printer mapping, my script for mapping a printer based on "ClientName" reads as follows.

  $citrixcliname=READVALUE("HKLM\SOFTWARE\Citrix\ICA\Session", "ClientName")
  If InStr($citrixcliname,"VDIC-LIB")
    addprinterconnection("\\printserver.domain.local\LibraryStudent-Kyocera400kx")
    SetDefaultPrinter("\\printserver.domain.local\LibraryStudent-Kyocera400kx")
  endif
And here is an example based on "ClientAddress", it looks for "192.168.10" in the IP address.
  $citrixcliaddr=READVALUE("HKLM\SOFTWARE\Citrix\ICA\Session", "ClientAddress")
  If InStr($citrixcliaddr,"192.168.10.")
    addprinterconnection("\\printserver.domain.local\LibraryStudent-Kyocera400kx")
    SetDefaultPrinter("\\printserver.domain.local\LibraryStudent-Kyocera400kx")
  endif
This is an extremely simple but powerful way to target thin clients in specific areas and deliver any settings you want.



Speeding up the mapping process

I strongly recommend you pre-install all the printer drivers you are planning to map as part of your login script into the virtual desktop image. This will dramatically cut down the printer mapping time as the driver is already installed. The different is something like 5-30 seconds per printer you are mapping, depending on how heavy the driver installation is.

Wednesday, 21 September 2011

Microsoft Research Worldwide Telescope deployment and custom proxy settings

Microsoft Research really have done a great job of creating an amazing research and educational tool in Microsoft Research Worldwide Telescope  (WWT), but where they have fallen down is the network installation and settings deployment for this application. Regardless of deployment deficiencies, staff see this as a "must have" for their classrooms, so we need to find a way to make it work.

Unfortunately while WWT is available in a MSI format, you have to jump through a number of hoops to get it to deploy successfully via SCCM or computer startup scripts. Not to mention that it doesn't "ask" internet explorer for the system proxy settings, it just does its own thing, so proxy settings also need to be specified in deployment process.




The Process

1. Create a folder for your SCCM package named "microsoft_worldwide_telescope_Penumbra"
and create another folder named "WWT" inside it.





2. Extract the contents of the WWT installer into the WWT folder you just created.



3. Next we need to do some modifications to the WWTExplorer.exe.config file, this is where all the proxy and banner suppression magic happens. If you want to change the proxy settings, change the below values.

            <setting name="ProxyServer" serializeAs="String">
                <value>YOURPROXYHERE</value>
            </setting>
            <setting name="ProxyPort" serializeAs="String">
                <value>8080</value>
            </setting>

and setting the following two settings will ensure no upgrade or banner messages appear when you start the program.

            <setting name="ShowNavHelp" serializeAs="String">
                <value>False</value>
            </setting>
            <setting name="UpgradeNeeded" serializeAs="String">
                <value>False</value>
            </setting>

You can just copy and paste the above sections over the top of the corresponding sections of your WWTExplorer.exe.config file.


4. Next we will create our installation batch file, go back to the "microsoft_worldwide_telescope_Penumbra" directory and create a file called "install.cmd", into that file put the following code.
xcopy /Y /E WWT c:\windows\WWT\
start /wait msiexec /x c:\windows\WWT\WWTSetupPenumbra.msi /quiet
start /wait c:\windows\WWT\dxsetup.exe /silent
start /wait msiexec /i c:\windows\WWT\install.msi /quiet /norestart

This will first uninstall any previous installation you might have (that might have a bad configuration), then install Direct X 11 and finally installs WWT itself. You might wonder why I am copying the installation folder to the local file system before I install it, good question! Every time a different user launches WWT, it calls upon the original MSI and briefly reruns the MSI install (the user doesn't need administrative privileges to do this). This means if you deploy the package from a network location it will fail to launch if the end user doesn't have access to that same network location and original MSI. You could (if you have an SCCM environment in place) use the SCCM package "Windows Installer" functionality.

















If you already have DirectX 9.0C installed (which  my Windows 7 clients didn't), you can simply remove the dxsetup.exe line from the installation.

5. Stick all that in a SCCM package, running install.cmd as the program and advertise it to the appropriate machines. There is no reason you couldn't deploy it with a group policy based computer start-up script either.



Network Based Cache Location Issues

Unfortunately you can't successfully change the cache location (funnily called the cahce location in the configuration file) to a shared network location, which is a shame as it could significantly increase content access speeds and lower bandwidth usage.

If multiple users are viewing the same "already downloaded" content it works flawlessly, but when multiple users try to download the same content at the same time both instances of the program fail and throw error messages.

The only situation where this could work is if you pre-download ALL of the WWT content to ensure no user is ever downloading to this shared location. I have instead opted to leave the cache location as default, which is %userprofile%\AppData\Local\Microsoft\WorldWideTelescope" to avoid any potential drama.

Friday, 16 September 2011

Windows startup script not running Windows 7 wireless clients

So many administrators are posting about their woes with Windows 7 processing group policy computer startup scripts.


The Root Cause

The root cause of this problem is that Window 7 simply ignores the group policy settings "Computer Configuration\Administrative Templates\System\Logon\Run logon scripts synchronously" and "Computer Configuration\Administrative Templates\System\Logon\Always wait for the network at computer startup and logon" that previously worked so well in Windows XP.


Some Background

I previous wrote a BLOG post about how to make the netlogon service start correctly on wireless clients by adding some service dependencies to netlogon service itself. This unfortunately still doesn't make the computer startup script run on all wireless clients.


The Solution

Here is a quick solution that will ensure group policy computer startup scripts are executed when the computer boots and its so easy, two words, task scheduler.
I have created a task that runs on startup with a 1 minute delay, runs as SYSTEM user and executes my computer startup script, I have then deployed this script with System Center Configuration Manager to all of my wireless clients. Yes it does mean that some of my clients will run the computer startup script twice, but at 300ms to complete the entire script, I am sure this won't inconvenience my users too much.

This is so easy it feels like cheating, but it solves my problems and all my computer startup scripts are running perfectly again.

Below is an example of a task schedule, you just need to replace "<Command>\\domain.local\scripts\launch.cmd</Command>" with the path to your startup script and then save it as "startupscript.xml".
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2011-09-16T13:31:06.4110949</Date>
    <Author>Administrator</Author>
  </RegistrationInfo>
  <Triggers>
    <BootTrigger>
      <Enabled>true</Enabled>
      <Delay>PT1M</Delay>
    </BootTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>S-1-5-18</UserId>
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT1H</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>\\domain.local\scripts\launch.cmd</Command>
    </Exec>
  </Actions>
</Task>
You can import the startupscript.xml file with the following command.
schtasks.exe /create /XML startupscript.xml /TN startupscript
To make it easier to deploy I put that into a SCCM package and deploy it to all my Wireless clients. Voila, problem solved!

Wednesday, 14 September 2011

OpenVPN config(FAILED) error on PowerPC based Linux hosts

OpenVPN is one of the heroes of the open source world, a product that has enterprise capabilities, great flexibility and amazing support. One of the bonuses of OpenVPN is that it is lightweight, so running on a low powered integrated system is no problem, just compile and go.

Recently I started work on a project to convert an old set top box (STB) into a home server, one of my requirements was the ability use it as an OpenVPN server, acting as a conduit to my home network.

The particular STB I have has an IBM PowerPC, which is very common amongst STB's. It also allows me to use PowerPC binaries on my unit and avoid the definite headaches of compiling on a low power and library light system.
/var/bin > uname -a
Linux imagine 2.6.9 #1 Tue Mar 10 10:17:56 CEST 2011 ppc unknown



The Problem


After setting up OpenVPN as I normally would, I started to get a repeated, very general, error message.

/var/bin > ./openvpn.sh start
Starting virtual private network daemon: config(FAILED).

This indicated that perhaps the configuration was a problem, but after redoing my configuration I found there to be no issues and no resolution to my problem.



The Resolution

Fortunately the resolution is very simple. This OpenVPN PPC binary doesn't seem to like the headers in OpenSSL generated certificates, the same certificates that work perfectly if I run them on a x86 Linux or Windows machine. So I simply removed the headers.

Example:

/var/etc/openvpn > cat certificate.cer
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 2 (0x2)
        Signature Algorithm: sha1WithRSAEncryption
..truncated..
-----BEGIN CERTIFICATE-----
..truncated..
-----END CERTIFICATE-----

Simply becomes

/var/etc/openvpn > cat certificate.cer
-----BEGIN CERTIFICATE-----
..truncated..
-----END CERTIFICATE-----

So just remove everything above the BEGIN CERTIFICATE line in your certificate, and of course ensure your key is unencrypted. Don't forget to CHOWN and CHMOD 700 your OpenVPN key directories appropriately also.

Server 2008 R2 Standard and Hyper-V dynamic memory management not working

This isn't exactly a blog post but just a note to those having problems with dynamic memory management with Server 2008 R2 standard hosts.

Microsoft were kind enough to include the great new dynamic memory management in Hyper-V, which is capable of balancing VM (virtual machine) memory allocation dynamically, and it does so quite well. Unfortunately they failed to mention one specific requirement for this to work properly, all Server 2008 R2 standard hosts require SP1 to be installed on the VM itself.

So for 2008 R2 Standard hosts you must:

1. Upgrade the hypervisor (server 2008 r2 Hyper-V) server to service pack 1, reboot.
2. Upgrade the integration services in the VM, reboot.
3. Upgrade the VM to service pack 1, reboot.

This is particularly unusual because Windows Vista, Server 2003 R2 with SP2 and Server 2008 only need the integration services upgraded, think you might have dropped the ball briefly on that one Microsoft.