{"id":8903,"date":"2015-03-18T06:00:00","date_gmt":"2015-03-18T13:00:00","guid":{"rendered":"http:\/\/www.sapien.com\/blog\/?p=8903"},"modified":"2016-04-08T16:31:57","modified_gmt":"2016-04-08T23:31:57","slug":"hidden-sort-of-the-hidden-keyword-in-windows-powershell-5-0-preview","status":"publish","type":"post","link":"https:\/\/dev.sapien.com\/blog\/2015\/03\/18\/hidden-sort-of-the-hidden-keyword-in-windows-powershell-5-0-preview\/","title":{"rendered":"Hidden &#8230; sort of: The Hidden Keyword in PowerShell Classes"},"content":{"rendered":"<p>The <strong>Hidden<\/strong> keyword hides properties and methods (and other members, like events) in a PowerShell class. When a member is hidden, you can still view and change it, but the <strong>Get-Member<\/strong> cmdlet doesn&#8217;t display it without the <strong>Force<\/strong> parameter and the hidden members are not available to auto-completion features, such as PrimalSense and IntelliSense.<\/p>\n<p>You can apply the <strong>Hidden<\/strong> keyword to any member (property, method, event, etc), including static members. It is not case sensitive and it can appear anywhere in the member signature before the member name. As a best practice, I suggest placing it first to simplify troubleshooting.<\/p>\n<p>I&#8217;ve spent quite a bit of time playing with classes in the Windows PowerShell 5.0. The ability to create and script with your own classes, and to create subclasses of those classes, is extremely powerful. I consider it to be the final frontier in the dev-ops continuum, so I&#8217;m determined to make sure that everyone understands it, even people who have no development background.<\/p>\n<p>One of the little quirks of scripted classes in Windows PowerShell is that all properties of instances of the class are public, visible, and read-write. When you add properties to a class, Windows PowerShell automatically creates special methods called <em>accessors<\/em> that let users of the class get and set (view and change) the property values.<\/p>\n<p>For example, I&#8217;ll create a little Tree\u00a0class\u00a0with a Species property. At this point, I haven&#8217;t created any methods, not even constructors.<\/p>\n<pre lang=\"powershell\">class Tree\r\n{\r\n    [String] $Species\r\n}<\/pre>\n<p>When I create an instance of the Tree class&#8230;<\/p>\n<pre lang=\"powershell\">$myTree = [Tree]::new()<\/pre>\n<p>&#8230; Windows PowerShell\u00a0adds <strong>get_Species<\/strong> and <strong>set_Species<\/strong> accessor methods so you can view and change the <strong>Species<\/strong> property value. These methods are hidden, but you can see them when you use the Force parameter of Get-Member.<\/p>\n<pre class=\"output\">PS C:\\&gt; $myTree | Get-Member -Name \"*Species*\"\r\n\r\n   TypeName: Tree\r\n\r\nName    MemberType Definition               \r\n----    ---------- ----------               \r\nSpecies Property   string Species {get;set;}\r\n\r\n\r\n\r\nPS C:\\&gt; $myTree | Get-Member -Name \"*Species*\" -Force\r\n\r\n   TypeName: Tree\r\n\r\nName        MemberType Definition               \r\n----        ---------- ----------               \r\nget_Species Method     string get_Species()     \r\nset_Species Method     void set_Species(string )\r\nSpecies     Property   string Species {get;set;}<\/pre>\n<p>In fact, every variable that you create in a class outside of a method becomes a property of that class with accessor methods to view and change it.<\/p>\n<p>For example, I&#8217;ve added a <strong>Height<\/strong> property and a <strong>Grow<\/strong> method to the Tree class, and a <strong>grow_times<\/strong> variable to hold the number of times that I&#8217;ve called the <strong>Grow<\/strong> method on my tree. But Windows PowerShell considers the <strong>grow_times<\/strong> variable to be a property, and adds get\/set methods for it to the class.<\/p>\n<pre lang=\"powershell\">class Tree\r\n{\r\n    # Properties\r\n    [String] $Species\r\n    [double] $Height\r\n\r\n    # Methods\r\n    [int] Grow ([int]$inches)\r\n    {\r\n        $this.Height += $inches\r\n        $this.grow_times++\r\n        return $this.Height\r\n    }\r\n\r\n    # Variables -- these are properties, too.\r\n    [int] $grow_times = 0\r\n}<\/pre>\n<p>When I create an instance of the Tree class, <strong>grow_times<\/strong> is a property with get and set accessor methods, just like <strong>Species<\/strong> and <strong>Height<\/strong>.<\/p>\n<pre class=\"output\">PS C:\\&gt; $myTree | Get-Member\r\n\r\nTypeName: Tree\r\n\r\nName\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 MemberType Definition\r\n----\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ---------- ----------\r\nEquals\u00a0\u00a0\u00a0\u00a0\u00a0 Method\u00a0\u00a0\u00a0\u00a0 bool Equals(System.Object obj)\r\nGetHashCode Method\u00a0\u00a0\u00a0\u00a0 int GetHashCode()\r\nGetType\u00a0\u00a0\u00a0\u00a0 Method\u00a0\u00a0\u00a0\u00a0 type GetType()\r\nGrow\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Method\u00a0\u00a0\u00a0\u00a0 int Grow(int inches)\r\nToString\u00a0\u00a0\u00a0 Method\u00a0\u00a0\u00a0\u00a0 string ToString()\r\ngrow_times\u00a0 Property\u00a0\u00a0 int grow_times {get;set;}\r\nHeight\u00a0\u00a0\u00a0\u00a0\u00a0 Property\u00a0\u00a0 int Height {get;set;}\r\nSpecies\u00a0\u00a0\u00a0\u00a0 Property\u00a0\u00a0 string Species {get;set;}<\/pre>\n<p>&nbsp;<\/p>\n<p>And, when I type <strong>$myTree<\/strong> and a dot, IntelliSense suggest the <strong>grow_times<\/strong> property, along with the other properties of the tree.<\/p>\n<blockquote>\n<p style=\"padding-left: 30px;\"><a href=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2015\/03\/image.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; border: 0px;\" title=\"image\" src=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2015\/03\/image_thumb.png\" alt=\"image\" width=\"417\" height=\"174\" border=\"0\" \/><\/a><\/p>\n<\/blockquote>\n<p>I can&#8217;t make my variable completely private to the class \u2013 there is no Private keyword &#8212; but there is a <strong>Hidden<\/strong> keyword that hides members from auto-complete features and from Get-Member without \u2013Force.<\/p>\n<p>In this example, I add the <strong>Hidden<\/strong> keyword to the <strong>grow_times<\/strong> property. I can place\u00a0&#8220;Hidden&#8221;\u00a0anywhere in the statement before the name, that is, it can go before or after &#8220;[int]&#8221; or an attribute, but I think it&#8217;s best to place it first, especially for troubleshooting.<\/p>\n<pre lang=\"powershell\">class Tree\r\n{\r\n    # Properties\r\n    [String] $Species\r\n    [double] $Height\r\n\r\n    # Methods\r\n    [int] Grow ([int]$inches)\r\n    {\r\n        $this.Height += $inches\r\n        $this.grow_times++\r\n        return $this.Height\r\n    }\r\n\r\n    # Hidden properties\r\n    hidden [int] $grow_times = 0\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>Now, when I create a tree object and run Get-Member, the <strong>grow_times<\/strong> property is not displayed.<\/p>\n<blockquote>\n<p style=\"padding-left: 30px;\"><a href=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2015\/03\/image1.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; border: 0px;\" title=\"image\" src=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2015\/03\/image_thumb1.png\" alt=\"image\" width=\"439\" height=\"185\" border=\"0\" \/><\/a><\/p>\n<\/blockquote>\n<p>The property is visible to Get-Member only with \u2013Force.<\/p>\n<pre class=\"output\">PS C:\\&gt; $myTree | Get-Member -MemberType Property\r\n\r\nTypeName: Tree\r\n\r\nName\u00a0\u00a0\u00a0 MemberType Definition\r\n----\u00a0\u00a0\u00a0 ---------- ----------\r\nHeight\u00a0 Property\u00a0\u00a0 int Height {get;set;}\r\nSpecies Property\u00a0\u00a0 string Species {get;set;}\r\n\r\n\r\nPS C:\\&gt; $myTree | Get-Member -MemberType Property -Force\r\n\r\nTypeName: Tree\r\n\r\nName\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 MemberType Definition\r\n----\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ---------- ----------\r\ngrow_times Property\u00a0\u00a0 int grow_times {get;set;}\r\nHeight\u00a0\u00a0\u00a0\u00a0 Property\u00a0\u00a0 int Height {get;set;}\r\nSpecies\u00a0\u00a0\u00a0 Property\u00a0\u00a0 string Species {get;set;}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Users of the class can get and set the <strong>grow_times<\/strong> property, but only if they know about it. It is not advertised to them.\u00a0(You cannot override or redefine the property accessors.)<\/p>\n<pre class=\"output\">PS C:\\&gt; $myTree.grow_times\r\n0\r\n\r\nPS C:\\ps-test&gt; $myTree.grow_times++\r\n\r\nPS C:\\ps-test&gt; $myTree.grow_times\r\n1<\/pre>\n<p>&nbsp;<\/p>\n<p>And, even though it is hidden, <strong>grow_times<\/strong> is available to all members of the class, including the Grow() method that increments it.<\/p>\n<pre class=\"output\">PS C:\\&gt; $myTree.Height = 10\r\n\r\nPS C:\\&gt; $myTree.grow_times\r\n0\r\n\r\nPS C:\\&gt; $myTree.Grow(2)\r\n12\r\n\r\nPS C:\\&gt; $myTree.grow_times\r\n1<\/pre>\n<p>Windows PowerShell classes give you a whole new level of power. And, the Hidden keyword is a handy tool for making classes work the way you designed them.<\/p>\n<p><strong>Update 4\/08\/2016<\/strong>: Bruce Payette, the PowerShell team language developer, explained that we don&#8217;t have a <strong>Private<\/strong> keyword because PowerShell uses PowerShell for debugging. If you were able to create a property that was invisible to PowerShell, you couldn&#8217;t debug it.<\/p>\n<p><em>June Blender is a technology evangelist at SAPIEN Technologies, Inc. You can reach her at <\/em><a href=\"mailto:juneb@sapien.com\"><em>juneb@sapien.com<\/em><\/a><em> or follow her on Twitter at <\/em><a href=\"https:\/\/twitter.com\/juneb_get_help\"><em>@juneb_get_help<\/em><\/a><em>.<\/em><\/p>\n<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/p>\n<p>More SAPIEN blog posts about the Windows PowerShell 5.0 classes:<\/p>\n<p><a title=\"Beyond custom objects- Create a .NET class\" href=\"http:\/\/www.sapien.com\/blog\/2014\/12\/02\/beyond-custom-objects-create-a-net-class\/\" target=\"_blank\">Beyond custom objects- Create a .NET class<\/a><br \/>\n<a title=\"Enumerated Types in Windows PowerShell 5.0\" href=\"http:\/\/www.sapien.com\/blog\/2015\/01\/05\/enumerators-in-windows-powershell-5-0\/\" target=\"_blank\">Enumerated Types in Windows PowerShell 5.0<\/a><br \/>\n<a title=\"Find variables with class\" href=\"http:\/\/www.sapien.com\/blog\/2014\/12\/24\/find-variables-with-class\/\" target=\"_blank\">Find variables with class<\/a><br \/>\n<a title=\"Creating Objects in Windows PowerShell\" href=\"https:\/\/www.sapien.com\/blog\/2015\/10\/26\/creating-objects-in-windows-powershell\/\" target=\"_blank\">Creating Objects in Windows PowerShell<\/a><br \/>\n<a title=\"Why Do We Need Constructors?\" href=\"https:\/\/www.sapien.com\/blog\/2015\/10\/21\/why-do-we-need-constructors\/\" target=\"_blank\">Why Do We Need Constructors?<\/a><br \/>\n<a title=\"Inheritance in PowerShell Classes\" href=\"https:\/\/www.sapien.com\/blog\/2016\/03\/16\/inheritance-in-powershell-classes\/\" target=\"_blank\">Inheritance in PowerShell Classes<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Hidden keyword hides properties and methods (and other members, like events) in a PowerShell class. When a member is hidden, you can still view and change it, but the Get-Member cmdlet doesn&#8217;t display it without the Force parameter and the hidden members are not available to auto-completion features, such as PrimalSense and IntelliSense. You [&hellip;]<\/p>\n","protected":false},"author":31,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[1033,941,1092,25],"tags":[934,28,962],"class_list":["post-8903","post","type-post","status-publish","format-standard","hentry","category-classes-in-powershell-5-0","category-powershell-5-0","category-powershell-5-0-14279-1000","category-windows-powershell","tag-juneb","tag-powershell","tag-powershell5-0"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/8903","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/users\/31"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/comments?post=8903"}],"version-history":[{"count":22,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/8903\/revisions"}],"predecessor-version":[{"id":11766,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/8903\/revisions\/11766"}],"wp:attachment":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/media?parent=8903"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/categories?post=8903"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/tags?post=8903"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}