{"id":1317,"date":"2014-05-19T00:01:00","date_gmt":"2014-05-19T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2014\/05\/19\/whats-in-your-powershell-profile-here-are-a-few-of-my-favorites\/"},"modified":"2014-05-19T00:01:00","modified_gmt":"2014-05-19T00:01:00","slug":"whats-in-your-powershell-profile-here-are-a-few-of-my-favorites","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/whats-in-your-powershell-profile-here-are-a-few-of-my-favorites\/","title":{"rendered":"What&#039;s In Your PowerShell Profile? Here Are a Few of My Favorites"},"content":{"rendered":"<p><b>Summary<\/b>: Microsoft Scripting Guy, Ed Wilson, shares a few favorites from his Windows PowerShell profile.\nMicrosoft Scripting Guy, Ed Wilson, is here. I was at the Windows PowerShell Summit a couple weeks ago. When Jason Shirk, a manager on the Windows PowerShell team, was doing a demo, I was able to glance into his Windows PowerShell profile. I was amazed by the number of cool things that were there. I thought, &ldquo;Hmmmmm&#8230;&rdquo;\nI have had a Windows PowerShell profile since the early beta days&mdash;back when it was called Monad. I hardly consider myself to be a noob, but I am also the first to admit that I do not know everything there is to know about Windows PowerShell. In fact, I learn new stuff every single day. One of the best ways to learn, is to talk to other Windows PowerShell enthusiasts and gurus. That is one of the reason the Scripting Wife and I are such big supporters of Windows PowerShell User Groups. I firmly believe that you get a bunch of Windows PowerShell people together, and great things will happen.\nSo, that is the source of this week&rsquo;s blog posts. I decided it would be fun to have people submit some of their favorite functions, tips, and tricks from their Windows PowerShell profile. I am also asking you to post your profile on the Scripting Guys Script Repository, or to paste your favorite function, tip, or trick into the comments section of this week&rsquo;s series of posts. It will be good stuff.<\/p>\n<p style=\"margin-left:30px\"><b>Note<\/b>&nbsp; I have <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/tags\/profiles\/\" target=\"_blank\">nearly twenty Hey, Scripting Guy! Blog posts<\/a> where I talk about Windows PowerShell profiles. I recommend you review them prior to getting too bogged down with this week&rsquo;s series.\nOver the years, I have had wild and wooly Windows PowerShell profiles, and simple and serene Windows PowerShell profiles. I generally add the following components into my Windows PowerShell profile. I like to create a section for each:<\/p>\n<ul>\n<li>Aliases<\/li>\n<li>PS Drives<\/li>\n<li>Functions<\/li>\n<li>Variables<\/li>\n<li>Initialization commands<\/li>\n<\/ul>\n<p>When I am in the midst of making a lot of changes to my Windows PowerShell profile, I like to back it up each time I open Windows PowerShell. It is pretty easy to do, all I need to do is to call the following command and specify a name and a destination:<\/p>\n<p style=\"margin-left:30px\">Copy-Item &ndash;path $profile\nOne of the things that people sometimes talk about is the need to check their profile to ensure it has not inadvertently changed &mdash;either by accident or by intention. For example, I recently downloaded a module&mdash;a reputable module from a reputable author. Come to find out, he modified my Windows PowerShell profile to call his module with specific parameters. It would have been nice if he had told me he was going to do this. Not that it caused any problems. It is just that I would have liked to have been prompted to do this myself, or given the option to allow him to do it. Know what I mean?\nSome people talk about signing the Windows PowerShell profile, but that means that every time it is modified, it needs to be resigned. An easier way to detect changes is to save a file hash of the profile, and then compare the file hash on startup.<\/p>\n<h2>Get-ProfileHash function<\/h2>\n<p>So I decided to create a <b>Get-ProfileHash<\/b> function. I added this to my ISE profile and to my Windows PowerShell console profile. I added logic to the function so that it will detect which profile is in use and check that one. You can find the complete function on the Script Center Repository: <a href=\"http:\/\/gallery.technet.microsoft.com\/scriptcenter\/Get-ProfileHash-function-6b04e6fe\" target=\"_blank\">Get-ProfileHash function<\/a>.\nI am using the <b>Get-FileHash<\/b> function from Windows PowerShell&nbsp;4.0 in Windows 8.1, but there are other ways to get a file hash. They are just not quite as easy. Because of this, I add a check for Windows PowerShell&nbsp;4.0 as shown here:<\/p>\n<p style=\"margin-left:30px\">#requires -version 4.0<\/p>\n<p style=\"margin-left:30px\">Function Get-ProfileHash<\/p>\n<p style=\"margin-left:30px\">{\nNow I need to get the name of the current Windows PowerShell profile. To do this, I use the <b>Split-Path<\/b> cmdlet and choose the <b>&ndash;Leaf<\/b> parameter. But this returns a string, and it includes the .PS1 file extension. So I cast the string into a <b>[system.io.fileinfo]<\/b> object type, and I then choose only the <b>basename<\/b> property. I could have parsed the string, but casting to an object and selecting a specific property works better. Here is that line of script:<\/p>\n<p style=\"margin-left:30px\">$profileName = ([system.io.fileinfo](Split-Path $profile -Leaf)).basename\nNow I want to get the folder that contains the <b>$profile<\/b>. That is easy, I choose the <b>&ndash;Parent<\/b> parameter from the <b>Split-Path<\/b>:<\/p>\n<p style=\"margin-left:30px\">$profileFolder = Split-Path $profile -Parent\nI need to build up a string for the profile name with an XML file extension. I use the <b>Join-Path<\/b> cmdlet and choose the profile folder, and I create a file name based on the profile name with the .xml file extension. This is shown here:<\/p>\n<p style=\"margin-left:30px\">$HashPath =<\/p>\n<p style=\"margin-left:30px\">&nbsp; Join-Path -Path $profileFolder -ChildPath (&#8220;{0}.{1}&#8221; -f $profileName,&#8221;XML&#8221;)\nI want to see if there is already an XML representation of the file hash. If there is, I will read it. Then I will get a new file hash for the current profile, and use <b>Compare-Object<\/b> to examine the hash property. This portion of the function is shown here:<\/p>\n<p style=\"margin-left:30px\">if(Test-Path -Path $HashPath)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; { $oldHash = Import-Clixml $HashPath<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; $newHash = Get-FileHash -Path $profile<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; $diff = Compare-Object -Property hash -ReferenceObject $oldHash `<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; -DifferenceObject $newHash\nIf there is a difference, I open Windows PowerShell with the <b>&ndash;noprofile<\/b> switch, and I open the current profile in Notepad. In this way, I can easily look at the profile in a safe environment. This script is shown here:<\/p>\n<p style=\"margin-left:30px\">If($diff)<\/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; powershell -noprofile -command &#8220;&amp;&#8221;Notepad $profile&#8221;&#8221;\nWhen I am done, I delete the old file hash of the profile, and I create a new file hash of the current Windows PowerShell profile. I store the hash in the XML file as shown here:<\/p>\n<p style=\"margin-left:30px\">Remove-Item $HashPath<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Get-FileHash -Path $profile |<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Export-Clixml -Path $HashPath -Force }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; }\nIf there is no stored file hash, I simply take a file hash and store it in the XML file. It will be referenced the next time I call the function:<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;Else { Get-FileHash -Path $profile |<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Export-Clixml -Path $HashPath -Force }\nThe complete function is shown here:<\/p>\n<p style=\"margin-left:30px\">#requires -version 4.0<\/p>\n<p style=\"margin-left:30px\">Function Get-ProfileHash<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;$profileName = ([system.io.fileinfo](Split-Path $profile -Leaf)).basename<\/p>\n<p style=\"margin-left:30px\">&nbsp;$profileFolder = Split-Path $profile -Parent<\/p>\n<p style=\"margin-left:30px\">&nbsp;$HashPath =<\/p>\n<p style=\"margin-left:30px\">&nbsp; Join-Path -Path $profileFolder -ChildPath (&#8220;{0}.{1}&#8221; -f $profileName,&#8221;XML&#8221;)<\/p>\n<p style=\"margin-left:30px\">&nbsp;if(Test-Path -Path $HashPath)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; { $oldHash = Import-Clixml $HashPath<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; $newHash = Get-FileHash -Path $profile<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; $diff = Compare-Object -Property hash -ReferenceObject $oldHash `<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; -DifferenceObject $newHash<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; If($diff)<\/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; powershell -noprofile -command &#8220;&amp;&#8221;Notepad $profile&#8221;&#8221;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Remove-Item $HashPath<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Get-FileHash -Path $profile |<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Export-Clixml -Path $HashPath -Force }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;Else { Get-FileHash -Path $profile |<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Export-Clixml -Path $HashPath -Force }<\/p>\n<p style=\"margin-left:30px\">}\nAll that remains to do is to add my <b>Get-ProfileHash<\/b> function to my profiles, and then add a line in the profile that calls the function. The rest is automatic.\nI have uploaded the complete function to the Script Center Repository: <a href=\"http:\/\/gallery.technet.microsoft.com\/scriptcenter\/Get-ProfileHash-function-6b04e6fe\" target=\"_blank\">Get-ProfileHash function<\/a>. It is best to copy if from there rather than trying to copy it from the blog because it may pick up entrenched cred.\nSo this is something cool from <b>my<\/b> Windows PowerShell profile. Windows PowerShell Profile Week will continue tomorrow when I will bring together a collection of tips and tricks from various Microsoft PowerShell enthusiasts. Hey, what&rsquo;s in your Windows PowerShell profile? Let me know.\nI 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=\"http:\/\/blogs.technet.commailto: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.\n<b>Ed Wilson, Microsoft Scripting Guy<\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, shares a few favorites from his Windows PowerShell profile. Microsoft Scripting Guy, Ed Wilson, is here. I was at the Windows PowerShell Summit a couple weeks ago. When Jason Shirk, a manager on the Windows PowerShell team, was doing a demo, I was able to glance into his Windows [&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,45],"class_list":["post-1317","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-profiles","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, shares a few favorites from his Windows PowerShell profile. Microsoft Scripting Guy, Ed Wilson, is here. I was at the Windows PowerShell Summit a couple weeks ago. When Jason Shirk, a manager on the Windows PowerShell team, was doing a demo, I was able to glance into his Windows [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/1317","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=1317"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/1317\/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=1317"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=1317"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=1317"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}