{"id":51363,"date":"2010-02-08T00:01:00","date_gmt":"2010-02-08T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2010\/02\/08\/hey-scripting-guy-how-do-i-format-with-windows-powershell-part-1\/"},"modified":"2010-02-08T00:01:00","modified_gmt":"2010-02-08T00:01:00","slug":"hey-scripting-guy-how-do-i-format-with-windows-powershell-part-1","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-do-i-format-with-windows-powershell-part-1\/","title":{"rendered":"Hey, Scripting Guy! How Do I Format with Windows PowerShell? (Part 1)"},"content":{"rendered":"<p><a class=\"addthis_button\" href=\"http:\/\/www.addthis.com\/bookmark.php?v=250&amp;pub=scriptingguys\"><img decoding=\"async\" alt=\"Bookmark and Share\" src=\"http:\/\/s7.addthis.com\/static\/btn\/v2\/lg-share-en.gif\" width=\"125\" height=\"16\"><\/a><\/p>\n<p>(<strong>Note<\/strong>: Today&#8217;s article is written by guest scripter, Thomas&nbsp;Lee. Here is Thomas&#8217; scripting autobiography from <a title=\"The Official Scripting Guys Forum!\" href=\"http:\/\/bit.ly\/scriptingforum\">The Official Scripting Guys Forum!<\/a> where he is a moderator: <span class=\"Apple-style-span\"><span class=\"Apple-style-span\"><font size=\"2\" face=\"arial,helvetica,sans-serif\">I&#8217;ve been scripting pretty much forever. I used to be pretty hot at JCL on the IBM 360 in the late 1960s, did a ton of shell scripting in the 70s on ICL VME. I learned batch scripting with DOS 2.0. I never really grokked VBS (and never got infected with *ix). But I truly \u201cgot\u201d Monad when I first saw it in September 2003 and never looked back. I&#8217;m proficient in Windows PowerShell 1.0 and 2.0, and specialize in the .NET and WMI aspects. My one interesting fact is that I was the first person to blog about Monad. Check out my <a title=\"Under the Stairs blog\" href=\"http:\/\/tfl09.blogspot.com\/\">Under the Stairs blog <\/a>and my <a title=\"PowerShel Scripts blog\" href=\"http:\/\/pshscripts.blogspot.com\/\">PowerShell Scripts blog<\/a>.<\/font><\/span><\/span><\/p>\n<p><span class=\"Apple-style-span\"><span class=\"Apple-style-span\"><font size=\"2\" face=\"arial,helvetica,sans-serif\">Part 1 is today. Part 2 will be published tomorrow. Thanks, Thomas!)<\/font><\/span><\/span><\/p>\n<p>&#8212;&#8212;&#8212;-<\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\">One of the many challenges IT pros face in managing their systems is getting information out of a computer system. Sometimes, you just want a number, such as how many e-mail messages are in the queue, or how much memory a particular server is using. When it&#8217;s simple, you don&#8217;t mind too much if the output is not particularly pretty. <\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><\/span>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\">But then there are the times you need nicely formatted output that can be read easily on paper or on the screen. You want currency to be presented as currency, not as a decimal number with some random number of digits. Or you want a number expressed as a percentage. In those cases, formatting matters. <\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><\/span>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\">Among Windows PowerShell many virtues is its ability to get simple output simply. But when you need more control over your output, you can get that too. Pithiness when you want it, richness when you need it. Some of the formatting power comes from Windows PowerShell, and some is built-in to the Microsoft .NET Framework.<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><\/span>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\">In this article, I first look at the basics of getting output and Windows PowerShell&#8217;s default formatting followed by a look at the <b>Format-*<\/b> cmdlets (and a few more). We then demonstrate how you can leverage the .NET Framework string-handling features before finishing off with using hash tables to get nicer output. As you read this article, why not open a Windows PowerShell window and type along as you read?<\/span><\/p>\n<h2><span lang=\"EN-GB\"><font size=\"3\">Formatting by Default<\/font><\/span><\/h2>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\">Most cmdlets produce objects of some sort. For example, in the Windows PowerShell console, type:<\/span><\/p>\n<p class=\"MsoNormal\"><span>LS <\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\">As you can see in the following image, you get a nice listing of your current directory. Although you can&#8217;t see it, the cmdlet actually produces a set of objects that Windows PowerShell formats so that you get output without having to do all the convoluted programming that VBScript users love. <\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><font size=\"3\"><font face=\"Times New Roman\"><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><img decoding=\"async\" title=\"Image of listing of current directory\" alt=\"Image of listing of current directory\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/fig1.jpg\" width=\"600\" height=\"385\"><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><\/span>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\">OK, so <b>LS<\/b> is really an alias of the <b>Get-ChildItem<\/b> cmdlet, but when issued against the file store provider, it still produces these object types that Windows PowerShell formats into a nice neat table. So how does the output end up looking like the directory listing we are used to? <\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><\/span>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\">The answer is simple: By default Windows PowerShell performs formatting of all the objects left in the pipeline (or the result of running a single cmdlet). The mechanism by which this happens is less simple but the basics are straightforward.<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><\/span>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\">Cmdlets typically leave something in the pipeline. You can demonstrate this by running some arbitrary Windows PowerShell cmdlet or script, and piping it to <b>Get-Member<\/b>. In the following image, you can see the object types that were produced.<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><font size=\"3\"><font face=\"Times New Roman\"><img decoding=\"async\" title=\"Image of Get-Member\" alt=\"Image of Get-Member\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/fig2.jpg\" width=\"600\" height=\"458\"><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><br \/>When Windows PowerShell finds objects that are &#8216;left over&#8217;, it just passes them to <b>Out-Host<\/b>. And Out-Host does one of two things: For most objects, it makes a call to either <b>Format-Table<\/b> or <b>Format-List<\/b> to create output. You can see this behavior by typing:<\/span><\/p>\n<p class=\"MsoNormal\"><span>ls | Format-Table<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\">As you can see if you try this, you get the same output as shown earlier (without having to pipe the output to <b>Format-Table<\/b>). Windows PowerShell chooses whether to call <b>Format-Table<\/b> or <b>Format-List<\/b> based on the number of properties that are to be displayed. By default, if the number of properties that the object contains is five or more, Windows PowerShell calls <b>Format-List<\/b>; otherwise, it calls <b>Format-Table<\/b>. The decision about which properties to display for a given object type is based on a set of PS1XML files. These XML files are installed by default, but naturally, you can override or extend them with ease to suit your needs. You can find more details about these files from within Windows PowerShell (<b>Get-Help about_Format.ps1xml<\/b>), and you can find the files themselves in C:\\Windows\\System32\\WindowsPowerShell.<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><\/span>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\">There are a few exceptions<span>&nbsp; <\/span>to this approach. The output of the <b>Format-*<\/b> cmdlets is such that <b>Out-Default<\/b> can produce output directly. The <b>Format-Table<\/b> and <b>Format-List<\/b> cmdlets produce a set of <b>Microsoft.PowerShell.Comands.Internal.Format.*<\/b> objects (as you can see in in the following image), and <b>Out-Default<\/b> is smart enough to know when to call a formatting cmdlet and when to send the output directly to the console. <\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><font size=\"3\"><font face=\"Times New Roman\"><img decoding=\"async\" title=\"Image of Format.* objects\" alt=\"Image of Format.* objects\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/fig3.jpg\" width=\"600\" height=\"587\"><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><br \/>This means that if you put one of the <b>Format-*<\/b> cmdlets at the end of a pipeline, you can override the defaults specified in the PS1XML files. And of course, there are some other output methods you can use. For example <b>Out-GridView<\/b> takes the objects left in the pipeline and formats them into a nice window, which you can see in the following image.<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><font size=\"3\"><font face=\"Times New Roman\"><img decoding=\"async\" title=\"Image of formatting with Out-GridView\" alt=\"Image of formatting with Out-GridView\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/fig4.jpg\" width=\"600\" height=\"433\"><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><br \/>This formatting scheme enables you to print by default, or to have total control over what Windows PowerShell outputs. You can specify the properties to display and a whole lot more as we shall see. <\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><b><span lang=\"EN-GB\">Format-List and Format-Table<br \/><\/span><\/b><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\">The two key cmdlets you use to display output on the screen are <b>Format-List<\/b> and <b>Format-Table<\/b>. They are very similar commands in structure. <b>Format-Table<\/b> creates a table with a set of columns, each with a column header. By default, the width of each column is determined by the size of what is being output (a file name, a count, etc). This sometimes results in very wide columns. You can use the <b>-AutoSize<\/b> parameter to get column widths as large as needed, which you can see in the following image.<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><font size=\"3\"><font face=\"Times New Roman\"><img decoding=\"async\" title=\"Image of formatting with -AutoSize\" alt=\"Image of formatting with -AutoSize\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/fig5.jpg\" width=\"600\" height=\"281\"><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><br \/>Both <b>Format-List <\/b>and <b>Format-Table<\/b> take the names of the properties of the objects in the pipeline to determine what to output. As you can see in the previous image, I&#8217;ve used just the <b>FullName<\/b> and <b>BaseName<\/b> (the name without both the folder and file type) of the files I&#8217;ve selected. <\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><\/span>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\">For any given object type, you can discover the properties available to you and what they represent by looking in the MSDN Library. Just search for the object&#8217;s full name and usually the first result is what you want. Looking for <b>System.IO.Fileinfo<\/b>, the class is defined at <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.io.fileinfo.aspx\"><font face=\"arial,helvetica,sans-serif\">http:\/\/msdn.microsoft.com\/en-us\/library\/system.io.fileinfo.aspx<\/font><\/a>. The MSDN Library is mainly aimed at developers, but if you are an experienced IT pro, you should be able to get what you need. Additionally, I&#8217;ve been slowly adding Windows PowerShell script samples to illustrate how to use a class. At the bottom of the System.IO.FileInfo page, you&#8217;ll see a short Windows PowerShell script demonstrating this object type.<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN-GB\"><\/span>&nbsp;<\/p>\n<p>See you tomorrow for Part 2!<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>(Note: Today&#8217;s article is written by guest scripter, Thomas&nbsp;Lee. Here is Thomas&#8217; scripting autobiography from The Official Scripting Guys Forum! where he is a moderator: I&#8217;ve been scripting pretty much forever. I used to be pretty hot at JCL on the IBM 360 in the late 1960s, did a ton of shell scripting in the [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[66,56,3,67,45],"class_list":["post-51363","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-net-framework","tag-guest-blogger","tag-scripting-guy","tag-thomas-lee","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>(Note: Today&#8217;s article is written by guest scripter, Thomas&nbsp;Lee. Here is Thomas&#8217; scripting autobiography from The Official Scripting Guys Forum! where he is a moderator: I&#8217;ve been scripting pretty much forever. I used to be pretty hot at JCL on the IBM 360 in the late 1960s, did a ton of shell scripting in the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/51363","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\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=51363"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/51363\/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=51363"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=51363"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=51363"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}