{"id":264,"date":"2014-12-01T00:01:00","date_gmt":"2014-12-01T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2014\/12\/01\/provide-support-by-using-verbose-and-debug-streams\/"},"modified":"2019-02-18T10:36:50","modified_gmt":"2019-02-18T17:36:50","slug":"provide-support-by-using-verbose-and-debug-streams","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/provide-support-by-using-verbose-and-debug-streams\/","title":{"rendered":"Provide Support by Using Verbose and Debug Streams"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">:&nbsp;<\/span><span style=\"font-size:12px\">Provide code support by using <strong>Verbose<\/strong> and <strong>Debug<\/strong> streams.<\/span><\/p>\n<p>Honorary Scripting Guy and Windows PowerShell MVP, Boe Prox, here today filling in for my good friend, The Scripting Guy. This is the first part in a series of five posts about troubleshooting Windows PowerShell scripts and functions. The series includes:<\/p>\n<ol>\n<li><b>Provide Support by Using Verbose and Debug Streams <\/b>(this post)<\/li>\n<li>Troubleshoot by Using Set-PSDebug<\/li>\n<li>Enforce Better Script Practices by Using Set-StrictMode<\/li>\n<li>Trace Your Commands by Using Trace-Command<\/li>\n<li>Use the PowerShell Debugger<\/li>\n<\/ol>\n<p>When you write a script or function, you want to make sure that things work correctly and that you have provided enough information for the individuals who will be using the code in their day-to-day activities. Although you have <b>Get-Help<\/b> and inline comments in the code, sometimes they don&rsquo;t provide the kind of troubleshooting that is needed when you are not getting the results that you are expecting.<\/p>\n<p>We need a way to provide on-screen information that can be turned on or off without much more than a simple parameter. If only we had some sort of <b>Verbose<\/b> or <b>Debug<\/b> capability that could make this happen&hellip;<\/p>\n<p>Oh, wait!<\/p>\n<p>We have this built-in with Windows PowerShell!<\/p>\n<p>Whenever a script or function is being built, all we have to do is add a couple of lines at the beginning of the code block to enable the <b>Verbose<\/b> and <b>Debug<\/b> parameters. As shown here, those pieces are <b>[cmdletbinding()]<\/b> and <b>Param()<\/b>:<\/p>\n<p style=\"margin-left:30px\">[cmdletbinding()]<\/p>\n<p style=\"margin-left:30px\">Param ()<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/UsingVerboseDebugStreams1.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/UsingVerboseDebugStreams1.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>You <b>must<\/b> have these attributes available to have this capability. After this is accomplished, you can use <b>Write-Verbose<\/b> and <b>Write-Debug<\/b> in your code to provide more information when the script runs. Of course, you could use <b>Write-Host<\/b>, but that doesn&rsquo;t turn off unless you provide your own parameter (a switch) and then use some logic to run the command if the parameter is used.<\/p>\n<p>Using <b>Verbose<\/b> and <b>Debug<\/b> provides a cleaner approach to providing output by having a single line (Write-Verbose or Write-Debug) that provides information to the users (or to yourself) when someone is attempting to figure out why a script isn&rsquo;t running the way it should. Another great feature that was introduced in Windows PowerShell&nbsp;3.0 is that you can redirect the streams to a file if needed.<\/p>\n<p style=\"margin-left:30px\"><b>Note&nbsp;<\/b> June Blender wrote an excellent post that you can read for more information: <a href=\"https:\/\/devblogs.microsoft.com\/scripting\/understanding-streams-redirection-and-write-host-in-powershell\/\" target=\"_blank\">Understanding Streams, Redirection, and Write-Host in PowerShell<\/a>.<\/p>\n<p>So how should I use <b>Write-Verbose<\/b> and <b>Write-Debug<\/b>? In the end, it depends on what you want to use them for. In my case, I use them in the following ways:<\/p>\n<ul>\n<li><b>Write-Verbose<\/b><br \/> More for the user experience to show what is happening during the execution of the script.<\/li>\n<li><b>Write-Debug<\/b><br \/> More for the code writer to show various points in the code, such as variables and their current values, that I can use to troubleshoot issues.<\/li>\n<\/ul>\n<p>Knowing what I need to do to use <b>Verbose<\/b> and <b>Debug<\/b> streams, I can add those to a function and give it a run to see what happens. The following function provides an example to show using <b>Verbose<\/b> and <b>Debug<\/b>:<\/p>\n<p style=\"margin-left:30px\">Function Invoke-Action {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; [cmdletbinding()]<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; Param (<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $Computername,<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [hashtable]$Options,<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $Timeout<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; )&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $PSBoundParameters.GetEnumerator() | ForEach {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write-Debug &quot;[PSBoundParameters] $($_)&quot;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; If ($PSBoundParameters[&#039;Options&#039;]) {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $Options.GetEnumerator() | ForEach {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write-Debug &quot;[Options] $($_.Name) -&gt; $($_.Value)&quot;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; ForEach ($Computer in $Computername) {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write-Verbose &quot;Testing $Computer&quot;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p>Running this with both the <b>&ndash;Verbose<\/b> and <b>&ndash;Debug<\/b> parameters will give us a couple of streams that we can use to help determine what is going on in the script when it is running. Notice that I do not have to specify <b>&ndash;Verbose<\/b> or <b>&ndash;Debug<\/b> when I use <b>Write-Verbose<\/b> and <b>Write-Debug<\/b>. I will have to specify these parameters when I call the function in order to see the desired results.<\/p>\n<p style=\"margin-left:30px\">Invoke-Action -Computername &#039;Computer1&#039;,&#039;Computer2&#039;,&#039;Computer3&#039; -Options @{SkipIfOffline=$True;TestIsAdmin=$False} -Timeout 100 -Verbose -Debug<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/UsingVerboseDebugStreams2.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/UsingVerboseDebugStreams2.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>As you can see in this image, I have <b>Debug<\/b> showing the values of my bound parameters and listing the values in my options parameter. When you use <b>&ndash;Debug<\/b> in the function, it automatically sets the <b>$DebugPreference<\/b> for the scope of the function to <b>&lsquo;Inquire&rsquo;<\/b>, which works by prompting for user interaction.<\/p>\n<p>I opted to use <b>Verbose<\/b> to say what was happening with the action being performed in the script. I could do more with either of these parameters, such as adding a time stamp, which can make it easier to see when each action is happening. I could also add a line number so myself or someone else can know exactly where the action is taking place.<\/p>\n<p>As mentioned earlier, it is my preference to use <b>Debug<\/b> and <b>Verbose<\/b>, and not everyone might share this approach. When you use these in your code to provide some sort of simple troubleshooting of a script, you really can&rsquo;t go wrong. The idea is to provide an approach so that you or someone else using your script can track down a possible issue and hopefully resolve it.<\/p>\n<p>That is all there is to using the <b>Verbose<\/b> and <b>Debug<\/b> streams in a script or function to provide a way to troubleshoot scripts. Tomorrow I will show you how to use the <b>Set-PSDebug<\/b> cmdlet to troubleshoot scripts.<\/p>\n<p>We invite you to follow the Scripting Guy on&nbsp;<a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a>&nbsp;and&nbsp;<a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to the Scripting Guy at&nbsp;<a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the&nbsp;<a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. Until then, see ya!<\/p>\n<p><b>Boe Prox<\/b>, Windows PowerShell MVP and Honorary Scripting Guy<span style=\"font-size:12px\">&nbsp;<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary:&nbsp;Provide code support by using Verbose and Debug streams. Honorary Scripting Guy and Windows PowerShell MVP, Boe Prox, here today filling in for my good friend, The Scripting Guy. This is the first part in a series of five posts about troubleshooting Windows PowerShell scripts and functions. The series includes: Provide Support by Using Verbose [&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":[162,3,554,134,45],"class_list":["post-264","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-boe-prox","tag-scripting-guy","tag-streams","tag-troubleshooting","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary:&nbsp;Provide code support by using Verbose and Debug streams. Honorary Scripting Guy and Windows PowerShell MVP, Boe Prox, here today filling in for my good friend, The Scripting Guy. This is the first part in a series of five posts about troubleshooting Windows PowerShell scripts and functions. The series includes: Provide Support by Using Verbose [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/264","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=264"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/264\/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=264"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=264"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=264"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}