I contacted Citrix.
The Xen API does not provide a mechanism for logging into a session using a secure string password.
So, I ended up using a C# program that executes two PowerShell scripts that do support a secure string password.
See the code below.
Notes:
I have the 7.1.1 XenServerPSModule installed in
%USERPROFILE%\Documents\WindowsPowerShell\Modules\XenServerPSModule. This module provides the Connect-XenServer cmdlet
I created the xml credentials file using PowerShell get-credentials
followed by using export-clixml
I loaded the requisite System.Management.Automation reference by installing
Microsoft.PowerShell.5.ReferenceAssemblies from NuGet
form1.cs (form has just a button)
using System;
using System.Windows.Forms;
using XenSnapshotsXenAccess;
namespace Create_XenSnapshotsUi
{
public partial class Form1 : Form
{
XenSessionAccess xenSession = null;
public Form1()
{
InitializeComponent();
}
private void Button1_Click(object sender, EventArgs e)
{
xenSession = new XenSessionAccess("https://xxx.xx.x.x", @"C:\foo\xml_credentials.xml");
xenSession.Logout();
}
}
}
XenSessionAccess class
using System;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using XenAPI;
namespace XenSnapshotsXenAccess
{
public class XenSessionAccess
{
private Session xenSession = null;
public Session XenSession { get => xenSession; set => xenSession = value; }
public void Logout()
{
if (XenSession != null)
{
XenSession.logout(XenSession);
}
}
public XenSessionAccess(string poolMasterServerUrl, string xml_creds_path)
{
Collection<PSObject> results = null;
PSCredential psCredential = null;
//https://learn.microsoft.com/en-us/powershell/developer/hosting/creating-an-initialsessionstate
//Createdefault2* loads only the commands required to host Windows PowerShell (the commands from the Microsoft.PowerShell.Core module.
InitialSessionState initialSessionState = InitialSessionState.CreateDefault2();
using (Runspace runSpace = RunspaceFactory.CreateRunspace(initialSessionState))
{
runSpace.Open();
using (PowerShell powerShell = PowerShell.Create())
{
powerShell.Runspace = runSpace;
powerShell.AddCommand("Import-CliXml");
powerShell.AddArgument(xml_creds_path);
results = powerShell.Invoke();
if (results.Count == 1)
{
PSObject psOutput = results[0];
//cast the result to a PSCredential object
psCredential = (PSCredential)psOutput.BaseObject;
}
else
{
throw new System.Exception("Could not obtain pool master server credentials");
}
}
runSpace.Close();
}
initialSessionState = InitialSessionState.CreateDefault2();
initialSessionState.ImportPSModule(new string[] { "XenServerPSModule" });
initialSessionState.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.Unrestricted;
SessionStateVariableEntry psCredential_var = new SessionStateVariableEntry("psCredential", psCredential, "Credentials to log into pool master server");
initialSessionState.Variables.Add(psCredential_var);
SessionStateVariableEntry poolUrl_var = new SessionStateVariableEntry("poolUrl", poolMasterServerUrl, "Url of pool master server");
initialSessionState.Variables.Add(poolUrl_var);
using (Runspace runSpace = RunspaceFactory.CreateRunspace(initialSessionState))
{
runSpace.Open();
using (PowerShell powerShell = PowerShell.Create())
{
powerShell.Runspace = runSpace;
powerShell.AddScript(@"$psCredential | Connect-XenServer -url $poolUrl -SetDefaultSession -PassThru");
results = powerShell.Invoke();
}
if (results.Count == 1)
{
PSObject psOutput = results[0];
//cast the result to a XenAPI.Session object
XenSession = (Session)psOutput.BaseObject;
}
else
{
throw new System.Exception(String.Format("Could not create session for {0}", poolMasterServerUrl));
}
runSpace.Close();
}
}
}
}