Scripting Citrix Online Plugin Settings

The Citrix Online Plugin has a number of settings that can be changed. This includes things as Window Size and Color Depth:

Session Options | Window size | Default | Full Screen | Requested Color Quality

In my case I wanted to preset the Window size to Full Screen so using Process Monitor I checked where the Online Plugin writes this setting. I Used a Filter that includes only the Online Plugin (PNAMain.exe) and the RegSetValue Operation:

Filter on Process Name is PNAMain.exe | Operation is RegSetValue

This yielded only few results:

RegSetValue Results

I changed the setting back and compared the registry, that made clear that the settings was written to “Configuration Model 000”.

Unfortunately the key is a REG_BINARY and I don’t like blindly importing this key into other systems since we have no idea what else we are importing.

However when editing the value in Regedit we see that the data looks like XML:

Edit Binary Value

I wrote a small PowerShell script to read this data into a string:

# Open Registry
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("CurrentUser", [String]::Empty)

# Read our Key (with write access)
$key = $Reg.OpenSubKey("Software\Citrix\PNAgent", $true)

# Copy the Bytes to a String
$encode = New-Object System.Text.ASCIIEncoding
$rawData = $Encode.GetString($Bytes)

However the string is hard to read because it’s not formatted and indented so I tried to cast it to an XML Object but this errors because there is no Root element and because some element names have a space.

So let’s fix this:

# Replace spaces in element names with underscores
$data = $rawData | Foreach-Object {
    [regex]::replace($_,'<([^>]+)>',{$args[0] -replace ' ','_'})
}

# Add dummy Root element
$data = "$data"

And now we can load the data into an XML Object:

 

# Load the data into XML Object
$xml = New-Object Xml.XmlDocument
$xml.LoadXml($data)

And finally we have readable data:

 


  
    
      DesktopDisplayEnabled
      false
    
    
      DesktopName
      
      
    
    
      LogonMethod
      prompt
    
    
      ServerURLEntered
      http://ctx.contoso.com/Citrix/PNAgent/config.xml
    
    
      ServerURLListUsers
      
        http://ctx.contoso.com/Citrix/PNAgent/config.xml
        http://ctx.contose.com/Citrix/PNAgent/config.xml
      
    
    
      StartMenuDisplayEnabled
      true
    
    
      StartMenuRoot
      
      
    
    
      StartMenuDisplayRootFolder
      
      
    
    
      SystemTrayDisplayEnabled
      true
    
    
      UserDisplayDimensions
      fullscreen
    
  
  
    
      DesktopName
      
      
    
    
      DesktopNameModifiable
      true
    
    
      ServerIndex
      0
    
    
      ServerURL
      http://ctx.contoso.com/Citrix/PNAgent/config.xml
    
    
      ServerURLModifiable
      true
    
    
      ServerURLListBackup
      
      
    
    
      StartMenuDisplayRootFolder
      
      
    
    
      StartMenuRootFolderModifiable
      true
    
  

To change an item we can use the following code:

 

# Let's make a change...
($xml.root.User_Blob.Item | Where-Object { $_.Key -eq 'DesktopDisplayEnabled' }).Value = $true.ToString()

To change the Window Size from Default to Full Screen I needed to add an Item with Key UserDisplayDimensions and Value “fullscreen”. This can be done like this:

 

$item = $xml.CreateElement("Item")
$itemKey = $xml.CreateElement("Key")
$itemKey.AppendChild($xml.CreateTextNode("UserDisplayDimensions"))
$item.AppendChild($itemKey)

$itemValue = $xml.CreateElement("Value")
$itemValue.AppendChild($xml.CreateTextNode("fullscreen"))
$item.AppendChild($itemValue)
$xml.root.User_Blob.AppendChild($item)

Before we can write the new data to the registry we need to get rid of the dummy root node and replace the underscores in the element names with a space again:

 

# Loose the dummy root elemented we've added
$data = $xml.root.InnerXml

# Replace the underscores with backspaces
$rawData = $data | Foreach-Object {
    [regex]::replace($_,'<([^>]+)>',{$args[0] -replace '_',' '})
}

And the final step, write it back to the registry:

 

# Copy the String to a Byte Array
$bytesOut = $encode.GetBytes($rawData)

# Write the Byte Array to the Registry
$key.SetValue("Configuration Model 000", $bytesOut)

Was once an enthusiastic PepperByte employee but is now working elsewhere. His blogs are still valuable to us and we hope to you too.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *