<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>xendesktop 4 &#8211; Carl Webster</title>
	<atom:link href="https://www.carlwebster.com/tag/xendesktop-4/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.carlwebster.com</link>
	<description>The Accidental Citrix Admin - The site for those who find themselves supporting Citrix involuntarily or accidentally</description>
	<lastBuildDate>Mon, 12 Jun 2023 19:20:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.2</generator>
<site xmlns="com-wordpress:feed-additions:1">42228915</site>	<item>
		<title>Documenting a Citrix XenDesktop 4 Farm with Microsoft PowerShell</title>
		<link>https://www.carlwebster.com/documenting-a-citrix-xendesktop-4-farm-with-microsoft-powershell/</link>
					<comments>https://www.carlwebster.com/documenting-a-citrix-xendesktop-4-farm-with-microsoft-powershell/#comments</comments>
		
		<dc:creator><![CDATA[Carl Webster]]></dc:creator>
		<pubDate>Mon, 12 Mar 2012 09:00:13 +0000</pubDate>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[XenDesktop 5.x]]></category>
		<category><![CDATA[powershell]]></category>
		<category><![CDATA[xendesktop]]></category>
		<category><![CDATA[xendesktop 4]]></category>
		<guid isPermaLink="false">https://www.carlwebster.com/?p=4783</guid>

					<description><![CDATA[A customer site I was at recently needed their XenDesktop 4 farm documented.  Since I had already created PowerShell scripts to document the various versions of XenApp, I figured a&#8230;]]></description>
										<content:encoded><![CDATA[<p>A customer site I was at recently needed their XenDesktop 4 farm documented.  Since I had already created PowerShell scripts to document the various versions of XenApp, I figured a XenDesktop script should be easy to create.  This article and the script were written for “SR” at the customer site.</p>
<p>This article will focus only on XenDesktop 4.  I am planning on writing articles and scripts for XenDesktop 5.x.<span id="more-4783"></span></p>
<p>The prerequisites to follow along with this article are:</p>
<ul>
<li>A computer, physical or virtual, running Microsoft Windows Server 2003, Server 2008, Server 2008 R2, or Microsoft Windows XP, Vista, or 7 for running the XenDesktop Desktop Delivery Controller SDK.</li>
<li>Citrix XenDesktop 4 Desktop Delivery Controller (DDC) installed with at least one Desktop Group created.</li>
</ul>
<p>In this article, we will be installing the Citrix Delivery Controller SDK.  You can install the SDK from either the XenDesktop 4 installation media or download it from citrix.com.  Since I am at a customer site creating this script on a production network, I do not have access to the installation media.  Therefore, I will be downloading the SDK.</p>
<p>My initial goal was to see if I could walk down the nodes in the Delivery Services Console (DSC) (Figure 1) and see if I could document every nook and cranny.</p>
<figure id="attachment_49414" aria-describedby="caption-attachment-49414" style="width: 282px" class="wp-caption alignnone"><a href="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure001.png"><img fetchpriority="high" decoding="async" class="size-full wp-image-49414" src="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure001.png" alt="Figure 1" width="282" height="403" srcset="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure001.png 282w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure001-210x300.png 210w" sizes="(max-width: 282px) 100vw, 282px" /></a><figcaption id="caption-attachment-49414" class="wp-caption-text">Figure 1</figcaption></figure>
<p><del><strong>Note:</strong>  For instructions on how to install the SDK from the XenDesktop 4 installation media, please see http://blogs.citrix.com/2010/08/11/xendesktop-4-powershell-sdk-primer-part-1-getting-started/.</del></p>
<p><strong>Update 7-July-2021: Citrix, obviously, killed these old XD4 links.</strong></p>
<p><strong>For the SDK install, go to <a href="https://carlwebster.sharefile.com/d-s6239e1f90eb043d7a2642fbc61db997a" target="_blank" rel="noopener">https://carlwebster.sharefile.com/d-s6239e1f90eb043d7a2642fbc61db997a</a></strong></p>
<p><strong>For the SDK Welcome, go to <a href="https://carlwebster.sharefile.com/d-s559804f9b3244ff58669263ab1e7dc06" target="_blank" rel="noopener">https://carlwebster.sharefile.com/d-s559804f9b3244ff58669263ab1e7dc06</a></strong></p>
<figure id="attachment_49415" aria-describedby="caption-attachment-49415" style="width: 834px" class="wp-caption alignnone"><a href="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure002.png"><img decoding="async" class="size-full wp-image-49415" src="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure002.png" alt="Figure 2" width="834" height="547" srcset="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure002.png 834w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure002-457x300.png 457w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure002-768x504.png 768w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure002-600x394.png 600w" sizes="(max-width: 834px) 100vw, 834px" /></a><figcaption id="caption-attachment-49415" class="wp-caption-text">Figure 2</figcaption></figure>
<p>Click <em>Start</em>, <em>Run</em>, type in <strong>C:\XD4SDK\XenDesktopControllerSDK.msi</strong> and press <em>Enter</em>.</p>
<p>Click <em>Run</em> (Figure 3).</p>
<div class="mceTemp"></div>
<figure id="attachment_49416" aria-describedby="caption-attachment-49416" style="width: 414px" class="wp-caption alignnone"><a href="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure003.png"><img decoding="async" class="size-full wp-image-49416" src="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure003.png" alt="Figure 3" width="414" height="310" srcset="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure003.png 414w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure003-401x300.png 401w" sizes="(max-width: 414px) 100vw, 414px" /></a><figcaption id="caption-attachment-49416" class="wp-caption-text">Figure 3</figcaption></figure>
<figure id="attachment_49417" aria-describedby="caption-attachment-49417" style="width: 499px" class="wp-caption alignnone"><a href="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure004.png"><img loading="lazy" decoding="async" class="size-full wp-image-49417" src="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure004.png" alt="Figure 4" width="499" height="388" srcset="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure004.png 499w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure004-386x300.png 386w" sizes="auto, (max-width: 499px) 100vw, 499px" /></a><figcaption id="caption-attachment-49417" class="wp-caption-text">Figure 4</figcaption></figure>
<p>Select <em>I accept the terms in the License Agreement</em> and click <em>Next</em> (Figure 5).</p>
<div class="mceTemp"></div>
<figure id="attachment_49418" aria-describedby="caption-attachment-49418" style="width: 499px" class="wp-caption alignnone"><a href="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure005.png"><img loading="lazy" decoding="async" class="size-full wp-image-49418" src="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure005.png" alt="Figure 5" width="499" height="388" srcset="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure005.png 499w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure005-386x300.png 386w" sizes="auto, (max-width: 499px) 100vw, 499px" /></a><figcaption id="caption-attachment-49418" class="wp-caption-text">Figure 5</figcaption></figure>
<figure id="attachment_49419" aria-describedby="caption-attachment-49419" style="width: 499px" class="wp-caption alignnone"><a href="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure006.png"><img loading="lazy" decoding="async" class="size-full wp-image-49419" src="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure006.png" alt="Figure 6" width="499" height="388" srcset="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure006.png 499w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure006-386x300.png 386w" sizes="auto, (max-width: 499px) 100vw, 499px" /></a><figcaption id="caption-attachment-49419" class="wp-caption-text">Figure 6</figcaption></figure>
<p>Click <em>Install</em> (Figure 7).</p>
<div class="mceTemp"></div>
<figure id="attachment_49420" aria-describedby="caption-attachment-49420" style="width: 499px" class="wp-caption alignnone"><a href="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure007.png"><img loading="lazy" decoding="async" class="size-full wp-image-49420" src="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure007.png" alt="Figure 7" width="499" height="388" srcset="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure007.png 499w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure007-386x300.png 386w" sizes="auto, (max-width: 499px) 100vw, 499px" /></a><figcaption id="caption-attachment-49420" class="wp-caption-text">Figure 7</figcaption></figure>
<figure id="attachment_49421" aria-describedby="caption-attachment-49421" style="width: 499px" class="wp-caption alignnone"><a href="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure008.png"><img loading="lazy" decoding="async" class="size-full wp-image-49421" src="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure008.png" alt="Figure 8" width="499" height="388" srcset="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure008.png 499w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure008-386x300.png 386w" sizes="auto, (max-width: 499px) 100vw, 499px" /></a><figcaption id="caption-attachment-49421" class="wp-caption-text">Figure 8</figcaption></figure>
<p>You now have new Start Menu items under <em>All Programs</em>, <em>Citrix</em>.  Windows 7 is shown in Figure 9.</p>
<figure id="attachment_49422" aria-describedby="caption-attachment-49422" style="width: 392px" class="wp-caption alignnone"><a href="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure009.png"><img loading="lazy" decoding="async" class="size-full wp-image-49422" src="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure009.png" alt="Figure 9" width="392" height="194" /></a><figcaption id="caption-attachment-49422" class="wp-caption-text">Figure 9</figcaption></figure>
<p>Everything is now set up for us to get started.  The download page for the SDK says to get a listing of the available XenDesktop commands to enter the following command:</p>
<p><strong>Get-Command -psSnapin XdCommands</strong></p>
<p>Typing that line into the PowerShell session returns a list of Citrix XenDesktop PowerShell commands.  A sample is shown in Figure 10.</p>
<figure id="attachment_49423" aria-describedby="caption-attachment-49423" style="width: 677px" class="wp-caption alignnone"><a href="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure010.png"><img loading="lazy" decoding="async" class="size-full wp-image-49423" src="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure010.png" alt="Figure 10" width="677" height="342" srcset="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure010.png 677w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure010-530x268.png 530w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure010-600x303.png 600w" sizes="auto, (max-width: 677px) 100vw, 677px" /></a><figcaption id="caption-attachment-49423" class="wp-caption-text">Figure 10</figcaption></figure>
<p>To get a list of the Get commands, showing just the Name, where the noun starts with “Xd”, type the following in the PowerShell session (results are shown in Figure 11):</p>
<p><strong>Get-Command –Noun Xd* -Verb Get | Select-Object Name</strong></p>
<figure id="attachment_49424" aria-describedby="caption-attachment-49424" style="width: 550px" class="wp-caption alignnone"><a href="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure011.png"><img loading="lazy" decoding="async" class="size-full wp-image-49424" src="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure011.png" alt="Figure 11" width="550" height="221" srcset="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure011.png 550w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure011-530x213.png 530w" sizes="auto, (max-width: 550px) 100vw, 550px" /></a><figcaption id="caption-attachment-49424" class="wp-caption-text">Figure 11</figcaption></figure>
<p>Of the eight Get-Xd* commands listed, only three are usable for documenting the Farm:</p>
<ul>
<li>Get-XdFarm</li>
<li>Get-XdController</li>
<li>Get-XdDesktopGroup</li>
</ul>
<p>One feature I like about the XenDesktop PowerShell commands is that you are not required to run them directly on a Controller.  You can use the –AdminAddress parameter to give the name or IP address of a Controller to run the command against.  Since I am developing this script on a production Farm, I am being safe and staying off the customer’s production Controllers.</p>
<p>Typing each of the commands into the PowerShell session gave me the results shown in Figure 12, Figure 13, and Figure 14.</p>
<p><strong>Note:</strong>  I am using a Formatted List (| fl) to see all the properties returned by each command.</p>
<figure id="attachment_49425" aria-describedby="caption-attachment-49425" style="width: 590px" class="wp-caption alignnone"><a href="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure012.png"><img loading="lazy" decoding="async" class="size-full wp-image-49425" src="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure012.png" alt="Figure 12" width="590" height="218" srcset="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure012.png 590w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure012-530x196.png 530w" sizes="auto, (max-width: 590px) 100vw, 590px" /></a><figcaption id="caption-attachment-49425" class="wp-caption-text">Figure 12</figcaption></figure>
<figure id="attachment_49427" aria-describedby="caption-attachment-49427" style="width: 526px" class="wp-caption alignnone"><a href="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure013.png"><img loading="lazy" decoding="async" class="size-full wp-image-49427" src="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure013.png" alt="Figure 13" width="526" height="281" /></a><figcaption id="caption-attachment-49427" class="wp-caption-text">Figure 13</figcaption></figure>
<figure id="attachment_49428" aria-describedby="caption-attachment-49428" style="width: 677px" class="wp-caption alignnone"><a href="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure014.png"><img loading="lazy" decoding="async" class="size-full wp-image-49428" src="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure014.png" alt="Figure 14" width="677" height="342" srcset="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure014.png 677w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure014-530x268.png 530w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure014-600x303.png 600w" sizes="auto, (max-width: 677px) 100vw, 677px" /></a><figcaption id="caption-attachment-49428" class="wp-caption-text">Figure 14</figcaption></figure>
<p>My goal is to use the same wording as what is seen in the DSC for headings, captions, and text.  In order to do that, I needed a way to format the output text.  Michael B. Smith (MBS) developed a function for me to use called Line.</p>
<pre class="brush: powershell; title: ; notranslate">
Function line
#function created by Michael B. Smith, Exchange MVP
#@essentialexchange on Twitter
#http://TheEssentialExchange.com

{
	Param( &#x5B;int]$tabs = 0, &#x5B;string]$name = ’’, &#x5B;string]$value = ’’, &#x5B;string]$newline = “`n”, &#x5B;switch]$nonewline )

	While( $tabs –gt 0 ) { $global:output += “`t”; $tabs--; }

	If( $nonewline )
	{
		$global:output += $name + $value
	}
	Else
	{
		$global:output += $name + $value + $newline
	}
}
</pre>
<p>Another lesson MBS taught me is to check to see if each cmdlet used returned an error and how to tell the cmdlet how I wanted to proceed if there was an error.  This is done by using –ErrorAction, or –EA.  ErrorAction has four values (Table 1):</p>
<p>Table 1</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="144">Enumeration</td>
<td valign="top" width="48">Value</td>
<td valign="top" width="433">Description</td>
</tr>
<tr>
<td valign="top" width="144">SilentlyContinue</td>
<td valign="top" width="48">0</td>
<td valign="top" width="433">The Windows PowerShell runtime will continue processing without notifying the user that an action has occurred.</td>
</tr>
<tr>
<td valign="top" width="144">Stop</td>
<td valign="top" width="48">1</td>
<td valign="top" width="433">The Windows PowerShell runtime will stop processing when an action occurs.</td>
</tr>
<tr>
<td valign="top" width="144">Continue</td>
<td valign="top" width="48">2</td>
<td valign="top" width="433">The Windows PowerShell runtime will continue processing and notify the user that an action has occurred.</td>
</tr>
<tr>
<td valign="top" width="144">Inquire</td>
<td valign="top" width="48">3</td>
<td valign="top" width="433">The Windows PowerShell runtime will stop processing and ask the user how it should proceed.</td>
</tr>
</tbody>
</table>
<p>For this documentation script, I always use 0.  If an error occurs, I want the rest of the script to continue.</p>
<p>Next, I needed to know how to test to see if an action, like Get-XdFarm, succeeded or had an error.  MBS said to use $? to test if the most recent action succeeded (True) or had an error (False).  For example:</p>
<pre class="brush: powershell; title: ; notranslate">
$farm = Get-XdFarm -EA 0
If( $? )
{
	#success
}
Else
{
	#error
}
</pre>
<p>Because this script does not have to run on a Controller, a parameter is created to allow a Controller name or IP address to be used.</p>
<p>Let’s get started.  We will build the script node by node.  Some of the lines may wrap.</p>
<p>The beginning of the script:</p>
<pre class="brush: powershell; title: ; notranslate">
#Carl Webster, CTP and independent consultant
#webster@carlwebster.com
#@carlwebster on Twitter
#https://www.carlwebster.com
#This script written for &quot;SR&quot;, March 9, 2012
#Thanks to Michael B. Smith, Joe Shock, Jarian Gibson and James Rankin
#for testing and fine-tuning tips

Param(
&#x5B;string]$DDCAddress = &quot;&quot;
)

Function line
#function created by Michael B. Smith, Exchange MVP
#@essentialexchange on Twitter
#http://TheEssentialExchange.com

{
	Param( &#x5B;int]$tabs = 0, &#x5B;string]$name = ’’, &#x5B;string]$value = ’’, &#x5B;string]$newline = “`n”, &#x5B;switch]$nonewline )

	While( $tabs –gt 0 ) { $global:output += “`t”; $tabs--; }

	If( $nonewline )
	{
		$global:output += $name + $value
	}
	Else
	{
		$global:output += $name + $value + $newline
	}
}

#script begins
</pre>
<p>The first node in the DSC is the Farm itself.</p>
<pre class="brush: powershell; title: ; notranslate">
#get farm information
$global:output = &quot;&quot;

If($DDCAddress)
{
	$farm = Get-XdFarm -adminaddress $DDCAddress -EA 0
}
Else
{
	$farm = Get-XdFarm -EA 0
}

If( $? )
{
	line 0 &quot;XenDesktop Farm Name: &quot; $farm.Name
	line 1 &quot;XenDesktop Edition: &quot; -nonewline
	switch ($farm.edition)
	{
		&quot;PLT&quot;   {line 0 &quot;Platinum&quot;  }
		&quot;STD&quot;   {line 0 &quot;VDI&quot;       }
		&quot;ADV&quot;   {line 0 &quot;Advanced&quot;  }
		&quot;ENT&quot;   {line 0 &quot;Enterprise&quot;}
		default {line 0 &quot;Farm Edition could not be determined: $($farm.edition)&quot;}
	}

	line 1 &quot;Base OU: &quot; $farm.BaseOU
	line 1 &quot;License server&quot;
	line 2 &quot;Name: &quot; $farm.LicenseServerName
	line 2 &quot;Port number: &quot; $farm.LicenseServerPort
	line 1 &quot;Session reliability&quot;
	line 2 &quot;Allow users to view sessions during broken connections: &quot; $farm.EnableSessionReliability

	If($farm.EnableSessionReliability)
	{
		line 3 &quot;Port number: &quot; $farm.SessionReliabilityPort
		line 3 &quot;Seconds to keep sessions active: &quot; $farm.SessionReliabilityDurationSeconds
	}
} 
Else 
{
	line 0 &quot;XenDesktop Farm information could not be retrieved&quot;
}
write-output $global:output
$farm = $null
$global:output = $null

$global:output = &quot;&quot;
</pre>
<p>Sample script output:</p>
<pre class="brush: plain; title: ; notranslate">
XenDesktop Farm Name: SAMPLEXD4
        XenDesktop Edition: Platinum
        Base OU: XD4BaseOU
        License server
                Name: CTXLICENSE
                Port number: 0
        Session reliability
                Allow users to view sessions during broken connections: True
                        Port number: 2598
                        Seconds to keep sessions active: 60
</pre>
<p>Even though the license server port number is displayed as 27000 in the console, the Citrix cmdlet returns  0.</p>
<p>The next node in the DSC is Administrators, but Citrix does not provide a way to retrieve any information about the Administrators.</p>
<p>The next node is the Controllers.  Even though Controllers can be in folders, Citrix does not provide a way to retrieve Folder information.</p>
<pre class="brush: powershell; title: ; notranslate">
#get controller information
If($DDCAddress)
{
	$XDControllers = Get-XdController -adminaddress $DDCAddress -EA 0
}
Else
{
	$XDControllers = Get-XdController -EA 0
}

If( $? )
{
	line 0 &quot;Desktop Delivery Controllers:&quot;
	ForEach($XDController in $XDControllers)
	{
		line 1 &quot;Controller: &quot; $XDController.Name
		line 1 &quot;Version: &quot; $XDController.Version
		line 1 &quot;Zone Election Preference: &quot; $XDController.ZoneElectionPreference
		line 1 &quot;License Server&quot;
		If($XDController.UseFarmLicenseServerSettings)
		{
			line 2 &quot;Using Farm Setting&quot;
		}
		Else
		{
			Line 2 &quot;License server&quot;
			line 3 &quot;Name: &quot; $XDController.LicenseServerName
			line 3 &quot;Port number: &quot; $XDController.LicenseServerPort
		}
		line 1 &quot;&quot;
	}
} 
Else 
{
	line 0 &quot;Desktop Delivery Controller information could not be retrieved&quot;
}
write-output $global:output
$XDControllers = $null
$global:output = $null
</pre>
<p>Sample script output:</p>
<pre class="brush: plain; title: ; notranslate">
Desktop Delivery Controllers:
        Controller: DDC1
        Version: 4.0
        Zone Election Preference: Member
        License Server
                Using Farm Setting

        Controller: DDC2
        Version: 4.0
        Zone Election Preference: Member
        License Server
                Using Farm Setting
</pre>
<p>The last node is Desktop Groups. There are different options available depending on if the Desktop Group is Pooled or Assigned.  Instead, I returned the AD Computer Account name as shown in the console, and the cmdlet returns the Machine SID.  Also, not every user account returned a name, but the User SID was always returned.  MBS showed me how to convert a Machine or User Account SID to the Machine or User Name.</p>
<pre class="brush: powershell; title: ; notranslate">
$objSID = New-Object System.Security.Principal.SecurityIdentifier ($Desktop.MachineSid.Value)
$objComputer = $objSID.Translate(&#x5B;System.Security.Principal.NTAccount])
&quot;AD Computer Account: &quot; $objComputer.Value
</pre>
<p>And</p>
<pre class="brush: powershell; title: ; notranslate">
$objSID = New-Object System.Security.Principal.SecurityIdentifier($Desktop.AssignedUserSid.Value)
$objUser = $objSID.Translate(&#x5B;System.Security.Principal.NTAccount])
“Assigned User: “ $objUser.Value
</pre>
<pre class="brush: powershell; title: ; notranslate">
#get desktop group information
$global:output = &quot;&quot;

If($DDCAddress)
{
	$XDGroups = Get-XdDesktopGroup -adminaddress $DDCAddress -EA 0
}
Else
{
	$XDGroups = Get-XdDesktopGroup -EA 0
}

If( $? )
{
	line 0 &quot;Desktop Groups:&quot;
	ForEach($XDGroup in $XDGroups)
	{
		line 1 &quot;Basic&quot;
		line 2 &quot;Desktop Group Name&quot;
		line 3 &quot;Display name: &quot; $XDGroup.Name
		line 3 &quot;Description: &quot; $XDGroup.Description
		line 3 &quot;Desktop Group name: &quot; $XDGroup.InternalName
		line 3 &quot;Disable desktop group: &quot; -nonewline
		If($XDGroup.Enabled)
		{
			line 0 &quot;group is enabled&quot;
		}
		Else
		{
			line 0 &quot;group is disabled&quot;
		}

		line 2 &quot;Assignment Type&quot;
		line 3 &quot;Assignment Behavior: &quot; $XDGroup.AssignmentBehavior

		If($XDGroup.IsHosted)
		{
			line 2 &quot;Hosting infrastructure: &quot; $XDGroup.HostingSettings.HostingServer
		}


		line 2 &quot;Users&quot;
		line 3 &quot;Configured users:&quot;
		ForEach($User in $XDGroup.Users)
		{
			line 4 $User
			#line 4 &quot;SID: &quot; $User.Sid
			line 4 &quot;Group or User: &quot; -nonewline
			If($User.IsSecurityGroup)
			{
				line 0 &quot;Group&quot;
			}
			Else
			{
				line 0 &quot;User&quot;
			}
		}
		line 2 &quot;Virtual Desktops&quot;
		line 3 &quot;Virtual desktops:&quot;
		ForEach($Desktop in $XDGroup.Desktops)
		{
			line 4 &quot;Folder: &quot; $XDGroup.Folder
			line 4 &quot;Virtual Machine: &quot; $Desktop
			$objSID = New-Object System.Security.Principal.SecurityIdentifier ($Desktop.MachineSid.Value)
			$objComputer = $objSID.Translate(&#x5B;System.Security.Principal.NTAccount])
			line 4 &quot;AD Computer Account: &quot; $objComputer.Value
			line 4 &quot;Desktop State: &quot; $Desktop.State
			line 4 &quot;Assigned User: &quot; -nonewline
			If($Desktop.AssignUserName)
			{
				line 0 $Desktop.AssignUserName
			}
			ElseIf($Desktop.AssignedUserSid)
			{
				$objSID = New-Object System.Security.Principal.SecurityIdentifier ($Desktop.AssignedUserSid.Value)
				$objUser = $objSID.Translate(&#x5B;System.Security.Principal.NTAccount])
				line 0 $objUser.Value
			}
			Else
			{
				line 0 &quot;&quot;
			}
			line 4 &quot;Maintenance Mode: &quot; $Desktop.MaintenanceMode
			line 4 &quot;Machine State: &quot; $Desktop.PowerState
			line 4 &quot;Controller: &quot; $Desktop.Controller
			line 4 &quot;Agent Version: &quot; $Desktop.AgentVersion
			line 1 &quot;&quot;
		}
		line 1 &quot;Advanced&quot;
		line 2 &quot;Access Control&quot;

		$test = $XDGroup.AccessGatewayControl.ToString()
		$test1 = $test.replace(&quot;, &quot;,&quot;`n`t`t&quot;)

		line 3 $test1
		line 2 &quot;Access Gateway Conditions: &quot;
		ForEach($Condition in $XDGroup.AccessGatewayConditions)
		{
			line 3 $Condition
		}
		line 2 &quot;Client Options&quot;
		line 3 &quot;Appearance&quot;
		line 4 &quot;Colors: &quot; -nonewline
		switch ($XDGroup.DefaultColorDepth)
		{
			&quot;FourBit&quot;       {line 0 &quot;16 colors&quot;          }
			&quot;EightBit&quot;      {line 0 &quot;256 colors&quot;         }
			&quot;SixteenBit&quot;    {line 0 &quot;High color (16-bit)&quot;}
			&quot;TwentyFourBit&quot; {line 0 &quot;True color (24-bit)&quot;}
			default         {line 0 &quot;Color depth could not be determined: $($XDGroup.DefaultColorDepth)&quot;}

		}
		line 3 &quot;Connection&quot;
		line 4 &quot;Encryption: &quot; -nonewline
		switch ($XDGroup.DefaultEncryptionLevel)
		{
			&quot;Basic&quot;               {line 0 &quot;Basic&quot;                    }
			&quot;LogOnRC5Using128Bit&quot; {line 0 &quot;128-Bit Login Only (RC-5)&quot;}
			&quot;RC5Using40Bit&quot;       {line 0 &quot;40-Bit (RC-5)&quot;            }
			&quot;RC5Using56Bit&quot;       {line 0 &quot;56-Bit (RC-5)&quot;            }
			&quot;RC5Using128Bit&quot;      {line 0 &quot;128-Bit (RC-5)&quot;           }
			default               {line 0 &quot;Encryption level could not be determined: $($XDGroup.DefaultEncryptionLevel)&quot;}

		}
		line 3 &quot;Connection Protocols: &quot;
		ForEach($Protocol in $XDGroup.Protocols)
		{
			line 4 &quot;Name: &quot; $Protocol.Protocol
			line 4 &quot;Enabled: &quot; $Protocol.Enabled
		}

		#only show the next section if the Desktop Group is Pooled
		If($XDGroup.AssignmentBehavior -eq &quot;Pooled&quot;)
		{
			line 2 &quot;Idle Pool Settings&quot;
			line 3 &quot;Business Hours&quot;
			line 4 &quot;Business days &quot;
			ForEach($Day in $XDGroup.HostingSettings.BusinessDays)
			{
				line 5 $Day
			}
			line 4 &quot;Time zone &quot;  $XDGroup.HostingSettings.IdleTimesTimeZone
			IF($XDGroup.HostingSettings.PeakHoursStart)
			{
				line 4 &quot;Day start &quot;  $XDGroup.HostingSettings.PeakHoursStart.ToString()
			}
			If($XDGroup.HostingSettings.PeakHoursEnd)
			{
				line 4 &quot;Peak end &quot;  $XDGroup.HostingSettings.PeakHoursEnd.ToString()
			}
			If($XDGroup.HostingSettings.BusinessHoursEnd)
			{
				line 4 &quot;Day end &quot; $XDGroup.HostingSettings.BusinessHoursEnd.ToString()
			}
			line 3 &quot;Idle Desktop Count&quot;
			line 2 &quot;Business hours &quot; $XDGroup.HostingSettings.BusinessHoursIdleCount
			line 2 &quot;Peak time &quot; $XDGroup.HostingSettings.PeakHoursIdleCount
			line 2 &quot;Out of hours &quot; $XDGroup.HostingSettings.OutOfHoursIdleCount
		}
		
		# I can't find these settings in the console
		line 1 &quot;Other settings&quot;
		line 2 &quot;Allow User Desktop Restart: &quot; $XDGroup.AllowUserDesktopRestart
		line 2 &quot;Tainted Machine Action: &quot; $XDGroup.HostingSettings.TaintedMachineAction
		line 3 &quot;Actions: &quot;
		ForEach($Action in  $XDGroup.HostingSettings.Actions)
		{
			line 4 &quot;Action point: &quot; $Action.ActionPoint
			line 4 &quot;Action: &quot; $Action.Action
			line 4 &quot;Delay: &quot; $Action.Delay
			line 4 &quot;&quot;
		}


		line 1 &quot;&quot;
	}
} 
Else 
{
	line 0 &quot;Desktop Group information could not be retrieved&quot;
}
write-output $global:output
$XDGroups = $null
$test = $null
$test1 = $null
$global:output = $null
</pre>
<p>Sample script output:</p>
<pre class="brush: plain; title: ; notranslate">
Desktop Groups:
Basic
		Desktop Group Name
			Display name: WebstersLab
			Description: Used in Webster’s Lab for writing purposes
			Desktop Group name: WebstersLab
			Disable desktop group: group is enabled
		Assignment Type
			Assignment Behavior: Pooled
		Hosting infrastructure: http://msvirtualcenter.carls.com/sdk
		Users
			Configured users:
				CARLS\TS_XD_Lab
				Group or User: Group
				CARLS\TS_XD_Lab_Admin
				Group or User: Group
		Virtual Desktops
			Virtual desktops:
				Folder: \
				Virtual Machine: CARLS\COMPUTER01$
				AD Computer Account: CARLS\COMPUTER01$
				Desktop State: Available
				Assigned User: 
				Maintenance Mode: False
				Machine State: On
				Controller: DDC1
				Agent Version: 4.0.4522
	
				Folder: \
				Virtual Machine: CARLS\COMPUTER06$
				AD Computer Account: CARLS\COMPUTER06$
				Desktop State: NotRegistered
				Assigned User: 
				Maintenance Mode: False
				Machine State: On
				Controller: 
				Agent Version: 

	Advanced
		Access Control
			AllowGatewayNoConditionsDefined
		AllowGatewayAnyCondition
		Access Gateway Conditions: 
		Client Options
			Appearance
				Colors: High color (16-bit)
			Connection
				Encryption: Basic
			Connection Protocols: 
				Name: ICA30
				Enabled: True
		Idle Pool Settings
			Business Hours
				Business days 
					Sunday
					Monday
					Tuesday
					Wednesday
					Thursday
					Friday
					Saturday
				Time zone (UTC-05:00) Eastern Time (US &amp;amp;amp; Canada)
				Day start 01:00:00
				Peak end 20:30:00
				Day end 23:30:00
			Idle Desktop Count
		Business hours 7
		Peak time 7
		Out of hours 7
	Other settings
		Allow User Desktop Restart: False
		Tainted Machine Action: Restart
			Actions: 
				Action point: Disconnect
				Action: DoNothing
				Delay: 300
				
				Action point: LogOff
				Action: Shutdown
				Delay: 420
		
</pre>
<p>How to use this script?</p>
<p>I saved the script as XD4_Inventory.ps1 in the Z:\ folder.  From the PowerShell prompt, change to the Z:\ folder or the folder where you saved the script.  From the PowerShell prompt, type in:</p>
<p><strong>.\XD4_Inventory.ps1 |out-file Z:\XD4Farm.txt </strong>and press <em>Enter</em>, or</p>
<p><strong>.\XD4_Inventory.ps1 DDCName|out-file Z:\XD4Farm.txt </strong>and press <em>Enter</em>, or</p>
<p><strong>.\XD4_Inventory.ps1 DDCIPAddress|out-file Z:\XD4Farm.txt </strong>and press <em>Enter</em>.</p>
<p>Open XD4Farm.txt in either WordPad or Microsoft Word (Figure 15).</p>
<figure id="attachment_49429" aria-describedby="caption-attachment-49429" style="width: 865px" class="wp-caption alignnone"><a href="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure015-1.png"><img loading="lazy" decoding="async" class="size-full wp-image-49429" src="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure015-1.png" alt="Figure 15" width="865" height="716" srcset="https://www.carlwebster.com/wp-content/uploads/2012/03/Figure015-1.png 865w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure015-1-362x300.png 362w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure015-1-768x636.png 768w, https://www.carlwebster.com/wp-content/uploads/2012/03/Figure015-1-600x497.png 600w" sizes="auto, (max-width: 865px) 100vw, 865px" /></a><figcaption id="caption-attachment-49429" class="wp-caption-text">Figure 15</figcaption></figure>
<p><strong>You can always find the most current script by going to </strong><a title="Current Scripts" href="https://www.carlwebster.com/downloads/" target="_blank" rel="noopener noreferrer"><strong>https://www.carlwebster.com/where-to-get-copies-of-the-documentation-scripts/</strong></a></p>
<p>Thanks</p>
<p>Webster</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.carlwebster.com/documenting-a-citrix-xendesktop-4-farm-with-microsoft-powershell/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4783</post-id>	</item>
	</channel>
</rss>
