{"id":3143,"date":"2013-07-29T00:01:00","date_gmt":"2013-07-29T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/07\/29\/add-a-couple-of-functions-to-powershell-profile\/"},"modified":"2013-07-29T00:01:00","modified_gmt":"2013-07-29T00:01:00","slug":"add-a-couple-of-functions-to-powershell-profile","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/add-a-couple-of-functions-to-powershell-profile\/","title":{"rendered":"Add a Couple of Functions to PowerShell Profile"},"content":{"rendered":"<p><strong style=\"font-size:12px\">Summary<\/strong><span style=\"font-size:12px\">: Microsoft Scripting Guy, Ed Wilson, adds a couple of new functions to his Windows PowerShell console profile.<\/span><\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. I have heard that necessity is the mother of invention. For me, annoyance is the mother of scripting. What I mean is that when it comes time for me to write a script (something short and quick), I only do it after I am tired of typing the same command over and over again. For example, consider the first two functions I recently added to my Windows PowerShell profile&hellip;<\/p>\n<h2>Load and unload modules<\/h2>\n<p>Everyone knows we have automatic module loading in Windows PowerShell&nbsp;3.0. But not everyone knows that when it comes time to use <strong>Get-Command<\/strong>, if I have not loaded the modules, an error generates, as shown here.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4237.hsg-7-29-13-01.png\"><img decoding=\"async\" title=\"Image of error message\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4237.hsg-7-29-13-01.png\" alt=\"Image of error message\" \/><\/a><\/p>\n<p>If this is the case, why don&rsquo;t I just add the command to load all modules into my profile? The reason is speed of launching. For example, on my laptop, it consistently takes 16 seconds to load all of my modules. This is shown here:<\/p>\n<p style=\"padding-left:30px\">PS C:\\&gt; Measure-Command {Import-AllModules}<\/p>\n<p style=\"padding-left:30px\">Warning:&nbsp; To run some commands exposed by this module on Windows Vista, Windows<\/p>\n<p style=\"padding-left:30px\">Server 2008, and later versions of Windows, you must start an elevated Windows<\/p>\n<p style=\"padding-left:30px\">PowerShell console.<\/p>\n<p style=\"padding-left:30px\">&nbsp;<\/p>\n<p style=\"padding-left:30px\">Days&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left:30px\">Hours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left:30px\">Minutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left:30px\">Seconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 16<\/p>\n<p style=\"padding-left:30px\">Milliseconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 43<\/p>\n<p style=\"padding-left:30px\">Ticks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 160435770<\/p>\n<p style=\"padding-left:30px\">TotalDays&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0.000185689548611111<\/p>\n<p style=\"padding-left:30px\">TotalHours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0.00445654916666667<\/p>\n<p style=\"padding-left:30px\">TotalMinutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0.26739295<\/p>\n<p style=\"padding-left:30px\">TotalSeconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 16.043577<\/p>\n<p style=\"padding-left:30px\">TotalMilliseconds : 16043.577<\/p>\n<p>I want to be able to load or to unload all of the modules, but do it only when I need to do so. Therefore, this becomes a good excuse for writing a couple of functions.<\/p>\n<p>I have been typing the commands to load and to unload all modules for at least a year (as long as I have been using Windows PowerShell&nbsp;3.0). Finally, it got to me, and I decided to write the simple functions that follow. Oh by the way, to make the functions easier to use, I created a couple of aliases for them too. Here are the two functions:<\/p>\n<p style=\"padding-left:30px\"><strong>Function Import-AllModules<\/strong><\/p>\n<p style=\"padding-left:30px\">{Get-Module -ListAvailable | Import-Module}<\/p>\n<p style=\"padding-left:30px\">&nbsp;<\/p>\n<p style=\"padding-left:30px\">Function Remove-AllModules<\/p>\n<p style=\"padding-left:30px\">{Get-Module -ListAvailable | Remove-Module}<\/p>\n<p style=\"padding-left:30px\">Set-Alias -Name ram -Value Remove-AllModules<\/p>\n<p style=\"padding-left:30px\">Set-Alias -Name iam -Value import-allmodules<\/p>\n<h2>Finding commands<\/h2>\n<p><strong>Get-Command<\/strong> works great. But the default output is not what I normally would do. For example, because of all the cmdlets and functions, the output invariably scrolls, so I need to pipe the results to <strong>More<\/strong>. In addition, I normally am looking for cmdlets from the same module, so I like to sort by the module. I therefore came up with this function that I call <strong>Get-Commands<\/strong> (I also created an alias for it).<\/p>\n<p style=\"padding-left:30px\"><strong>Function Get-Commands<\/strong><\/p>\n<p style=\"padding-left:30px\">{<\/p>\n<p style=\"padding-left:30px\">&nbsp;Param($verb,<\/p>\n<p style=\"padding-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $noun)<\/p>\n<p style=\"padding-left:30px\">&nbsp;Get-Command @PSBoundParameters | Sort-Object module | more<\/p>\n<p style=\"padding-left:30px\">}<\/p>\n<p style=\"padding-left:30px\">&nbsp;<\/p>\n<p style=\"padding-left:30px\">Set-Alias -Name gcms -Value get-commands<\/p>\n<p>About the only thing notable here, is the use of <strong>$psBoundParameters<\/strong>. This cool automatic variable keeps track of parameters that are supplied to a function. I need to know if <strong>&ndash;Verb<\/strong> or <strong>&ndash;Noun<\/strong> or both <strong>&ndash;Verb<\/strong> and <strong>&ndash;Noun<\/strong> are supplied so I can create the syntax for the <strong>Get-Command<\/strong> cmdlet.<\/p>\n<p>In the past, I would have needed to use a series of If \/ Else \/ Elseif types of construction to get the correct syntax. By using <strong>$PSBoundParameters<\/strong>, I do not need to do this. I simply pass whatever is supplied as arguments to the function to the command line via <strong>$PSBoundParameters<\/strong>. I then sort the results on the <strong>Module<\/strong> parameter and send the results to the <strong>More<\/strong> command. It works great, and saves me a lot of repetitive typing.<\/p>\n<h2>Removing the AD: drive<\/h2>\n<p>Part of the slowness in loading the Active Directory module is due to the creation of the AD: drive. I do not use this drive all the time, but I do use the Active Directory cmdlets on nearly a daily basis. So I created a function to disable creating the AD: drive. Here is the function:<\/p>\n<p style=\"padding-left:30px\">Function Remove-ADDrive<\/p>\n<p style=\"padding-left:30px\">{$Env:ADPS_LoadDefaultDrive = 0}<span style=\"font-size:12px\">&nbsp;<\/span><\/p>\n<p>I load it directly via my Windows PowerShell profile. If I want the AD: drive, I just comment out the line that calls the <strong>Remove-ADDrive<\/strong> function.<\/p>\n<h2>Admin or not?<\/h2>\n<p>The last thing I did was modify the title of my Windows PowerShell console based on if I have Admin rights. My <strong>Test-ISAdministrator<\/strong> function has been talked about (and copied) widely, so I am not going to repeat it here. I use it to see if I have Admin rights. If I do, I set the Windows PowerShell console title to SUPER PowerShell dude! If I do not have Admin rights, I set the title of the Windows PowerShell console to Regular PowerShell dude. The function is shown here:<\/p>\n<p style=\"padding-left:30px\">Function Set-ConsoleConfig<\/p>\n<p style=\"padding-left:30px\">{<\/p>\n<p style=\"padding-left:30px\">&nbsp;if(-not (Test-IsAdministrator))<\/p>\n<p style=\"padding-left:30px\">&nbsp; {$Host.ui.RawUI.WindowTitle = &quot;Regular PowerShell dude&quot;}<\/p>\n<p style=\"padding-left:30px\">&nbsp;else {$Host.ui.RawUI.WindowTitle = &quot;SUPER PowerShell dude!&quot;}<\/p>\n<p style=\"padding-left:30px\">} #end function set-consoleconfig<\/p>\n<p>The Windows PowerShell console when launched with non-elevated permissions is shown here:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0216.hsg-7-29-13-02.png\"><img decoding=\"async\" title=\"Image of console\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0216.hsg-7-29-13-02.png\" alt=\"Image of console\" \/><\/a><\/p>\n<p>That is all there is to adding a couple of functions to my profile. Join me tomorrow when I will talk about more cool Windows PowerShell 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><strong>Ed Wilson, Microsoft Scripting Guy<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, adds a couple of new functions to his Windows PowerShell console profile. Microsoft Scripting Guy, Ed Wilson, is here. I have heard that necessity is the mother of invention. For me, annoyance is the mother of scripting. What I mean is that when it comes time for me to [&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":[51,144,3,4,45],"class_list":["post-3143","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-getting-started","tag-profiles","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, adds a couple of new functions to his Windows PowerShell console profile. Microsoft Scripting Guy, Ed Wilson, is here. I have heard that necessity is the mother of invention. For me, annoyance is the mother of scripting. What I mean is that when it comes time for me to [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3143","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=3143"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3143\/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=3143"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=3143"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=3143"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}