Remko Weijnen's Blog (Remko's Blog)

About Virtualization, VDI, SBC, Application Compatibility and anything else I feel like

Archive for the ‘PowerShell’ Category

SSL Certificates in termsrv.dll

I was digging around in termsrv.dll yesterday when I noticed that there are some (well 372 to be exact) SSL certificates inside the Terminal Server binary (termsrv.dll):


Two of them seem to actually contain the private keys as well, but I am not 100% sure it may be just a certificate in another format.



The Case of the Citrix Ready Printer Driver

I had a very interesting issue today on a new Citrix XenApp 5 farm. We went into production yesterday and we noticed a number of issues:

  • Printing in general was slow, especially when a user connects to a printer for the first time.
  • User Profiles were rapidly growing in size (from the expected 1-2 MB to over 40 MB).
  • Logons took much longer then in the testing period (and since we use a Full Screen Desktop the user doesn’t see any progress).
  • Performance monitoring showed CPU spikes in Word, Excel and IE processes.

I took a look at the profiles first and noticed that the size growth was due to a Xerox subfolder in %APPDATA%:

For my Reboot Script I needed to get the last character of the computername and convert it to an integer.

We can do it like this in PowerShell:

I wanted to create a Scheduled Task on my Citrix Servers to have the reboot every other night.

The idea is that half of the servers will reboot in a night and the other half the following night.

The TSSHUTDN tool is handy since it can issue a warning to logged on users, log them out after a certain period and finally issue the reboot.

Since I needed to add a scheduled task to many servers I wanted to do this with a script.

WMI Exposes the Win32_ScheduledJob Class and it’s Create Method.


On a Citrix XenApp 5 environment a user reported that he was unable to start a Full Screen session on a Dual Monitor Configuration.

He received this error message:

foutmelding (2)

Citrix has a KB Article: “How to Allow More Memory for Session Graphics on Windows Server 2003” that explains exactly how we can solve this.

We need to change the MaxLVBMem registry value and we can use the Excel Sheet from the KB Article to calculate the proper value.

Please don’t set this value too high because a higher value means you will restrict other kernel memory pools.

You also need to deny the SYSTEM account the SetValue permission on the HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management key to prevent the Citrix IMA service from overwriting the new value.

So I wrote a small PowerShell script to change the permission and set the value:

Enabling Privileges for WMI in PowerShell

A few days ago I wrote about a PowerShell Script to Install Printer Drivers.

I noticed there was a problem with this script: some drivers fail to load with error 1797 which means ERROR_UNKNOWN_PRINTER_DRIVER.

I reread the AddPrinterConnection documentation on MSDN but it didn’t mention anything about additional required permissions or anything.

But then I read the remarks sections of the Win32_Printer Class and it mentions that for some operations the SeLoadDriverPrivilege is required.

In VBScript we can indicate it like this:

But how to do this in PowerShell?

I didn’t find a way to enable a specific privilege but we can enable all by setting Scope.Options.EnablePrivileges to $true.

So I modified the script like this:

I wrote a PowerShell script to install all printer drivers on a Citrix or Terminal Server.

Actually the script isn’t specific to Citrix or Terminal Server but on such environments we need to preload all drivers because users do not have the permissions to do that.

I have chosen for PowerShell because you can do it in a one-liner which makes it easy to run this script from my Altiris server on all Citrix Servers.

The idea is that we enumerate all the shared printers on a Printer Server and make a connection to each printer. This will make sure that the driver is installed if it wasn’t already present.

The script could even be scheduled to enforce that newly added printer drivers are added to each Citrix Server.


Adding a hidden Exchange mailbox to Outlook

In Exchange it’s possible to hide a Mailbox from the (Global) Address List. You can do that in the Exchange System Manager:


But after you have hidden a Mailbox you cannot create an Outlook profile for it (or add it as an extra mailbox).


When you click Check Name in the wizard you’ll get an error:


The common workaround is to remove the “Hide from Exchange address lists” setting, create the profile (or add the Mailbox) and afterwards set it again.

Once the profile is created it all keeps working.

There is an easier solution though!


Recursive Groups #2

In my previous post I explained how to get the recursive group membership with a very simple Powershell Script.

Commenter Michel thought that the script only tested one level deep but it doesn’t.

But let’s prove that!

Create 3 Global Groups in your Active Directory and name them Level1, 2 and 3:


Make Level3 a Member of Level 2 and make Level a member of Level 1 and finally add an account to the Level 3 group:





Recursive group Membership in Powershell

In this post I will show an easy way to get the recursive group membership for the current user.

I use this in a logon script to handle certain tasks based on group membership.

Most scripts I see for this task do a manual recursive enumeration but in a large environment this could be very slow.

A better way would be to use the tokenGroups attribute of the Active Directory user object.

The tokenGroups attribute is an array of SIDs computed by Active Directory and is used to verify user access.

We need to translate these SIDs to their sAMAccountNames to get the actual group names.

In unmanaged code this could be accomplished by calling the DsCrackNames API or the IADsNameTranslate interface.