{"id":5314,"date":"2013-07-24T18:30:53","date_gmt":"2013-07-24T16:30:53","guid":{"rendered":"https:\/\/ingmarverheij.com\/?p=5314"},"modified":"2014-06-18T08:12:17","modified_gmt":"2014-06-18T06:12:17","slug":"citrix-pvs-optimize-endpoint-with-powershell","status":"publish","type":"post","link":"https:\/\/ingmarverheij.com\/en\/citrix-pvs-optimize-endpoint-with-powershell\/","title":{"rendered":"Citrix PVS: Optimize endpoint with PowerShell"},"content":{"rendered":"<p>With Citrix <strong>PVS<\/strong> the content of a disk is <strong>streamed<\/strong> over the <strong>network<\/strong> to an endpoint. This requires sufficient bandwidth and an <strong>optimized<\/strong> configuration. If both criteria are not met the endpoint suffers from delays, retries or failures.<\/p>\n<p><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2013\/07\/Aint-nobody-got-time-for-that.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; float: right; padding-top: 0px; padding-left: 0px; margin: 0px 0px 0px 5px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"Ain't nobody got time for that\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2013\/07\/Aint-nobody-got-time-for-that_thumb.png\" alt=\"Ain't nobody got time for that\" width=\"154\" height=\"107\" align=\"right\" border=\"0\" \/><\/a>A number of <strong>best practices<\/strong> apply when using Citrix PVS, most of them probably apply for your situation. In the past I had to optimize my VM\u2019s <strong>manually<\/strong> each and every time I had to create a new vDisk! <em>Ain\u2019t nobody got time for that (<a href=\"https:\/\/www.youtube.com\/watch?v=JaAd8OuwwPk\" target=\"_blank\">link<\/a>)!<\/em><\/p>\n<p>I wrote a <strong>PowerShell<\/strong> script that optimizes the endpoint for Citrix PVS and would like to share it with you.<\/p>\n<p><em>Updated on June\u00a018th, 2014 with version 1.7<\/em><\/p>\n<p><!--more--><\/p>\n<h1><span style=\"font-weight: bold;\">Applied best practices<\/span><\/h1>\n<p>The script applies a number of best practices to optimize the performance of the PVS endpoint. Some are enabled by default, some are not.<\/p>\n<p><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2013\/07\/OptimizePVSendpoint-v1.3.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin: 0px auto; display: block; padding-right: 0px; border-width: 0px;\" title=\"OptimizePVSendpoint\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2013\/07\/OptimizePVSendpoint-v1.3_thumb.png\" alt=\"OptimizePVSendpoint\" width=\"273\" height=\"184\" border=\"0\" \/><\/a><\/p>\n<h4>Disable Task Offload<\/h4>\n<p>The most generic best practice that applies for (almost) every PVS environment, disabling all of the task offloads from the TCP\/IP transport. See also <a href=\"https:\/\/support.citrix.com\/article\/CTX117491\" target=\"_blank\">CTX117491<\/a><\/p>\n<p>&nbsp;<\/p>\n<h4>Disable IPv6<\/h4>\n<p><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2013\/07\/vmxnet3-Ethernet-Adapter-Bindings.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; float: right; padding-top: 0px; padding-left: 0px; margin: 0px 0px 0px 5px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"vmxnet3 Ethernet Adapter - Bindings\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2013\/07\/vmxnet3-Ethernet-Adapter-Bindings_thumb.png\" alt=\"vmxnet3 Ethernet Adapter - Bindings\" width=\"104\" height=\"130\" align=\"right\" border=\"0\" \/><\/a>Although Citrix is working hard to get IPv6 working for all Citrix products, PVS does not support IPv6. Disabling IPv6 on your PVS endpoints prevent intermittent failures. For each network adapter the IPv6 binding is removed using the <a href=\"https:\/\/archive.msdn.microsoft.com\/nvspbind\">nvspbind<\/a> utility. This utility is included in the download. Also, slow boots could occur due to IPv6. See also this <a href=\"https:\/\/social.technet.microsoft.com\/wiki\/contents\/articles\/10130.root-causes-for-slow-boots-and-logons-sbsl.aspx\" target=\"_blank\">TechNet article<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<h4>Disable TSO and DMA on XenTools<\/h4>\n<p>When you\u2019re running your PVS endpoints on Citrix XenServer 5.0 or 5.5 poor target device performance, sluggish mouse responsiveness, application latency and slow moving screen changes might occur. This is a known bug that\u2019s solved in (a hotfix of XenServer 5.6). See also <a href=\"https:\/\/support.citrix.com\/article\/CTX125157\" target=\"_blank\">CTX125157<\/a>. <br clear=\"all\" \/> <br clear=\"all\" \/><em> <br clear=\"all\" \/><\/em><\/p>\n<h4>Increase UDP FastSend threshold<\/h4>\n<p>For every UDP packet larger than 1024 bytes, the Windows network stack waits for a transmit completion interrupt before sending the next packet. Unlike for earlier releases, vSphere 5.1 does not provide a transparent workaround of the situation. See also <a href=\"https:\/\/kb.vmware.com\/selfservice\/microsites\/search.do?language=en_US&amp;cmd=displayKC&amp;externalId=2040065\" target=\"_blank\">KB2040065<\/a><\/p>\n<p>&nbsp;<\/p>\n<h4>Set multiplication factor to the default UDP scavenge value<\/h4>\n<p>High CPU usage occurs when a Windows Server 2008 R2-based server is under a very heavy UDP load. This issue occurs because a table is too aggressively scavenged. See also <a href=\"https:\/\/support.microsoft.com\/kb\/2685007\/en-us\" target=\"_blank\">KB2685007<\/a><\/p>\n<p>&nbsp;<\/p>\n<h4>Icons are hidden<\/h4>\n<p>To prevent users from accessing system tools like the PVS target device software or VMware tools the icons are removed.<\/p>\n<p>&nbsp;<\/p>\n<h4>Disable VMware debug driver<\/h4>\n<p>The virtual machine debug driver was disabled for this virtual machine message displays in event log. The virtual machine debug driver is not required in an ESX host. The driver is used for record\/play functions in Fusion and Workstation products. See also <a href=\"https:\/\/kb.vmware.com\/selfservice\/microsites\/search.do?language=en_US&amp;cmd=displayKC&amp;externalId=1007652\" target=\"_blank\">KB1007652<\/a>.<\/p>\n<h4><\/h4>\n<h4>Receive Side Scaling is disabled<\/h4>\n<p>VMXNET3 resets frequently when RSS is enabled in a multi vCPU Windows virtual machine. When Receive Side Scaling (RSS) is enabled on a multi vCPU Windows virtual machine, you see NetPort messages for repeating MAC addresses indicating that ports are being disabled and then re-enabled. See also <a href=\"https:\/\/kb.vmware.com\/selfservice\/microsites\/search.do?language=en_US&amp;cmd=displayKC&amp;externalId=2055853\" target=\"_blank\">KB2055853<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<h4><\/h4>\n<h4>Remove non-present NICs<\/h4>\n<p><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2013\/07\/Device-Manager-Network-adapters-Show-non-present-devices.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; float: right; padding-top: 0px; padding-left: 0px; margin: 0px 0px 0px 5px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"Device Manager - Network adapters - Show non present devices\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2013\/07\/Device-Manager-Network-adapters-Show-non-present-devices_thumb.png\" alt=\"Device Manager - Network adapters - Show non present devices\" width=\"154\" height=\"114\" align=\"right\" border=\"0\" \/><\/a>After removing a network adapter &#8211; for instance to replace an E1000 adapter with a vmxnet3 (because your deployment tool does not support vmxnet3) \u2013 the network adapter still exists on your Windows machine. The network adapter is not visible in device manager (see <a href=\"https:\/\/support.microsoft.com\/kb\/241257\/en-us\" target=\"_blank\">KB241257<\/a>) but it\u2019s active in the IP stack and, most likely, has a higher priority. As a result the PVS target device software is unable to communicate with the streaming server.<\/p>\n<p>All Ethernet adapters that are not present on the machine are removed using the <a href=\"https:\/\/support.microsoft.com\/kb\/311272\/en-us\" target=\"_blank\">DevCon<\/a> utility. The utility is included in the download, in case you lost it make sure you use version 6.1.7600.16385 from the <a href=\"https:\/\/www.microsoft.com\/en-us\/download\/details.aspx?id=11800\" target=\"_blank\">Windows 7 WDK<\/a> for x64 machines.<\/p>\n<p><em>Default setting: Enabled <br clear=\"all\" \/><\/em><\/p>\n<h4><br clear=\"all\" \/> <br clear=\"all\" \/>Network Adapter specific optimization<\/h4>\n<p><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2013\/07\/vmxnet3-Ethernet-Adapter.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; float: right; padding-top: 0px; padding-left: 0px; margin: 0px 0px 0px 5px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"vmxnet3 Ethernet Adapter\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2013\/07\/vmxnet3-Ethernet-Adapter_thumb.png\" alt=\"vmxnet3 Ethernet Adapter\" width=\"104\" height=\"115\" align=\"right\" border=\"0\" \/><\/a>For each network adapter (E1000, vmxnet3, vmbus, etc.) best practices exists, the most generic is disabling TCP offloading. Depending on the network adapter this has different names and some have more than one feature to disable.<\/p>\n<p><em>Default setting: Enabled<\/em><\/p>\n<p>&nbsp;<\/p>\n<p>The script changes the following sets the following properties:<\/p>\n<table style=\"width: 588px;\" border=\"1\" cellspacing=\"0\" cellpadding=\"1\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"132\"><strong>Network Adapter<\/strong><\/td>\n<td valign=\"top\" width=\"224\"><strong>Property<\/strong><\/td>\n<td valign=\"top\" width=\"230\"><strong>Value<\/strong><\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"132\">E1000 (VMware)<\/td>\n<td valign=\"top\" width=\"224\">Large Send Offload (IPv4)<\/td>\n<td valign=\"top\" width=\"230\">Disabled<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"132\">vmxnet3 (VMware)<\/td>\n<td valign=\"top\" width=\"224\">IPv4 Giant TSO Offload<\/td>\n<td valign=\"top\" width=\"230\">Disabled<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"132\"><\/td>\n<td valign=\"top\" width=\"224\">IPv4 TSO Offload<\/td>\n<td valign=\"top\" width=\"230\">Disabled<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"132\">xennet6 (XenServer)<\/td>\n<td valign=\"top\" width=\"224\">Large Send Offload Version 2 (IPv4)<\/td>\n<td valign=\"top\" width=\"230\">Disabled<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"132\">vmbus (Hyper-V)<\/td>\n<td valign=\"top\" width=\"224\">Large Send Offload Version 2 (IPv4)<\/td>\n<td valign=\"top\" width=\"230\">Disabled<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"132\"><\/td>\n<td valign=\"top\" width=\"224\"><\/td>\n<td valign=\"top\" width=\"230\"><\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"132\"><em>Missing an adapter?<\/em><\/td>\n<td valign=\"top\" width=\"224\"><em>Drop me an e-mail at<\/em><\/td>\n<td valign=\"top\" width=\"230\"><a href=\"mailto:info@ingmarverheij.com\"><em>info@ingmarverheij.com<\/em><\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>All other properties listed in the Ethernet Adapter Properties dialog can be changed as well. All known properties and values are provided in the script, all you have to do is uncomment (removing the #-character) and set the value you want.\u00a0 <em>Do NOT enable options before you\u2019ve tested this first and understand what the implications are.<\/em><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Example <br clear=\"all\" \/><\/strong>You want disable <em>IPv4 Checksum Offload <\/em>for the vmxnet3 adapter. The default value is 3 (Tx and Rx Enabled), to disable the feature you need to set the value to 0.\u00a0 In the script go to lines 256, remove the # in front of\u00a0 \u2018Set-ItemProperty\u2019 and set the value \u201c0\u201d and the end of the statement.<\/p>\n<pre lang=\"powershell\"># --- IPv4 Checksum Offload ---\r\n$strRegistryKeyName = \"*IPChecksumOffloadIPv4\"\r\n# 0 - Disabled\r\n# 1 - Tx Enabled\r\n# 2 - Rx Enabled\r\n# 3 - Tx and Rx Enabled (default)\r\nSet-ItemProperty -Path (\"HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Class\\{0}\\{1}\" -f \"{4D36E972-E325-11CE-BFC1-08002BE10318}\", ( \"{0:D4}\" -f $intNICid)) -Name $strRegistryKeyName -Value \"0\"<\/pre>\n<p>&nbsp;<\/p>\n<h1><span style=\"font-weight: bold;\">Tested platforms<\/span><\/h1>\n<p>The script is tested on multiple hypervisor platforms to ensure it covers the majority of the environments. In case your missing a hypervisor (or a version) feel free to contact me at <a href=\"mailto:info@ingmarverheij.com\">info@ingmarverheij.com<\/a>.<\/p>\n<ul>\n<li>Citrix XenServer (6.0, 6.02 and 6.2)<\/li>\n<li>Microsoft Hyper-V (2.0, 3.0 \/ 2012 and 2012 R2)<\/li>\n<li>VMware ESX (4.0, 5.0, 5.1 and 5.5)<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h1 id=\"download\"><span style=\"font-weight: bold;\">Usage <\/span>and download<\/h1>\n<p>The script runs without arguments but requires elevated privileges, this is enforced by the script. Within the script you can enable \/ disable the features in the <em>global options <\/em>section (eg removing hidden NIC\u2019s or unbinding IPv6). If wanted you can set advanced NIC properties by uncommenting the statement and providing the new value.<\/p>\n<p>The script is best executed before the vDisk is uploaded but can also be run in Private mode (starting v1.6).<\/p>\n<p>You can download the files here:\u00a0<a  data-e-disable-page-transition=\"true\" class=\"download-link\" title=\"Version 1.7\" href=\"https:\/\/ingmarverheij.com\/en\/download\/6883\/?tmstv=1776445935\" rel=\"nofollow\" id=\"download-link-6883\" data-redirect=\"false\" >\n\tOptimizePVSendpoint<\/a>\n<\/p>\n<p>&nbsp;<\/p>\n<p>.<\/p>\n<h1><span style=\"font-weight: bold;\">Thanks<\/span><\/h1>\n<p>I would like to thank the following people who where kind enough to test the script and provide me with feedback and test data:<\/p>\n<ul>\n<li>Kees Baggerman \u2013 <a href=\"https:\/\/blog.myvirtualvision.com\/\" target=\"_blank\">link<\/a><\/li>\n<li>Wilco van Bragt \u2013 <a href=\"https:\/\/virtualization.vanbragt.net\/\" target=\"_blank\">link<\/a><\/li>\n<li>Iain Brighton \u2013 <a href=\"https:\/\/virtualengine.co.uk\/author\/iainbrighton\/\" target=\"_blank\">link<\/a><\/li>\n<li>Tom Gamull \u2013 <a href=\"https:\/\/magicalyak.wordpress.com\/\" target=\"_blank\">link<\/a><\/li>\n<li>Andrew Morgan \u2013 <a href=\"https:\/\/andrewmorgan.ie\/\" target=\"_blank\">link<\/a><\/li>\n<li>Shaun Ritchie \u2013 <a href=\"https:\/\/www.shaunritchie.co.uk\/\" target=\"_blank\">link<\/a><\/li>\n<li>Jeff Wouters \u2013 <a href=\"https:\/\/jeffwouters.nl\/\" target=\"_blank\">link<\/a><\/li>\n<li>Bram Wolfs \u2013 <a href=\"https:\/\/bramwolfs.com\/\" target=\"_blank\">link<\/a><\/li>\n<li>Jonathan Pitre \u2013 <a href=\"https:\/\/ca.linkedin.com\/in\/jpitre\" target=\"_blank\">link<\/a><\/li>\n<li>Julien Destombes &#8211; <a href=\"https:\/\/fr.linkedin.com\/pub\/julien-destombes\/51\/287\/5b2\" target=\"_blank\">link<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>.<\/p>","protected":false},"excerpt":{"rendered":"<p>With Citrix PVS the content of a disk is streamed over the network to an endpoint. This requires sufficient bandwidth and an optimized configuration. If both criteria are not met the endpoint suffers from delays, retries or failures. A number of best practices apply when using Citrix PVS, most of them probably apply for your [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"site-container-style":"default","site-container-layout":"default","site-sidebar-layout":"default","disable-article-header":"default","disable-site-header":"default","disable-site-footer":"default","disable-content-area-spacing":"default","footnotes":""},"categories":[152,418],"tags":[577,578,672,505,579],"class_list":["post-5314","post","type-post","status-publish","format-standard","hentry","category-powershell","category-provisioning-server","tag-endpoint","tag-optimize","tag-powershell","tag-pvs","tag-tcp-offload"],"_links":{"self":[{"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/posts\/5314","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/comments?post=5314"}],"version-history":[{"count":31,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/posts\/5314\/revisions"}],"predecessor-version":[{"id":6887,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/posts\/5314\/revisions\/6887"}],"wp:attachment":[{"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/media?parent=5314"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/categories?post=5314"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/tags?post=5314"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}