{"id":1237,"date":"2014-06-07T00:01:00","date_gmt":"2014-06-07T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2014\/06\/07\/weekend-scripter-cool-powershell-profile-functions-from-bruce-payette\/"},"modified":"2014-06-07T00:01:00","modified_gmt":"2014-06-07T00:01:00","slug":"weekend-scripter-cool-powershell-profile-functions-from-bruce-payette","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/weekend-scripter-cool-powershell-profile-functions-from-bruce-payette\/","title":{"rendered":"Weekend Scripter: Cool PowerShell Profile Functions from Bruce Payette"},"content":{"rendered":"<p><b>Summary<\/b>: Windows PowerShell principal SDE, Bruce Payette, shares a couple of cool profile functions.<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. The week of May 19, we had Profile Week. (To read about some great ideas that you can use for your Windows PowerShell profile, see these <a href=\"\/b\/heyscriptingguy\/archive\/tags\/profiles\/\" target=\"_blank\">Hey, Scripting Guy! Blog posts<\/a>.) I saved one individual&#039;s profile for a special post. Today we will look inside Bruce Payette&rsquo;s profile. For anyone who may not know, Bruce is a principal software development engineer (SDE) on the Windows PowerShell team. Now you know why this is a special post.<\/p>\n<p>Bruce supplied three way cool functions. The first function is a <strong>CD<\/strong>&nbsp;function that stores a list of directories that are typed. Then there is a <b>DIRS<\/b> function that will list the directories that have been typed. Each directory is associated with a number. Lastly, there is a <b>MY<\/b> function that creates directories relative to the users documents folder. I copied the functions below into my Windows PowerShell console profile. I typed <b>ise $profile<\/b> to open my profile in the Windows PowerShell ISE. Here is my Windows PowerShell ISE:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-7-14-01.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-7-14-01.png\" alt=\"Image of console\" title=\"Image of console\" \/><\/a><\/p>\n<h2>A new CD function<\/h2>\n<p>In a default installation of Windows PowerShell, the <b>CD<\/b> alias is mapped to the <b>Set-Location<\/b> cmdlet. It changes directories. So the first thing that Bruce does is remove the <b>CD<\/b> alias, and then create a new function named <b>CD<\/b>. The cool thing about the new <b>CD<\/b> function is that it stores a list of directories that I visit. Each path is added once. With the new function, I can use <b>CD<\/b>, and move backwards in the directory bag.<\/p>\n<p>With the <b>DIRS<\/b> function, I get a list of the directories stored in the directory bag. I can list them by typing <b>dirs<\/b>, or I can go to a specific folder by typing <b>dirs 2<\/b>, or whatever directory I want to navigate to. This is shown in the following image:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-7-14-02.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-7-14-02.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>The <b>MY<\/b> function maps directories in reference to my personal profile. It allows me to go directly to my personal module folder by typing <b>my modules<\/b>, as shown here:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-7-14-03.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-7-14-03.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>Following is the complete script for the three way cool profile functions:<\/p>\n<p style=\"margin-left:30px\"># remove any existing cd alias&#8230;<\/p>\n<p style=\"margin-left:30px\">rm -force alias:\/cd 2&gt; $null<\/p>\n<p style=\"margin-left:30px\">$global:DIRLIST = @{}<\/p>\n<p style=\"margin-left:30px\"># a cd function that maintains a list of directories visited. Each path is added only once (bag not stack)<\/p>\n<p style=\"margin-left:30px\"># it also implements the UNIX-like &lsquo;cd &ndash;&lsquo; to jump back to the previous directory<\/p>\n<p style=\"margin-left:30px\"># cd &#8230; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # go up 2 levels<\/p>\n<p style=\"margin-left:30px\"># cd &#8230;.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # go up three levels<\/p>\n<p style=\"margin-left:30px\"># cd &#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # go back to the previous directory<\/p>\n<p style=\"margin-left:30px\">function cd<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp; param ($path=&#039;~&#039;, [switch] $parent, [string[]] $replace, [switch] $my, [switch] $one)<\/p>\n<p>&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;if ($index = $path -as [int])<\/p>\n<p style=\"margin-left:30px\">&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; dirs $index<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; return<\/p>\n<p style=\"margin-left:30px\">&nbsp; }<\/p>\n<p>&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;if ($replace)<\/p>\n<p style=\"margin-left:30px\">&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $path = $path -replace $replace<\/p>\n<p style=\"margin-left:30px\">&nbsp; }<\/p>\n<p>&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;if ($parent)<\/p>\n<p style=\"margin-left:30px\">&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $path = Split-Path path<\/p>\n<p style=\"margin-left:30px\">&nbsp; }<\/p>\n<p>&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;if ($my)<\/p>\n<p style=\"margin-left:30px\">&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; if ($path -eq &#039;~&#039;) { $path = &#039;&#039; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $path = &quot;~\/documents\/$path&quot;<\/p>\n<p style=\"margin-left:30px\">&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp; elseif ($one)<\/p>\n<p style=\"margin-left:30px\">&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; if ($path -eq &#039;~&#039;) { $path = &#039;&#039; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $path = &quot;~\/skydrive\/documents\/$path&quot;<\/p>\n<p style=\"margin-left:30px\">&nbsp; }<\/p>\n<p>&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;# .&#039;ing shortcuts<\/p>\n<p style=\"margin-left:30px\">&nbsp; switch ($path)<\/p>\n<p style=\"margin-left:30px\">&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; &#039;&#8230;&#039; { $path = &#039;..\\..&#039; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; &#039;&#8230;.&#039; { $path = &#039;..\\..\\..&#039; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; &#039;-&#039; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (test-path variable:global:oldpath)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # pop back to your old path<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write-Host &quot;cd&#039;ing back to $global:OLDPATH&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$temp = Get-Location<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set-Location $global:OLDPATH<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $global:OLDPATH=$temp<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write-Warning &#039;OLDPATH not set&#039;<\/p>\n<p style=\"margin-left:30px\">&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; default {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $temp = Get-Location<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set-Location $path<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($?) {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $global:OLDPATH = $temp<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $DIRLIST[(Get-Location).path] = $true<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write-Warning &#039;cd failed!&#039;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp; }<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p>&nbsp;<\/p>\n<p style=\"margin-left:30px\">#<\/p>\n<p style=\"margin-left:30px\"># lists the directories accumulated by the cd function<\/p>\n<p style=\"margin-left:30px\"># dirs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # list the accumulated directories<\/p>\n<p style=\"margin-left:30px\"># dirs &lt;number&gt; &nbsp;&nbsp;&nbsp; # cd to the directory entry corresponding to &lt;number&gt;<\/p>\n<p style=\"margin-left:30px\">function dirs<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp; param ($id = -1)<\/p>\n<p style=\"margin-left:30px\">&nbsp; $dl = $dirlist.keys | sort<\/p>\n<p style=\"margin-left:30px\">&nbsp; if ($dl)<\/p>\n<p style=\"margin-left:30px\">&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; if ($id -ge 0)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cd $dl[$id]<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; else<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $count=0;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach ($d in $dl)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#039;{0,3} {1}&#039; -f $count++, $d<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp; }<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p>&nbsp;<\/p>\n<p style=\"margin-left:30px\"># A function that cd&#039;s relative to ~\/documents, with special handling for &#039;my modules&#039;<\/p>\n<p style=\"margin-left:30px\"># Works with the cd function<\/p>\n<p style=\"margin-left:30px\"># my &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;# go to ~\/documents<\/p>\n<p style=\"margin-left:30px\"># my modules&nbsp; &nbsp;# cd to ~\/documents\/windowspowershell\/modules<\/p>\n<p style=\"margin-left:30px\"># my foobar&nbsp;&nbsp;&nbsp; # cd to ~\/documents\/foobar<\/p>\n<p style=\"margin-left:30px\">function my ($path=&#039;&#039;, [switch] $resolve=$false)<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp; switch ($path)<\/p>\n<p style=\"margin-left:30px\">&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; modules {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $resolvedPath = (rvpa &#039;~\/documents\/windowspowershell\/modules&#039;).Path<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($resolve) { return $resolvePath }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cd $resolvedPath<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp; $resolvedPath = $null<\/p>\n<p style=\"margin-left:30px\">&nbsp; $resolvedPath =&nbsp; (rvpa &quot;~\/documents\/$path&quot;).Path<\/p>\n<p style=\"margin-left:30px\">&nbsp; if (! $resolvedPath ) { return }<\/p>\n<p style=\"margin-left:30px\">&nbsp; if ($resolve)<\/p>\n<p style=\"margin-left:30px\">&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; return $resolvedPath<\/p>\n<p style=\"margin-left:30px\">&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp; else<\/p>\n<p style=\"margin-left:30px\">&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; if ((get-item $resolvedPath).PSIsContainer)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cd &quot;~\/documents\/$path&quot;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; else<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $resolvedPath<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp; }<\/p>\n<p style=\"margin-left:30px\">}<\/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>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Windows PowerShell principal SDE, Bruce Payette, shares a couple of cool profile functions. Microsoft Scripting Guy, Ed Wilson, is here. The week of May 19, we had Profile Week. (To read about some great ideas that you can use for your Windows PowerShell profile, see these Hey, Scripting Guy! Blog posts.) I saved one [&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":[144,3,4,61,45],"class_list":["post-1237","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-profiles","tag-scripting-guy","tag-scripting-techniques","tag-weekend-scripter","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Windows PowerShell principal SDE, Bruce Payette, shares a couple of cool profile functions. Microsoft Scripting Guy, Ed Wilson, is here. The week of May 19, we had Profile Week. (To read about some great ideas that you can use for your Windows PowerShell profile, see these Hey, Scripting Guy! Blog posts.) I saved one [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/1237","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=1237"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/1237\/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=1237"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=1237"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=1237"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}