$theTitle=wp_title(" - ", false); if($theTitle != "") { ?>
About Virtualization, VDI, SBC, Application Compatibility and anything else I feel like
31 Jan // php the_time('Y') ?>
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.
31 Jan // php the_time('Y') ?>
In every project I do I will have to migrate data at some point. This usually involves three types of data:
Home Directory Data is usually a flat copy although I tend to filter out the garbage (temp files and such).
Workgroup data usually needs to be cleaned up so it involves some kind of data mapping (folder x goes to place y).
Application Data is usually a flat copy from old to new location but often there are things like ini files that are adjusted and we don’t want to overwrite that.
30 Jan // php the_time('Y') ?>
As you may know, Fast User Switching (FUS) is not available (disabled) on Windows XP computers joined to a domain, Microsoft confirms this in kb280758.
However, Microsoft doesn’t tell us there’s an undocumented registry value that allows us to have FUS when joined to a domain!
To enable FUS you need to set the DWORD registry value HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\ForceFriendlyUI.
It can also be set by Group Policy at HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System.
When the value is set to 1, and LogonType key is also set to 1, it allows you to use a Friendly UI on a computer joined in a domain:
(more…)
29 Jan // php the_time('Y') ?>
If you want to obtain a user’s token in a Terminal Server or Citrix session (eg to launch a process in a session) you can call the WTSQueryUserToken function.
On the x64 versions of Windows XP and Server 2003 this function fails however and returns ERROR_INSUFFICIENT_BUFFER (“The data area passed to a system call is too small.”) when called from a 32 bit process.
Internally WTSQueryUserToken calls the undocumented function WinstationQueryInformationW with the WinStationUserToken class (14) and passing a WINSTATIONUSERTOKEN struct, filled with caller ProcessId and ThreadId.
But on x64 Windows the size of this structure is 24 bytes, while on 32 bit Windows the size of the structure is 12 bytes!
29 Jan // php the_time('Y') ?>
I don’t do much programming in .NET based languages but I have to for some things like the Windows Live Writer plugin I am creating.
I didn’t expect this but the String.IndexOf Method is by default case sensitive.
But we can make it case insensitive if we use one of the overloads: IndexOf(String, StringComparison).
Example:
1 | int preFrom = value.IndexOf(prePrefix, System.StringComparison.CurrentCultureIgnoreCase); |
28 Jan // php the_time('Y') ?>
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:
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | $keyName = "SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\icawd\thin16" $valueName = "MaxLVBMem" # Calculate your value! http://support.citrix.com/article/CTX114497 [int]$value = 0xc00000 # Set Identity to SYSTEM via it's Well Known SID [System.Security.Principal.SecurityIdentifier]$ident = "S-1-5-18" # Open Registry Key (with Write Permissions) $regKey = Get-Item "HKLM:" $regKey = $regKey.OpenSubKey($keyName, $true) # Fetch Existing permissions $acl = $regKey.GetAccessControl() # Construct a new Ace $rights = [Enum]::Parse([Security.AccessControl.RegistryRights], "SetValue") $deny = [Enum]::Parse([Security.AccessControl.AccessControlType], "Deny") $rule = New-Object Security.AccessControl.RegistryAccessRule($ident, $rights, $deny) # Add the new Ace to the Acl $acl.AddAccessRule($rule) # Apply the new Acl to the Registry key: $regKey.SetAccessControl($acl) # Now set the required Value $regKey.SetValue($valueName, $value) # Close the key $regKey.Close() |
27 Jan // php the_time('Y') ?>
If you want to be able save the password in Office Communicator you must create the key HKLM\Software\Microsoft\Communicator or on x64 OS HKLM\Software\Wow6432Node\Policies\Microsoft\Communicator and set the DWORD value SavePassword to 1.
Now you will have the Save my password checkbox (which will save the encrpted password to HKCU\Software\Microsoft\Communicator\AccountPassword
27 Jan // php the_time('Y') ?>
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:
1 2 3 | Set objPrinter = GetObject( _ "winmgmts:{impersonationLevel=Impersonate ," _ & "(LoadDriver)}!//./root/cimv2:Win32_Printer") |
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:
1 | powershell.exe "& { $Wmi = ([wmiclass]'Win32_Printer') ; $Wmi.Scope.Options.EnablePrivileges = $true; gwmi win32_printer -ComputerName 'ADNRD02' -Filter 'shared=true' | foreach {$Wmi.AddPrinterConnection( [string]::Concat('\\', $_.__SERVER, '\', $_.ShareName) )} }" |
25 Jan // php the_time('Y') ?>
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.
25 Jan // php the_time('Y') ?>
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!