0
votes

We have developed a new web based application which makes calls to Citrix Xenapp Powershell cmdlets through C#. The web application is hosted on the Citrix server(This is already in the farm) itself which we feel is enough to access all the servers in the Citrix farm.The code gives the output when it runs from Visual Studio IDE. However, when I make a virtual directory on IIS and access it through Browser.

at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate) at System.Management.Automation.Runspaces.LocalPipeline.InvokeHelper() at System.Management.Automation.Runspaces.LocalPipeline.InvokeThreadProc()

The following is the code

protected void Page_Load(object sender, EventArgs e)
{
    string usrname = "";
    string svrname = "";
    string appname = "";
    string clntnme = "";
    string clntip="";
    string farm = "";

    Runspace rsp = RunspaceFactory.CreateRunspace();
    //rsp.ApartmentState = System.Threading.ApartmentState.STA;
    //rsp.ThreadOptions = PSThreadOptions.UseCurrentThread;
    rsp.Open();
    PSSnapInException exp;
    rsp.RunspaceConfiguration.AddPSSnapIn("Citrix.XenApp.Commands", out exp);
    try
    {
        PowerShell ps3 = PowerShell.Create().AddCommand("Get-XAFarm");
        ps3.Runspace = rsp;
        foreach (PSObject pss in ps3.Invoke())
        {
            farm = pss.Properties["FarmName"].Value.ToString();
        }
        Response.Write("<DIV align=" + "center" + " style=" + "width:100%;height:100%" + ">" + farm + "<TABLE style=" + "width:100%" + ">");
        Response.Write("<TR><TH>User</TH><TH>Server</TH><TH>Application</TH><TH>Address</TH><TH>Client Name</TH></TR>");
        PowerShell sessions = PowerShell.Create().AddCommand("Get-XASession").AddParameter("Full").AddCommand("where-object").AddParameter("FilterScript", ScriptBlock.Create("{$_.BrowserName -ne $null }"));

        sessions.Runspace = rsp;
        foreach (PSObject psr in sessions.Invoke())
        {
            //IPAddress.Parse(psr.Properties["ClientAddress"].Value.ToString());
            usrname = psr.Properties["AccountName"].Value.ToString();
            svrname = psr.Properties["ServerName"].Value.ToString();
            appname = psr.Properties["BrowserName"].Value.ToString();
            clntnme = psr.Properties["ClientName"].Value.ToString();
            //if (psr.Properties["ClientAddress"].Value != null)
            //{
                clntip = psr.Properties["ClientAddress"].Value.ToString();
            //}
            //clntip = psr.Properties["ClientIPV4"].Value.ToString();
            Response.Write("<TR><TD>" + usrname + "</TD><TD>" + svrname + "</TD><TD>" + appname + "</TD><TD>" + clntip + "</TD><TD>" + clntnme + "</TD></TR>");
        }
        Response.Write("</TABLE>");
    }
    catch (Exception ex)
    {
        Response.Write(ex.StackTrace.ToString());
    }
    finally
    {
        rsp.Close();
    }
}**

Please let me know if any changes have to be done at IIS to enable me access the aspx page successfully.

1
I have figured it out. I have changed the application Pool Identity to Local System for the application in IIS and it's working now. Thanks for Help - abhi v
Why do you create multiple instances of PowerShell? Just execute a PowerShell.Commands.Clear() between command invocations. Also, if you are using PowerShell v3, it uses the DLR so you can simplify your foreach loops e.g. foreach (dynamic pss in ps3.Invoke()) { farm = pss.FarmName; }. - Keith Hill
Thank you.. I have changed the code as per your observation. - abhi v
However I would like to have any suggestions to avoid running my application with LocalSystem Privileges - abhi v

1 Answers

0
votes

The app needs to run as a user that has sufficient admin privileges in the XenApp farm. You could create a dedicated service account and make it an admin in the XenApp farm. To list farm state as your sample does, it only needs to be a 'View Only' XenApp administrator. Then configure IIS to run as that service account.