{"id":716,"date":"2022-07-11T05:34:23","date_gmt":"2022-07-11T12:34:23","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/powershell-community\/?p=716"},"modified":"2022-07-11T05:34:23","modified_gmt":"2022-07-11T12:34:23","slug":"cheat-sheet-console-experience","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell-community\/cheat-sheet-console-experience\/","title":{"rendered":"Cheat Sheet &#8211; Console Experience"},"content":{"rendered":"<p>PowerShell can take some getting used to. Especially if you come at it from a different Shell and don&#8217;t see any way to get your good old experience back. However, hidden behind that plain white on blue shell, there is actually a wide range of customization options that help make your life less painful. See below for the most commonly appreciated options.<\/p>\n<h2>Tab Completion<\/h2>\n<p>The classic complaint we hear is that in Windows, Tab Completion is so much less helpful than for example in Bash. This is mostly because <kbd>Ctrl<\/kbd>+<kbd>Space<\/kbd> is hard to discover, unless somebody shows you. Same menu choice as in Bash, but you can pick your preferred option using the arrow keys and each option may come with some documentation:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-content\/uploads\/sites\/69\/2022\/07\/tab-completion-1.png\" alt=\"Console excerpt, showing a menu of parameter options for dir\" \/><\/p>\n<blockquote>\n<p>Use whenever you would use the Tab Key<\/p>\n<\/blockquote>\n<h2>Key Bindings<\/h2>\n<p>There are a few keybindings that come in handy to know:<\/p>\n<table>\n<thead>\n<tr>\n<th>Keybinding<\/th>\n<th>Function<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><kbd>Ctrl<\/kbd>+<kbd>Space<\/kbd><\/td>\n<td>Tab Menu<\/td>\n<\/tr>\n<tr>\n<td><kbd>Ctrl<\/kbd>+<kbd>r<\/kbd><\/td>\n<td>Search in your input history<\/td>\n<\/tr>\n<tr>\n<td><kbd>Ctrl<\/kbd>+<kbd>a<\/kbd><\/td>\n<td>Select everything in your current input\/command line<\/td>\n<\/tr>\n<tr>\n<td><kbd>Ctrl<\/kbd>+<kbd>c<\/kbd><\/td>\n<td>Copy everything currently selected in your input\/command line to your clipboard<\/td>\n<\/tr>\n<tr>\n<td><kbd>Ctrl<\/kbd>+<kbd>v<\/kbd><\/td>\n<td>Paste your clipboard into the current input\/command line<\/td>\n<\/tr>\n<tr>\n<td><kbd>Shift<\/kbd>+<kbd>Enter<\/kbd><\/td>\n<td>Type multiline text in your console without executing the command<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Specifically, it is important to get used to not pasting with <strong>right-click<\/strong> &#8211; by using <kbd>Ctrl<\/kbd>+<kbd>v<\/kbd> instead, you get a single input history for multiple lines, you can preview your input before sending it (helps with those artifacts you get when pasting from Teams) and you stop accidentally overwriting your clipboard by selecting something in the console window.<\/p>\n<p>Also, with right-click, you sometimes get the wrong order.<\/p>\n<p>Oh, and you can <a href=\"https:\/\/github.com\/PowerShell\/PSReadLine\/blob\/master\/PSReadLine\/SamplePSReadLineProfile.ps1\">define your own keybindings<\/a> if you want to. No need to accept the defaults.<\/p>\n<h2>Packages<\/h2>\n<p>There are plenty of PowerShell packages out there that can make console life a lot less painful. Use <code>Find-Module<\/code> to search for them and <code>Install-Module<\/code> to install them. Example:<\/p>\n<pre><code class=\"language-powershell\">Find-Module *SQL*\nInstall-Module Powerline<\/code><\/pre>\n<p>Looking for a command but don&#8217;t know the module it is from?<\/p>\n<pre><code class=\"language-powershell\">Find-Module -Command Write-PSFMessage<\/code><\/pre>\n<h2>Profile \/ Start Script<\/h2>\n<p>The key to ultimate customization is to have a way to define code that runs on each console start without requiring manual action. Now if only there were a way to do that in PowerShell &#8230;<\/p>\n<pre><code class=\"language-powershell\">$profile<\/code><\/pre>\n<p>Yeah, that simple. As long as that file exists, it will be run.<\/p>\n<pre><code class=\"language-powershell\">notepad $profile<\/code><\/pre>\n<p>Add code, save, and you are good to go.<\/p>\n<blockquote>\n<p>There are different profile files per application running PowerShell &#8211; VSCode has a different one than pwsh.exe than powershell.exe. Make sure you edit the file you meant to edit. Or update the global profile for all applications: <code>$profile.CurrentUserAllHosts<\/code><\/p>\n<\/blockquote>\n<h2>PowerShell 7 \/ PowerShell Core<\/h2>\n<p>There&#8217;s Windows PowerShell, which comes installed by default on any Windows. But there&#8217;s also a <a href=\"https:\/\/aka.ms\/powershell-release?tag=stable\">cool version you have to first install<\/a>. It adds great convenience, better performance and the ability to actually like using Visual Studio Code with PowerShell. You can grab it via a wide variety of sources, such as the Microsoft Store, Github or your preferred package manager.<\/p>\n<p>You can also install it on MacOS or Linux.<\/p>\n<p>You should do so, it&#8217;s awesome.<\/p>\n<h2>Prompt<\/h2>\n<p>Want to customize your prompt to be more colorful \/ fancy \/ whatever else you want it to do?<\/p>\n<p>Well, all you need to do is override the function named <code>prompt<\/code> and put it in your profile and that&#8217;s that. Don&#8217;t know how or want to borrow from others to make your life easier?<\/p>\n<p>Give <a href=\"https:\/\/github.com\/Jaykul\/PowerLine\">Powerline (for PowerShell)<\/a> a chance. They have some <a href=\"https:\/\/github.com\/Jaykul\/PowerLine\/tree\/master\/Source\/Examples\">fancy examples<\/a> as well!<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-content\/uploads\/sites\/69\/2022\/07\/prompt-1.png\" alt=\"A colorful command prompt\" \/><\/p>\n<h2>Dynamic Tab Completion<\/h2>\n<p>With the previous notes on Tab Completion, you already saw how to get better tab completion. But PowerShell is still not reading your mind when it comes to the values provided &#8211; if a command doesn&#8217;t offer it, you&#8217;re out of luck. Right?<\/p>\n<p>Well no, there&#8217;s tools to fix that. There are some options, but the simple-most is probably from the <a href=\"https:\/\/psframework.org\/documentation\/documents\/psframework\/tab-completion.html\">PSFramework project<\/a>. To install it, run this line (once):<\/p>\n<pre><code class=\"language-powershell\">Install-Module PSFramework<\/code><\/pre>\n<p>Then you can add the magic to your profile. Here is a quick example on how to add values to the &#8220;-Tenant&#8221; parameter on &#8220;Set-AzContext&#8221;:<\/p>\n<pre><code class=\"language-powershell\">Register-PSFTeppScriptblock -Name AZ.Tenant -ScriptBlock {\n  (Get-AZTenant).DefaultDomain\n}\nRegister-PSFTeppArgumentCompleter -Command Set-AZContext -Parameter Tenant -Name AZ.Tenant<\/code><\/pre>\n<h2>The Clipboard<\/h2>\n<p>The clipboard is always a handy tool to interactively cross over between applications. Now if only there were commands in PowerShell to do so &#8230;<\/p>\n<pre><code class=\"language-powershell\">Get-Clipboard\nSet-Clipboard<\/code><\/pre>\n<p>And since we&#8217;re all about being lazy, there&#8217;s aliases for that: &#8220;gcb&#8221; and &#8220;scb&#8221;. On that note, if you want to paste multiple columns into Excel, you want to use the tab delimiter. Don&#8217;t do manual labor though, here&#8217;s the easy way to get data ready to paste to Excel:<\/p>\n<pre><code class=\"language-powershell\">dir | ConvertTo-Csv -Delimiter \"`t\" | scb<\/code><\/pre>\n<p>That <code>ConvertTo-Csv<\/code> is way too much text though. Wouldn&#8217;t it be nice to make that shorter?<\/p>\n<h2>Aliases<\/h2>\n<p>In PowerShell, there is an easy way to be lazy: Aliases. Use their power to abbreviate your commonly used commands. Then put it in your <code>$profile<\/code> so you don&#8217;t have to remember to add them.<\/p>\n<pre><code class=\"language-powershell\">Set-Alias ctc ConvertTo-Csv<\/code><\/pre>\n<p>And now that previous line can be shortened to:<\/p>\n<pre><code class=\"language-powershell\">dir | ctc -d \"`t\" | scb<\/code><\/pre>\n<p>Where is that &#8220;-d&#8221; coming from though?<\/p>\n<h2>Short Parameter Names<\/h2>\n<p>You know all these commandline tools that have a long and a short notation for their parameters? Like where you can either specify &#8220;&#8211;help&#8221; or &#8220;-h&#8221;?<\/p>\n<p>Well, PowerShell takes that a step further: You only need to type enough of the parameter name to uniquely identify it.<\/p>\n<p>Using the example above with <code>ConvertTo-Csv<\/code>, there is only a single parameter that starts with &#8220;D&#8221;, so that&#8217;s enough to specify it.<\/p>\n<blockquote>\n<p>Actually, there is a common parameter named &#8220;Debug&#8221;, but those don&#8217;t count here.<\/p>\n<\/blockquote>\n<h2>More Tools to improve the Console Experience<\/h2>\n<p>A lot more tools have been created to help being lazy &amp; comfortable than could possibly all be listed, but here a few more projects out there that can help make console life more comfortable:<\/p>\n<table>\n<thead>\n<tr>\n<th>Tool<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><a href=\"https:\/\/docs.microsoft.com\/powershell\/azure\/az-predictor\">AZ.Tools.Predictor<\/a><\/td>\n<td>Predictive intellisense for the AZ modules<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/www.powershellgallery.com\/packages\/TabExpansionPlusPlus\/1.2\">TabExpansionPlusPlus<\/a><\/td>\n<td>Adds tab completion for classic commandline tools such as ROBOCOPY<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/www.powershellgallery.com\/packages\/PSUtil\">PSUtil<\/a><\/td>\n<td>Adds keybindings, aliases and other conveniences<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/ohmyposh.dev\/\">oh-my-posh<\/a><\/td>\n<td>Transform your prompt, alternative to the Powerline module shown above<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/github.com\/dahlbyk\/posh-git\">posh-git<\/a><\/td>\n<td>Add git integration to your prompt<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Paths, Explorer &amp; PowerShell<\/h2>\n<p>Often enough you want to interact with the file system across applications:<\/p>\n<ul>\n<li>Got the explorer open and want to start PowerShell in that path?<\/li>\n<li>Just created an output file and want to open it?<\/li>\n<li>Open the explorer in the current path?<\/li>\n<\/ul>\n<p>For all of that there are convenient options. From within the shell, <code>Invoke-Item<\/code> or its alias <code>ii<\/code> allow you to open a path in its default application:<\/p>\n<pre><code class=\"language-powershell\">ii .\\report.csv # Probably Excel\nii . # Current path in Explorer<\/code><\/pre>\n<p>The other way around works just as convenient. In the Windows Explorer, just type <code>pwsh.exe<\/code> (or <code>powershell.exe<\/code>, if you didn&#8217;t upgrade):<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-content\/uploads\/sites\/69\/2022\/07\/explorer-1.png\" alt=\"The Windows Explorer address bar, with the path replaced with &quot;pwsh.exe&quot;\" \/><\/p>\n<h2>Inspecting Output<\/h2>\n<p>When you run a command, often enough you get some nice table, that is easy to read, but kind of lacking in data:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-content\/uploads\/sites\/69\/2022\/07\/format-table-1.png\" alt=\"Results of a dir command in a neat table\" \/><\/p>\n<p>Fortunately, by piping to <code>FL *<\/code>, you get to see everything (even if it is a bit much):<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-content\/uploads\/sites\/69\/2022\/07\/format-list-1.png\" alt=\"Results of a dir command, with a long list of properties, hiding nothing\" \/><\/p>\n<h2>Concluding<\/h2>\n<blockquote>\n<p>&#8220;I designed PowerShell to optimize the user, not the code&#8221;<\/p>\n<p>-Jeffrey Snover, inventor of the PowerShell<\/p>\n<\/blockquote>\n<p>PowerShell allows us to optimize the way we work in the console, it is designed to help us automate and make problems go away. So why do I see so many people who don&#8217;t apply that same perspective to their own, personal console environment? Go ahead and settle in in your console &#8230; or face the charge of being insufficiently lazy!<\/p>\n<p>\ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to have more control of preferences in functions and the role of modules on inheritance.<\/p>\n","protected":false},"author":95665,"featured_media":77,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[13],"tags":[73,3,63,74],"class_list":["post-716","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell","tag-convenience","tag-powershell","tag-preference-variables","tag-tab-expansion"],"acf":[],"blog_post_summary":"<p>How to have more control of preferences in functions and the role of modules on inheritance.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/posts\/716","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/users\/95665"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/comments?post=716"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/posts\/716\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/media\/77"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/media?parent=716"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/categories?post=716"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/tags?post=716"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}