{"id":2847,"date":"2013-09-19T00:01:00","date_gmt":"2013-09-19T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/09\/19\/helpinfouri-helpuri-and-other-help-mysteries\/"},"modified":"2013-09-19T00:01:00","modified_gmt":"2013-09-19T00:01:00","slug":"helpinfouri-helpuri-and-other-help-mysteries","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/helpinfouri-helpuri-and-other-help-mysteries\/","title":{"rendered":"HelpInfoUri, HelpUri, and other Help Mysteries"},"content":{"rendered":"<p><strong>Summary<\/strong>: Learn about Updatabe Help in Windows PowerShell 3.0.<\/p>\n<p>Scripting Guy, Ed Wilson here. Today June Blender is back to tell us about Updatable Help in Windows PowerShell&nbsp;3.0. Take it away, June&hellip;<\/p>\n<p>One of the great advances in Windows PowerShell&nbsp;3.0 is Updatable Help.&nbsp;The advantages of updating the Help files on the box between releases are significant, far outweighing the minor hassle of running that first <strong>Update-Help<\/strong> or <strong>Save-Help<\/strong> command if the module does not include Help files. But there is still a bit of confusion associated with Updatable Help, and I&#8217;m here to explain.<\/p>\n<h2>Does this module support Updatable Help?<\/h2>\n<p>Some modules support Updatable Help and others do not. Fortunately, there&#8217;s an easy way to tell which modules support Updatable Help.<\/p>\n<p>If the <strong>HelpInfoUri<\/strong> property of a command (such as cmdlet, function, CIM command, or workflow) has a value, and the value is valid (that is, it begins with &#8220;http&#8221; or &#8220;https&#8221;), the module supports Updatable Help.<\/p>\n<p class=\"Code\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PS C:\\&gt; Get-Module -ListAvailable | where HelpInfoUri<\/p>\n<p>The <strong>HelpInfoUri<\/strong> property of each module object comes from the <strong>HelpInfoUri <\/strong>key in the module manifest. Following is the module manifest of the <strong>NetQos<\/strong> module, and you can see the <strong>HelpInfoUri<\/strong> key:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:\\ps-test&gt; cat (get-module -list netqos).path<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">@{<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; GUID = &#8216;743692B7-A227-4389-B082-2B47DE1D0D2D&#8217;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Author = &#8220;Microsoft Corporation&#8221;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; CompanyName = &#8220;Microsoft Corporation&#8221;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Copyright = &#8220;&copy; Microsoft Corporation. All rights reserved.&#8221;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; ModuleVersion = &#8216;1.0&#8217;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; PowerShellVersion = &#8216;3.0&#8217;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; NestedModules = @(&#8216;MSFT_NetQosPolicy.cdxml&#8217;)<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; FormatsToProcess = @(&#8216;MSFT_NetQosPolicy.format.ps1xml&#8217;)<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; TypesToProcess = @(&#8216;MSFT_NetQosPolicy.types.ps1xml&#8217;)<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; HelpInfoUri = &#8220;http:\/\/go.microsoft.com\/fwlink\/?LinkId=216150&#8221;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; FunctionsToExport = @(<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8216;Get-NetQosPolicy&#8217;,<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8216;Set-NetQosPolicy&#8217;,<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8216;Remove-NetQosPolicy&#8217;,<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8216;New-NetQosPolicy&#8217;)<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">}<\/p>\n<p>This command gets the manifest as a hash table, so you can get the keys as properties. The command returns the value of the <strong>HelpInfoUri<\/strong> key.<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:\\ps-test&gt;(Invoke-Expression (Get-Content (Get-Module -List NetQos).Path -Raw)).HelpInfoUri<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkId=216150\" target=\"_blank\">http:\/\/go.microsoft.com\/fwlink\/?LinkId=216150<\/a><\/p>\n<h2>Why is it called HelpInfoUri?<\/h2>\n<p>You might think that the Windows PowerShell team spends its lunch hours dreaming up weird property names, like <strong>HelpInfoUri<\/strong>, but if you know a bit about the innards of Updatable Help, this name actually makes sense.<\/p>\n<p>The URI in <strong>HelpInfoUri<\/strong> is the address of the HelpInfo.xml file for the module&#8217;s Updatable Help files. So the value is really the URI of <strong>HelpInfo<\/strong>. (The Updatable Help files can be in the same location, and often are, but they can also be in a different location.)<\/p>\n<p>The HelpInfo.xml file is like an old-fashioned .inf file. Remember <a href=\"http:\/\/en.wikipedia.org\/wiki\/Autorun.inf\" target=\"_blank\">Autorun.inf<\/a>? These INFormation files store options for programs like the registry does. We use XML files for efficiency and easy parsing (see <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=135255\" target=\"_blank\">Select-XML<\/a>) but the idea is the same.<\/p>\n<h2>The HelpInfo XML file<\/h2>\n<p>Because we&#8217;re picking on <strong>NetQos<\/strong> today (an AWESOME module), let&#8217;s look at the HelpInfo.xml file for the <strong>NetQos<\/strong> module. When you use <strong>Update-Help<\/strong> or <strong>Save-Help<\/strong> to download Updatable Help files, the cmdlets also download the <strong>HelpInfo<\/strong> XML file and save it in the module directory on your hard drive. So, we can examine the file locally:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:\\ps-test&gt; Get-Content C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\Modules\\NetQos\\NetQos<br \/> _743692b7-a227-4389-b082-2b47de1d0d2d_HelpInfo.xml<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243;?&gt;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&lt;HelpInfo xmlns=&#8221;http:\/\/schemas.microsoft.com\/powershell\/help\/2010\/05&#8243;&gt;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp; &lt;HelpContentURI&gt;http:\/\/go.microsoft.com\/fwlink\/?LinkId=216150&lt;\/HelpContentURI&gt;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp; &lt;SupportedUICultures&gt;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; &lt;UICulture&gt;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;UICultureName&gt;en-US&lt;\/UICultureName&gt;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;UICultureVersion&gt;3.0.0.0&lt;\/UICultureVersion&gt;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; &lt;\/UICulture&gt;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp; &lt;\/SupportedUICultures&gt;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&lt;\/HelpInfo&gt;<\/p>\n<p>The <strong>HelpInfo<\/strong> XML file has an element for each supported UI culture. Each <strong>SupportedUICulture<\/strong> element contains the <strong>HelpContentUri<\/strong>, which is the URI of the Updatable Help CAB file. If the <strong>HelpInfo<\/strong> XML file and the CAB file are in the same place, the <strong>HelpContentUri<\/strong> value is same as the <strong>HelpInfoUri<\/strong> value. The <strong>SupportedUICulture<\/strong> element also contains information for each UI culture, including the version number of the Help files.<\/p>\n<p>The <strong>Update-Help<\/strong> and <strong>Save-Help<\/strong> cmdlets use the version number in the <strong>HelpInfo<\/strong> XML file to determine whether you have the latest Help files on your machine. Otherwise, the cmdlets download and install the latest version.<\/p>\n<h2>Why can&#8217;t I read Help at the HelpInfoUri location?<\/h2>\n<p>I bet everyone who&#8217;s played with Windows PowerShell Updatable Help has tried a variation of this command, which opens your default Internet browser to the location that is specified by the <strong>HelpInfoUri<\/strong> value:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:\\&gt; $u = (Get-Module -List NetQos).HelpInfoUri<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:\\&gt; (new-object -com shell.application).Open($u)<\/p>\n<p>Or you might have pasted the URI in your browser address bar. And you expected to see the Help topics for the module, or some interesting content. But there was nothing there except a file.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3276.01.png\"><img decoding=\"async\" title=\"Image of file\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3276.01.png\" alt=\"Image of file\" width=\"400\" height=\"325\" \/><\/a><\/p>\n<p>In the location where Windows stores Updatable Help files, there are no HTML files to display content. There are just the lowly CAB files, which are very valuable, but don&#8217;t create an UI.<\/p>\n<p>If you try the same trick with the <strong>HelpUri<\/strong> property of a cmdlet, the result is much better.<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:\\&gt; $u = (Get-Command Get-History).HelpUri<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:\\&gt; (New-Object -Com Shell.Application).Open($u)<\/p>\n<p>Or, better yet:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:\\&gt; Get-Help Get-History -Online<\/p>\n<h2>What is HelpUri?<\/h2>\n<p>Now that we know about the <strong>HelpInfoUri<\/strong> property of modules, what is the <strong>HelpUri<\/strong> property of commands?<\/p>\n<p>The URI in the value of the <strong>HelpUri<\/strong>&nbsp;property is the online location of the Help topic for the command:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">PS C:\\ps-test&gt; (Get-Command Get-History).HelpUri<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=113317\" target=\"_blank\">http:\/\/go.microsoft.com\/fwlink\/?LinkID=113317<\/a><\/p>\n<p>The <strong>Online<\/strong> parameter of <strong>Get-Help<\/strong> uses the <strong>HelpUri<\/strong> (among other things) to find the online Help topic. It can be overridden, but it&#8217;s the best guess for the URI at the time that the command is written.<\/p>\n<p>The value of the <strong>HelpUri<\/strong> comes from the command script. In cmdlets, <strong>HelpUri<\/strong> is a named parameter of the <strong>Cmdlet<\/strong> attribute:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">[Cmdlet(VerbsCommon.Get, &#8220;History&#8221;, HelpUri = &#8220;http:\/\/go.microsoft.com\/fwlink\/?LinkID=001122&#8221;)]<\/p>\n<p>In functions, <strong>HelpUri<\/strong> is a parameter of the <strong>CmdletBinding<\/strong> attribute:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">function New-Calendar {<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; [CmdletBinding(SupportsShouldProcess=$true,<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; HelpURI=&#8221;http:\/\/go.microsoft.com\/fwlink\/?LinkID=01122&#8243;)]<\/p>\n<p>You can also specify a <strong>HelpUri<\/strong> property value in CIM commands and workflows. For the details, see <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=242132\" target=\"_blank\">Supporting Online Help<\/a> in the Windows PowerShell SDK.<\/p>\n<p>Now, about the &#8220;it can be overridden&#8221; part. When a Help topic for the command is installed on the computer, and the first related link in the Help topic is a valid URL, the first related link URL takes precedence over the <strong>HelpUri<\/strong> value of the command. That is, the <strong>Online<\/strong> parameter of <strong>Get-Help<\/strong> uses the first related link if it&#8217;s a URL. And if it&#8217;s not, it uses the value of the <strong>HelpUri<\/strong> property of the command.<\/p>\n<p>Why? In Windows PowerShell&nbsp;3.0, the <strong>HelpUri<\/strong> property value of a command comes from the <strong>HelpUri<\/strong> attribute in the cmdlet code. But, in Windows PowerShell&nbsp;2.0, the <strong>HelpUri<\/strong> property value came from the first related link in the Help topic, if that link included a URL.<\/p>\n<p>When we developed Updatable Help, we wanted online Help to work even when the Help files were not installed on the local machine&mdash;so we couldn&#8217;t rely on a value in a local Help file. That&#8217;s when we added the <strong>HelpUri<\/strong> attribute to the cmdlet (and function, CIM command, and workflow) script.<\/p>\n<p>But, we maintained the first related link source for backward compatibility and to provide a way to change the online Help topic location without changing the cmdlet.<\/p>\n<p>Here&#8217;s the relevant section from the <strong>Get-History <\/strong>Help topic:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Related Links<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Online Version: http:\/\/go.microsoft.com\/fwlink\/?LinkID=113317<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Add-History<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Clear-History<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Invoke-History<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; about_History<\/p>\n<p>And here&#8217;s the XML for the first related link:<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&lt;maml:relatedLinks&gt;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp; &lt;maml:navigationLink&gt;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><strong>&nbsp;&nbsp; <\/strong>&lt;maml:linkText&gt;<strong>Online Version:<\/strong>&lt;\/maml:linkText&gt;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><strong>&nbsp;&nbsp; <\/strong>&lt;maml:uri&gt;<strong>http:\/\/go.microsoft.com\/fwlink\/?LinkID=113317<\/strong>&lt;\/maml:uri&gt;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><strong>&nbsp; <\/strong>&lt;\/maml:navigationLink&gt;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\"><strong>&nbsp;<\/strong>&lt;\/maml:relatedLinks&gt;<\/p>\n<h2>&hellip;and other Help mysteries<\/h2>\n<p>The Help system in Windows PowerShell is not simple. In fact, it&#8217;s quite revolutionary. And you can use every feature of the Help system to make the modules and commands that you write really easy for users to use.<\/p>\n<p>If you have question about the Updatable Help system, or any other aspect of Windows PowerShell, please reply in the Feedback section at the bottom of this page or tweet me a question at @juneb_get_help, and I&#8217;ll answer them in a follow-up blog post.<\/p>\n<p>If you are confused about URIs, URLs, URNs, and other URs, see this great blog post by Windows Azure Active Directory PM, Vittorio Bertocci. It&#8217;s the best one I&#8217;ve seen: <a href=\"http:\/\/www.cloudidentity.com\/blog\/2013\/03\/02\/url-urn-uri-oh-my\/\">URL, URN, URI: Oh My!<\/a><\/p>\n<p>~June<\/p>\n<p>Thank you, June.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Ed Wilson, Microsoft Scripting Guy<\/strong><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Learn about Updatabe Help in Windows PowerShell 3.0. Scripting Guy, Ed Wilson here. Today June Blender is back to tell us about Updatable Help in Windows PowerShell&nbsp;3.0. Take it away, June&hellip; One of the great advances in Windows PowerShell&nbsp;3.0 is Updatable Help.&nbsp;The advantages of updating the Help files on the box between releases are [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[56,370,52,3,45],"class_list":["post-2847","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-guest-blogger","tag-june-blender","tag-modules","tag-scripting-guy","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Learn about Updatabe Help in Windows PowerShell 3.0. Scripting Guy, Ed Wilson here. Today June Blender is back to tell us about Updatable Help in Windows PowerShell&nbsp;3.0. Take it away, June&hellip; One of the great advances in Windows PowerShell&nbsp;3.0 is Updatable Help.&nbsp;The advantages of updating the Help files on the box between releases are [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2847","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=2847"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2847\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=2847"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=2847"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=2847"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}