{"id":913,"date":"2014-07-30T00:01:00","date_gmt":"2014-07-30T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2014\/07\/30\/use-powershell-to-write-verbose-output\/"},"modified":"2014-07-30T00:01:00","modified_gmt":"2014-07-30T00:01:00","slug":"use-powershell-to-write-verbose-output","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-powershell-to-write-verbose-output\/","title":{"rendered":"Use PowerShell to Write Verbose Output"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to write verbose output.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p align=\"left\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Question\" \/>&nbsp;Hey, Scripting Guy! The other day, you said that I should not use <b>Write-Host<\/b>. I even read that such usage is dangerous to the health of small canines in <a href=\"http:\/\/powershell.com\/cs\/blogs\/donjones\/archive\/2012\/04\/06\/2012-scripting-games-commentary-stop-using-write-host.aspx\" target=\"_blank\">2012 Scripting Games Commentary: STOP USING WRITE-HOST!<\/a>.<\/p>\n<p>&mdash;BP<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Answer\" \/>&nbsp;Hello BP,<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. This morning I am sipping a cup of English Breakfast tea with a cinnamon stick and a squeeze of lemon. I am using my Surface Pro&nbsp;2 to check my <a href=\"mailto:scripter@microsoft.com\">scripter@microsoft.com<\/a> email, and I saw another email from you. I decide to crank up <a href=\"http:\/\/en.wikipedia.org\/wiki\/Allen_Parsons\" target=\"_blank\">Alan Parsons<\/a> on my <a href=\"http:\/\/en.wikipedia.org\/wiki\/Zunehd\" target=\"_blank\">64-gig Zune HD<\/a>, and dive right in.<\/p>\n<h2>Use Write-Verbose<\/h2>\n<p>To provide status updates, detailed tracking information, and the like, use the <b>Write-Verbose<\/b> cmdlet The cool thing about using <b>Write-Verbose<\/b> is that I never need to modify the script. For example, if I use a whole bunch of <b>Write-Ho<\/b>st statements, eventually I may become tired of the clutter. But with <b>Write-Verbose<\/b>, I can turn on the extra output only if I decide I need it. In addition, because <b>Write-Verbose<\/b> writes to the verbose output stream, I can decide if I want to capture that output. This makes it a great option.<\/p>\n<h2>Easy way to Write-Verbose<\/h2>\n<p>By default, Windows PowerShell is set up to use <b>Write-Verbose<\/b>. The issue is that out of the box, verbose messages do not display. The <b>$VerbosePreference<\/b> preference variable controls if <b>Write-Verbose<\/b> statements appear. By default, the value of <b>$VerbosePreference<\/b> is set to <b>SilentlyContinue<\/b>, which means the messages do not appear. Because this is a simple preference variable, all I need to do is to change it in my profile. Now all verbose messages will appear in the output. This is probably not a good idea. If I want to change it, the statement is this:<\/p>\n<p style=\"margin-left:30px\">$VerbosePreference = &quot;continue&quot;<\/p>\n<p>If I do not want to make the change in my profile (we really, really do not want to make this change in our profiles), I can easily change it in my script. To do this, I first read the old value of <b>$verbosePreference<\/b>, store that in a variable, and then change <b>$verbosePreference<\/b> to <b>continue<\/b><i>. <\/i>Here is the command to do this:<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;$oldverbose = $VerbosePreference<\/p>\n<p style=\"margin-left:30px\">&nbsp; $VerbosePreference = &quot;continue&quot;<\/p>\n<p>Now, when I am done doing whatever I need to do, I simply set the old value. Here is that command:<\/p>\n<p style=\"margin-left:30px\">$VerbosePreference = $oldverbose<\/p>\n<p>To put this into a function, I create a switched parameter named <b>$verbose<\/b>, and if I call that parameter, I change the existing value of <b>$verbosePreference<\/b> to <b>continue<\/b>, and then I can use <b>Write-Verbose<\/b> to display progress, updates, and other information. Here is the complete function:<\/p>\n<p style=\"margin-left:30px\">Function test-verbose<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;Param ([switch]$verbose)<\/p>\n<p style=\"margin-left:30px\">&nbsp;if($verbose) {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; $oldverbose = $VerbosePreference<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; $VerbosePreference = &quot;continue&quot; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;Write-Verbose &quot;verbose output&quot;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&quot;Regular output&quot;<\/p>\n<p style=\"margin-left:30px\">&nbsp;$VerbosePreference = $oldverbose<\/p>\n<p style=\"margin-left:30px\">&nbsp;}<\/p>\n<p>This is pretty simple. When I call the function the first time, only regular output displays. When I call the function with <b>&ndash;verbose<\/b>, the verbose output appears along with the regular output. This is shown in the following image:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-30-14-01.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-30-14-01.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<h2>Easier way to verbose output<\/h2>\n<p>The point of the earlier command is to show you how the preference variables effect the way <b>Write-Verbose<\/b> works. (It is the same thing for other cmdlets, such as <b>Write-Debug<\/b>). But there is a slightly easier way to do this, and it is to use the <b>[cmdletbinding()]<\/b> attribute.<\/p>\n<p style=\"margin-left:30px\"><b>Note<\/b>&nbsp; There is a bit of confusion because that I must include <b>Param() <\/b>in my function&mdash;even if I am not accepting parameterized input to the function. The reason is that I am using <b>[cmdletbinding()]<\/b> as an attribute for my parameters. It does more than turn on automatic support for <b>Write-Verbose<\/b>. See the following topic (which, incidentally, does not say anything about <b>Write-Verbose<\/b>) for details: <a href=\"http:\/\/technet.microsoft.com\/en-us\/library\/hh847872.aspx\" target=\"_blank\">about_Functions_CmdletBindingAttribute<\/a>.<\/p>\n<p>All I need to do is add the <b>[cmdletbinding()]<\/b> attribute over the <b>Param()<\/b><i> <\/i>statement, and I automatically gain support for <b>Write-Verbose<\/b>. Here is the command:<\/p>\n<p style=\"margin-left:30px\">Function Test-VerboseTwo<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;[cmdletbinding()]<\/p>\n<p style=\"margin-left:30px\">&nbsp;Param()<\/p>\n<p style=\"margin-left:30px\">&nbsp;Write-Verbose &quot;Verbose output&quot;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&quot;Regular output&quot;<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p>This is seven lines as opposed to ten lines of script. It saves me three lines. Of course, <b>[cmdletbinding()]<\/b> does more than automatically wire <b>Write-Verbose<\/b>, so the savings are potentially greater. To be honest, the script is not quite as easy to read, and <b>[cmdletbinding()]<\/b> (which does not appear via Tab expansion in the ISE, nor does it really tell me what it is doing) behaves more like a black box. But hey, there is a whole topic that tells me what this little attribute does, so it is not really a black box.<\/p>\n<p>Here is the new function in action:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-30-14-02.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-30-14-02.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>It is all good, and pretty simple. Perhaps best of all, no small canines were harmed.<\/p>\n<p>BP, that is all there is to writing verbose output. Script Week will continue tomorrow when I will talk about more cool stuff.<\/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><b>Ed Wilson, Microsoft Scripting Guy<\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to write verbose output. &nbsp; &nbsp;Hey, Scripting Guy! The other day, you said that I should not use Write-Host. I even read that such usage is dangerous to the health of small canines in 2012 Scripting Games Commentary: STOP USING WRITE-HOST!. &mdash;BP &nbsp;Hello BP, [&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":[479,3,4,45],"class_list":["post-913","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-output","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to write verbose output. &nbsp; &nbsp;Hey, Scripting Guy! The other day, you said that I should not use Write-Host. I even read that such usage is dangerous to the health of small canines in 2012 Scripting Games Commentary: STOP USING WRITE-HOST!. &mdash;BP &nbsp;Hello BP, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/913","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=913"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/913\/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=913"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=913"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=913"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}