{"id":6411,"date":"2015-04-27T00:01:00","date_gmt":"2015-04-27T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2015\/04\/27\/favorite-powershell-tips-and-tricks\/"},"modified":"2019-02-18T10:29:45","modified_gmt":"2019-02-18T17:29:45","slug":"favorite-powershell-tips-and-tricks","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/favorite-powershell-tips-and-tricks\/","title":{"rendered":"Favorite PowerShell Tips and Tricks"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">: Microsoft Scripting Guy, Ed Wilson, talks about Windows PowerShell tips and tricks from the Charlotte User Group meeting.<\/span><\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Last week was a special meeting at the Charlotte Windows PowerShell User Group. It followed immediately after the Windows PowerShell Summit, and as a result, the user group included five members of the Windows PowerShell team, nearly a dozen MVPs, and at least that many Microsoft employees. All in all, there were nearly a hundred people in the room, and that, I believe, makes it the largest Windows PowerShell User Group meeting so far in Charlotte.<\/p>\n<p>Lee Holmes led the meeting, and the subject was Windows PowerShell tips and tricks. But instead of Lee standing in front of us, doing a show-and-tell, he showed a trick, and then asked for one from the audience. The trick had to be something that people used on a regular basis, which means they are useful, not simply esoteric. The meeting was amazing, and this week I am going to share the best with you in Tips and Tricks Week.<\/p>\n<h2>Add resource usage to your Windows PowerShell prompt<\/h2>\n<p>This tip actually incorporates several tips at once. One tip involves making sure that you read the automatic variables list and descriptions from time-to-time (see <a href=\"https:\/\/technet.microsoft.com\/en-us\/library\/hh847768.aspx\" target=\"_blank\">about_Automatic_Variables<\/a>). As Lee Holmes said, &ldquo;If the Windows PowerShell team takes the time to create an automatic variable and to include it in everything, then it is obviously important.&rdquo;<\/p>\n<p>There are a lot of automatic variables, and some of them only appear at certain times and at certain places. So, one cannot simply use <b>Get-Variable<\/b> and see all of the automatic variables.<\/p>\n<p>Two more tips involve creating and using a Windows PowerShell profile and modifying the Windows PowerShell prompt. For more information, read these Hey, Scripting Guy! Blog posts:<\/p>\n<ul>\n<li><a href=\"\/b\/heyscriptingguy\/archive\/2012\/05\/21\/understanding-the-six-powershell-profiles.aspx\" target=\"_blank\">Understanding the Six PowerShell Profiles<\/a><\/li>\n<li><a href=\"\/b\/heyscriptingguy\/archive\/2014\/12\/28\/weekend-scripter-playing-with-powershell-prompt.aspx\" target=\"_blank\">Playing with PowerShell Prompt<\/a><\/li>\n<\/ul>\n<p>One of the attendees at the Charlotte Windows PowerShell User Group meeting mentioned that he once ran into trouble with a long running Windows PowerShell job that soaked up a lot of resources. To help to indicate what was going on with the long running job, he modified his Windows PowerShell prompt to include information about Windows PowerShell resource usage.<\/p>\n<p>The Windows PowerShell prompt, is simply a function that is named &ldquo;prompt.&rdquo; It is a bit different, depending on whether one is running in the Windows PowerShell console or in the Windows PowerShell ISE. But if I use the following command, I will always return the appropriate prompt function:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; Get-Content Function:\\prompt<\/p>\n<p style=\"margin-left:30px\">&quot;PS $($executionContext.SessionState.Path.CurrentLocation)$(&#039;&gt;&#039; * ($nestedPromptLevel<\/p>\n<p style=\"margin-left:30px\">+ 1)) &quot;<\/p>\n<p style=\"margin-left:30px\"># .Link<\/p>\n<p style=\"margin-left:30px\"># http:\/\/go.microsoft.com\/fwlink\/?LinkID=225750<\/p>\n<p style=\"margin-left:30px\"># .ExternalHelp System.Management.Automation.dll-help.xml<\/p>\n<p><span style=\"font-size:12px\">I like to copy the contents of the function, so I have something to begin playing around with:<\/span><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-4-27-15-01.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-4-27-15-01.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>From looking over the automatic variable list, I found a <b>$pid<\/b> automatic variable. This variable displays the process ID for the Windows PowerShell process that hosts the current Windows PowerShell session. This is shown here:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $pid<\/p>\n<p style=\"margin-left:30px\">2972<\/p>\n<p>This means that I can use the <b>Get-Process<\/b> cmdlet to retrieve performance information about the current Windows PowerShell process. This is important to do because there could be multiple Windows PowerShell processes running, and I want to return the correct one. This technique is shown here:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; Get-Process -Id $pid<\/p>\n<p style=\"margin-left:30px\">Handles&nbsp; NPM(K)&nbsp;&nbsp;&nbsp; PM(K)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WS(K) VM(M)&nbsp;&nbsp; CPU(s)&nbsp;&nbsp;&nbsp;&nbsp; Id ProcessName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"margin-left:30px\">&#8212;&#8212;-&nbsp; &#8212;&#8212;&nbsp;&nbsp;&nbsp; &#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8211; &#8212;&#8211;&nbsp;&nbsp; &#8212;&#8212;&nbsp;&nbsp;&nbsp;&nbsp; &#8212; &#8212;&#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; 1093&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 79&nbsp;&nbsp; 167652&nbsp;&nbsp;&nbsp;&nbsp; 196780&nbsp; 1070&nbsp;&nbsp;&nbsp; 11.44&nbsp;&nbsp; 2972 powershell_ise&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"margin-left:30px\"><b style=\"font-size:12px\">Note&nbsp;<\/b><span style=\"font-size:12px\"> It is important to supply the <\/span><b style=\"font-size:12px\">&ndash;ID<\/b><span style=\"font-size:12px\"> parameter when using <\/span><b style=\"font-size:12px\">$pid<\/b><span style=\"font-size:12px\"> with <\/span><b style=\"font-size:12px\">Get-Process<\/b><span style=\"font-size:12px\"> because the default parameter for <\/span><b style=\"font-size:12px\">Get-Process<\/b><span style=\"font-size:12px\"> is name, and an error occurs if I use <\/span><b style=\"font-size:12px\">$pid<\/b><span style=\"font-size:12px\"> and do not supply the appropriate parameter. In other words, the cmdlet is not smart enough to recognize a number, and realize that I am supplying a process ID.<\/span><\/p>\n<p>In addition to the process ID, I want to include information about the CPU, virtual memory, working set, and paged memory. To do this, I store the results from <b>Get-Process<\/b> into a variable:<\/p>\n<p style=\"margin-left:30px\">$ps = Get-Process -id $pid<\/p>\n<p>Then I use parameter substitution and the format operator to supply the process information. I do this because I also want to format the numbers to two decimal places to make things easier to read. I can write my prompt function, and when I run it, it will change my Windows PowerShell ISE prompt in the output pane. The function is shown here:<\/p>\n<p style=\"margin-left:30px\">function prompt<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;$ps = Get-Process -id $pid<\/p>\n<p style=\"margin-left:30px\">&nbsp;&quot;PS PID: $pid PM(M) {0:N2} WS(M) {1:N2} VM(M) {2:N2} CPU(s) {3:N2}<\/p>\n<p style=\"margin-left:30px\">$($executionContext.SessionState.Path.CurrentLocation)$(&#039;&gt;&#039; * `<\/p>\n<p style=\"margin-left:30px\">($nestedPromptLevel + 1))&quot; `<\/p>\n<p style=\"margin-left:30px\">-f ($ps.PM\/1MB), ($ps.ws\/1MB), ($ps.vm\/1MB), $ps.cpu<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p>Here is the modified output pane after I run the function:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-4-27-15-02.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-4-27-15-02.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>Now I start a background job, and see what happens. Here is a simple background job that will run for a while, and use a bit of memory and CPU time:<\/p>\n<p style=\"margin-left:30px\">start-job -ScriptBlock {<\/p>\n<p style=\"margin-left:30px\">1..1000000000 | % {[math]::Cos([math]::Sin($_)) } }<\/p>\n<p>As shown here, as soon as I run my background job, I can see that the memory changes and the CPU time is going up:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-4-27-15-03.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-4-27-15-03.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>Because this is a background job, I can continue to work in my Windows PowerShell ISE. I can, for example, look at other things in the Windows PowerShell output pane. Here, I look at all processes that have a name that includes <b>PowerShell<\/b><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-4-27-15-04.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-4-27-15-04.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>Because I have not added this particular prompt function to my Windows PowerShell ISE profile, when I close the Windows PowerShell ISE and open it again, the prompt reverts to the original prompt. This is shown here:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-4-27-15-05.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-4-27-15-05.png\" alt=\"Image of prompt\" title=\"Image of prompt\" \/><\/a><\/p>\n<p>But, even if I did add the function to my Windows PowerShell ISE profile, I can always open the Windows PowerShell ISE by using <b>Run<\/b> and specifying the <b>&ndash;NoProfile<\/b> parameter:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7380.hsg-4-27-15-06.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7380.hsg-4-27-15-06.png\" alt=\"Image of command\" title=\"Image of command\" \/><\/a><\/p>\n<p>There is a beginning for Windows PowerShell tips and tricks. Tips and Tricks 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><span style=\"font-size:12px\">&nbsp;<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about Windows PowerShell tips and tricks from the Charlotte User Group meeting. Microsoft Scripting Guy, Ed Wilson, is here. Last week was a special meeting at the Charlotte Windows PowerShell User Group. It followed immediately after the Windows PowerShell Summit, and as a result, the user group included [&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":[3,4,578,45],"class_list":["post-6411","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-scripting-guy","tag-scripting-techniques","tag-tips-and-tricks","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about Windows PowerShell tips and tricks from the Charlotte User Group meeting. Microsoft Scripting Guy, Ed Wilson, is here. Last week was a special meeting at the Charlotte Windows PowerShell User Group. It followed immediately after the Windows PowerShell Summit, and as a result, the user group included [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/6411","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=6411"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/6411\/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=6411"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=6411"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=6411"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}