{"id":8343,"date":"2021-04-22T10:21:57","date_gmt":"2021-04-22T14:21:57","guid":{"rendered":"https:\/\/jdhitsolutions.com\/blog\/?p=8343"},"modified":"2021-04-22T10:22:02","modified_gmt":"2021-04-22T14:22:02","slug":"a-better-way-to-manage-powershell-functions","status":"publish","type":"post","link":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/","title":{"rendered":"A Better Way to Manage PowerShell Functions"},"content":{"rendered":"\n<div class=\"wp-block-image is-style-default\"><figure class=\"alignleft size-large\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-thisisengineering-3861969.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"320\" height=\"213\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-thisisengineering-3861969.jpg\" alt=\"\" class=\"wp-image-8345\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-thisisengineering-3861969.jpg 320w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-thisisengineering-3861969-300x200.jpg 300w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a><\/figure><\/div>\n\n\n\n<p>Like many of you, I write a lot of PowerShell code. Much of it I use on a daily basis since I essentially spend my day at a PowerShell prompt. Also like many of you, I often assemble functions into a module. A module makes it easier to load the functions I need, and also provides a versioning mechanism. When I run Get-Command on a module function, I can see the module name and the loaded version. But, there is more to my PowerShell life than modules. I have a number of stand-alone functions that I rely on. Many of these are dot-sourced in my PowerShell profile scripts. I know I am not the only PowerShell professional that relies on stand-alone PowerShell functions. The challenge, at least from my perspective, is that there is no versioning mechanism. There's no way to get similar information about a stand-alone function when I run Get-Command. That's the problem I wanted to solve.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">PSFunctionInfo<\/h2>\n\n\n\n<p>Over the last year, I've been working on a solution. I've been using it and finding it helpful. My friend Gladys Kravitz was also bemoaning the lack of tools for managing stand-alone functions. And while she had her own approach, I thought my solution might offer more. So I polished it up, setup a Github repository, and published a preview release to the PowerShell Gallery. The module is called PSFunctionInfo. You can find the <a href=\"https:\/\/github.com\/jdhitsolutions\/PSFunctionInfo\" target=\"_blank\" rel=\"noreferrer noopener\">repository on Github.<\/a>  Because it is a pre-release, you might need to install the newest version of the PowerShellGet module so you have the prerelease parameters.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Install-Module PSFunctionInfo -AllowPrerelease<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Function Metadata<\/h2>\n\n\n\n<p>The module works around the idea of a metadata comment block inserted into the function definition. It looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Function New-GHIssue {\n &lt;# PSFunctionInfo\n Version 1.1.0\n Author Jeffery Hicks\n CompanyName JDH IT Solutions, Inc.\n Copyright (c) JDH IT Solutions, Inc.\n Description Create a Github issue using gh.exe\n Guid 99b832ff-f003-4394-baca-7043b1f13ab2\n Tags github,profile\n LastUpdate 4\/22\/2021 8:56 AM\n Source C:\\Scripts\\New-GHIssue.ps1\n #>\n <code>[cmdletbinding(SupportsShouldProcess)] <\/code>\n<code>Param(<\/code> ...<\/code><\/pre>\n\n\n\n<p>The module command Get-PSFunctionInfo will process all functions loaded into your PowerShell session and show you your stand-alone functions. This is the default view.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo.png\"><img loading=\"lazy\" decoding=\"async\" width=\"874\" height=\"500\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo.png\" alt=\"\" class=\"wp-image-8347\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo.png 874w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-300x172.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-768x439.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-850x486.png 850w\" sizes=\"auto, (max-width: 874px) 100vw, 874px\" \/><\/a><\/figure>\n\n\n\n<p>The module includes a custom format file with an additional named view.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-source.png\"><img loading=\"lazy\" decoding=\"async\" width=\"807\" height=\"618\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-source.png\" alt=\"\" class=\"wp-image-8348\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-source.png 807w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-source-300x230.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-source-768x588.png 768w\" sizes=\"auto, (max-width: 807px) 100vw, 807px\" \/><\/a><\/figure>\n\n\n\n<p>I tried to design a rich object so I would have flexibility when it came to searching or  examining a function.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-object.png\"><img loading=\"lazy\" decoding=\"async\" width=\"723\" height=\"298\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-object.png\" alt=\"\" class=\"wp-image-8349\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-object.png 723w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-object-300x124.png 300w\" sizes=\"auto, (max-width: 723px) 100vw, 723px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-tag.png\"><img loading=\"lazy\" decoding=\"async\" width=\"835\" height=\"123\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-tag.png\" alt=\"\" class=\"wp-image-8350\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-tag.png 835w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-tag-300x44.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-tag-768x113.png 768w\" sizes=\"auto, (max-width: 835px) 100vw, 835px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Adding PSFunctionInfo<\/h2>\n\n\n\n<p>While getting information works on loaded functions, adding function metadata must update the source .ps1 file. The command you'll use is New-PSFunctionInfo.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">New-PSFunctionInfo -Name Show-WeatherSummary -Path C:\\scripts\\show-weathersummary.ps1 -Tags profile,web -Author \"Jeff Hicks\" -CompanyName \"JDH IT Solutions, Inc.\" -Copyright \"(c) 2021 JDH IT Solutions, Inc\" -Description \"display weather snapshot\" -Version \"1.0.0\" -Verbose<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/new-psfunctioninfo.png\"><img loading=\"lazy\" decoding=\"async\" width=\"869\" height=\"344\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/new-psfunctioninfo.png\" alt=\"\" class=\"wp-image-8351\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/new-psfunctioninfo.png 869w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/new-psfunctioninfo-300x119.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/new-psfunctioninfo-768x304.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/new-psfunctioninfo-850x336.png 850w\" sizes=\"auto, (max-width: 869px) 100vw, 869px\" \/><\/a><\/figure>\n\n\n\n<p>I used all the parameters, even though some of them have default values. You can see the metadata that will be inserted. Note that this *<em>will<\/em>* update the ps1 file.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-content.png\"><img loading=\"lazy\" decoding=\"async\" width=\"725\" height=\"557\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-content.png\" alt=\"\" class=\"wp-image-8352\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-content.png 725w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/psfunctioninfo-content-300x230.png 300w\" sizes=\"auto, (max-width: 725px) 100vw, 725px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Limitations<\/h2>\n\n\n\n<p>There are a few limitations. First, the command will not work with a one-line function declaration like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Function Get-Noun {Get-Command -CommandType Function,Cmdlet | group noun -NoElement | sort count -Descending }<\/code><\/pre>\n\n\n\n<p>The function should look like one of these:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Function Get-Noun {\n Param()\n Get-Command -CommandType Function,Cmdlet | \n Group noun -NoElement | sort count -Descending \n }\n Function Get-Noun \n {\n Param()\n Get-Command -CommandType Function,Cmdlet | \n Group noun -NoElement | sort count -Descending \n }<\/code><\/pre>\n\n\n\n<p>It also assumed that you don't have multiple copies of the same function in the same .ps1 file. I'm working on the assumption that the stand-alone functions you want to manage a slightly more complex than a few lines of code.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Editing PSFunctionInfo Metadata<\/h2>\n\n\n\n<p>The current version of the module has no commands to edit, update, or remove function meta data from the file. I'm expecting that if you are editing the function, you can revise the metadata block at the same time. Be careful not to adjust the spacing or formatting of the comment block. I tried several approaches and decided the multi-line comment block struck the right balance between ease of use and management.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">PSFunctionInfoDefaults<\/h2>\n\n\n\n<p>Finally, even though New-PSFunctionInfo has a few default parameter values, since you might want to maintain some consistency in your function metadata, the module includes a few commands for managing default values. You can run Set-PSFunctionInfoDefaults to specify metadata defaults like Author and Company. The command will create a JSON file under $Home called psfunctioninfo-defaults.json. When you import the PSFunctionInfo module, if this file is found, it will be imported and used to set entries in $PSDefaultParameterValues. <\/p>\n\n\n\n<p>You can set new defaults at any time.  Use Get-PSFunctionInfoDefaults to view your settings. If you make a change, you can either re-import the module or run Update-PSFunctionInfoDefaults to refresh $PSDefaultParameterValues.  If you uninstall the module, you'll need to manually delete the JSON file.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Do You Need This?<\/h2>\n\n\n\n<p>If this looks like something you need, I hope you'll install the module and give it a try. I'd suggest you have a backup of any files you intend to modify. Of course, being the pro that you are that should be a given! Please use the Github Issues section of the repository to post any comments, bugs, or feature requests. I'm hoping to get some real-world feedback before I remove the prelease tag. Thanks in advance for your help.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Like many of you, I write a lot of PowerShell code. Much of it I use on a daily basis since I essentially spend my day at a PowerShell prompt. Also like many of you, I often assemble functions into a module. A module makes it easier to load the functions I need, and also&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"New on the blog: A Better Way to Manage #PowerShell Functions","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[4,8],"tags":[32,221,534,654],"class_list":["post-8343","post","type-post","status-publish","format-standard","hentry","category-powershell","category-scripting","tag-functions","tag-module","tag-powershell","tag-psfunctioninfo"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>A Better Way to Manage PowerShell Functions &#8226; The Lonely Administrator<\/title>\n<meta name=\"description\" content=\"I rely a lot on stand-alone PowerShell functions. Yet, there is no good way to manage them with features like versioning. Until now.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"A Better Way to Manage PowerShell Functions &#8226; The Lonely Administrator\" \/>\n<meta property=\"og:description\" content=\"I rely a lot on stand-alone PowerShell functions. Yet, there is no good way to manage them with features like versioning. Until now.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/\" \/>\n<meta property=\"og:site_name\" content=\"The Lonely Administrator\" \/>\n<meta property=\"article:published_time\" content=\"2021-04-22T14:21:57+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-04-22T14:22:02+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-thisisengineering-3861969.jpg\" \/>\n<meta name=\"author\" content=\"Jeffery Hicks\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:site\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jeffery Hicks\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8343\\\/a-better-way-to-manage-powershell-functions\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8343\\\/a-better-way-to-manage-powershell-functions\\\/\"},\"author\":{\"name\":\"Jeffery Hicks\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"headline\":\"A Better Way to Manage PowerShell Functions\",\"datePublished\":\"2021-04-22T14:21:57+00:00\",\"dateModified\":\"2021-04-22T14:22:02+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8343\\\/a-better-way-to-manage-powershell-functions\\\/\"},\"wordCount\":762,\"commentCount\":7,\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8343\\\/a-better-way-to-manage-powershell-functions\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/pexels-thisisengineering-3861969.jpg\",\"keywords\":[\"functions\",\"module\",\"PowerShell\",\"PSFunctionInfo\"],\"articleSection\":[\"PowerShell\",\"Scripting\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8343\\\/a-better-way-to-manage-powershell-functions\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8343\\\/a-better-way-to-manage-powershell-functions\\\/\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8343\\\/a-better-way-to-manage-powershell-functions\\\/\",\"name\":\"A Better Way to Manage PowerShell Functions &#8226; The Lonely Administrator\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8343\\\/a-better-way-to-manage-powershell-functions\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8343\\\/a-better-way-to-manage-powershell-functions\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/pexels-thisisengineering-3861969.jpg\",\"datePublished\":\"2021-04-22T14:21:57+00:00\",\"dateModified\":\"2021-04-22T14:22:02+00:00\",\"description\":\"I rely a lot on stand-alone PowerShell functions. Yet, there is no good way to manage them with features like versioning. Until now.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8343\\\/a-better-way-to-manage-powershell-functions\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8343\\\/a-better-way-to-manage-powershell-functions\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8343\\\/a-better-way-to-manage-powershell-functions\\\/#primaryimage\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/pexels-thisisengineering-3861969.jpg\",\"contentUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/pexels-thisisengineering-3861969.jpg\",\"width\":320,\"height\":213},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8343\\\/a-better-way-to-manage-powershell-functions\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"PowerShell\",\"item\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/category\\\/powershell\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"A Better Way to Manage PowerShell Functions\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/\",\"name\":\"The Lonely Administrator\",\"description\":\"Practical Advice for the Automating IT Pro\",\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\",\"name\":\"Jeffery Hicks\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"caption\":\"Jeffery Hicks\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"A Better Way to Manage PowerShell Functions &#8226; The Lonely Administrator","description":"I rely a lot on stand-alone PowerShell functions. Yet, there is no good way to manage them with features like versioning. Until now.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/","og_locale":"en_US","og_type":"article","og_title":"A Better Way to Manage PowerShell Functions &#8226; The Lonely Administrator","og_description":"I rely a lot on stand-alone PowerShell functions. Yet, there is no good way to manage them with features like versioning. Until now.","og_url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/","og_site_name":"The Lonely Administrator","article_published_time":"2021-04-22T14:21:57+00:00","article_modified_time":"2021-04-22T14:22:02+00:00","og_image":[{"url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-thisisengineering-3861969.jpg","type":"","width":"","height":""}],"author":"Jeffery Hicks","twitter_card":"summary_large_image","twitter_creator":"@JeffHicks","twitter_site":"@JeffHicks","twitter_misc":{"Written by":"Jeffery Hicks","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/#article","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/"},"author":{"name":"Jeffery Hicks","@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"headline":"A Better Way to Manage PowerShell Functions","datePublished":"2021-04-22T14:21:57+00:00","dateModified":"2021-04-22T14:22:02+00:00","mainEntityOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/"},"wordCount":762,"commentCount":7,"publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-thisisengineering-3861969.jpg","keywords":["functions","module","PowerShell","PSFunctionInfo"],"articleSection":["PowerShell","Scripting"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/","url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/","name":"A Better Way to Manage PowerShell Functions &#8226; The Lonely Administrator","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/#primaryimage"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-thisisengineering-3861969.jpg","datePublished":"2021-04-22T14:21:57+00:00","dateModified":"2021-04-22T14:22:02+00:00","description":"I rely a lot on stand-alone PowerShell functions. Yet, there is no good way to manage them with features like versioning. Until now.","breadcrumb":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/#primaryimage","url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-thisisengineering-3861969.jpg","contentUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-thisisengineering-3861969.jpg","width":320,"height":213},{"@type":"BreadcrumbList","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8343\/a-better-way-to-manage-powershell-functions\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"PowerShell","item":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},{"@type":"ListItem","position":2,"name":"A Better Way to Manage PowerShell Functions"}]},{"@type":"WebSite","@id":"https:\/\/jdhitsolutions.com\/blog\/#website","url":"https:\/\/jdhitsolutions.com\/blog\/","name":"The Lonely Administrator","description":"Practical Advice for the Automating IT Pro","publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/jdhitsolutions.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9","name":"Jeffery Hicks","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","url":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","caption":"Jeffery Hicks"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg"}}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":8741,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8741\/building-a-powershell-module-inception-style\/","url_meta":{"origin":8343,"position":0},"title":"Building a PowerShell Module Inception-Style","author":"Jeffery Hicks","date":"December 17, 2021","format":false,"excerpt":"Over the course of the last week or so, I've been sharing PowerShell functions and scripts for working with PowerShell functions and scripts. I showed PowerShell functions to export functions to a script file and code to convert scripts to functions It has all been very Inception-like. To wrap this\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/12\/psinception.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":8787,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8787\/prerelease-of-psfunctiontools-for-powershell\/","url_meta":{"origin":8343,"position":1},"title":"Prerelease of PSFunctionTools for PowerShell","author":"Jeffery Hicks","date":"January 13, 2022","format":false,"excerpt":"At the end of last year wrote a series of blog posts describing tools and techniques for working with PowerShell scripts and functions. My goal was to build a framework of tools that I could use to automate PowerShell scripting work, such as creating a new module from a group\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/psfunctiontools-commands.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/psfunctiontools-commands.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/psfunctiontools-commands.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/psfunctiontools-commands.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/psfunctiontools-commands.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/psfunctiontools-commands.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":8793,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell-7\/8793\/profile-powershell-functions\/","url_meta":{"origin":8343,"position":2},"title":"Profile PowerShell Functions","author":"Jeffery Hicks","date":"January 17, 2022","format":false,"excerpt":"I've published a stable release of the PSFunctionTools module to the PowerShell Gallery. Previously, it was pre-release. The module requires PowerShell 7.1 and later. Although, as I have mentioned in the past, you are welcome to fork the repository and create a version that will run on Windows PowerShell. I\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/get-functionprofile2.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/get-functionprofile2.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/get-functionprofile2.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/get-functionprofile2.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":5319,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/5319\/a-classy-christmas-powershell-module\/","url_meta":{"origin":8343,"position":3},"title":"A Classy Christmas PowerShell Module","author":"Jeffery Hicks","date":"December 20, 2016","format":false,"excerpt":"Yesterday I showed you a class-based PowerShell script. My intention was to have a little bit of fun and teach you the basics of using a class. But what I gave you was really just the first step. If you wanted to create an actual tool around a class, you\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2016\/12\/christmas-wreath13.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":8693,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8693\/exporting-powershell-functions-to-files\/","url_meta":{"origin":8343,"position":4},"title":"Exporting PowerShell Functions to Files","author":"Jeffery Hicks","date":"December 3, 2021","format":false,"excerpt":"When I write a PowerShell module, it typically includes more than one export function. Where you store your module functions is a great discussion topic and I don't think there is necessarily one best practice for everyone. I think it might depend on the number and complexity of the functions.\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/12\/export-function3.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/12\/export-function3.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/12\/export-function3.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/12\/export-function3.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":1502,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/1502\/managing-virtualbox-with-powershell\/","url_meta":{"origin":8343,"position":5},"title":"Managing VirtualBox with PowerShell","author":"Jeffery Hicks","date":"June 13, 2011","format":false,"excerpt":"In my line of work I simply can't afford not to use virtualization, and I use just about all the major tools from time to time. But most of the time I rely on the free VirtualBox program from Oracle. One of the reasons I like it is it's relatively\u2026","rel":"","context":"In &quot;PowerShell v2.0&quot;","block_context":{"text":"PowerShell v2.0","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell-v2-0\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2011\/06\/vbox.png?resize=350%2C200","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/8343","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=8343"}],"version-history":[{"count":0,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/8343\/revisions"}],"wp:attachment":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=8343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=8343"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=8343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}