{"id":89746,"date":"2021-02-02T19:39:45","date_gmt":"2021-02-02T19:39:45","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=89746"},"modified":"2021-03-15T15:20:02","modified_gmt":"2021-03-15T15:20:02","slug":"powershell-editors-environments-part-1","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/powershell-editors-environments-part-1\/","title":{"rendered":"PowerShell editors and environments part 1"},"content":{"rendered":"<p>During the 2020 PASS Virtual Summit, a person tweeted something about how he wanted to scream at the next presenter who used the PowerShell ISE that comes with Windows. Several people leapt to the defense of that particular tool. In addition, during the live panel discussion on PowerShell, someone asked what would be the best editor to use. Between these two incidents, and my previous desire to write an article on moving from the ISE to Visual Studio Code, I thought it was time to write an article on the tools you can use to write PowerShell scripts, so this article covers PowerShell editors and environments.<\/p>\n<p>I\u2019ll start by saying that, most of the time, I still use the PowerShell ISE that comes with Windows, but I really should be moving to Visual Studio Code, and, in this article and the second part, I\u2019ll explain why I should but also why I haven\u2019t.<\/p>\n<h2>Editing versus running<\/h2>\n<p>Before I go too deep into this article, I want to distinguish between editing a file and running it. I\u2019m going to focus on editors here, but most development environments include a way to execute a PowerShell script or PowerShell commands. However, do not confuse the editor with the execution environment.<\/p>\n<h2>Notepad<\/h2>\n<p>The simplest tool one can use to write and edit PowerShell Scripts is Notepad. A PowerShell script is basically a text file that is interpreted when it\u2019s run. If no other tool is available on the machine you\u2019re on, Notepad is almost certainly there. That said, it only allows you to edit a file, you can\u2019t actually execute your file. You have to save it and then execute it using another tool such as the PowerShell shell.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-89747\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image.png\" alt=\"powershell code in notepad\" width=\"389\" height=\"183\" \/><\/p>\n<p>This <a href=\"https:\/\/github.com\/stridergdm\/SimpleTalk_PowerShell-Scripts\/tree\/master\/Comments%20and%20more\">script<\/a> is valid PowerShell, and I could edit the file, for example, replace the name of the service if I wanted, but I can\u2019t do more than simple editing. For a quick and dirty edit, this may be all that is needed. In my experience, it is the fastest way to open, edit, and then close a file, but that\u2019s about the only real advantage. If I want to run this script, I still need to have an execution environment.<\/p>\n<h2>PowerShell shell<\/h2>\n<p>If you go to your start menu and enter Windows PowerShell, you should see something like the following:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-89748\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-1.png\" alt=\"list of PowerShell editors and environments\" width=\"427\" height=\"266\" \/><\/p>\n<p>In this case, select the second choice: Windows PowerShell.<\/p>\n<p>This action opens a window that looks similar to the following:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"611\" height=\"195\" class=\"wp-image-89749\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-2.png\" \/><\/p>\n<p>The window looks a lot like a standard CMD window, but with the addition of PS before the prompt. You can also get here from a CMD window itself by typing PowerShell in the CMD window.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"680\" height=\"252\" class=\"wp-image-89750\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-3.png\" \/><\/p>\n<p>Other than the color, these are the same. You can type PowerShell Cmdlets into either one and execute them, or even run actual PowerShell scripts.<\/p>\n<p>However, you can\u2019t edit a PowerShell script here. The window is only the CMD line for PowerShell.<\/p>\n<p>To execute a cmdlet, you can simply type it:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"681\" height=\"121\" class=\"wp-image-89751\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-4.png\" \/><\/p>\n<p>To run an actual script, you need to tell PowerShell the string you\u2019re giving it is the name of a script to run, not a string to echo back.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"696\" height=\"105\" class=\"wp-image-89752\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-5.png\" \/><\/p>\n<p>Note here that PowerShell takes the passed string and echoes it back.<\/p>\n<p>To force PowerShell to execute the string in quotes, start with an <code>&amp;<\/code> symbol:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"688\" height=\"140\" class=\"wp-image-89753\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-6.png\" \/><\/p>\n<p>The <code>&amp;<\/code> causes the script to be executed.<\/p>\n<p>Note, however, if the script has no spaces in the name, you don\u2019t need quote marks. As a result, PowerShell attempts to execute it:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"693\" height=\"102\" class=\"wp-image-89754\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-7.png\" \/><\/p>\n<p>If you do put quotes around it, PowerShell treats it as a string.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"683\" height=\"142\" class=\"wp-image-89755\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-8.png\" \/><\/p>\n<p>Generally it\u2019s safer to use the &amp; symbol, which is also known as the call operator<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"687\" height=\"162\" class=\"wp-image-89756\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-9.png\" \/><\/p>\n<p>Note that in the PowerShell Command Line, generally auto-completion works as you might expect and will intelligently try to insert the &amp; and quotes as needed if it can find a script in the directory that matches what you type.<\/p>\n<p>One last tip: if you already have a CMD window open, you can start the PowerShell shell by running the command <code>powershell<\/code>. This command gets you to the shell the same way as if you had done it via the GUI.<\/p>\n<h2>Linux<\/h2>\n<p>One of PowerShell&#8217;s wonderful features is that you are not limited to running it only on Windows. You can, of course, write scripts and execute them on Linux. In the examples below, I am running Ubuntu Linux, but this should work for other distributions of Linux also.<\/p>\n<p>Whereas the command on Windows to open the PowerShell shell is PowerShell, on Linux it\u2019s <code>pwsh<\/code>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"573\" height=\"173\" class=\"wp-image-89757\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-10.png\" \/><\/p>\n<p>You can run most PowerShell scripts and cmdlets on Linux just like you would in Windows. However, some scripts or cmdlets such as those that make calls to the Windows GUI or Windows specific concepts will obviously fail. For example, <code>get-services<\/code> can\u2019t run on Linux, but <code>get-help<\/code> will.<\/p>\n<p>Another important detail is that Linux is case sensitive, as seen in the examples below:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"733\" height=\"278\" class=\"wp-image-89758\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-11.png\" \/><\/p>\n<p>Note that <em>simple.ps1<\/em> and <em>Simple.ps1<\/em> are not treated the same on Linux like they would be under Windows.<\/p>\n<p>While Linux won\u2019t have Notepad like Windows, you should be able to find VIM or a similar text editor available in your distro.<\/p>\n<h2>PowerShell ISE<\/h2>\n<p>A comment about this the PowerShell ISE prompted this article. The PowerShell ISE is the PowerShell <strong>I<\/strong>ntegrated <strong>S<\/strong>cripting <strong>E<\/strong>nvironment. Despite it being disparaged by some, honestly, it\u2019s my go-to tool most of the time. Let me start by saying what it is not and why it is often disparaged: it\u2019s not a modern IDE. Most of all, I would say what it lacks that I would look for the most in a modern IDE is tight control with some sort of source control system such as git. This limitation is not a show-stopper since you can still use git and other source control systems via the command line, but it can be inconvenient.<\/p>\n<p>That said, an advantage of the PowerShell ISE is that you will almost certainly find a copy of it on every Windows computer where you might run PowerShell Scripts. It is not available on Linux.<\/p>\n<p>There are three main parts to the PowerShell ISE. The most obvious one is the largest, the Script Editing Window. This window is where you can open scripts, edit them and even run them. In the screenshot below, it\u2019s the large white area with the red circle and text. In this case, PowerShell ISE has just been opened and is ready for creating a new script. By default, it is titled <em>Untitled1.ps1<\/em>. To open another window, press <strong>Ctrl-N<\/strong>. This action creates a new window called <em>Untitled2.ps1<\/em><strong>,<\/strong> and so on. The file menu allows you to open and save files.<\/p>\n<p>Below this window in the default layout is the command line window. This window operates very similarly to the PowerShell shell described above. It has one important addition that I find very helpful that I will describe in a bit.<\/p>\n<p>Finally, a help window is found to the right of both windows. This windows shows installed cmdlets and allows searching for them and to get additional help. This functionality can be quite useful at times.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-89759\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-12.png\" alt=\"PowerShell ISE\" width=\"1182\" height=\"802\" \/><\/p>\n<h3>Script editing window<\/h3>\n<p>This section is not meant to be a full tutorial on all the PowerShell ISE features, but I wanted to call out a couple of important features.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1232\" height=\"350\" class=\"wp-image-89760\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-13.png\" \/><\/p>\n<p>There are two icons with a green arrow on them. The one circled in Orange runs the entire script in the current edit window. If there are mandatory parameters, you are prompted for them. If a parameter is not mandatory, you will not be prompted for it and cannot provide a value when running it this way.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"483\" height=\"69\" class=\"wp-image-89761\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-14.png\" \/><\/p>\n<p>Pressing F5 performs the same action; this is your basic run command.<\/p>\n<p>However, if you highlight just a portion of the script and press the button circled in purple, or press F8, it runs ONLY the lines highlighted.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"527\" height=\"401\" class=\"wp-image-89762\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-15.png\" \/><\/p>\n<p>Now note, that in the ISE, variables remain in scope within the session. Since the last time I ran this script I had given <code>$counter<\/code> the value of <em>5<\/em>, it remembered that for this script scrap.<\/p>\n<p>This behavior can be confusing but also useful.<\/p>\n<p>Using this ability to run only a portion of your script, and the fact that variables remain in scope and valid during your session can be convenient when debugging. However, it can also mean that sometimes you get unexpected results if you aren\u2019t keeping track of what you last ran and what value some variables may have.<\/p>\n<h3>Command line window<\/h3>\n<p>The command line window of the ISE has several useful features. You can execute simple scripts and cmdlets in it if you desire.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"974\" height=\"104\" class=\"wp-image-89763\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-16.png\" \/><\/p>\n<p>Notice this too will recall the last value of a variable.<\/p>\n<p>You can execute many CMD commands here, though many will be interpreted using a PowerShell native cmdlet.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"626\" height=\"183\" class=\"wp-image-89764\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-17.png\" \/><\/p>\n<p>That\u2019s a <code>dir<\/code> command but acting much like the PowerShell cmdlet <code>Get-ChildItem<\/code> because it\u2019s an alias.<\/p>\n<p>You can also start other programs in there.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"728\" height=\"240\" class=\"wp-image-89765\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-18.png\" \/><\/p>\n<p>However, what\u2019s most powerful about this window is the way it handles parameters for PowerShell scripts.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"636\" height=\"285\" class=\"wp-image-89766\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-19.png\" \/><\/p>\n<p>Notice that as soon as I press the <code>\u2013<\/code> key, a drop-down appears showing the available parameters. The drop-down window helps run a seldom-used script when I don\u2019t recall the available parameters.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"724\" height=\"276\" class=\"wp-image-89767\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-20.png\" \/><\/p>\n<p>Notice that as you provide parameters, the available parameter list shrinks, only showing you the ones that have not yet been assigned a value. This behavior prevents you from entering the same parameter twice.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"713\" height=\"95\" class=\"wp-image-89768\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-21.png\" \/><\/p>\n<p>Finally, you\u2019ll notice that the available options are shown if a parameter has a <code>validateset<\/code>. This means I\u2019m far less likely to enter <em>Development<\/em> when I really need to enter <em>Dev<\/em>.<\/p>\n<p>I mentioned above there\u2019s a reason I still tend to use PowerShell ISE a lot and honestly, it\u2019s because of this auto-completion. It\u2019s a VERY handy tool and saves me a lot of time and effort when running seldom used scripts or initially debugging them.<\/p>\n<h3>Threads<\/h3>\n<p>One more area of interest in the PowerShell ISE is how it handles running multiple scripts at once.<\/p>\n<p>To demonstrate load the following two scripts:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"484\" height=\"115\" class=\"wp-image-89769\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-22.png\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"441\" height=\"93\" class=\"wp-image-89770\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-23.png\" \/><\/p>\n<p><em>Wait-Example.ps1<\/em> and <em>Wait-Example_Part2.ps1<\/em> are both available at <a href=\"https:\/\/github.com\/stridergdm\/SimpleTalk_PowerShell-Scripts\/tree\/master\/Editors\">github<\/a> for this article.<\/p>\n<p>If you go to the first tab and press F5, it starts to execute. It sleeps for 60 seconds, giving you plenty of time to go to the 2<sup>nd<\/sup> tab and try to execute <em>Wait-Example_Part2.ps1<\/em>. However, you will find that you can\u2019t.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"566\" height=\"285\" class=\"wp-image-89771\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-24.png\" \/><\/p>\n<p>The red box is a button to let you know a script is running, but you can also press that to abort a script&#8217;s execution. As long as the first script is running, you don\u2019t have the option to execute the second script.<\/p>\n<p>Normally, this is not an issue, but there are times when you may want to start a long-running script and do other work in the meantime. Fortunately, the PowerShell ISE offers a solution.<\/p>\n<p>Instead of pressing <strong>Ctrl-N<\/strong> or using the menu to open a new PowerShell editor window, press <strong>Ctrl-T<\/strong> or use the menu to open a new PowerShell Tab<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"903\" height=\"267\" class=\"wp-image-89772\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-25.png\" \/><\/p>\n<p>You will end up with a window similar to below.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"665\" height=\"326\" class=\"wp-image-89773\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/02\/word-image-26.png\" \/><\/p>\n<p>Now you can execute a long-running script in the PowerShell 1 tab and continue working in your second tab (in my case it\u2019s <em>PowerShell 4<\/em> because I had previously opened two other tabs and then closed them).<\/p>\n<p>Essentially, you\u2019re running two instances of PowerShell at this point which can be very useful at times.<\/p>\n<h2>PowerShell editors and environments<\/h2>\n<p>More can be done in the PowerShell ISE such as opening a remote window or debugging, but this should be enough to get you started. As I mentioned, it\u2019s not a full-fledged modern IDE with git support and other features, but honestly, it\u2019s often good enough for what it does. I would not look askance at anyone for using it for demos and quick scripting needs.<\/p>\n<p>That said, there are other tools out there, and in my <a href=\"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/powershell-editors-and-environments-part-2\/\">next article<\/a>, I\u2019ll discuss those.<\/p>\n<p>Until then, happy scripting!<\/p>\n<p>&nbsp;<\/p>\n<p><em>If you liked this article, you might also like<\/em>\u00a0<a href=\"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/how-to-use-parameters-in-powershell\/\">How to Use Parameters in PowerShell<\/a><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There is no shortage of PowerShell editors and environments for developing and running scripts. Greg Moore explains some of his favorites.&hellip;<\/p>\n","protected":false},"author":319367,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[53,35],"tags":[4635,136325,5134],"coauthors":[61343],"class_list":["post-89746","post","type-post","status-publish","format-standard","hentry","category-featured","category-powershell","tag-powershell","tag-powershell-editor","tag-sql-prompt"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/89746","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/319367"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=89746"}],"version-history":[{"count":5,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/89746\/revisions"}],"predecessor-version":[{"id":90351,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/89746\/revisions\/90351"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=89746"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=89746"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=89746"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=89746"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}