├── .github └── ISSUE_TEMPLATE │ ├── bug-report.yml │ ├── config.yml │ ├── feature-request.yml │ └── other-request.yml ├── License.txt ├── PSFunctionTools-Help.pdf ├── PSFunctionTools.psd1 ├── PSFunctionTools.psm1 ├── README.md ├── changelog.md ├── docs ├── Convert-ScriptToFunction.md ├── Export-FunctionFromFile.md ├── Export-FunctionToFile.md ├── Export-ModuleLayout.md ├── Format-FunctionName.md ├── Get-FunctionAlias.md ├── Get-FunctionAttribute.md ├── Get-FunctionName.md ├── Get-FunctionProfile.md ├── Get-ModuleLayout.md ├── Get-PSFunctionTools.md ├── Get-PSRequirements.md ├── Get-ParameterBlock.md ├── Import-ModuleLayout.md ├── New-CommentHelp.md ├── New-ModuleFromFiles.md ├── New-ModuleFromLayout.md ├── Open-PSFunctionToolsHelp.md ├── Open-PSFunctionToolsSamples.md └── Test-FunctionName.md ├── en-us └── PSFunctionTools-help.xml ├── formats ├── modulelayout.format.ps1xml ├── psfunctionname.format.ps1xml ├── psfunctiontool.format.ps1xml └── psscriptrequirements.format.ps1xml ├── functions ├── private │ └── helpers.ps1 └── public │ ├── Convert-ScriptToFunction.ps1 │ ├── Export-FunctionFromFile.ps1 │ ├── Export-FunctionToFile.ps1 │ ├── Export-ModuleLayout.ps1 │ ├── Format-FunctionName.ps1 │ ├── Get-FunctionAlias.ps1 │ ├── Get-FunctionAttribute.ps1 │ ├── Get-FunctionName.ps1 │ ├── Get-FunctionProfile.ps1 │ ├── Get-ModuleLayout.ps1 │ ├── Get-PSFunctionTools.ps1 │ ├── Get-PSRequirements.ps1 │ ├── Get-ParameterBlock.ps1 │ ├── Import-ModuleLayout.ps1 │ ├── New-CommentHelp.ps1 │ ├── New-ModuleFromFiles.ps1 │ ├── New-ModuleFromLayout.ps1 │ ├── Open-PSFunctionToolsSamples.ps1 │ ├── Open-README.ps1 │ └── Test-FunctionName.ps1 ├── images ├── export-modulelayout.png ├── get-functionprofile.png ├── get-functionprofile2.png ├── get-modulelayout-source.png ├── get-modulelayout.png ├── get-psfunctiontools.png ├── get-relativepath.png ├── import-modulelayout-whatif.png ├── import-modulelayout.png ├── layout-metadata.png ├── psrobot-icon.png └── sample-module-layout.png ├── samples ├── BuildModule.ps1 ├── Demo-ExportFunctions.ps1 ├── Demo-NewModuleFromFiles.ps1 ├── Get-ZeroSize.ps1 ├── ModuleLayout.json ├── POC-NewModule.ps1 ├── POC-NewModule2.ps1 ├── SampleScript.ps1 ├── SampleScript2.ps1 ├── SampleScript3.ps1 ├── SampleScript4.ps1 ├── SampleScript5.ps1 ├── Tools.psm1 └── samplefunction.ps1 └── tests ├── psfunctiontools.tests.ps1 └── runtests.ps1 /.github/ISSUE_TEMPLATE/bug-report.yml: -------------------------------------------------------------------------------- 1 | name: 🪲 Bug Report 2 | description: Report a bug or problem. 3 | title: "[Bug]: " 4 | labels: ["bug","triage"] 5 | assignees: 6 | - jdhitsolutions 7 | body: 8 | - type: markdown 9 | attributes: 10 | value: "## Thank you for bringing this to our attention." 11 | - type: textarea 12 | id: description 13 | attributes: 14 | label: Describe the problem 15 | description: Please describe the bug or problem including the exact syntax you are using and any error or warning messages. 16 | validations: 17 | required: true 18 | - type: textarea 19 | id: expected-behavior 20 | attributes: 21 | label: Expectation 22 | description: What did you expect to happen? 23 | - type: textarea 24 | id: additional-info 25 | attributes: 26 | label: Additional Information 27 | description: Do you have any additional information or context that you think will be helpful in resolving this issue? 28 | - type: dropdown 29 | id: psversion 30 | attributes: 31 | label: PowerShell version 32 | description: What version of PowerShell are you running? 33 | options: 34 | - '4.0' 35 | - '5.1' 36 | - 6.x 37 | - '7.0' 38 | - '7.1' 39 | - '7.2' 40 | - Other 41 | validations: 42 | required: true 43 | - type: dropdown 44 | id: platform 45 | attributes: 46 | label: Platform 47 | description: What operating system are you running? 48 | options: 49 | - Windows 10 Home 50 | - Windows 11 Home 51 | - Windows 10 Pro or Enterprise 52 | - Windows 11 Pro or Enterprise 53 | - MacOS 54 | - Linux 55 | - Other 56 | - type: checkboxes 57 | id: checks 58 | attributes: 59 | label: Additional Checks 60 | description: Have you verified the following? 61 | options: 62 | - label: You are using the latest version of this module. 63 | required: true 64 | - label: You have read this repository's README file. 65 | - label: You have read full help and examples for the command you are having problems with. 66 | - label: You are running PowerShell in an elevated session. 67 | - label: You are running in a traditional PowerShell console or Windows Terminal 68 | 69 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: README 4 | url: https://github.com/jdhitsolutions/PSFunctionTools/blob/main/README.md 5 | about: Open this module's README.md file. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.yml: -------------------------------------------------------------------------------- 1 | name: 💡Feature Request 2 | description: Request a new feature or enhancement 3 | title: "[Request]: " 4 | labels: ["enhancement","triage"] 5 | assignees: 6 | - jdhitsolutions 7 | body: 8 | - type: markdown 9 | attributes: 10 | value: "## Thank you for bringing this to our attention." 11 | - type: textarea 12 | id: description 13 | attributes: 14 | label: Describe the request 15 | description: Please describe your feature request or enhancement in detail. What deficiency does it address in the module? What use cases support your request? 16 | validations: 17 | required: true 18 | - type: dropdown 19 | id: psversion 20 | attributes: 21 | label: PowerShell version 22 | description: What version of PowerShell are you running? 23 | options: 24 | - '4.0' 25 | - '5.1' 26 | - 6.x 27 | - '7.0' 28 | - '7.1' 29 | - '7.2' 30 | - Other 31 | validations: 32 | required: false 33 | - type: dropdown 34 | id: platform 35 | attributes: 36 | label: Platform 37 | description: What operating system are you running? 38 | options: 39 | - Windows 10 Home 40 | - Windows 11 Home 41 | - Windows 10 Pro or Enterprise 42 | - Windows 11 Pro or Enterprise 43 | - MacOS 44 | - Linux 45 | - Other 46 | 47 | 48 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/other-request.yml: -------------------------------------------------------------------------------- 1 | name: 🤔Other Request or Question 2 | description: Open a request for all other issues 3 | title: "[Question]: " 4 | labels: ["question","triage"] 5 | assignees: 6 | - jdhitsolutions 7 | body: 8 | - type: textarea 9 | id: description 10 | attributes: 11 | label: Describe the question or issue 12 | description: What is on your mind? 13 | validations: 14 | required: true 15 | - type: dropdown 16 | id: psversion 17 | attributes: 18 | label: PowerShell version 19 | description: What version of PowerShell are you running? 20 | options: 21 | - '4.0' 22 | - '5.1' 23 | - 6.x 24 | - '7.0' 25 | - '7.1' 26 | - '7.2' 27 | - Other 28 | validations: 29 | required: false 30 | - type: dropdown 31 | id: platform 32 | attributes: 33 | label: Platform 34 | description: What operating system are you running? 35 | options: 36 | - Windows 10 Home 37 | - Windows 11 Home 38 | - Windows 10 Pro or Enterprise 39 | - Windows 11 Pro or Enterprise 40 | - MacOS 41 | - Linux 42 | - Other 43 | 44 | 45 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2025 JDH Information Technology Solutions, Inc. 4 | 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | -------------------------------------------------------------------------------- /PSFunctionTools-Help.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhitsolutions/PSFunctionTools/7406fa1a1026f0a899316584bc95fa7626937312/PSFunctionTools-Help.pdf -------------------------------------------------------------------------------- /PSFunctionTools.psd1: -------------------------------------------------------------------------------- 1 | # 2 | # Module manifest for module PSFunctionTools 3 | # 4 | 5 | @{ 6 | RootModule = 'PSFunctionTools.psm1' 7 | ModuleVersion = '1.3.0' 8 | CompatiblePSEditions = 'Core' 9 | GUID = '151466e0-a952-4b6a-ad81-40dafc9ef9bb' 10 | Author = 'Jeff Hicks' 11 | CompanyName = 'JDH Information Technology Solutions, Inc.' 12 | Copyright = '(c) 2021-2025 JDH Information Technology Solutions, Inc.' 13 | Description = 'A set of PowerShell 7 commands for managing and automating PowerShell scripts, functions, and modules. You can use these tools to accelerate PowerShell script development.' 14 | PowerShellVersion = '7.4' 15 | # TypesToProcess = @() 16 | FormatsToProcess = @( 17 | 'formats\modulelayout.format.ps1xml', 18 | 'formats\psscriptrequirements.format.ps1xml', 19 | 'formats\psfunctionname.format.ps1xml', 20 | 'formats\psfunctiontool.format.ps1xml' 21 | ) 22 | FunctionsToExport = @( 23 | 'Convert-ScriptToFunction', 24 | 'Export-FunctionFromFile', 25 | 'Export-FunctionToFile', 26 | 'Export-ModuleLayout', 27 | 'Format-FunctionName', 28 | 'Get-FunctionAlias', 29 | 'Get-FunctionAttribute', 30 | 'Get-FunctionName', 31 | 'Get-FunctionProfile', 32 | 'Get-ModuleLayout', 33 | 'Get-ParameterBlock', 34 | 'Get-PSFunctionTools', 35 | 'Get-PSRequirements', 36 | 'Import-ModuleLayout', 37 | 'New-CommentHelp', 38 | 'New-ModuleFromFiles', 39 | 'New-ModuleFromLayout', 40 | 'Open-PSFunctionToolsHelp', 41 | 'Open-PSFunctionToolsSamples', 42 | 'Test-FunctionName' 43 | ) 44 | CmdletsToExport = @() 45 | # VariablesToExport = @() 46 | AliasesToExport = @( 47 | 'csf', 48 | 'eff', 49 | 'eml', 50 | 'etf', 51 | 'ffn', 52 | 'ga', 53 | 'gfa', 54 | 'gfal', 55 | 'gfn', 56 | 'gfp', 57 | 'gpb', 58 | 'iml', 59 | 'nch', 60 | 'tfn' 61 | ) 62 | PrivateData = @{ 63 | PSData = @{ 64 | Tags = @('AST', 'scripting', 'module', 'function', 'script', 'toolmaking') 65 | LicenseUri = 'https://github.com/jdhitsolutions/PSFunctionTools/blob/main/License.txt' 66 | ProjectUri = 'https://github.com/jdhitsolutions/PSFunctionTools' 67 | IconUri = 'https://raw.githubusercontent.com/jdhitsolutions/PSFunctionTools/main/images/psrobot.png' 68 | ReleaseNotes = @' 69 | ## [1.3.0] - 2025-01-14 70 | 71 | ### Added 72 | 73 | - Added command `Open-PSFunctionToolsSamples` to change to the Samples folder and list the sample files. 74 | - Added command `Open-PSFunctionToolsHelp`. 75 | 76 | ### Changed 77 | 78 | - Updated demo file `Demo-NewModuleFromFiles.ps1`. 79 | - Help documentation updates. 80 | - Minor code cleanup. 81 | - Bumped minimum PowerShell version to 7.4. __This is a potential breaking change.__ 82 | - Converted changelog to new format. 83 | '@ 84 | } # End of PSData hashtable 85 | } # End of PrivateData hashtable 86 | } 87 | -------------------------------------------------------------------------------- /PSFunctionTools.psm1: -------------------------------------------------------------------------------- 1 | 2 | Get-ChildItem $PSScriptRoot\functions\*.ps1 -recurse | 3 | Foreach-Object { 4 | . $_.FullName 5 | } 6 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # Changelog for PSFunctionTools 2 | 3 | ## [Unreleased] 4 | 5 | ## [1.3.0] - 2025-01-14 6 | 7 | ### Added 8 | 9 | - Added command `Open-PSFunctionToolsSamples` to change to the Samples folder and list the sample files. 10 | - Added command `Open-PSFunctionToolsHelp`. 11 | 12 | ### Changed 13 | 14 | - Updated demo file `Demo-NewModuleFromFiles.ps1`. 15 | - Help documentation updates. 16 | - Minor code cleanup. 17 | - Bumped minimum PowerShell version to 7.4. __This is a potential breaking change.__ 18 | - Converted changelog to new format. 19 | 20 | ## [v1.2.0] - 2023-04-18 21 | 22 | ### Changed 23 | 24 | - Pester test revisions. 25 | - Modified `Format-FunctionName` to let you capitalize N number of characters in the Noun portion of the command name. 26 | - Help updates. 27 | - Updated `README.md`. 28 | 29 | ### Added 30 | 31 | - Added missing online help links. 32 | 33 | ### Removed 34 | 35 | - Deleted unused `Types` folder. 36 | 37 | ## [v1.1.0] - 2023-03-03 38 | 39 | ### Changed 40 | 41 | - Code clean up and reformatting. 42 | - Image resizing. 43 | 44 | ## [v1.0.0] - 2022-02-28 45 | 46 | - Added online help links for previously published commands. 47 | - Bumped version number to reflect feature-complete release. 48 | - Added `Export-FunctionToFile` to export a loaded function from your session to a script file. 49 | - Help updates. 50 | - Updated `README.md`. 51 | 52 | ## [v0.6.0] - 2022-01-17 53 | 54 | - Added online help links for previously published commands. 55 | - Modified `Get-FunctionAttribute` to accept pipeline input for `Name` and `Path` parameters. 56 | - Modified `Get-FunctionAlias` to accept pipeline input for `Path`. 57 | - Added command `Get-PSFunctionTools` and a related custom format file. This command makes it easy to see all module commands. 58 | - Added alias `ffn` for `Format-FunctionName`. 59 | - Added alias `gfn` for `Get-FunctionName`. 60 | - Added alias `tfn` for `Test-FunctionName`. 61 | - Added command `Get-FunctionProfile` and alias `gfp`. 62 | - Revised warning message in `Get-FunctionAttribute` and `Get-ParameterBlock` to include function name and path. 63 | - Updated `README.md`. 64 | - Help updates. 65 | - Initial public release to the PowerShell Gallery. 66 | 67 | ## v0.5.0 - 2022-01-11 68 | 69 | - Module will be written to support PowerShell 7.1 and later. Commands may run in Windows PowerShell but I am __not__ marking the module as `Desktop` compatible. 70 | - Added a parameter called `AsTree` to `Get-ModuleLayout` to show module layout as a tree. 71 | - Moved code to parse path for `AST` data to a private helper function. 72 | - Help documentation updates. 73 | - Initial Pester 5 tests for the module and functions. 74 | - Module manifest updates. 75 | - Updated `README.md`. 76 | - First public preview release. 77 | 78 | ## v0.4.0 - 2021-12-24 79 | 80 | - Moved helper functions in `New-ModuleFromFiles` to `functions\private\helpers.ps1'`. 81 | - Updated `New-ModuleFromFiles` to use `FunctionPath` parameter when creating the root psm1 file. 82 | - Added function `New-ModuleFromLayout`. 83 | - Help updates. 84 | 85 | ## v0.3.0 - 2021-12-21 86 | 87 | - Added sample scripts. 88 | - Modified `New-CommentHelp` with a `-TemplateOnly` parameter to generate help without any parameter definitions. 89 | - Modified `Get-FunctionName` to accept `Path` parameter values from pipeline input. 90 | - Modified `Get-ParameterBlock` to accept `Path` and `Name` values from pipeline input by property name. 91 | - Added function `New-ModuleFromFiles`. This should be considered experimental. 92 | 93 | ## v0.2.0 - 2021-12-20 94 | 95 | - Updated help documentation. 96 | - Modified `Format-FunctionName` to accept pipeline input by value. 97 | - Added function `Get-ParameterBlock` with an alias of `gpb`. 98 | - Added function `Get-FunctionAttribute` with an alias of `gfa`. 99 | - Added a parameter called `Detailed` to `Get-FunctionName` to write a custom object to the pipeline which includes the path to the file. Added a custom format file `psfunctionname.format.ps1xml`. 100 | 101 | ## v0.1.0 - 2021-12-20 102 | 103 | - Initial files. 104 | - Added `Get-ModuleLayout` with format file `modulelayout.format.ps1xml`. 105 | - Modified `Get-PSScriptRequirements` to write a `PSScriptRequirements` object to the pipeline. Added the format file `psscriptrequirements.format.ps1xml`. 106 | - Updated help documentation. 107 | 108 | [Unreleased]: https://github.com/jdhitsolutions/PSFunctionTools/compare/v1.3.0..HEAD 109 | [1.3.0]: https://github.com/jdhitsolutions/PSFunctionTools/compare/vv1.2.0..v1.3.0 110 | [v1.2.0]: https://github.com/jdhitsolutions/PSFunctionTools/compare/v1.1.0..v1.2.0 111 | [v1.1.0]: https://github.com/jdhitsolutions/PSFunctionTools/compare/v1.0.0..v1.1.0 112 | [v1.0.0]: https://github.com/jdhitsolutions/PSFunctionTools/compare/v0.6.0..v1.0.0 113 | [v0.6.0]: https://github.com/jdhitsolutions/PSFunctionTools/compare/v0.5.0..v0.6.0 114 | [v0.5.0]: 115 | [v0.4.0]: 116 | [v0.3.0]: 117 | [v0.2.0]: -------------------------------------------------------------------------------- /docs/Convert-ScriptToFunction.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/3Fgi4gY 5 | schema: 2.0.0 6 | --- 7 | 8 | # Convert-ScriptToFunction 9 | 10 | ## SYNOPSIS 11 | 12 | Convert a script file to a PowerShell function. 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | Convert-ScriptToFunction [-Path] [-Name] [-Alias ] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | This command takes the body of a script file and wraps it in a function declaration. The command will insert missing elements like cmdletbinding() and comment-based help. You will most likely need to edit and clean up the result in your scripting editor. 23 | 24 | If you run this command in the PowerShell ISE or the VS Code PowerShell integrated terminal, you can use the dynamic parameter ToEditor to open a new file with with the output. You can edit and save the file manually. 25 | 26 | It is assumed that your script file is complete and without syntax errors. 27 | 28 | ## EXAMPLES 29 | 30 | ### EXAMPLE 1 31 | 32 | ```powershell 33 | PS C:\> Convert-ScriptToFunction c:\scripts\Daily.ps1 -name Invoke-DailyTask | Set-Clipboard 34 | ``` 35 | 36 | Convert Daily.ps1 to a function called Invoke-DailyTask and copy the results to the Windows clipboard. You can then paste the results into scripting editor. 37 | 38 | ### EXAMPLE 2 39 | 40 | ```powershell 41 | PS C:\> Convert-ScriptToFunction c:\scripts\systemreport.ps1 -name New-SystemReport | Out-File c:\scripts\New-SystemReport.ps1 42 | ``` 43 | 44 | Convert the SystemReport.ps1 script file to a function called New-SystemReport and save the results to a file. 45 | 46 | ### EXAMPLE 3 47 | 48 | ```powershell 49 | PS C:\> Convert-ScriptToFunction c:\scripts\systemreport.ps1 -name New-System -alias nsr | Tee-Object -variable f 50 | ``` 51 | 52 | Convert the script to a function called New-System and tee the output to $f. This will also define an function alias of nsr. 53 | 54 | ## PARAMETERS 55 | 56 | ### -Path 57 | 58 | Enter the path to your PowerShell script file. 59 | 60 | ```yaml 61 | Type: String 62 | Parameter Sets: (All) 63 | Aliases: 64 | 65 | Required: True 66 | Position: 1 67 | Default value: None 68 | Accept pipeline input: True (ByPropertyName) 69 | Accept wildcard characters: False 70 | ``` 71 | 72 | ### -Name 73 | 74 | What is the name of your new function? It should have a standard Verb-Noun name. 75 | 76 | ```yaml 77 | Type: String 78 | Parameter Sets: (All) 79 | Aliases: 80 | 81 | Required: True 82 | Position: 2 83 | Default value: None 84 | Accept pipeline input: True (ByPropertyName) 85 | Accept wildcard characters: False 86 | ``` 87 | 88 | ### -Alias 89 | 90 | Define an optional alias for your new function. 91 | 92 | ```yaml 93 | Type: String[] 94 | Parameter Sets: (All) 95 | Aliases: 96 | 97 | Required: False 98 | Position: Named 99 | Default value: None 100 | Accept pipeline input: True (ByPropertyName) 101 | Accept wildcard characters: False 102 | ``` 103 | 104 | ### CommonParameters 105 | 106 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 107 | 108 | ## INPUTS 109 | 110 | ## OUTPUTS 111 | 112 | ### System.String 113 | 114 | ## NOTES 115 | 116 | ## RELATED LINKS 117 | -------------------------------------------------------------------------------- /docs/Export-FunctionFromFile.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/3GopWyo 5 | schema: 2.0.0 6 | --- 7 | 8 | # Export-FunctionFromFile 9 | 10 | ## SYNOPSIS 11 | 12 | Export a PowerShell function from a script file. 13 | 14 | ## SYNTAX 15 | 16 | ### All (Default) 17 | 18 | ```yaml 19 | Export-FunctionFromFile [-Path] [-OutputPath ] [-PassThru] 20 | [-Remove] [-WhatIf] [-Confirm] [] 21 | ``` 22 | 23 | ### byName 24 | 25 | ```yaml 26 | Export-FunctionFromFile [-Path] [-OutputPath ] 27 | [-Name ] [-PassThru] [-Remove] [-WhatIf] [-Confirm] [] 28 | ``` 29 | 30 | ### all 31 | 32 | ```yaml 33 | Export-FunctionFromFile [-Path] [-OutputPath ] [-All] [-Remove] [-PassThru] [-WhatIf] [-Confirm] [] 34 | ``` 35 | 36 | ## DESCRIPTION 37 | 38 | You should use Export-FunctionFromFile when you want to export PowerShell functions defined in in a single script file, placing each function in its own file. You might want to do this to build or restructure a PowerShell module. 39 | 40 | You can export all functions from a file or specific functions. The default behavior is to only export functions that follow a standard verb-noun naming convention. The source must be a .ps1 or .psm1 script file. 41 | 42 | If you run this command in the PowerShell ISE or the VS Code integrated PowerShell Terminal, you can use the dynamic parameter Remove to delete the function from the source file. 43 | 44 | ## EXAMPLES 45 | 46 | ### Example 1 47 | 48 | ```powershell 49 | PS C:\> Export-FunctionFromFile C:\scripts\MyInternetTools.psm1 -Name get-zipinfo -OutputPath c:\scripts\psinternettools\functions 50 | ``` 51 | 52 | Export the Get-ZipInfo function from C:\scripts\MyInternetTools.psm1 to its own file. The original file remains unchanged. 53 | 54 | ### Example 2 55 | 56 | ```powershell 57 | PS C:\> Export-FunctionFromFile C:\scripts\MyInternetTools.psm1 -OutputPath c:\scripts\psinternettools\functions 58 | ``` 59 | 60 | Export all functions that follow the verb-noun naming convention to separate files under C:\Scripts\PSInternetTools\Functions. 61 | 62 | ## PARAMETERS 63 | 64 | ### -All 65 | 66 | Export all detected functions regardless of name. 67 | 68 | ```yaml 69 | Type: SwitchParameter 70 | Parameter Sets: all 71 | Aliases: 72 | 73 | Required: False 74 | Position: Named 75 | Default value: None 76 | Accept pipeline input: False 77 | Accept wildcard characters: False 78 | ``` 79 | 80 | ### -Confirm 81 | 82 | Prompts you for confirmation before running the cmdlet. 83 | 84 | ```yaml 85 | Type: SwitchParameter 86 | Parameter Sets: (All) 87 | Aliases: cf 88 | 89 | Required: False 90 | Position: Named 91 | Default value: None 92 | Accept pipeline input: False 93 | Accept wildcard characters: False 94 | ``` 95 | 96 | ### -Name 97 | 98 | Specify a function by name. 99 | 100 | ```yaml 101 | Type: String[] 102 | Parameter Sets: byName 103 | Aliases: 104 | 105 | Required: False 106 | Position: Named 107 | Default value: None 108 | Accept pipeline input: False 109 | Accept wildcard characters: False 110 | ``` 111 | 112 | ### -OutputPath 113 | 114 | Specify the output path. The default is the same directory as the .ps1 file. 115 | 116 | ```yaml 117 | Type: String 118 | Parameter Sets: (All) 119 | Aliases: 120 | 121 | Required: False 122 | Position: Named 123 | Default value: None 124 | Accept pipeline input: False 125 | Accept wildcard characters: False 126 | ``` 127 | 128 | ### -PassThru 129 | 130 | Pass the output file to the pipeline. 131 | 132 | ```yaml 133 | Type: SwitchParameter 134 | Parameter Sets: (All) 135 | Aliases: 136 | 137 | Required: False 138 | Position: Named 139 | Default value: None 140 | Accept pipeline input: False 141 | Accept wildcard characters: False 142 | ``` 143 | 144 | ### -Path 145 | 146 | Specify the .ps1 or .psm1 file with defined functions. 147 | 148 | ```yaml 149 | Type: String 150 | Parameter Sets: (All) 151 | Aliases: 152 | 153 | Required: True 154 | Position: 0 155 | Default value: None 156 | Accept pipeline input: False 157 | Accept wildcard characters: False 158 | ``` 159 | 160 | ### -WhatIf 161 | 162 | Shows what would happen if the cmdlet runs. 163 | The cmdlet is not run. 164 | 165 | ```yaml 166 | Type: SwitchParameter 167 | Parameter Sets: (All) 168 | Aliases: wi 169 | 170 | Required: False 171 | Position: Named 172 | Default value: None 173 | Accept pipeline input: False 174 | Accept wildcard characters: False 175 | ``` 176 | 177 | ### -Remove 178 | 179 | This is a dynamic parameter that is only available if you are running this command in the PowerShell ISE of the VS Code integrated PowerShell terminal. The function will be deleted from the source file after it has been exported. 180 | 181 | ```yaml 182 | Type: SwitchParameter 183 | Parameter Sets: (All) 184 | Aliases: 185 | 186 | Required: False 187 | Position: Named 188 | Default value: None 189 | Accept pipeline input: False 190 | Accept wildcard characters: False 191 | ``` 192 | 193 | ### CommonParameters 194 | 195 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 196 | 197 | ## INPUTS 198 | 199 | ### None 200 | 201 | ## OUTPUTS 202 | 203 | ### None 204 | 205 | ### System.IO.FileInfo 206 | 207 | ## NOTES 208 | 209 | ## RELATED LINKS 210 | 211 | [Get-FunctionName](Get-FunctionName.md) 212 | 213 | [Export-FunctionToFile](Export-FunctionToFile.md) 214 | -------------------------------------------------------------------------------- /docs/Export-FunctionToFile.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/3mI7E6w 5 | schema: 2.0.0 6 | --- 7 | 8 | # Export-FunctionToFile 9 | 10 | ## SYNOPSIS 11 | 12 | Export a PowerShell function to a file. 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | Export-FunctionToFile [-Name] [-Path ] [-PassThru] [-Requires ] [-WhatIf] [-Confirm] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | You can use this command to export a function which is loaded into your PowerShell session. You might need to do this when you create an ad-hoc function and want to save it to a file. This command will take the content of the function and export it to a ps1 file. The function name will be used for the file name. Although, characters like the colon will be stripped to create a filesystem-compatible filename. 23 | 24 | ## EXAMPLES 25 | 26 | ### Example 1 27 | 28 | ```powershell 29 | PS C:\> Export-FunctionToFile -Name prompt -Path c:\scripts 30 | ``` 31 | 32 | Get the prompt function from your PowerShell session and export it to C:\Scripts. The filename will be prompt.ps1 33 | 34 | ### Example 2 35 | 36 | ```powershell 37 | PS C:\> Export-FunctionToFile -Name New-FileLink -Path c:\work -Requires "#requires -version 5.1","#requires -RunAsAdministrator" -PassThru 38 | 39 | Directory: C:\work 40 | 41 | Mode LastWriteTime Length Name 42 | ---- ------------- ------ ---- 43 | -a--- 2/28/2022 1:28 PM 1987 New-FileLink.ps1 44 | ``` 45 | 46 | Export the New-FileLInk function to a file and specify runtime requirements. 47 | 48 | ## PARAMETERS 49 | 50 | ### -Confirm 51 | 52 | Prompts you for confirmation before running the cmdlet. 53 | 54 | ```yaml 55 | Type: SwitchParameter 56 | Parameter Sets: (All) 57 | Aliases: cf 58 | 59 | Required: False 60 | Position: Named 61 | Default value: None 62 | Accept pipeline input: False 63 | Accept wildcard characters: False 64 | ``` 65 | 66 | ### -Name 67 | 68 | Specify the name of a function loaded in your PowerShell session. 69 | 70 | ```yaml 71 | Type: String 72 | Parameter Sets: (All) 73 | Aliases: 74 | 75 | Required: True 76 | Position: 0 77 | Default value: None 78 | Accept pipeline input: True (ByValue) 79 | Accept wildcard characters: False 80 | ``` 81 | 82 | ### -PassThru 83 | 84 | Show the file result. 85 | 86 | ```yaml 87 | Type: SwitchParameter 88 | Parameter Sets: (All) 89 | Aliases: 90 | 91 | Required: False 92 | Position: Named 93 | Default value: None 94 | Accept pipeline input: False 95 | Accept wildcard characters: False 96 | ``` 97 | 98 | ### -Path 99 | 100 | Specify the location for the new file. The function name will be used for the file name, stripping off any characters that invalid filename characters. 101 | 102 | ```yaml 103 | Type: String 104 | Parameter Sets: (All) 105 | Aliases: 106 | 107 | Required: False 108 | Position: Named 109 | Default value: None 110 | Accept pipeline input: False 111 | Accept wildcard characters: False 112 | ``` 113 | 114 | ### -Requires 115 | 116 | Specify #Requires statements, including the # character. 117 | 118 | ```yaml 119 | Type: String[] 120 | Parameter Sets: (All) 121 | Aliases: 122 | 123 | Required: False 124 | Position: Named 125 | Default value: None 126 | Accept pipeline input: False 127 | Accept wildcard characters: False 128 | ``` 129 | 130 | ### -WhatIf 131 | 132 | Shows what would happen if the cmdlet runs. 133 | The cmdlet is not run. 134 | 135 | ```yaml 136 | Type: SwitchParameter 137 | Parameter Sets: (All) 138 | Aliases: wi 139 | 140 | Required: False 141 | Position: Named 142 | Default value: None 143 | Accept pipeline input: False 144 | Accept wildcard characters: False 145 | ``` 146 | 147 | ### CommonParameters 148 | 149 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 150 | 151 | ## INPUTS 152 | 153 | ### System.String 154 | 155 | ## OUTPUTS 156 | 157 | ### None 158 | 159 | ### System.IO.FileInfo 160 | 161 | ## NOTES 162 | 163 | ## RELATED LINKS 164 | 165 | [Export-FunctionFromFile](Export-FunctionFromFile.md) 166 | -------------------------------------------------------------------------------- /docs/Export-ModuleLayout.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/3nlhmJd 5 | schema: 2.0.0 6 | --- 7 | 8 | # Export-ModuleLayout 9 | 10 | ## SYNOPSIS 11 | 12 | Export a model module layout. 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | Export-ModuleLayout -SourcePath [-Version ] 18 | [-FilePath ] [-PassThru] [] 19 | ``` 20 | 21 | ## DESCRIPTION 22 | 23 | Use Export-ModuleLayout to export a model module directory structure to a json file. You can use Import-ModuleLayout to recreate the layout from the json file. The export process will include not only directories, but also text files like a readme or license file. 24 | 25 | ## EXAMPLES 26 | 27 | ### Example 1 28 | 29 | ```powershell 30 | PS C:\> Export-ModuleLayout c:\work\sample -FilePath c:\work\layout.json -Verbose 31 | VERBOSE: Starting Export-ModuleLayout 32 | VERBOSE: Exporting directory structure from c:\work\sample 33 | VERBOSE: Processing .github 34 | VERBOSE: Processing .vscode 35 | VERBOSE: Processing docs 36 | VERBOSE: Processing en-us 37 | VERBOSE: Processing formats 38 | VERBOSE: Processing functions 39 | VERBOSE: Processing icons 40 | VERBOSE: Processing images 41 | VERBOSE: Processing samples 42 | VERBOSE: Processing tests 43 | VERBOSE: Processing types 44 | VERBOSE: Processing changelog.md 45 | VERBOSE: Processing License.txt 46 | VERBOSE: Processing README.md 47 | VERBOSE: Processing scratch-changelog.md 48 | VERBOSE: Processing .vscode\tasks.json 49 | VERBOSE: Processing formats\readme.txt 50 | VERBOSE: Processing functions\private 51 | VERBOSE: Processing functions\public 52 | VERBOSE: Processing functions\private\readme.txt 53 | VERBOSE: Processing functions\public\readme.txt 54 | VERBOSE: Processing tests\readme.txt 55 | VERBOSE: Processing types\readme.txt 56 | VERBOSE: Exporting module layout to c:\work\layout.json. 57 | PS C:\> 58 | ``` 59 | 60 | Export the directory layout defined under C:\Work\sample to a c:\work\layout.json. 61 | 62 | ## PARAMETERS 63 | 64 | ### -FilePath 65 | 66 | Specify the name of the Json file to store the result. 67 | 68 | ```yaml 69 | Type: String 70 | Parameter Sets: (All) 71 | Aliases: 72 | 73 | Required: False 74 | Position: Named 75 | Default value: modulelayout.json 76 | Accept pipeline input: False 77 | Accept wildcard characters: False 78 | ``` 79 | 80 | ### -PassThru 81 | 82 | Show the file result. 83 | 84 | ```yaml 85 | Type: SwitchParameter 86 | Parameter Sets: (All) 87 | Aliases: 88 | 89 | Required: False 90 | Position: Named 91 | Default value: None 92 | Accept pipeline input: False 93 | Accept wildcard characters: False 94 | ``` 95 | 96 | ### -SourcePath 97 | 98 | Specify the model module path. 99 | 100 | ```yaml 101 | Type: String 102 | Parameter Sets: (All) 103 | Aliases: 104 | 105 | Required: True 106 | Position: Named 107 | Default value: None 108 | Accept pipeline input: False 109 | Accept wildcard characters: False 110 | ``` 111 | 112 | ### -Version 113 | 114 | Define a version number for this layout. 115 | 116 | ```yaml 117 | Type: String 118 | Parameter Sets: (All) 119 | Aliases: 120 | 121 | Required: False 122 | Position: Named 123 | Default value: 1.0 124 | Accept pipeline input: False 125 | Accept wildcard characters: False 126 | ``` 127 | 128 | ### CommonParameters 129 | 130 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 131 | 132 | ## INPUTS 133 | 134 | ### None 135 | 136 | ## OUTPUTS 137 | 138 | ### None 139 | 140 | ### System.IO.FileInfo 141 | 142 | ## NOTES 143 | 144 | ## RELATED LINKS 145 | 146 | [Import-ModuleLayout](Import-ModuleLayout.md) 147 | 148 | [Get-ModuleLayout](Get-ModuleLayout.md) 149 | -------------------------------------------------------------------------------- /docs/Format-FunctionName.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/3nnpKYy 5 | schema: 2.0.0 6 | --- 7 | 8 | # Format-FunctionName 9 | 10 | ## SYNOPSIS 11 | 12 | Format a function name to proper case. 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | Format-FunctionName [-Name] [-NounCapitals ] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | Format-FunctionName is intended to be used as a helper function in your scripting automation. This is a simple function that will format a verb-noun function name into proper case. It will take an input such as test-data and format it as Test-Data. It will not format as Pascal case, although you can capitalize N number of characters in the Noun portion of your command name. The command also will not verify that the verb component is acceptable. Use Test-FunctionName for that process. 23 | 24 | ## EXAMPLES 25 | 26 | ### Example 1 27 | 28 | ```powershell 29 | PS C:\> Format-FunctionName test-data 30 | Test-Data 31 | ``` 32 | 33 | Format the lower-case command name to proper case. 34 | 35 | ### Example 2 36 | 37 | ```powershell 38 | PS C:\> Format-FunctionName try-pssystem 39 | Try-Pssystem 40 | ``` 41 | 42 | The command does not validate the verb nor can it produce a Pascal Case result like Try-PsSystem. 43 | 44 | ### Example 3 45 | 46 | ```powershell 47 | PS C:\> Format-FunctionName test-pssystem -NounCapitals 3 48 | Test-PSSystem 49 | ``` 50 | 51 | Even though you can't format in Pascal case, you can specify how many characters of the Noun portion of your command that you want to capitalize. 52 | 53 | ## PARAMETERS 54 | 55 | ### -Name 56 | 57 | What is the name of your function? It should follow the Verb-Noun naming convention. Although the verb will not be validated. 58 | 59 | ```yaml 60 | Type: String 61 | Parameter Sets: (All) 62 | Aliases: 63 | 64 | Required: True 65 | Position: 0 66 | Default value: None 67 | Accept pipeline input: True (ByValue) 68 | Accept wildcard characters: False 69 | ``` 70 | 71 | ### -NounCapitals 72 | 73 | Capitalize the first N number of characters in the Noun. 74 | 75 | ```yaml 76 | Type: Int32 77 | Parameter Sets: (All) 78 | Aliases: 79 | 80 | Required: False 81 | Position: Named 82 | Default value: None 83 | Accept pipeline input: False 84 | Accept wildcard characters: False 85 | ``` 86 | 87 | ### CommonParameters 88 | 89 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 90 | 91 | ## INPUTS 92 | 93 | ### None 94 | 95 | ## OUTPUTS 96 | 97 | ### System.String 98 | 99 | ## NOTES 100 | 101 | ## RELATED LINKS 102 | 103 | [Test-FunctionName](Test-FunctionName.md) 104 | -------------------------------------------------------------------------------- /docs/Get-FunctionAlias.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/3fjNFUw 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-FunctionAlias 9 | 10 | ## SYNOPSIS 11 | 12 | Get a defined function alias. 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | Get-FunctionAlias [-Path] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | Get-FunctionAlias is a tool you can use in your scripting automation. It will extract function names and aliases from a PowerShell script file. The source must be a .ps1 or .psm1 file. The command will only identify aliases defined as part of the function using code like [alias('foo')]. 23 | 24 | ## EXAMPLES 25 | 26 | ### Example 1 27 | 28 | ```powershell 29 | PS C:\> Get-FunctionAlias -Path C:\scripts\SQLBackup.psm1 30 | 31 | Name Alias 32 | ---- ----- 33 | Backup-SQLDatabase Backup-SQL 34 | Restore-SQLdatabase rsql 35 | ``` 36 | 37 | Get functions and aliases from the specified file. 38 | 39 | ## PARAMETERS 40 | 41 | ### -Path 42 | 43 | Specify the .ps1 or .psm1 file with defined functions. 44 | 45 | ```yaml 46 | Type: String 47 | Parameter Sets: (All) 48 | Aliases: PSPath 49 | 50 | Required: True 51 | Position: 0 52 | Default value: None 53 | Accept pipeline input: True (ByPropertyName) 54 | Accept wildcard characters: False 55 | ``` 56 | 57 | ### CommonParameters 58 | 59 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 60 | 61 | ## INPUTS 62 | 63 | ### None 64 | 65 | ## OUTPUTS 66 | 67 | ### PSFunctionAlias 68 | 69 | ## NOTES 70 | 71 | ## RELATED LINKS 72 | 73 | [Get-FunctionName](Get-FunctionName.md) 74 | 75 | [Get-FunctionAttribute](Get-FunctionAttribute.md) 76 | -------------------------------------------------------------------------------- /docs/Get-FunctionAttribute.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/3KhHkY7 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-FunctionAttribute 9 | 10 | ## SYNOPSIS 11 | 12 | Get function attributes like cmdletbinding. 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | Get-FunctionAttribute [-Name] -Path [-ToString] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | This command can be used to get function attributes such as cmdletbinding or alias settings. 23 | 24 | ## EXAMPLES 25 | 26 | ### Example 1 27 | 28 | ```powershell 29 | PS C:\> Get-FunctionAttribute -path c:\scripts\Get-ParameterBlock.ps1 -Name Get-ParameterBlock 30 | 31 | 32 | Type : cmdletbinding 33 | NamedArguments : {} 34 | PositionalArguments : {} 35 | String : [cmdletbinding()] 36 | Function : Get-ParameterBlock 37 | Path : C:\scripts\Get-ParameterBlock.ps1 38 | 39 | Type : alias 40 | NamedArguments : {} 41 | PositionalArguments : {"gpb"} 42 | String : [alias("gpb")] 43 | Function : Get-ParameterBlock 44 | Path : C:\scripts\Get-ParameterBlock.ps1 45 | 46 | Type : OutputType 47 | NamedArguments : {} 48 | PositionalArguments : {"ParamBlockAst", "String"} 49 | String : [OutputType("ParamBlockAst","String")] 50 | Function : Get-ParameterBlock 51 | Path : C:\scripts\PSFunctionTools\functions\public\Get-ParameterB 52 | lock.ps1 53 | ``` 54 | 55 | Get detailed function attributes. 56 | 57 | ### Example 2 58 | 59 | ```powershell 60 | PS C:\> Get-FunctionName C:\scripts\New-OneDriveLink.ps1 -Detailed | Get-FunctionAttribute -ToString 61 | [cmdletbinding(SupportsShouldProcess)] 62 | [alias("odl")] 63 | ``` 64 | 65 | Get function attributes as a string. 66 | 67 | ## PARAMETERS 68 | 69 | ### -Name 70 | 71 | Specify the name of the PowerShell function. 72 | 73 | ```yaml 74 | Type: String 75 | Parameter Sets: (All) 76 | Aliases: 77 | 78 | Required: True 79 | Position: 0 80 | Default value: None 81 | Accept pipeline input: True (ByPropertyName) 82 | Accept wildcard characters: False 83 | ``` 84 | 85 | ### -Path 86 | 87 | Specify the path to the .ps1 or .psm1 file. 88 | 89 | ```yaml 90 | Type: String 91 | Parameter Sets: (All) 92 | Aliases: 93 | 94 | Required: True 95 | Position: Named 96 | Default value: None 97 | Accept pipeline input: True (ByPropertyName) 98 | Accept wildcard characters: False 99 | ``` 100 | 101 | ### -ToString 102 | 103 | Display the attribute block as a string. 104 | 105 | ```yaml 106 | Type: SwitchParameter 107 | Parameter Sets: (All) 108 | Aliases: 109 | 110 | Required: False 111 | Position: Named 112 | Default value: None 113 | Accept pipeline input: False 114 | Accept wildcard characters: False 115 | ``` 116 | 117 | ### CommonParameters 118 | 119 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 120 | 121 | ## INPUTS 122 | 123 | ### None 124 | 125 | ## OUTPUTS 126 | 127 | ### PSFunctionAttribute 128 | 129 | ### String 130 | 131 | ## NOTES 132 | 133 | ## RELATED LINKS 134 | 135 | [Get-ParameterBlock](Get-ParameterBlock.md) 136 | 137 | [Get-FunctionAlias](Get-FunctionAlias.md) 138 | -------------------------------------------------------------------------------- /docs/Get-FunctionName.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/3I3PdhR 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-FunctionName 9 | 10 | ## SYNOPSIS 11 | 12 | Identify the names of PowerShell functions in a PowerShell script file. 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | Get-FunctionName [-Path] [-All] [-Detailed] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | When exporting functions from files, you may only want to export specific functions. Which you can do if you know the name. Use Get-FunctionName to identify the names of functions. The default behavior is to get names of functions that follow the Verb-Noun naming convention. 23 | 24 | ## EXAMPLES 25 | 26 | ### Example 1 27 | 28 | ```powershell 29 | PS C:\> Get-FunctionName C:\scripts\MyInternetTools.psm1 30 | Get-MyWhoIs 31 | Get-GeoIP 32 | Get-MyPublicIP 33 | Get-MyWeather 34 | Get-WeatherByProxy 35 | Get-WeatherLocation 36 | Get-QOTD 37 | Get-ZipInfo 38 | Get-RSSFeed 39 | Open-URL 40 | ``` 41 | 42 | Get the names of all standard functions in the specified file. 43 | 44 | ### Example 2 45 | 46 | ```powershell 47 | PS C:\> Get-FunctionName C:\scripts\MyInternetTools.psm1 -All 48 | _log 49 | _parseOutput 50 | Get-MyWhoIs 51 | Get-GeoIP 52 | Get-MyPublicIP 53 | Get-MyWeather 54 | Get-WeatherByProxy 55 | Get-WeatherLocation 56 | Get-QOTD 57 | Get-ZipInfo 58 | Get-RSSFeed 59 | Open-URL 60 | ``` 61 | 62 | Get the names of all functions in the specified file regardless of naming convention. 63 | 64 | ### Example 3 65 | 66 | ```powershell 67 | PS C:\> Get-FunctionName C:\scripts\Convert-FunctionToFile.ps1 -Detailed 68 | 69 | Path: C:\scripts\Convert-FunctionToFile.ps1 70 | 71 | Name 72 | ---- 73 | Export-FunctionFromFile 74 | Get-FunctionAlias 75 | Get-FunctionName 76 | Test-FunctionName 77 | ``` 78 | 79 | Get detailed output from the command which includes the path to source file. 80 | 81 | ## PARAMETERS 82 | 83 | ### -All 84 | 85 | List all detected function names regardless of naming convention. 86 | 87 | ```yaml 88 | Type: SwitchParameter 89 | Parameter Sets: (All) 90 | Aliases: 91 | 92 | Required: False 93 | Position: Named 94 | Default value: None 95 | Accept pipeline input: False 96 | Accept wildcard characters: False 97 | ``` 98 | 99 | ### -Path 100 | 101 | Specify the .ps1 or .psm1 file with defined functions. 102 | 103 | ```yaml 104 | Type: String 105 | Parameter Sets: (All) 106 | Aliases: PSPath 107 | 108 | Required: True 109 | Position: 0 110 | Default value: None 111 | Accept pipeline input: True (ByValue) 112 | Accept wildcard characters: False 113 | ``` 114 | 115 | ### -Detailed 116 | 117 | Write a rich detailed object to the pipeline. 118 | 119 | ```yaml 120 | Type: SwitchParameter 121 | Parameter Sets: (All) 122 | Aliases: 123 | 124 | Required: False 125 | Position: Named 126 | Default value: None 127 | Accept pipeline input: False 128 | Accept wildcard characters: False 129 | ``` 130 | 131 | ### CommonParameters 132 | 133 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 134 | 135 | ## INPUTS 136 | 137 | ### None 138 | 139 | ## OUTPUTS 140 | 141 | ### string 142 | 143 | ### PSFunctionName 144 | 145 | ## NOTES 146 | 147 | ## RELATED LINKS 148 | 149 | [Get-FunctionAlias](Get-FunctionAlias.md) 150 | 151 | [Get-FunctionAttribute](Get-FunctionAttribute.md) 152 | 153 | [Get-ParameterBlock](Get-Parameterblock.md) 154 | 155 | [Get-FunctionProfile](Get-FunctionProfile.md) 156 | -------------------------------------------------------------------------------- /docs/Get-FunctionProfile.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/325JY1E 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-FunctionProfile 9 | 10 | ## SYNOPSIS 11 | 12 | Get a technical summary of a PowerShell function. 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | Get-FunctionProfile [-Name] -Path [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | Get-FunctionProfile is designed to give you a technical summary of a PowerShell function. You might use this to preview what commands a function might execute or if it supports -Whatif. The function might be something someone else wrote, or perhaps you want to double-check your code. The command writes an object to the pipeline with properties that indicate the following: 23 | 24 | + Name : The function name 25 | 26 | + FunctionAlias : Defined aliases for the function 27 | 28 | + SupportsShouldProcess : Does the function support -WhatIf 29 | 30 | + ParameterSets : A list of any detected parameter sets 31 | 32 | + DynamicParameters : Does the function have dynamic parameters 33 | 34 | + RequiredVersion : Show a required PowerShell version 35 | 36 | + RequiredModules : List any required modules 37 | 38 | + RequiresElevation : Must the command be run as administrator 39 | 40 | + Commands : A list of detected PowerShell commands 41 | 42 | + ExternalCommands : A list of external commands that PowerShell can resolve 43 | 44 | + DotNet : A list of .NET detected classes and methods 45 | 46 | + Aliases : A list of detected PowerShell aliases 47 | 48 | + Unresolved : A list of unrecognized items detected as commands 49 | 50 | + Path : The path to the script file 51 | 52 | Note that the analysis may not be 100% complete. For example, it is difficult to distinguish between the alias 'foreach' and the 'foreach' enumerator. 53 | 54 | ## EXAMPLES 55 | 56 | ### Example 1 57 | 58 | ```powershell 59 | PS C:\...\samples> Get-FunctionProfile -path .\SampleScript5.ps1 -name Get-Result 60 | 61 | Name : Get-Result 62 | FunctionAlias : grx 63 | SupportsShouldProcess : False 64 | ParameterSets : 65 | DynamicParameters : False 66 | RequiredVersion : 5.1 67 | RequiredModules : {} 68 | RequiresElevation : True 69 | Commands : {Get-CimInstance, Get-Random, Join-Path, New-Timespan…} 70 | ExternalCommands : {c:\scripts\cleanup.bat, notepad.exe} 71 | DotNet : {[system.datetime]::now, 72 | [system.environment]::getenvironmentvariable("temp")} 73 | Aliases : {gcim, tee} 74 | Unresolved : {w} 75 | Path : C:\Scripts\PSFunctionTools\samples\SampleScript5.ps1 76 | ``` 77 | 78 | A sample analysis. Commands should be PowerShell cmdlets, including resolved aliases. Detected command aliases will also be retrieved. Unresolved commands might be undefined aliases or some other command that PowerShell could not resolve. 79 | 80 | ### Example 2 81 | 82 | ```powershell 83 | PS C:\Scripts\mymodule\functions> dir *.ps1 | Get-FunctionName -Detailed | Get-FunctionProfile | Where-Object aliases 84 | ``` 85 | 86 | Profile all function files in a module looking for those that still have command aliases defined. 87 | 88 | ## PARAMETERS 89 | 90 | ### -Name 91 | 92 | Specify the name of the PowerShell function. 93 | 94 | ```yaml 95 | Type: String 96 | Parameter Sets: (All) 97 | Aliases: 98 | 99 | Required: True 100 | Position: 0 101 | Default value: None 102 | Accept pipeline input: True (ByPropertyName) 103 | Accept wildcard characters: False 104 | ``` 105 | 106 | ### -Path 107 | 108 | Specify the path to the .ps1 or .psm1 file. 109 | 110 | ```yaml 111 | Type: String 112 | Parameter Sets: (All) 113 | Aliases: 114 | 115 | Required: True 116 | Position: Named 117 | Default value: None 118 | Accept pipeline input: True (ByPropertyName) 119 | Accept wildcard characters: False 120 | ``` 121 | 122 | ### CommonParameters 123 | 124 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 125 | 126 | ## INPUTS 127 | 128 | ### System.String 129 | 130 | ## OUTPUTS 131 | 132 | ### PSFunctionProfile 133 | 134 | ## NOTES 135 | 136 | ## RELATED LINKS 137 | 138 | [Get-ParameterBlock](Get-ParameterBlock.md) 139 | 140 | [Get-FunctionAlias](Get-FunctionAlias.md) 141 | 142 | [Get-FunctionAttribute](Get-FunctionAttribute.md) 143 | -------------------------------------------------------------------------------- /docs/Get-ModuleLayout.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/3FnnVkP 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-ModuleLayout 9 | 10 | ## SYNOPSIS 11 | 12 | Get information about a module layout file. 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | Get-ModuleLayout [-Path] [-AsTree] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | This command will provide information about a module layout folder which was created using Export-ModuleLayout. The default output is custom object. You can elect to view the layout as a tree. This parameter requires the tree command-line utility which should be available on Windows systems by default. On non-Windows platforms, you may need to install the utility. 23 | 24 | ## EXAMPLES 25 | 26 | ### Example 1 27 | 28 | ```powershell 29 | PS C:\> Get-ModuleLayout C:\scripts\ModuleLayout.json 30 | 31 | Path: C:\scripts\ModuleLayout.json 32 | 33 | Created CreatedBy Version Folders Files 34 | ------- --------- ------- ------- ----- 35 | 12/16/2024 11:42 AM THINKP1\Jeff 1.0 13 10 36 | ``` 37 | 38 | The default output is a custom object. 39 | 40 | ### Example 2 41 | 42 | ```powershell 43 | PS C:\> Get-ModuleLayout C:\scripts\ModuleLayout.json | Format-List 44 | 45 | Path : C:\scripts\ModuleLayout.json 46 | Created : 12/16/2024 11:42 AM 47 | CreatedBy : THINKP1\Jeff 48 | SourcePath : C:\work\sample 49 | LayoutVersion : 1.0 50 | SourceComputer : THINKP1 51 | Folders : {.github, .vscode, docs, en-us…} 52 | Files : {changelog.md, License.txt, README.md, scratch-changelog.md…} 53 | ``` 54 | 55 | The default output is a rich object. 56 | 57 | ### Example 3 58 | 59 | ```powershell 60 | PS C:\> Get-ModuleLayout C:\scripts\simplelayout.json -AsTree 61 | C:\\ 62 | | changelog.md 63 | | README.md 64 | | 65 | +---.vscode 66 | +---docs 67 | +---en-us 68 | +---formats 69 | | readme.txt 70 | | 71 | +---functions 72 | | 73 | +---tests 74 | | readme.txt 75 | | 76 | \---types 77 | readme.txt 78 | ``` 79 | 80 | Display the layout as a tree. 81 | 82 | ## PARAMETERS 83 | 84 | ### -AsTree 85 | 86 | Show the module layout as a tree. This will create a temporary folder structure in %TEMP% or its equivalent on non-Windows platforms.This parameter relies on tree command line utility which should be installed by default on Windows systems. You may need to install a tree utility on non-Windows platforms. 87 | 88 | ```yaml 89 | Type: SwitchParameter 90 | Parameter Sets: (All) 91 | Aliases: 92 | 93 | Required: False 94 | Position: Named 95 | Default value: None 96 | Accept pipeline input: False 97 | Accept wildcard characters: False 98 | ``` 99 | 100 | ### -Path 101 | 102 | Specify the path to the module layout json file. 103 | 104 | ```yaml 105 | Type: String 106 | Parameter Sets: (All) 107 | Aliases: 108 | 109 | Required: True 110 | Position: 0 111 | Default value: None 112 | Accept pipeline input: True (ByValue) 113 | Accept wildcard characters: False 114 | ``` 115 | 116 | ### CommonParameters 117 | 118 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 119 | 120 | ## INPUTS 121 | 122 | ### System.String 123 | 124 | ## OUTPUTS 125 | 126 | ### ModuleLayout 127 | 128 | ### String 129 | 130 | ## NOTES 131 | 132 | ## RELATED LINKS 133 | 134 | [Export-ModuleLayout](Export-ModuleLayout.md) 135 | -------------------------------------------------------------------------------- /docs/Get-PSFunctionTools.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/3Kipd3Y 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-PSFunctionTools 9 | 10 | ## SYNOPSIS 11 | 12 | Get a summary of PSFunctionTools commands. 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | Get-PSFunctionTools [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | This command will give you a brief summary of all commands, including aliases, in the PSFunctionTools module. 23 | 24 | ## EXAMPLES 25 | 26 | ### Example 1 27 | 28 | ```text 29 | PS C:\> Get-PSFunctionTools 30 | 31 | Module: PSFunctionTools [v1.2.0] 32 | 33 | Name Alias Synopsis 34 | ---- ----- -------- 35 | Convert-ScriptToFunction csf Convert a script file to a PowerShell funct… 36 | Export-FunctionFromFile eff Export a PowerShell function from a script … 37 | Export-FunctionToFile etf Export a PowerShell function to a file. 38 | Export-ModuleLayout eml Export a model module layout. 39 | Format-FunctionName ffn Format a function name to proper case. 40 | Get-FunctionAlias {ga, gfal} Get a defined function alias. 41 | Get-FunctionAttribute gfa Get function attributes like cmdletbinding. 42 | Get-FunctionName gfn Identify the names of PowerShell functions … 43 | Get-FunctionProfile gfp Get a technical summary of a PowerShell fun… 44 | Get-ModuleLayout Get information about a module layout file. 45 | Get-ParameterBlock gpb Get a function's parameter block. 46 | Get-PSFunctionTools Get a summary of PSFunctionTools commands. 47 | Get-PSRequirements List PowerShell command requirements. 48 | Import-ModuleLayout iml Create a module structure from a layout fil… 49 | New-CommentHelp nch Create comment based help. 50 | New-ModuleFromFiles Create a PowerShell module from a set of fi… 51 | New-ModuleFromLayout Create a new module based on a layout. 52 | Test-FunctionName tfn Test the validity of a PowerShell function … 53 | ``` 54 | 55 | The default output is formatted as a table. 56 | 57 | ## PARAMETERS 58 | 59 | ### CommonParameters 60 | 61 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 62 | 63 | ## INPUTS 64 | 65 | ### None 66 | 67 | ## OUTPUTS 68 | 69 | ### PSFunctionTool 70 | 71 | ## NOTES 72 | 73 | ## RELATED LINKS 74 | 75 | [Get-Command]() 76 | -------------------------------------------------------------------------------- /docs/Get-PSRequirements.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/3KhHsa3 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-PSRequirements 9 | 10 | ## SYNOPSIS 11 | 12 | List PowerShell command requirements. 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | Get-PSRequirements [-Path] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | As part of your scripting automation, you may want to capture requirements defined in a script file such as '# requires -version 5.1'. Get-PSRequirements will process a PowerShell script file for these type of requirements. 23 | 24 | ## EXAMPLES 25 | 26 | ### Example 1 27 | 28 | ```powershell 29 | PS C:\> Get-PSRequirements -Path C:\scripts\SQLBackup.psm1 30 | 31 | Path : C:\scripts\SQLBackup.psm1 32 | RequiredApplicationId : 33 | RequiredPSVersion : 5.1 34 | RequiredPSEditions : {} 35 | RequiredModules : {} 36 | RequiresPSSnapIns : {} 37 | RequiredAssemblies : {} 38 | IsElevationRequired : True 39 | ``` 40 | 41 | If you run this command in the PowerShell console or VS Code, and elevation is required, the 'True' value will be displayed in green. 42 | 43 | ## PARAMETERS 44 | 45 | ### -Path 46 | 47 | The path to your PowerShell script file. It must be a .ps1 or .psm1 file. 48 | 49 | ```yaml 50 | Type: String 51 | Parameter Sets: (All) 52 | Aliases: 53 | 54 | Required: True 55 | Position: 0 56 | Default value: None 57 | Accept pipeline input: True (ByPropertyName, ByValue) 58 | Accept wildcard characters: False 59 | ``` 60 | 61 | ### CommonParameters 62 | 63 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 64 | 65 | ## INPUTS 66 | 67 | ### System.String 68 | 69 | ## OUTPUTS 70 | 71 | ### PSScriptRequirements 72 | 73 | ## NOTES 74 | 75 | ## RELATED LINKS 76 | -------------------------------------------------------------------------------- /docs/Get-ParameterBlock.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/3HTXULi 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-ParameterBlock 9 | 10 | ## SYNOPSIS 11 | 12 | Get a function's parameter block. 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | Get-ParameterBlock [-Name] -Path [-ToString] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | This command is designed to use the PowerShell AST and retrieve a function's parameter block. You might use this to build comment-based help. 23 | 24 | ## EXAMPLES 25 | 26 | ### Example 1 27 | 28 | ```powershell 29 | PS C:\> Get-ParameterBlock -path c:\scripts\SimpleFunction.ps1 -name Get-FolderData 30 | 31 | Attributes Parameters Extent 32 | ---------- ---------- ------ 33 | {} {$Path, $Cutoff, $Filter} Param (… 34 | ``` 35 | 36 | Get the AST parameter block object. 37 | 38 | ### Example 2 39 | 40 | ```powershell 41 | PS C:\> Get-ParameterBlock -path c:\scripts\SimpleFunction.ps1 -name Get-FolderData -ToString 42 | [parameter(HelpMessage = "Specify the folder to analyze")] 43 | [string]$Path="." 44 | [datetime]$Cutoff 45 | [string]$Filter="*.*" 46 | ``` 47 | 48 | Get the parameter block for the given function as a string. 49 | 50 | ## PARAMETERS 51 | 52 | ### -Name 53 | 54 | Specify the name of the PowerShell function. 55 | 56 | ```yaml 57 | Type: String 58 | Parameter Sets: (All) 59 | Aliases: 60 | 61 | Required: True 62 | Position: 0 63 | Default value: None 64 | Accept pipeline input: False 65 | Accept wildcard characters: False 66 | ``` 67 | 68 | ### -Path 69 | 70 | Specify the path to the .ps1 or .psm1 file. 71 | 72 | ```yaml 73 | Type: String 74 | Parameter Sets: (All) 75 | Aliases: 76 | 77 | Required: True 78 | Position: Named 79 | Default value: None 80 | Accept pipeline input: False 81 | Accept wildcard characters: False 82 | ``` 83 | 84 | ### -ToString 85 | 86 | Display the parameter block as a string. 87 | 88 | ```yaml 89 | Type: SwitchParameter 90 | Parameter Sets: (All) 91 | Aliases: 92 | 93 | Required: False 94 | Position: Named 95 | Default value: None 96 | Accept pipeline input: False 97 | Accept wildcard characters: False 98 | ``` 99 | 100 | ### CommonParameters 101 | 102 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 103 | 104 | ## INPUTS 105 | 106 | ### None 107 | 108 | ## OUTPUTS 109 | 110 | ### ParamBlockAst 111 | 112 | ### String 113 | 114 | ## NOTES 115 | 116 | ## RELATED LINKS 117 | 118 | [New-CommentHelp](New-CommentHelp.md) 119 | 120 | [Get-FunctionAlias](Get-FunctionAlias.md) 121 | 122 | [Get-FunctionAttribute](Get-FunctionAttribute.md) 123 | -------------------------------------------------------------------------------- /docs/Import-ModuleLayout.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/3foUNyJ 5 | schema: 2.0.0 6 | --- 7 | 8 | # Import-ModuleLayout 9 | 10 | ## SYNOPSIS 11 | 12 | Create a module structure from a layout file. 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | Import-ModuleLayout [-Name] [-ParentPath ] -Layout [-WhatIf] [-Confirm] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | Use Import-ModuleLayout to recreate a module structure from a json file created with Export-ModuleLayout. Importing the json file will recreate the folders and files. 23 | 24 | ## EXAMPLES 25 | 26 | ### Example 1 27 | 28 | ```powershell 29 | PS C:\> Import-ModuleLayout -Name PSDemo -ParentPath D:\scripts -Layout C:\work\layout.json 30 | 31 | Directory: C:\scripts\PSDemo 32 | 33 | Mode LastWriteTime Length Name 34 | ---- ------------- ------ ---- 35 | d---- 12/16/2024 9:45 AM types 36 | d---- 12/16/2024 9:45 AM .github 37 | d---- 12/16/2024 9:45 AM .vscode 38 | d---- 12/16/2024 9:45 AM docs 39 | ... 40 | Directory: D:\scripts\PSDemo\functions 41 | 42 | Mode LastWriteTime Length Name 43 | ---- ------------- ------ ---- 44 | d---- 12/16/2024 9:45 AM public 45 | d---- 12/16/2024 9:45 AM private 46 | 47 | Directory: D:\scripts\PSDemo\functions\public 48 | 49 | Mode LastWriteTime Length Name 50 | ---- ------------- ------ ---- 51 | -a--- 12/16/2024 9:49 AM 276 readme.txt 52 | ... 53 | ``` 54 | 55 | Create the directory structure from C:\work\layout.json under a new path of D:\scripts\PSDemo. The parent path, D:\scripts, must already exist. 56 | 57 | ## PARAMETERS 58 | 59 | ### -Confirm 60 | 61 | Prompts you for confirmation before running the cmdlet. 62 | 63 | ```yaml 64 | Type: SwitchParameter 65 | Parameter Sets: (All) 66 | Aliases: cf 67 | 68 | Required: False 69 | Position: Named 70 | Default value: None 71 | Accept pipeline input: False 72 | Accept wildcard characters: False 73 | ``` 74 | 75 | ### -Layout 76 | 77 | Specify the path to the module layout json file. 78 | 79 | ```yaml 80 | Type: String 81 | Parameter Sets: (All) 82 | Aliases: 83 | 84 | Required: True 85 | Position: Named 86 | Default value: None 87 | Accept pipeline input: False 88 | Accept wildcard characters: False 89 | ``` 90 | 91 | ### -Name 92 | 93 | What is the name of your new module? 94 | 95 | ```yaml 96 | Type: String 97 | Parameter Sets: (All) 98 | Aliases: 99 | 100 | Required: True 101 | Position: 0 102 | Default value: None 103 | Accept pipeline input: False 104 | Accept wildcard characters: False 105 | ``` 106 | 107 | ### -ParentPath 108 | 109 | What is the parent path? 110 | The default is the current location 111 | 112 | ```yaml 113 | Type: String 114 | Parameter Sets: (All) 115 | Aliases: 116 | 117 | Required: False 118 | Position: Named 119 | Default value: . 120 | Accept pipeline input: False 121 | Accept wildcard characters: False 122 | ``` 123 | 124 | ### -WhatIf 125 | 126 | Shows what would happen if the cmdlet runs. 127 | The cmdlet is not run. 128 | 129 | ```yaml 130 | Type: SwitchParameter 131 | Parameter Sets: (All) 132 | Aliases: wi 133 | 134 | Required: False 135 | Position: Named 136 | Default value: None 137 | Accept pipeline input: False 138 | Accept wildcard characters: False 139 | ``` 140 | 141 | ### CommonParameters 142 | 143 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 144 | 145 | ## INPUTS 146 | 147 | ### None 148 | 149 | ## OUTPUTS 150 | 151 | ### System.IO.FileInfo 152 | 153 | ### System.IO.DirectoryInfo 154 | 155 | ## NOTES 156 | 157 | ## RELATED LINKS 158 | 159 | [Export-ModuleLayout](Export-ModuleLayout.md) 160 | -------------------------------------------------------------------------------- /docs/New-CommentHelp.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/3fg4wYe 5 | schema: 2.0.0 6 | --- 7 | 8 | # New-CommentHelp 9 | 10 | ## SYNOPSIS 11 | 12 | Create comment based help. 13 | 14 | ## SYNTAX 15 | 16 | ### ast (Default) 17 | 18 | ```yaml 19 | New-CommentHelp [-ParamBlock] [-Synopsis ] [-Description ] [] 20 | ``` 21 | 22 | ### template 23 | 24 | ```yaml 25 | New-CommentHelp [-Synopsis ] [-Description ] [-TemplateOnly] [] 26 | ``` 27 | 28 | ## DESCRIPTION 29 | 30 | You can use this command in your scripting automation to generate a comment-based help block for a function. The function will use the parameter block which you can get with Get-ParameterBlock to define help parameters. If your parameter has a HelpMessage defined, the value will be used in the parameter description. 31 | 32 | You can also specify a synopsis and/or description. Otherwise, you can edit the placeholders later. 33 | 34 | ## EXAMPLES 35 | 36 | ### Example 1 37 | 38 | ```powershell 39 | PS C:\> Get-ParameterBlock -path c:\scripts\SimpleFunction.ps1 -name Get-FolderData | New-CommentHelp -Synopsis "Get folder details" 40 | <# 41 | .Synopsis 42 | Get folder details 43 | .Description 44 | 45 | .Parameter Path 46 | Specify the folder to analyze 47 | .Parameter Cutoff 48 | 49 | .Parameter Filter 50 | 51 | .Example 52 | PS C:\> 53 | 54 | .Inputs 55 | 56 | .Outputs 57 | 58 | .Notes 59 | 60 | .Link 61 | 62 | #> 63 | ``` 64 | 65 | This example is getting the parameter block for the specified function and creating comment-base help. The Path parameter has a HelpMessage defined so that value is used in the help. You would need to fill in your own descriptions for the other parameters. 66 | 67 | ### EXAMPLE 2 68 | 69 | ```powershell 70 | PS C:\> New-CommentHelp -Synopsis "Get something" -Description "This is the beginning" -TemplateOnly 71 | <# 72 | .Synopsis 73 | Get something 74 | .Description 75 | This is the beginning 76 | .Example 77 | PS C:\> 78 | 79 | .Inputs 80 | 81 | .Outputs 82 | 83 | .Notes 84 | 85 | .Link 86 | 87 | #> 88 | ``` 89 | 90 | Create a comment help block template without relying on a parameter block. 91 | 92 | ## PARAMETERS 93 | 94 | ### -ParamBlock 95 | 96 | A parameter block AST object. Use Get-ParameterBlock. 97 | 98 | ```yaml 99 | Type: ParamBlockAst 100 | Parameter Sets: ast 101 | Aliases: 102 | 103 | Required: True 104 | Position: 0 105 | Default value: None 106 | Accept pipeline input: True (ByValue) 107 | Accept wildcard characters: False 108 | ``` 109 | 110 | ### -Description 111 | 112 | Provide a longer description. You can always edit this later. 113 | 114 | ```yaml 115 | Type: String 116 | Parameter Sets: (All) 117 | Aliases: 118 | 119 | Required: False 120 | Position: Named 121 | Default value: "" 122 | Accept pipeline input: False 123 | Accept wildcard characters: False 124 | ``` 125 | 126 | ### -Synopsis 127 | 128 | Provide a short description. You can always edit this later. 129 | 130 | ```yaml 131 | Type: String 132 | Parameter Sets: (All) 133 | Aliases: 134 | 135 | Required: False 136 | Position: Named 137 | Default value: "" 138 | Accept pipeline input: False 139 | Accept wildcard characters: False 140 | ``` 141 | 142 | ### -TemplateOnly 143 | 144 | Insert a standard help template without any parameter definitions. 145 | 146 | ```yaml 147 | Type: SwitchParameter 148 | Parameter Sets: template 149 | Aliases: 150 | 151 | Required: False 152 | Position: Named 153 | Default value: None 154 | Accept pipeline input: False 155 | Accept wildcard characters: False 156 | ``` 157 | 158 | ### CommonParameters 159 | 160 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 161 | 162 | ## INPUTS 163 | 164 | ### ParamBlockAST 165 | 166 | ## OUTPUTS 167 | 168 | ### string 169 | 170 | ## NOTES 171 | 172 | ## RELATED LINKS 173 | 174 | [Get-ParameterBlock](Get-ParameterBlock.md) 175 | -------------------------------------------------------------------------------- /docs/New-ModuleFromFiles.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/3GurmYk 5 | schema: 2.0.0 6 | --- 7 | 8 | # New-ModuleFromFiles 9 | 10 | ## SYNOPSIS 11 | 12 | Create a PowerShell module from a set of files. 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | New-ModuleFromFiles [-NewModuleName] [-ParentPath] -Description -Files -Layout [-FunctionPath ] [-WhatIf] [-Confirm] [-CreateHelp] [-MarkdownPath ] [-InitializeGit] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | New-ModuleFromFiles is an experimental function. It is not guaranteed to run without error and may change significantly between module versions. The command is designed to process a collection of PowerShell script files which contain PowerShell functions. Each function will be exported to an individual file to a location you specify. 23 | 24 | The function relies on a module layout file to scaffold the module directory. 25 | 26 | If you have the Platyps module installed, you can also choose to create help documentation. If you have git installed, you can initialize the module as a git repository. This process will also checkout a new branch. 27 | 28 | ## EXAMPLES 29 | 30 | ### Example 1 31 | 32 | ```powershell 33 | PS C:\> $splat = @{ 34 | Description = "Demo exported module" 35 | Files = "c:\scripts\pstools.psm1","c:\scripts\servertools.ps1" 36 | Layout = "c:\scripts\ModuleLayout.json" 37 | NewModuleName = "PSTools" 38 | ParentPath = "c:\scripts" 39 | CreateHelp = $True 40 | FunctionPath = "functions\public" 41 | InitializeGit = $true 42 | } 43 | PS C:\> New-ModuleFromFiles @splat 44 | ``` 45 | 46 | Using the parameter values defined in the hashtable, create a new module called PSTools using the functions from pstools.psm1 and servertools.ps1. Only functions with valid verb-noun names will be exported. This example will also create the initial help documentation and initialize a git repository. 47 | 48 | ## PARAMETERS 49 | 50 | ### -Confirm 51 | 52 | Prompts you for confirmation before running the cmdlet. 53 | 54 | ```yaml 55 | Type: SwitchParameter 56 | Parameter Sets: (All) 57 | Aliases: cf 58 | 59 | Required: False 60 | Position: Named 61 | Default value: None 62 | Accept pipeline input: False 63 | Accept wildcard characters: False 64 | ``` 65 | 66 | ### -CreateHelp 67 | 68 | Create help documentation using the Platyps module. This is a dynamic parameter that only exists if the Platyps module is detected. 69 | 70 | ```yaml 71 | Type: SwitchParameter 72 | Parameter Sets: (All) 73 | Aliases: 74 | 75 | Required: False 76 | Position: Named 77 | Default value: None 78 | Accept pipeline input: False 79 | Accept wildcard characters: False 80 | ``` 81 | 82 | ### -Description 83 | 84 | Enter a module description. 85 | 86 | ```yaml 87 | Type: String 88 | Parameter Sets: (All) 89 | Aliases: 90 | 91 | Required: True 92 | Position: Named 93 | Default value: None 94 | Accept pipeline input: False 95 | Accept wildcard characters: False 96 | ``` 97 | 98 | ### -Files 99 | 100 | Enter the paths to PowerShell script files with functions to export. These should be files with a .ps1 or .psm1 extension. Only functions with valid verb-noun names will be exported. Each function be exported to an individual file. 101 | 102 | ```yaml 103 | Type: String[] 104 | Parameter Sets: (All) 105 | Aliases: 106 | 107 | Required: True 108 | Position: Named 109 | Default value: None 110 | Accept pipeline input: False 111 | Accept wildcard characters: False 112 | ``` 113 | 114 | ### -FunctionPath 115 | 116 | Specify the relative path for the exported functions. This should be in your module layout. 117 | 118 | ```yaml 119 | Type: String 120 | Parameter Sets: (All) 121 | Aliases: 122 | 123 | Required: False 124 | Position: Named 125 | Default value: functions 126 | Accept pipeline input: False 127 | Accept wildcard characters: False 128 | ``` 129 | 130 | ### -InitializeGit 131 | 132 | Initialize the new module as a git repository. This is a dynamic parameter that only exists if git is detected. This process will also checkout a new branch. 133 | 134 | ```yaml 135 | Type: SwitchParameter 136 | Parameter Sets: (All) 137 | Aliases: 138 | 139 | Required: False 140 | Position: Named 141 | Default value: None 142 | Accept pipeline input: False 143 | Accept wildcard characters: False 144 | ``` 145 | 146 | ### -Layout 147 | 148 | Specify the module layout json file created with Export-ModuleLayout. 149 | 150 | ```yaml 151 | Type: String 152 | Parameter Sets: (All) 153 | Aliases: 154 | 155 | Required: True 156 | Position: Named 157 | Default value: None 158 | Accept pipeline input: False 159 | Accept wildcard characters: False 160 | ``` 161 | 162 | ### -MarkdownPath 163 | 164 | Specify the path for the markdown help files. This is a dynamic parameter that only exists if the Platyps module is detected. You can specify location that is in your module layout. 165 | 166 | ```yaml 167 | Type: String 168 | Parameter Sets: (All) 169 | Aliases: 170 | 171 | Required: False 172 | Position: Named 173 | Default value: docs 174 | Accept pipeline input: False 175 | Accept wildcard characters: False 176 | ``` 177 | 178 | ### -NewModuleName 179 | 180 | What is the name of the new module? 181 | 182 | ```yaml 183 | Type: String 184 | Parameter Sets: (All) 185 | Aliases: 186 | 187 | Required: True 188 | Position: 0 189 | Default value: None 190 | Accept pipeline input: False 191 | Accept wildcard characters: False 192 | ``` 193 | 194 | ### -ParentPath 195 | 196 | What is the parent path for the new module? It must already exist. 197 | 198 | ```yaml 199 | Type: String 200 | Parameter Sets: (All) 201 | Aliases: 202 | 203 | Required: True 204 | Position: 1 205 | Default value: none 206 | Accept pipeline input: False 207 | Accept wildcard characters: False 208 | ``` 209 | 210 | ### -WhatIf 211 | 212 | Shows what would happen if the cmdlet runs. 213 | The cmdlet is not run. 214 | 215 | ```yaml 216 | Type: SwitchParameter 217 | Parameter Sets: (All) 218 | Aliases: wi 219 | 220 | Required: False 221 | Position: Named 222 | Default value: None 223 | Accept pipeline input: False 224 | Accept wildcard characters: False 225 | ``` 226 | 227 | ### CommonParameters 228 | 229 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 230 | 231 | ## INPUTS 232 | 233 | ### None 234 | 235 | ## OUTPUTS 236 | 237 | ### System.Object 238 | 239 | ## NOTES 240 | 241 | ## RELATED LINKS 242 | 243 | [Export-ModuleLayout](Export-ModuleLayout.md) 244 | 245 | [Import-ModuleLayout](Import-ModuleLayout.md) 246 | 247 | [Export-FunctionFromFile](Export-FunctionFromFile.md) 248 | 249 | [New-ModuleFromLayout](New-ModuleFromLayout.md) 250 | -------------------------------------------------------------------------------- /docs/New-ModuleFromLayout.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/3foUOCN 5 | schema: 2.0.0 6 | --- 7 | 8 | # New-ModuleFromLayout 9 | 10 | ## SYNOPSIS 11 | 12 | Create a new module based on a layout. 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | New-ModuleFromLayout [-NewModuleName] [-ParentPath] -Description -Layout [-FunctionPath ] [-WhatIf] [-Confirm] [-InitializeGit] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | This command is very similar to New-ModuleFromFiles. That function builds a module structure from existing files. This function creates a new module but without defining any commands. New-ModuleFromLayout will still create a module structure based on a layout and it will still create module files. Specifically,the module manifest and root module files. 23 | 24 | If git.exe is detected, you can use the InitializeGit dynamic parameter to initialize the module as a git repository. 25 | 26 | ## EXAMPLES 27 | 28 | ### Example 1 29 | 30 | ```powershell 31 | PS C:\> New-ModuleFromLayout -NewModuleName PSDataResource -ParentPath c:\scripts -Description "A class-based DSC resource to do something." -Layout .c:\scripts\DSCModuleLayout.json 32 | ``` 33 | 34 | Create a new and empty module under C:\Scripts\PSDataResource using the layout file c:\scripts\dscmodulelayout.json. 35 | 36 | ## PARAMETERS 37 | 38 | ### -Confirm 39 | 40 | Prompts you for confirmation before running the cmdlet. 41 | 42 | ```yaml 43 | Type: SwitchParameter 44 | Parameter Sets: (All) 45 | Aliases: cf 46 | 47 | Required: False 48 | Position: Named 49 | Default value: None 50 | Accept pipeline input: False 51 | Accept wildcard characters: False 52 | ``` 53 | 54 | ### -Description 55 | 56 | Enter a module description. 57 | 58 | ```yaml 59 | Type: String 60 | Parameter Sets: (All) 61 | Aliases: 62 | 63 | Required: True 64 | Position: Named 65 | Default value: None 66 | Accept pipeline input: False 67 | Accept wildcard characters: False 68 | ``` 69 | 70 | ### -FunctionPath 71 | 72 | Specify the relative path where your functions will be created. 73 | 74 | ```yaml 75 | Type: String 76 | Parameter Sets: (All) 77 | Aliases: 78 | 79 | Required: False 80 | Position: Named 81 | Default value: functions 82 | Accept pipeline input: False 83 | Accept wildcard characters: False 84 | ``` 85 | 86 | ### -InitializeGit 87 | 88 | Initialize the new module as a git repository. This is a dynamic parameter that only exists if git.exe is detected. 89 | 90 | ```yaml 91 | Type: SwitchParameter 92 | Parameter Sets: (All) 93 | Aliases: 94 | 95 | Required: False 96 | Position: Named 97 | Default value: None 98 | Accept pipeline input: False 99 | Accept wildcard characters: False 100 | ``` 101 | 102 | ### -Layout 103 | 104 | Specify the module layout json file created with Export-ModuleLayout. 105 | 106 | ```yaml 107 | Type: String 108 | Parameter Sets: (All) 109 | Aliases: 110 | 111 | Required: True 112 | Position: Named 113 | Default value: None 114 | Accept pipeline input: False 115 | Accept wildcard characters: False 116 | ``` 117 | 118 | ### -NewModuleName 119 | 120 | What is the name of the new module? 121 | 122 | ```yaml 123 | Type: String 124 | Parameter Sets: (All) 125 | Aliases: 126 | 127 | Required: True 128 | Position: 0 129 | Default value: None 130 | Accept pipeline input: False 131 | Accept wildcard characters: False 132 | ``` 133 | 134 | ### -ParentPath 135 | 136 | What is the parent path for the new module? 137 | It must already exist. 138 | 139 | ```yaml 140 | Type: String 141 | Parameter Sets: (All) 142 | Aliases: 143 | 144 | Required: True 145 | Position: 1 146 | Default value: none 147 | Accept pipeline input: False 148 | Accept wildcard characters: False 149 | ``` 150 | 151 | ### -WhatIf 152 | 153 | Shows what would happen if the cmdlet runs. 154 | The cmdlet is not run. 155 | 156 | ```yaml 157 | Type: SwitchParameter 158 | Parameter Sets: (All) 159 | Aliases: wi 160 | 161 | Required: False 162 | Position: Named 163 | Default value: None 164 | Accept pipeline input: False 165 | Accept wildcard characters: False 166 | ``` 167 | 168 | ### CommonParameters 169 | 170 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 171 | 172 | ## INPUTS 173 | 174 | ### None 175 | 176 | ## OUTPUTS 177 | 178 | ### System.IO.FileInfo 179 | 180 | ### System.IO.DirectoryInfo 181 | 182 | ## NOTES 183 | 184 | ## RELATED LINKS 185 | 186 | [New-ModuleFromFiles](New-ModuleFromFiles.md) 187 | 188 | [Import-ModuleLayout](Import-ModuleLayout.md) 189 | -------------------------------------------------------------------------------- /docs/Open-PSFunctionToolsHelp.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Open-PSFunctionToolsHelp 9 | 10 | ## SYNOPSIS 11 | 12 | Open the PSFunctionTools help document. 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | Open-PSFunctionToolsHelp [-AsMarkdown] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | Use this command to open the PDF help document for the PSFunctionTools module with the associated application for PDF files. As an alternative you can view the documentation as a markdown document. 23 | 24 | ## EXAMPLES 25 | 26 | ### Example 1 27 | 28 | ```powershell 29 | PS C:\> Open-PSFunctionToolsHelp 30 | ``` 31 | 32 | The file should open in the default application for PDF files. 33 | 34 | ### Example 2 35 | 36 | ```powershell 37 | PS C:\> Open-PSFunctionToolsHelp -AsMarkdown 38 | ``` 39 | 40 | View the help file a markdown document. 41 | 42 | ## PARAMETERS 43 | 44 | ### -AsMarkdown 45 | 46 | Open the help file as markdown. 47 | 48 | ```yaml 49 | Type: SwitchParameter 50 | Parameter Sets: (All) 51 | Aliases: md 52 | 53 | Required: False 54 | Position: Named 55 | Default value: None 56 | Accept pipeline input: False 57 | Accept wildcard characters: False 58 | ``` 59 | 60 | ### CommonParameters 61 | 62 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 63 | 64 | ## INPUTS 65 | 66 | ### None 67 | 68 | ## OUTPUTS 69 | 70 | ### None 71 | 72 | ### System.String 73 | 74 | ## NOTES 75 | 76 | ## RELATED LINKS 77 | 78 | [Get-PSFunctionTools](Get-PSFunctionTools.md) 79 | 80 | [PSFunctionTools GitHub Repository:](https://github.com/jdhitsolutions/PSFunctionTools) 81 | -------------------------------------------------------------------------------- /docs/Open-PSFunctionToolsSamples.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Open-PSFunctionToolsSamples 9 | 10 | ## SYNOPSIS 11 | 12 | Open the PSFunction Tools samples folder 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | Open-PSFunctionToolsSamples [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | This simple command will change location to the PSFunctionTools Samples folder and list the directory contents. 23 | 24 | ## EXAMPLES 25 | 26 | ### Example 1 27 | 28 | ```powershell 29 | PS C:\> Open-PSFunctionToolsSamples 30 | 31 | Directory: C:\Program Files\PowerShell\Modules\PSFunctionTools\1.3.0\samples 32 | 33 | 34 | Mode LastWriteTime Length Name 35 | ---- ------------- ------ ---- 36 | -a--- 1/13/2025 5:25 PM 180 BuildModule.ps1 37 | -a--- 1/13/2025 5:29 PM 203 Demo-ExportFunctions.ps1 38 | -a--- 1/13/2025 6:28 PM 1005 Demo-NewModuleFromFiles.ps1 39 | -a--- 1/13/2025 5:26 PM 4146 Get-ZeroSize.ps1 40 | -a--- 1/13/2025 5:32 PM 4278 ModuleLayout.json 41 | -a--- 1/13/2025 5:36 PM 1574 POC-NewModule.ps1 42 | -a--- 1/13/2025 5:36 PM 3941 POC-NewModule2.ps1 43 | -a--- 4/18/2023 9:08 PM 1371 samplefunction.ps1 44 | -a--- 4/18/2023 9:08 PM 206 SampleScript.ps1 45 | -a--- 4/18/2023 9:08 PM 577 SampleScript2.ps1 46 | -a--- 4/18/2023 9:08 PM 503 SampleScript3.ps1 47 | -a--- 4/18/2023 9:08 PM 1371 SampleScript4.ps1 48 | -a--- 4/18/2023 9:08 PM 1536 SampleScript5.ps1 49 | -a--- 1/13/2025 6:16 PM 15148 Tools.psm1 50 | ``` 51 | 52 | ## PARAMETERS 53 | 54 | ### CommonParameters 55 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 56 | 57 | ## INPUTS 58 | 59 | ### None 60 | 61 | ## OUTPUTS 62 | 63 | ### System.IO.FileInfo 64 | 65 | ## NOTES 66 | 67 | ## RELATED LINKS 68 | -------------------------------------------------------------------------------- /docs/Test-FunctionName.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: PSFunctionTools-help.xml 3 | Module Name: PSFunctionTools 4 | online version: https://bit.ly/3I2oxh8 5 | schema: 2.0.0 6 | --- 7 | 8 | # Test-FunctionName 9 | 10 | ## SYNOPSIS 11 | 12 | Test the validity of a PowerShell function name. 13 | 14 | ## SYNTAX 15 | 16 | ```yaml 17 | Test-FunctionName [-Name] [-Quiet] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | 22 | PowerShell function names should follow naming convention of Verb-Noun. The verb should be a standard verb that you see with Get-Verb. Use this command in your scripting automation to validate a PowerShell function name. 23 | 24 | If the name passes validation it will be written to the pipeline. Or you can use the -Quiet parameter to return a traditional boolean result. 25 | 26 | ## EXAMPLES 27 | 28 | ### Example 1 29 | 30 | ```powershell 31 | PS C:\> Test-FunctionName Test-Widget 32 | Test-Widget 33 | ``` 34 | 35 | Because the name passes validation, it is written to the pipeline. 36 | 37 | ### Example 2 38 | 39 | ```powershell 40 | PS C:\> Test-FunctionName -Name stop-foo | Format-FunctionName 41 | Stop-Foo 42 | ``` 43 | 44 | Test the function name and format the result. 45 | 46 | ### Example 3 47 | 48 | ```powershell 49 | PS C:\> Test-FunctionName kill-system -Quiet 50 | False 51 | ``` 52 | 53 | Test with boolean result. 54 | 55 | ## PARAMETERS 56 | 57 | ### -Name 58 | 59 | Specify a function name. 60 | 61 | ```yaml 62 | Type: String 63 | Parameter Sets: (All) 64 | Aliases: 65 | 66 | Required: True 67 | Position: 0 68 | Default value: None 69 | Accept pipeline input: True (ByValue) 70 | Accept wildcard characters: False 71 | ``` 72 | 73 | ### -Quiet 74 | 75 | Get a boolean test result. 76 | 77 | ```yaml 78 | Type: SwitchParameter 79 | Parameter Sets: (All) 80 | Aliases: 81 | 82 | Required: False 83 | Position: Named 84 | Default value: None 85 | Accept pipeline input: False 86 | Accept wildcard characters: False 87 | ``` 88 | 89 | ### CommonParameters 90 | 91 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). 92 | 93 | ## INPUTS 94 | 95 | ### System.String 96 | 97 | ## OUTPUTS 98 | 99 | ### boolean 100 | 101 | ### string 102 | 103 | ## NOTES 104 | 105 | ## RELATED LINKS 106 | 107 | [Format-FunctionName](Format-FunctionName.md) 108 | -------------------------------------------------------------------------------- /formats/modulelayout.format.ps1xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | default 14 | 15 | ModuleLayout 16 | 17 | 18 | Path 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 22 28 | left 29 | 30 | 31 | 32 | 15 33 | left 34 | 35 | 36 | 37 | 8 38 | center 39 | 40 | 41 | 42 | 8 43 | right 44 | 45 | 46 | 47 | 6 48 | right 49 | 50 | 51 | 52 | 53 | 54 | 55 | Created 56 | 57 | 58 | CreatedBy 59 | 60 | 61 | LayoutVersion 62 | 63 | 64 | $_.folders.count 65 | 66 | 67 | $_.Files.count 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | source 77 | 78 | ModuleLayout 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 31 87 | left 88 | 89 | 90 | 91 | 22 92 | left 93 | 94 | 95 | 96 | 8 97 | center 98 | 99 | 100 | 101 | 17 102 | left 103 | 104 | 105 | 106 | 17 107 | left 108 | 109 | 110 | 111 | 112 | 113 | 117 | 118 | Path 119 | 120 | 121 | Created 122 | 123 | 124 | LayoutVersion 125 | 126 | 127 | SourcePath 128 | 129 | 130 | SourceComputer 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /formats/psfunctionname.format.ps1xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | default 14 | 15 | PSFunctionName 16 | 17 | 18 | Path 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 26 28 | left 29 | 30 | 31 | 32 | 33 | 34 | 35 | Name 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /formats/psfunctiontool.format.ps1xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | default 14 | 15 | PSFunctionTool 16 | 17 | 18 | "{0} [v{1}]" -f $_.Module, $_.ModuleVersion 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 27 28 | left 29 | 30 | 31 | 32 | 8 33 | center 34 | 35 | 36 | 37 | 50 38 | left 39 | 40 | 41 | 42 | 43 | 44 | 45 | Name 46 | 47 | 48 | Alias 49 | 50 | 51 | Synopsis 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /formats/psscriptrequirements.format.ps1xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | default 14 | 15 | PSScriptRequirements 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | Path 24 | 25 | 26 | 27 | RequiredApplicationId 28 | 29 | 30 | 31 | RequiredPSVersion 32 | 33 | 34 | 35 | RequiredPSEditions 36 | 37 | 38 | 39 | RequiredModules 40 | 41 | 42 | 43 | RequiresPSSnapIns 44 | 45 | 46 | 47 | RequiredAssemblies 48 | 49 | 50 | 51 | 52 | If ($_.IsElevationRequired -AND $host.name -match "console|code") { 53 | "$([char]27)[92m$($_.IsElevationRequired)$([char]27)[0m" 54 | } 55 | else { 56 | $_.IsElevationRequired 57 | } 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | default 68 | 69 | PSScriptRequirements 70 | 71 | 72 | Path 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 20 82 | left 83 | 84 | 85 | 86 | 20 87 | right 88 | 89 | 90 | 91 | 15 92 | left 93 | 94 | 95 | 96 | 25 97 | left 98 | 99 | 100 | 101 | 25 102 | left 103 | 104 | 105 | 106 | 22 107 | center 108 | 109 | 110 | 111 | 112 | 113 | 114 | RequiredApplicationId 115 | 116 | 117 | RequiredPSVersion 118 | 119 | 120 | RequiredPSEditions 121 | 122 | 123 | RequiresPSSnapIns 124 | 125 | 126 | RequiredAssemblies 127 | 128 | 129 | IsElevationRequired 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /functions/private/helpers.ps1: -------------------------------------------------------------------------------- 1 | # private helper functions 2 | 3 | Function _mkHelp { 4 | [cmdletbinding()] 5 | Param( 6 | #the path to the psd1 file 7 | [string]$ModulePath, 8 | #where to put the md files 9 | [string]$MarkdownPath, 10 | #where to put the xml output 11 | [string]$OutputPath 12 | ) 13 | 14 | Write-Verbose "Invoking Import-Module on $ModulePath" 15 | Import-Module -Name $ModulePath -Scope global 16 | $ModuleName = (Get-Item $ModulePath).BaseName 17 | Get-Command -Module $NewModuleName -OutVariable ModCmds | Out-String | Write-Verbose 18 | Write-Verbose "Invoking New-MarkdownHelp for module $ModuleName" 19 | Try { 20 | New-MarkdownHelp -Module $ModuleName -OutputFolder $MarkdownPath -Force -ErrorAction Stop 21 | Write-Verbose "Invoking New-Externalhelp to $OutputPath" 22 | New-ExternalHelp -Path $MarkdownPath -OutputPath $OutputPath -Force -ErrorAction Stop 23 | } 24 | Catch { 25 | Write-Warning "Failed to generate help content. $($_.exception.message)" 26 | } 27 | } 28 | 29 | Function _getAST { 30 | [cmdletbinding()] 31 | Param([string]$Path) 32 | 33 | #always create the variables 34 | New-Variable astTokens -Force -WhatIf:$false 35 | New-Variable astErr -Force -WhatIf:$false 36 | Write-Verbose "Parsing file $path for AST tokens" 37 | $AST = [System.Management.Automation.Language.Parser]::ParseFile($Path, [ref]$astTokens, [ref]$astErr) 38 | $AST 39 | } 40 | -------------------------------------------------------------------------------- /functions/public/Convert-ScriptToFunction.ps1: -------------------------------------------------------------------------------- 1 | Function Convert-ScriptToFunction { 2 | [cmdletbinding()] 3 | [OutputType('System.String')] 4 | [alias('csf')] 5 | Param( 6 | [Parameter( 7 | Position = 0, 8 | Mandatory, 9 | ValueFromPipelineByPropertyName, 10 | HelpMessage = 'Enter the path to your PowerShell script file.' 11 | )] 12 | [ValidateScript({ Test-Path $_ })] 13 | [ValidatePattern('\.ps1$')] 14 | [string]$Path, 15 | 16 | [Parameter( 17 | Position = 1, 18 | Mandatory, 19 | ValueFromPipelineByPropertyName, 20 | HelpMessage = 'What is the name of your new function?')] 21 | [ValidateScript({ 22 | if ($_ -match '^\w+-\w+$') { 23 | $true 24 | } 25 | else { 26 | Throw 'Your function name should have a Verb-Noun naming convention' 27 | $False 28 | } 29 | })] 30 | [string]$Name, 31 | 32 | [Parameter(ValueFromPipelineByPropertyName, HelpMessage = 'Specify an optional alias for your new function. You can define multiple aliases separated by commas.')] 33 | [ValidateNotNullOrEmpty()] 34 | [string[]]$Alias 35 | ) 36 | DynamicParam { 37 | <# 38 | If running this function in the PowerShell ISE or VS Code, 39 | define a ToEditor switch parameter 40 | #> 41 | If ($host.name -match 'ISE|Code') { 42 | $paramDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary 43 | 44 | # Defining parameter attributes 45 | $attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute] 46 | $attributes = New-Object System.Management.Automation.ParameterAttribute 47 | $attributes.ParameterSetName = '__AllParameterSets' 48 | $attributeCollection.Add($attributes) 49 | 50 | # Defining the runtime parameter 51 | $dynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('ToEditor', [Switch], $attributeCollection) 52 | $paramDictionary.Add('ToEditor', $dynParam1) 53 | 54 | return $paramDictionary 55 | } # end if 56 | } #end DynamicParam 57 | Begin { 58 | Write-Verbose "Starting $($MyInvocation.MyCommand)" 59 | Write-Verbose 'Initializing' 60 | $new = [System.Collections.Generic.list[string]]::new() 61 | } #begin 62 | Process { 63 | #normalize 64 | $Path = Convert-Path $path 65 | $Name = Format-FunctionName $Name 66 | 67 | Write-Verbose "Processing $path" 68 | $AST = _getAST $path 69 | 70 | if ($ast.extent) { 71 | Write-Verbose 'Getting any comment based help' 72 | $ch = $astTokens | Where-Object { $_.kind -eq 'comment' -AND $_.text -match '\.synopsis' } 73 | 74 | if ($ast.ScriptRequirements) { 75 | Write-Verbose 'Adding script requirements' 76 | if ($ast.ScriptRequirements.RequiredPSVersion) { 77 | $new.Add("#requires -version $($ast.ScriptRequirements.RequiredPSVersion.ToString())") 78 | } 79 | if ($ast.ScriptRequirements.RequiredModules) { 80 | Foreach ($m in $ast.ScriptRequirements.RequiredModules) { 81 | #test for version requirements 82 | $ver = $m.PSObject.properties.where({ $_.name -match 'version' -AND $_.value }) 83 | if ($ver) { 84 | $new.Add("#requires -module @{ModuleName = '$($m.name)';$($ver.Name) = '$($ver.value)'}") 85 | } 86 | else { 87 | $new.add("#requires -module $($m.Name)") 88 | } 89 | } 90 | } 91 | if ($ast.ScriptRequirements.IsElevationRequired) { 92 | $new.Add('#requires -RunAsAdministrator') 93 | } 94 | If ($ast.ScriptRequirements.requiredPSEditions) { 95 | $new.add("#requires -PSEdition $($ast.ScriptRequirements.requiredPSEditions)") 96 | } 97 | 98 | $new.Add("`n") 99 | } 100 | else { 101 | Write-Verbose 'No script requirements found' 102 | } 103 | 104 | $head = @" 105 | # Function exported from $Path 106 | 107 | Function $Name { 108 | 109 | "@ 110 | $new.add($head) 111 | 112 | if ($ch) { 113 | $new.Add($ch.text) 114 | $new.Add("`n") 115 | } 116 | else { 117 | Write-Verbose 'Generating new comment based help from parameters' 118 | if ($ast.ParamBlock) { 119 | New-CommentHelp -ParamBlock $ast.ParamBlock | ForEach-Object { $new.Add("$_") } 120 | } 121 | else { 122 | New-CommentHelp -TemplateOnly | ForEach-Object { $new.Add("$_") } 123 | } 124 | $new.Add("`n") 125 | } 126 | 127 | [regex]$rx = '\[cmdletbinding\(.*\)\]' 128 | if ($rx.IsMatch($ast.Extent.text)) { 129 | Write-Verbose 'Using existing cmdletbinding' 130 | #use the first match 131 | $cb = $rx.match($ast.extent.text).Value 132 | $new.Add("`t$cb") 133 | } 134 | else { 135 | Write-Verbose 'Adding [cmdletbinding()]' 136 | $new.Add("`t[cmdletbinding()]") 137 | } 138 | 139 | if ($alias) { 140 | Write-Verbose "Adding function alias definition $($alias -join ',')" 141 | $new.Add("`t[Alias('$($alias -join "','")')]") 142 | } 143 | if ($ast.ParamBlock) { 144 | Write-Verbose 'Adding defined Param() block' 145 | [void]($ast.ParamBlock.ToString().split("`n").Foreach({ $new.add("`t$_") }) -join "`n") 146 | $new.Add("`n") 147 | } 148 | else { 149 | Write-Verbose 'Adding Param() block' 150 | $new.add("`tParam()") 151 | } 152 | if ($ast.DynamicParamBlock) { 153 | #assumes no more than 1 dynamic parameter 154 | Write-Verbose 'Adding dynamic parameters' 155 | [void]($ast.DynamicParamBlock.ToString().split("`n").Foreach({ $new.Add($_) }) -join "`n") 156 | } 157 | 158 | if ($ast.BeginBlock.Extent.text) { 159 | Write-Verbose 'Adding defined Begin block' 160 | [void]($ast.BeginBlock.Extent.ToString().split("`n").Foreach({ $new.Add($_) }) -join "`n") 161 | $UseBPE = $True 162 | } 163 | 164 | if ($ast.ProcessBlock.Extent.text) { 165 | Write-Verbose 'Adding defined Process block' 166 | [void]($ast.ProcessBlock.Extent.ToString().split("`n").Foreach({ $new.add($_) }) -join "`n") 167 | } 168 | 169 | if ($ast.EndBlock.Extent.text) { 170 | if ($UseBPE) { 171 | Write-Verbose 'Adding opening End{} block' 172 | $new.Add("`tEnd {") 173 | } 174 | Write-Verbose 'Adding the remaining code or defined endblock' 175 | [void]($ast.Endblock.Statements.foreach({ $_.ToString() }).Foreach({ $new.Add($_) })) 176 | if ($UseBPE) { 177 | Write-Verbose 'Adding closing End {} block' 178 | $new.Add("`t}") 179 | } 180 | } 181 | else { 182 | $new.Add('End { }') 183 | } 184 | Write-Verbose 'Closing the function' 185 | $new.Add( "`n} #close $name") 186 | 187 | if ($PSBoundParameters.ContainsKey('ToEditor')) { 188 | Write-Verbose 'Opening result in editor' 189 | if ($host.name -match 'ISE') { 190 | $NewFile = $psISE.CurrentPowerShellTab.Files.add() 191 | $NewFile.Editor.InsertText(($new -join "`n")) 192 | $NewFile.editor.select(1, 1, 1, 1) 193 | } 194 | elseif ($host.name -match 'Code') { 195 | $psEditor.Workspace.NewFile() 196 | $ctx = $psEditor.GetEditorContext() 197 | $ctx.CurrentFile.InsertText($new -join "`n") 198 | } 199 | else { 200 | $new -join "`n" | Set-Clipboard 201 | Write-Warning "Can't detect the PowerShell ISE or VS Code. Output has been copied to the clipboard." 202 | } 203 | } 204 | else { 205 | Write-Verbose "Writing output [$($new.count) lines] to the pipeline" 206 | $new -join "`n" 207 | } 208 | } #if ast found 209 | else { 210 | Write-Warning 'Failed to find a script body to convert to a function.' 211 | } 212 | 213 | } #process 214 | End { 215 | Write-Verbose "Ending $($MyInvocation.MyCommand)" 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /functions/public/Export-FunctionFromFile.ps1: -------------------------------------------------------------------------------- 1 | Function Export-FunctionFromFile { 2 | [cmdletbinding(SupportsShouldProcess, DefaultParameterSetName = "All")] 3 | [alias("eff")] 4 | [OutputType("None", "System.IO.FileInfo")] 5 | Param( 6 | [Parameter(Position = 0, Mandatory, HelpMessage = "Specify the .ps1 or .psm1 file with defined functions.")] 7 | [ValidateScript({ 8 | If (Test-Path $_ ) { 9 | $True 10 | If ($_ -match "\.ps(m)?1$") { 11 | $True 12 | } 13 | Else { 14 | Throw "The path must be to a .ps1 or .psm1 file." 15 | $False 16 | } 17 | } 18 | Else { 19 | Throw "Can't validate that $_ exists. Please verify and try again." 20 | $False 21 | } 22 | })] 23 | [string]$Path, 24 | [Parameter(HelpMessage = "Specify the output path. The default is the same directory as the .ps1 file.")] 25 | [string]$OutputPath, 26 | [Parameter(HelpMessage = "Specify a function by name", ParameterSetName = "byName")] 27 | [string[]]$Name, 28 | [Parameter(HelpMessage = "Export all detected functions.", ParameterSetName = "all")] 29 | [switch]$All, 30 | [Parameter(HelpMessage = "Pass the output file to the pipeline.")] 31 | [switch]$PassThru 32 | ) 33 | DynamicParam { 34 | 35 | If ( $Host.name -match 'ise|Code') { 36 | 37 | $paramDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary 38 | 39 | # Defining parameter attributes 40 | $attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute] 41 | $attributes = New-Object System.Management.Automation.ParameterAttribute 42 | $attributes.ParameterSetName = '__AllParameterSets' 43 | $attributes.HelpMessage = 'Delete the function from the source file.' 44 | $attributeCollection.Add($attributes) 45 | 46 | # Adding a parameter alias 47 | $dynAlias = New-Object System.Management.Automation.AliasAttribute -ArgumentList 'rm' 48 | $attributeCollection.Add($dynAlias) 49 | 50 | # Defining the runtime parameter 51 | $dynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('Remove', [Switch], $attributeCollection) 52 | $paramDictionary.Add('Remove', $dynParam1) 53 | 54 | return $paramDictionary 55 | } # end if 56 | } #end DynamicParam 57 | 58 | Begin { 59 | 60 | Write-Verbose "[BEGIN ] Starting $($MyInvocation.MyCommand) [$($PSCmdlet.ParameterSetName)]" 61 | Write-Verbose ($PSBoundParameters | Out-String) 62 | 63 | if (-Not $OutputPath) { 64 | #use the parent path of the file unless the user specifies a different path 65 | $OutputPath = Split-Path -Path $Path -Parent 66 | } 67 | if ($Name) { 68 | Write-Verbose "[BEGIN ] Looking for functions $($name -join ',')" 69 | } 70 | 71 | #insert a temporary line for each line of the function 72 | #this will be deleted at the end. Define this in the Begin block so 73 | #that it remains static 74 | $line = "DEL-FUNCTION-$(Get-Date -f 'hhmmss')`n" 75 | } #begin 76 | Process { 77 | #Convert the path to a full file system path 78 | $path = Convert-Path -Path $path 79 | Write-Verbose "[PROCESS] Processing $path for functions" 80 | #the file will always be parsed regardless of WhatIfPreference 81 | $AST = _getAST $path 82 | 83 | #parse out functions using the AST 84 | $functions = $ast.FindAll({ $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] }, $true) 85 | 86 | if ($functions.count -gt 0) { 87 | Write-Verbose "[PROCESS] Found $($functions.count) functions" 88 | Write-Verbose "[PROCESS] Creating files in $OutputPath" 89 | Foreach ($item in $functions) { 90 | Write-Verbose "[PROCESS] Detected function $($item.name)" 91 | 92 | Switch ($PSCmdlet.ParameterSetName) { 93 | 94 | "byName" { 95 | if ($Name -contains $item.Name) { 96 | #export named function 97 | Write-Verbose "[PROCESS] $($item.name) matches by name" 98 | $export = $True 99 | } 100 | else { 101 | $export = $False 102 | } 103 | } 104 | 105 | "All" { 106 | if ($All -OR (Test-FunctionName -name $item.name)) { 107 | #only export functions with standard names or if -All is detected. 108 | $export = $True 109 | } 110 | else { 111 | $export = $False 112 | } 113 | } 114 | 115 | } #switch 116 | 117 | If ($export) { 118 | $NewFile = Join-Path -Path $OutputPath -ChildPath "$($item.name).ps1" 119 | Write-Verbose "[PROCESS] Creating new file $NewFile" 120 | Set-Content -Path $NewFile -Value $item.ToString() -Force 121 | 122 | if ($PSBoundParameters.ContainsKey("Remove")) { 123 | $f = $item.extent 124 | $span = $f.EndLineNumber - $f.StartLineNumber 125 | 126 | Switch -Regex ($host.name) { 127 | "PowerShell ISE" { 128 | Write-Verbose "[PROCESS] Removing from the PowerShell ISE" 129 | psedit $path 130 | $source = ($psISE.CurrentPowerShellTab.Files).where({ $_.fullpath -eq $path }) 131 | Write-Verbose "[PROCESS] Selecting a span of $span lines" 132 | $source.Editor.Select($f.StartLineNumber, $f.StartColumnNumber, $f.EndLineNumber, $f.EndColumnNumber) 133 | if ($PSCmdlet.ShouldProcess($item.name, "Deleting from $Path at $($f.StartLineNumber),$($f.StartColumnNumber),$($f.EndLineNumber),$($f.EndColumnNumber)")) { 134 | $source.Editor.InsertText($line * $span) 135 | #set a flag to save the file at the end 136 | $SaveISE = $True 137 | } 138 | } 139 | "Visual Studio Code" { 140 | Write-Verbose "[PROCESS] Removing from VS Code" 141 | Open-EditorFile $Path 142 | $ctx = $psEditor.getEditorContext() 143 | if ($PSCmdlet.ShouldProcess($item.name, "Deleting from $Path at $($f.StartLineNumber),$($f.StartColumnNumber),$($f.EndLineNumber),$($f.EndColumnNumber)")) { 144 | $psEditor.Window.SetStatusBarMessage("Removing lines $($f.StartLineNumber) to $($f.EndLineNumber) from $path", 1000) 145 | $ctx.CurrentFile.InsertText(($line * $span), $f.StartLineNumber, $f.StartColumnNumber, $f.EndLineNumber, $f.EndColumnNumber) 146 | Start-Sleep -Milliseconds 250 147 | #set a flag to save the file at the end 148 | $SaveVSCode = $True 149 | } 150 | } 151 | } 152 | } 153 | if ($PassThru -AND (-Not $WhatIfPreference)) { 154 | Get-Item -Path $NewFile 155 | } 156 | } 157 | else { 158 | Write-Verbose "[PROCESS] Skipping $($item.name)" 159 | } 160 | } #foreach item 161 | } 162 | else { 163 | Write-Warning "No PowerShell functions detected in $Path." 164 | } 165 | } #process 166 | End { 167 | if ($SaveISE) { 168 | Write-Verbose "[END ] Removing temporary lines $line" 169 | $rev = $source.editor.Text -replace $line, '' 170 | $source.editor.text = $rev 171 | Write-Verbose "[END ] Saving $path in the PowerShell ISE" 172 | Start-Sleep -Milliseconds 500 173 | $source.Save() 174 | #keep the file open in the ISE in case you need to do anything 175 | #else with it. 176 | $source.Editor.SetCaretPosition(1, 1) 177 | } 178 | elseif ($SaveVSCode) { 179 | Write-Verbose "[END ] Saving and re-opening $path" 180 | $ctx.CurrentFile.Save() 181 | #need to give the file time to close 182 | Start-Sleep -Seconds 2 183 | Write-Verbose "[END ] Getting file contents" 184 | $txt = Get-Content $path -Raw 185 | 186 | # $txt | Out-File d:\temp\t.txt -force 187 | Write-Verbose "[END ] Filtering for line $($line.TrimEnd())" 188 | 189 | $rev = ([System.Text.RegularExpressions.Regex]::Matches($txt, "^((?!$($line.trimend())).)*$", "multiline")).value.replace("`r", "") 190 | 191 | Write-Verbose "[END ] Saving $path in VS Code" 192 | $rev | Out-File -FilePath $Path -Force 193 | #set cursor selection to top of file. 194 | #not sure how to force scrolling to the top 195 | $ctx.SetSelection(1, 1, 1, 1) 196 | } 197 | Write-Verbose "[END ] Ending $($MyInvocation.MyCommand)" 198 | } #end 199 | } 200 | -------------------------------------------------------------------------------- /functions/public/Export-FunctionToFile.ps1: -------------------------------------------------------------------------------- 1 | 2 | 3 | Function Export-FunctionToFile { 4 | [cmdletbinding(SupportsShouldProcess)] 5 | [alias("etf")] 6 | [OutputType("none", "System.IO.FileInfo")] 7 | Param( 8 | [Parameter( 9 | Position = 0, 10 | Mandatory, 11 | ValueFromPipeline, 12 | HelpMessage = "Specify the name of a function loaded in your PowerShell session." 13 | )] 14 | [string]$Name, 15 | [Parameter(HelpMessage = "Specify the location for the new file.")] 16 | [ValidateScript({ Test-Path $_ })] 17 | [string]$Path = ".", 18 | [Parameter(HelpMessage = "Show the file result.")] 19 | [switch]$PassThru, 20 | [Parameter(HelpMessage = "Specify #Requires statements, including the #")] 21 | [ValidatePattern("^#[rR]equires")] 22 | [string[]]$Requires 23 | ) 24 | Begin { 25 | Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($MyInvocation.MyCommand)" 26 | } #begin 27 | 28 | Process { 29 | 30 | Try { 31 | $fun = Get-Item function:\$name -ErrorAction Stop 32 | 33 | } 34 | Catch { 35 | Throw "Can't find a loaded function called $Name." 36 | } 37 | 38 | if ($fun) { 39 | 40 | $value = @" 41 | $($requires -join "`n") 42 | 43 | <# 44 | $(Get-Date) 45 | This function was exported from $env:computername by $env:username. 46 | Feel free to delete this comment. 47 | #> 48 | 49 | Function $($fun.Name) { 50 | $($fun.Definition.Trim()) 51 | } #Close $($fun.name) 52 | "@ 53 | 54 | #parse out illegal filesystem characters from the name 55 | $Name = $Name -replace "[:\\\/\.]", "" 56 | $export = Join-Path -Path (Convert-Path $path) -ChildPath "$Name.ps1" 57 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Exporting $Name to $Export" 58 | Set-Content -Path $export -Value $value 59 | if ($PassThru -AND (-Not $WhatIfPreference)) { 60 | Get-Item -Path $export 61 | } 62 | } 63 | 64 | } #process 65 | 66 | End { 67 | Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($MyInvocation.MyCommand)" 68 | } #end 69 | 70 | } #close Export-FunctionToFile -------------------------------------------------------------------------------- /functions/public/Export-ModuleLayout.ps1: -------------------------------------------------------------------------------- 1 | Function Export-ModuleLayout { 2 | [cmdletbinding()] 3 | [alias("eml")] 4 | [OutputType("None","System.IO.FileInfo")] 5 | 6 | Param( 7 | [Parameter(Position = 0, Mandatory, HelpMessage = "Specify the model module path.")] 8 | [ValidateScript( { Test-Path $_ })] 9 | [string]$SourcePath, 10 | [Parameter(HelpMessage = "Define a version number for this layout.")] 11 | [string]$Version = "1.0", 12 | [Parameter(HelpMessage = "Specify the name of the Json file to store the result.")] 13 | [ValidateNotNullOrEmpty()] 14 | [ValidatePattern("\.json$")] 15 | [string]$FilePath = ".\modulelayout.json", 16 | [Parameter(HelpMessage = "Show the file result.")] 17 | [switch]$PassThru 18 | ) 19 | Write-Verbose "Starting $($MyInvocation.MyCommand)" 20 | 21 | $out = [System.Collections.Generic.list[object]]::New() 22 | #making the metadata work cross-platform 23 | $meta = [PSCustomObject]@{ 24 | ItemType = "ModuleLayoutMetadata" 25 | Created = (Get-Date -Format g) 26 | CreatedBy = "$([System.Environment]::UserDomainName)\$([System.Environment]::UserName)" 27 | Computername = [System.Environment]::MachineName 28 | Source = (Convert-Path $SourcePath) 29 | Version = $version 30 | } 31 | $out.Add($meta) 32 | Push-Location 33 | #change location to the folder so that the relative path structure can be used. 34 | Set-Location -path $SourcePath 35 | Write-Verbose "Exporting directory structure from $SourcePath" 36 | 37 | Get-ChildItem -Recurse | 38 | ForEach-Object { 39 | $relPath = (Resolve-Path -Path $_.FullName -Relative) -replace "\.\\", "" 40 | Write-Verbose "Processing $relPath" 41 | if ($_.GetType().name -eq 'FileInfo') { 42 | $f = [PSCustomObject]@{ 43 | ItemType = "file" 44 | Path = $relPath 45 | #Windows PowerShell adds PS environment data to json conversions 46 | #this is a work around 47 | Content = (Get-Content -Path $_.FullName | Out-String) 48 | } 49 | $out.add($f) 50 | } 51 | else { 52 | $d = [PSCustomObject]@{ 53 | ItemType = "directory" 54 | Path = $relPath 55 | } 56 | $out.Add($d) 57 | } 58 | } #foreach-object 59 | 60 | Write-Verbose "Exporting module layout to $FilePath" 61 | $out | ConvertTo-Json | Out-File -FilePath $FilePath 62 | Pop-Location 63 | if ($PassThru) { 64 | Get-Item $Filepath 65 | } 66 | Write-Verbose "Ending $($MyInvocation.MyCommand)" 67 | } 68 | -------------------------------------------------------------------------------- /functions/public/Format-FunctionName.ps1: -------------------------------------------------------------------------------- 1 | Function Format-FunctionName { 2 | [cmdletbinding()] 3 | [alias("ffn")] 4 | [OutputType("String")] 5 | Param ( 6 | [parameter( 7 | Position = 0, 8 | Mandatory, 9 | ValueFromPipeline, 10 | HelpMessage = "What is the name of your function? It should follow the Verb-Noun naming convention." 11 | )] 12 | [ValidateScript( { 13 | if ($_ -match "^\w+-\w+$") { 14 | $true 15 | } 16 | else { 17 | Throw "Your function name should have a Verb-Noun naming convention" 18 | $False 19 | } 20 | })] 21 | [string]$Name, 22 | [Parameter(HelpMessage = "Capitalize the first N number of characters in the Noun.")] 23 | [ValidateScript({$_ -gt 0})] 24 | [int]$NounCapitals 25 | ) 26 | 27 | Begin { 28 | Write-Verbose "[$((Get-Date).TimeofDay) BEGIN] Starting $($MyInvocation.MyCommand)" 29 | } #begin 30 | Process { 31 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Processing $name" 32 | $split = $name -split "-" 33 | $verb = $split[0] 34 | $noun = $split[1] 35 | #"{0}{1}-{2}{3}" -f $split[0][0].ToString().ToUpper(), $split[0].Substring(1).ToLower(), $split[1][0].ToString().ToUpper(), $split[1].Substring(1).ToLower() 36 | If ($NounCapitals -gt 0) { 37 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Using custom noun formatting" 38 | "{0}{1}-{2}{3}" -f $verb[0].ToString().ToUpper(), $verb.Substring(1).ToLower(), $n.Substring(0,$NounCapitals).ToUpper(), $noun.Substring($NounCapitals).ToLower() 39 | } 40 | Else { 41 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Using standard formatting" 42 | "{0}{1}-{2}{3}" -f $verb[0].ToString().ToUpper(), $verb.Substring(1).ToLower(), $noun[0].ToString().ToUpper(), $noun.Substring(1).ToLower() 43 | } 44 | 45 | } #process 46 | End { 47 | Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($MyInvocation.MyCommand)" 48 | } #end 49 | } 50 | -------------------------------------------------------------------------------- /functions/public/Get-FunctionAlias.ps1: -------------------------------------------------------------------------------- 1 | Function Get-FunctionAlias { 2 | [cmdletbinding()] 3 | [alias("gfal", "ga")] 4 | [OutputType("string")] 5 | Param( 6 | [Parameter( 7 | Position = 0, 8 | Mandatory, 9 | ValueFromPipelineByPropertyName, 10 | HelpMessage = "Specify the .ps1 or .psm1 file with defined functions." 11 | )] 12 | [alias("PSPath")] 13 | [ValidateScript({ 14 | If (Test-Path $_ ) { 15 | $True 16 | If ($_ -match "\.ps(m)?1$") { 17 | $True 18 | } 19 | Else { 20 | Throw "The path must be to a .ps1 or .psm1 file." 21 | $False 22 | } 23 | } 24 | Else { 25 | Throw "Can't validate that $_ exists. Please verify and try again." 26 | $False 27 | } 28 | })] 29 | [string]$Path 30 | ) 31 | Begin { 32 | Write-Verbose "[$((Get-Date).TimeofDay) BEGIN] Starting $($MyInvocation.MyCommand)" 33 | } #begin 34 | Process { 35 | $Path = Convert-Path -Path $path 36 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS]Processing $path for AST data." 37 | $AST = _getAST $path 38 | 39 | #parse out functions using the AST 40 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS]Parsing AST data for functions." 41 | $functions = $ast.FindAll( { $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] }, $true) 42 | if ($functions.count -gt 0) { 43 | foreach ($f in $functions) { 44 | #thanks to https://twitter.com/PrzemyslawKlys for this suggestion 45 | $aliasAST = $f.FindAll( { 46 | $args[0] -is [System.Management.Automation.Language.AttributeAst] -and 47 | $args[0].TypeName.Name -eq 'Alias' -and 48 | $args[0].Parent -is [System.Management.Automation.Language.ParamBlockAst] 49 | }, $true) 50 | 51 | if ($aliasAST.positionalArguments) { 52 | [PSCustomObject]@{ 53 | PSTypeName = "PSFunctionAlias" 54 | Name = $f.name 55 | Alias = $aliasAST.PositionalArguments.Value 56 | } 57 | } 58 | } 59 | } #if functions.count > 0 60 | } #process 61 | End { 62 | Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($MyInvocation.MyCommand)" 63 | } #end 64 | } #end function -------------------------------------------------------------------------------- /functions/public/Get-FunctionAttribute.ps1: -------------------------------------------------------------------------------- 1 | Function Get-FunctionAttribute { 2 | [cmdletbinding()] 3 | [alias("gfa")] 4 | [OutputType("PSFunctionAttribute", "String")] 5 | Param( 6 | [Parameter( 7 | Position = 0, 8 | Mandatory, 9 | ValueFromPipelineByPropertyName, 10 | HelpMessage = "Specify the name of the PowerShell function." 11 | )] 12 | [ValidateNotNullOrEmpty()] 13 | [string]$Name, 14 | [Parameter( 15 | Mandatory, 16 | ValueFromPipelineByPropertyName, 17 | HelpMessage = "Specify the path to the .ps1 or .psm1 file." 18 | )] 19 | [ValidateScript( { 20 | If (Test-Path $_ ) { 21 | $True 22 | If ($_ -match "\.ps(m)?1$") { 23 | $True 24 | } 25 | Else { 26 | Throw "The path must be to a .ps1 or .psm1 file." 27 | $False 28 | } 29 | } 30 | Else { 31 | Throw "Can't validate that $_ exists. Please verify and try again." 32 | $False 33 | } 34 | })] 35 | [string]$Path, 36 | [Parameter(HelpMessage = "Display the attribute block as a string.")] 37 | [switch]$ToString 38 | ) 39 | Begin { 40 | Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($MyInvocation.MyCommand)" 41 | } #begin 42 | Process { 43 | $Path = Convert-Path -Path $path 44 | $Name = Format-FunctionName $Name 45 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Processing function $name from $Path " 46 | $AST = _getAST $path 47 | #parse out functions using the AST 48 | $function = $ast.Find( { 49 | $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] -AND 50 | $args[0].name -eq $Name }, $true) 51 | 52 | if ($function) { 53 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Found function $($function.name)" 54 | $pb = $function.find( { $args[0] -is [System.Management.Automation.Language.ParamBlockAst] }, $True) 55 | 56 | if ($pb.attributes.extent.text -AND $ToString) { 57 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Showing as string" 58 | $pb.attributes.extent.text 59 | } 60 | elseif ($pb.attributes.extent.text) { 61 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Processing extent text" 62 | foreach ($item in $pb.attributes) { 63 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] $($item.typename.name)" 64 | [PSCustomObject]@{ 65 | PSTypeName = "PSFunctionAttribute" 66 | Type = $item.TypeName.name 67 | NamedArguments = $item.NamedArguments 68 | PositionalArguments = $item.PositionalArguments 69 | String = $item.extent.text 70 | Function = $Name 71 | Path = $Path 72 | } 73 | } 74 | } 75 | else { 76 | Write-Warning "No defined function attributes detected for $name in $path." 77 | } 78 | } 79 | else { 80 | Write-Warning "Failed to find a function called $name in $path." 81 | } 82 | } #process 83 | End { 84 | Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($MyInvocation.MyCommand)" 85 | } #end 86 | 87 | } #close Get-FunctionAttribute -------------------------------------------------------------------------------- /functions/public/Get-FunctionName.ps1: -------------------------------------------------------------------------------- 1 | Function Get-FunctionName { 2 | [cmdletbinding()] 3 | [alias('gfn')] 4 | [OutputType("string", "PSFunctionName")] 5 | Param( 6 | [Parameter( 7 | Position = 0, 8 | Mandatory, 9 | ValueFromPipeline, 10 | HelpMessage = "Specify the .ps1 or .psm1 file with defined functions." 11 | )] 12 | [ValidateScript({ 13 | If (Test-Path $_ ) { 14 | $True 15 | If ($_ -match "\.ps(m)?1$") { 16 | $True 17 | } 18 | Else { 19 | Throw "The path must be to a .ps1 or .psm1 file." 20 | $False 21 | } 22 | } 23 | Else { 24 | Throw "Can't validate that $_ exists. Please verify and try again." 25 | $False 26 | } 27 | })] 28 | [alias("PSPath")] 29 | [string]$Path, 30 | [Parameter(HelpMessage = "List all detected function names.")] 31 | [switch]$All, 32 | [Parameter(HelpMessage = "Write a rich detailed object to the pipeline.")] 33 | [switch]$Detailed 34 | ) 35 | 36 | Begin { 37 | Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($MyInvocation.MyCommand)" 38 | } #begin 39 | Process { 40 | $Path = Convert-Path -Path $path 41 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Parsing $path for functions." 42 | $AST = _getAst $path 43 | 44 | #parse out functions using the AST 45 | $functions = $ast.FindAll({ $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] }, $true) 46 | if ($functions.count -gt 0) { 47 | if ($All) { 48 | $out = $Functions.Name 49 | } 50 | Else { 51 | $out = $functions.Name | Test-FunctionName 52 | } 53 | if ($Detailed) { 54 | foreach ($item in $($out | Sort-Object)) { 55 | [PSCustomObject]@{ 56 | PSTypeName = "PSFunctionName" 57 | Name = $item 58 | Path = $Path 59 | } 60 | } 61 | } 62 | else { 63 | $out 64 | } 65 | } 66 | else { 67 | Write-Warning "No PowerShell functions detected in $path." 68 | } 69 | } #process 70 | End { 71 | Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($MyInvocation.MyCommand)" 72 | } #end 73 | } #close function 74 | -------------------------------------------------------------------------------- /functions/public/Get-FunctionProfile.ps1: -------------------------------------------------------------------------------- 1 | Function Get-FunctionProfile { 2 | [cmdletbinding()] 3 | [alias("gfp")] 4 | [OutputType("PSFunctionProfile")] 5 | Param( 6 | [Parameter( 7 | Position = 0, 8 | Mandatory, 9 | ValueFromPipelineByPropertyName, 10 | HelpMessage = "Specify the name of the PowerShell function." 11 | )] 12 | [ValidateNotNullOrEmpty()] 13 | [string]$Name, 14 | [Parameter( 15 | Mandatory, 16 | ValueFromPipelineByPropertyName, 17 | HelpMessage = "Specify the path to the .ps1 or .psm1 file." 18 | )] 19 | [ValidateScript({ 20 | If (Test-Path $_ ) { 21 | $True 22 | If ($_ -match "\.ps(m)?1$") { 23 | $True 24 | } 25 | Else { 26 | Throw "The path must be to a .ps1 or .psm1 file." 27 | $False 28 | } 29 | } 30 | Else { 31 | Throw "Can't validate that $_ exists. Please verify and try again." 32 | $False 33 | } 34 | })] 35 | [string]$Path 36 | ) 37 | Begin { 38 | Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($MyInvocation.MyCommand)" 39 | 40 | New-Variable astTokens -Force 41 | New-Variable astErr -Force 42 | } #begin 43 | 44 | Process { 45 | $Name = Format-FunctionName $Name 46 | $Path = Convert-Path -Path $path 47 | $cmds = [System.Collections.Generic.list[string]]::new() 48 | $aliasList = [System.Collections.Generic.list[string]]::new() 49 | $Unresolved = [System.Collections.Generic.list[string]]::new() 50 | $dotnet = [System.Collections.Generic.list[string]]::new() 51 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Profiling function $name in $path" 52 | 53 | $fa = Get-FunctionAttribute @PSBoundParameters 54 | $pb = Get-ParameterBlock @PSBoundParameters 55 | $attrib = ($pb.parameters.attributes).where({ $_.NamedArguments.ArgumentName -eq "ParameterSetName" }).NamedArguments | Where-Object { $_.ArgumentName -eq 'parameterSetName' } 56 | $req = Get-PSRequirements -Path $Path 57 | 58 | $AST = [System.Management.Automation.Language.Parser]::ParseFile($Path, [ref]$astTokens, [ref]$astErr) 59 | 60 | $fd = $AST.FindAll({ $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] -AND $args[0].name -eq $Name }, $True) 61 | $content = $fd.Extent.Text 62 | $funAST = [System.Management.Automation.Language.Parser]::ParseInput($content, [ref]$astTokens, [ref]$astErr) 63 | 64 | #find .NET expressions 65 | $t = $funAST.findAll({ $args[0] -is [System.Management.Automation.Language.TypeExpressionAst] }, $true) 66 | if ($t) { 67 | foreach ($item in $t) { 68 | $value = $item.parent.Extent.text.ToLower() 69 | if (-Not $dotnet.Contains($value)) { 70 | $dotnet.add($value) 71 | } 72 | } 73 | } 74 | #get commands 75 | $RawList = ($astTokens).where({ ($_.TokenFlags -contains 'CommandName') -AND ($_.kind -eq 'generic') }).Text.ToLower() | 76 | Select-Object -Unique 77 | foreach ($item in $RawList) { 78 | if ($item -match "^\w+-\w+$") { 79 | $item = Format-FunctionName -Name $item 80 | } 81 | if (-Not $cmds.Contains($item)) { 82 | Write-Verbose "found command $item" 83 | $cmds.Add($item) 84 | } 85 | } 86 | 87 | #get aliases 88 | $aliases = ($astTokens).where({ ($_.TokenFlags -contains 'CommandName') -AND ($_.kind -eq 'identifier') }) 89 | if ($aliases) { 90 | Write-Verbose "Detected $($aliases.count) aliases" 91 | $filteredAliases = $aliases.Text.toLower() | Select-Object -Unique 92 | foreach ($alias in $filteredAliases) { 93 | Try { 94 | $a = Get-Alias -Name $alias -ErrorAction stop 95 | if (-Not $cmds.Contains($a.Definition)) { 96 | Write-Verbose "Adding resolved command $($a.definition)" 97 | $cmds.Add($a.Definition) 98 | } 99 | if (-Not $aliasList.Contains($alias)) { 100 | Write-Verbose "Saving alias ($alias)" 101 | $aliasList.Add($alias) 102 | } 103 | } 104 | Catch { 105 | Write-Verbose "Could not resolve potential alias $alias" 106 | $Unresolved.Add($alias) 107 | } 108 | } 109 | } 110 | #separate PowerShell cmdlets from external commands 111 | $cmdlets, $external = $cmds.Where({ $_ -notmatch ".*(exe|bat|sh|cmd|vbs|wsf)$" }, "Split") 112 | [PSCustomObject]@{ 113 | PSTypeName = "PSFunctionProfile" 114 | Name = $Name 115 | FunctionAlias = $fa.where({ $_.type -eq 'alias' }).PositionalArguments.Value 116 | SupportsShouldProcess = $fa.where({ $_.type -eq 'cmdletbinding' }).NamedArguments.ArgumentName -contains "SupportsShouldProcess" 117 | ParameterSets = $attrib.argument.value | Select-Object -Unique 118 | DynamicParameters = (Get-Content $path | Select-String '^(\s+)?DynamicParam\s+{') ? $True : $False 119 | RequiredVersion = $req.RequiredPSVersion 120 | RequiredModules = $req.RequiredModules 121 | RequiresElevation = $req.IsElevationRequired 122 | Commands = $cmdlets | Sort-Object 123 | ExternalCommands = $external | Sort-Object 124 | DotNet = $dotnet 125 | Aliases = $aliasList 126 | Unresolved = $Unresolved 127 | Path = $Path 128 | } 129 | } #process 130 | 131 | End { 132 | Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($MyInvocation.MyCommand)" 133 | 134 | } #end 135 | 136 | } #close Get-FunctionProfile -------------------------------------------------------------------------------- /functions/public/Get-ModuleLayout.ps1: -------------------------------------------------------------------------------- 1 | Function Get-ModuleLayout { 2 | [cmdletbinding()] 3 | [OutputType("ModuleLayout", "String")] 4 | Param( 5 | [Parameter( 6 | Position = 0, 7 | Mandatory, 8 | HelpMessage = "Specify the path to the module layout json file.", 9 | ValueFromPipeline 10 | )] 11 | [ValidateNotNullOrEmpty()] 12 | [ValidatePattern("\.json$")] 13 | [ValidateScript({ Test-Path $_ })] 14 | [string]$Path, 15 | 16 | [Parameter(HelpMessage = "Show the module layout as a tree. This will create a temporary folder structure in %TEMP%.")] 17 | [switch]$AsTree 18 | ) 19 | Begin { 20 | Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($MyInvocation.MyCommand)" 21 | } #begin 22 | 23 | Process { 24 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Getting module layout from $Path " 25 | 26 | if ($AsTree) { 27 | Try { 28 | [void](Get-Command -Name tree -CommandType Application -ErrorAction stop) 29 | 30 | #create a random name 31 | $name = [system.io.path]::GetRandomFileName().Substring(0, 8) 32 | $parent = [system.io.path]::GetTempPath() 33 | 34 | $tmpModPath = Join-Path -Path $parent -ChildPath $name 35 | Write-Verbose "Using temporary path $tmpModPath" 36 | Try { 37 | [void](Import-ModuleLayout -Layout $Path -parentpath $parent -name $name -ErrorAction Stop) 38 | if ($IsWindows) { 39 | (tree $tmpModPath /f /a | Select-Object -Skip 2) -replace ($tmpModPath.replace("\", "\\")), "C:\\" 40 | } 41 | else { 42 | #assume Linux and hoping MacOS is the same 43 | (tree $tmpModPath) -replace "$tmpModPath", "/path/to/module" 44 | } 45 | } 46 | catch { 47 | Write-Warning "This option isn't supported on this platform at this time." 48 | } 49 | if (Test-Path $tmpModPath) { 50 | Write-Verbose "Removing temporary folder" 51 | Remove-Item $tmpModPath -Recurse -Force 52 | } 53 | } 54 | Catch { 55 | Write-Warning "This parameter requires a tree command-line utility." 56 | } 57 | } #AsTree 58 | else { 59 | 60 | $in = Get-Content -Path $path | ConvertFrom-Json 61 | 62 | [PSCustomObject]@{ 63 | PSTypeName = "ModuleLayout" 64 | Path = (Convert-Path $Path) 65 | Created = $in[0].Created 66 | CreatedBy = $in[0].CreatedBy 67 | SourcePath = $in[0].Source 68 | LayoutVersion = $in[0].Version 69 | SourceComputer = $in[0].computername 70 | Folders = $in.where({ $_.ItemType -eq 'directory' }).Path 71 | Files = $in.where({ $_.ItemType -eq 'file' }).Path 72 | } 73 | } 74 | } #process 75 | 76 | End { 77 | Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($MyInvocation.MyCommand)" 78 | } #end 79 | 80 | } #close Get-ModuleLayout -------------------------------------------------------------------------------- /functions/public/Get-PSFunctionTools.ps1: -------------------------------------------------------------------------------- 1 | 2 | 3 | Function Get-PSFunctionTools { 4 | [cmdletbinding()] 5 | [OutputType("PSFunctionTool")] 6 | Param() 7 | Begin { 8 | Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($MyInvocation.MyCommand)" 9 | 10 | } #begin 11 | 12 | Process { 13 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Getting commands from the PSFunctionTools module" 14 | $cmds = Get-Command -Module PSFunctionTools -CommandType Function | where-object { Test-FunctionName $_.name -Quiet } 15 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Found $($cmds.count) commands" 16 | foreach ($cmd in $cmds) { 17 | [PSCustomObject]@{ 18 | PSTypeName = "PSFunctionTool" 19 | Name = $cmd.Name 20 | Alias = ($n = Get-Alias -Definition $cmd.name -ErrorAction SilentlyContinue) ? $n.name : $null 21 | Synopsis = (Get-Help $cmd.name).Synopsis 22 | Module = "PSFunctionTools" 23 | ModuleVersion = $cmd.version 24 | } 25 | } 26 | } #process 27 | 28 | End { 29 | Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($MyInvocation.MyCommand)" 30 | } #end 31 | 32 | } #close Get-PSFunctionTools -------------------------------------------------------------------------------- /functions/public/Get-PSRequirements.ps1: -------------------------------------------------------------------------------- 1 | Function Get-PSRequirements { 2 | [cmdletbinding()] 3 | [OutputType("PSScriptRequirements")] 4 | Param( 5 | [Parameter( 6 | Position = 0, 7 | Mandatory, 8 | ValueFromPipeline, 9 | ValueFromPipelineByPropertyName 10 | )] 11 | [ValidateScript({ 12 | If (Test-Path $_ ) { 13 | $True 14 | If ($_ -match "\.ps(m)?1$") { 15 | $True 16 | } 17 | Else { 18 | Throw "The path must be to a .ps1 or .psm1 file." 19 | $False 20 | } 21 | } 22 | Else { 23 | Throw "Can't validate that $_ exists. Please verify and try again." 24 | $False 25 | } 26 | })] 27 | [string]$Path 28 | ) 29 | Begin { 30 | Write-Verbose "Starting $($MyInvocation.MyCommand)" 31 | } 32 | Process { 33 | $Path = Convert-Path $path 34 | Write-Verbose "Processing $path" 35 | 36 | $AST = _getAST $path 37 | 38 | #add the Path as a property 39 | if ($ast.ScriptRequirements) { 40 | $out = $ast.ScriptRequirements | 41 | Add-Member -MemberType NoteProperty -Name "Path" -Value $Path -Force -PassThru 42 | #insert a custom type name for formatting purposes 43 | $out.PSObject.TypeNames.insert(0,'PSScriptRequirements') 44 | #write the object to the pipeline 45 | $out 46 | } 47 | else { 48 | Write-Verbose "No requirements detected in $Path." 49 | } 50 | } 51 | End { 52 | Write-Verbose "Ending $($MyInvocation.MyCommand)" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /functions/public/Get-ParameterBlock.ps1: -------------------------------------------------------------------------------- 1 | Function Get-ParameterBlock { 2 | [cmdletbinding()] 3 | [alias("gpb")] 4 | [OutputType("ParamBlockAst","String")] 5 | Param( 6 | [Parameter( 7 | Position = 0, 8 | Mandatory, 9 | ValueFromPipelineByPropertyName, 10 | HelpMessage = "Specify the name of the PowerShell function." 11 | )] 12 | [ValidateNotNullOrEmpty()] 13 | [string]$Name, 14 | [Parameter( 15 | Mandatory, 16 | ValueFromPipelineByPropertyName, 17 | HelpMessage = "Specify the path to the .ps1 or .psm1 file." 18 | )] 19 | [ValidateScript({ 20 | If (Test-Path $_ ) { 21 | $True 22 | If ($_ -match "\.ps(m)?1$") { 23 | $True 24 | } 25 | Else { 26 | Throw "The path must be to a .ps1 or .psm1 file." 27 | $False 28 | } 29 | } 30 | Else { 31 | Throw "Can't validate that $_ exists. Please verify and try again." 32 | $False 33 | } 34 | })] 35 | [string]$Path, 36 | [Parameter(HelpMessage = "Display the parameter block as a string.")] 37 | [switch]$ToString 38 | ) 39 | Begin { 40 | Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($MyInvocation.MyCommand)" 41 | } #begin 42 | Process { 43 | $Path = Convert-Path -Path $path 44 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Processing function $(Format-FunctionName $name) from $Path " 45 | $AST = _getAST $Path 46 | #parse out functions using the AST 47 | $function = $ast.Find({ 48 | $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] -AND 49 | $args[0].name -eq $Name}, $true) 50 | 51 | if ($function) { 52 | Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Found function $(Format-FunctionName $function.name)" 53 | $pb = $function.find({$args[0] -is [System.Management.Automation.Language.ParamBlockAst]},$True) 54 | 55 | if ($pb.parameters.extent.text -AND $ToString) { 56 | $pb.parameters.extent.text 57 | } 58 | elseif ($pb.parameters.extent.text) { 59 | $pb 60 | } 61 | else { 62 | Write-Warning "No defined parameters detected for $name in $path." 63 | } 64 | } 65 | else { 66 | Write-Warning "Failed to find a function called $name in $path." 67 | } 68 | } #process 69 | End { 70 | Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($MyInvocation.MyCommand)" 71 | } #end 72 | 73 | } #close Get-ParameterBlock -------------------------------------------------------------------------------- /functions/public/Import-ModuleLayout.ps1: -------------------------------------------------------------------------------- 1 | function Import-ModuleLayout { 2 | [CmdletBinding(SupportsShouldProcess)] 3 | [alias("iml")] 4 | [OutputType("none")] 5 | Param( 6 | [Parameter(Position = 0, Mandatory, HelpMessage = "What is the name of your new module?")] 7 | [ValidateNotNullOrEmpty()] 8 | [ValidatePattern("^\w+$")] 9 | [string]$Name, 10 | [Parameter(HelpMessage = "What is the parent path? The default is the current location")] 11 | [ValidateScript( { Test-Path $_ })] 12 | [string]$ParentPath = ".", 13 | [Parameter(Mandatory, HelpMessage = "Specify the path to the module layout json file.")] 14 | [ValidateScript({Test-Path $_ })] 15 | [ValidatePattern("\.json$")] 16 | [string]$Layout 17 | ) 18 | 19 | Write-Verbose "Starting $($MyInvocation.MyCommand)" 20 | $ParentPath = Convert-Path $ParentPath 21 | Write-Verbose "Creating module layout for $name under $ParentPath using layout from $layout." 22 | $ModPath = New-Item -Path $ParentPath -Name $name -ItemType Directory -Force 23 | 24 | <# 25 | ConvertFrom-Json has a bug in Windows PowerShell so 26 | piping the converted content to ForEach-Object and 27 | passing each object back to the pipeline works around it 28 | #> 29 | Get-Content -path $Layout | 30 | ConvertFrom-Json | ForEach-Object {$_} | 31 | Sort-Object -Property ItemType | 32 | ForEach-Object { 33 | #create all the directories first 34 | if ($_.ItemType -eq 'directory') { 35 | if ($PSCmdlet.ShouldProcess($_.path, "Create directory")) { 36 | New-Item -Path $ModPath -Name $_.path -ItemType Directory -Force 37 | } 38 | } #directory item 39 | elseif ($_.ItemType -eq 'file') { 40 | if ($PSCmdlet.ShouldProcess($_.path, "Create file")) { 41 | $NewFile = (Join-Path -Path $ModPath -ChildPath $_.path) 42 | Set-Content -Path $NewFile -Value $_.content 43 | Get-Item -path $NewFile 44 | } 45 | } #file item 46 | } #foreach-object 47 | 48 | Write-Verbose "Ending $($MyInvocation.MyCommand)" 49 | } 50 | -------------------------------------------------------------------------------- /functions/public/New-CommentHelp.ps1: -------------------------------------------------------------------------------- 1 | Function New-CommentHelp { 2 | [cmdletbinding(DefaultParameterSetName="ast")] 3 | [alias('nch')] 4 | [OutputType("System.String")] 5 | Param( 6 | [Parameter( 7 | Position = 0, 8 | Mandatory, 9 | ValueFromPipeline, 10 | HelpMessage = "Specify ParamBlockAST object.", 11 | ParameterSetName = "ast" 12 | )] 13 | [System.Management.Automation.Language.ParamBlockAst]$ParamBlock, 14 | [Parameter(HelpMessage = "Provide a short description. You can always edit this later.")] 15 | [string]$Synopsis = "", 16 | [Parameter(HelpMessage = "Provide a longer description. You can always edit this later.")] 17 | [string]$Description = "", 18 | [Parameter(HelpMessage = "Insert help template",ParameterSetName = "template")] 19 | [switch]$TemplateOnly 20 | ) 21 | 22 | Begin { 23 | Write-Verbose "Starting $($MyInvocation.MyCommand)" 24 | Write-Verbose "Defining help opening" 25 | $h = [System.Collections.Generic.List[string]]::new() 26 | $h.Add("<#") 27 | $h.Add(" .Synopsis") 28 | $h.Add(" $Synopsis") 29 | $h.Add(" .Description") 30 | $h.Add(" $Description") 31 | } 32 | 33 | Process { 34 | if ($PSCmdlet.ParameterSetName -eq 'ast') { 35 | Write-Verbose "Processing a ParamBlock AST object" 36 | foreach ($p in $ParamBlock.Parameters) { 37 | $ParamName = $p.name.VariablePath.UserPath 38 | Write-Verbose "Adding parameter help for $ParamName" 39 | $h.Add(" .Parameter $ParamName") 40 | $paramHelp = $p.Attributes.namedArguments.where({ $_.ArgumentName -eq 'helpmessage' }) 41 | if ($paramHelp) { 42 | $h.Add(" $($paramHelp.argument.value)") 43 | } 44 | else { 45 | $h.Add(" ") 46 | } 47 | } 48 | } #if ParamBlock 49 | 50 | } #process 51 | End { 52 | Write-Verbose "Adding closing help content" 53 | $h.Add(" .Example") 54 | $h.Add(" PS C:\> $Name") 55 | $h.Add(" ") 56 | $h.Add(" .Inputs") 57 | $h.Add(" ") 58 | $h.Add(" .Outputs") 59 | $h.Add(" ") 60 | $h.Add(" .Notes") 61 | $h.Add(" ") 62 | $h.Add(" .Link") 63 | $h.Add(" ") 64 | $h.Add("#>") 65 | $h 66 | Write-Verbose "Ending $($MyInvocation.MyCommand)" 67 | } #end 68 | } 69 | -------------------------------------------------------------------------------- /functions/public/New-ModuleFromFiles.ps1: -------------------------------------------------------------------------------- 1 | Function New-ModuleFromFiles { 2 | [cmdletbinding(SupportsShouldProcess)] 3 | [OutputType("System.IO.FileInfo","System.IO.DirectoryInfo")] 4 | Param( 5 | [Parameter( 6 | Position = 0, 7 | Mandatory, 8 | HelpMessage = "What is the name of the new module?" 9 | )] 10 | [ValidateNotNullOrEmpty()] 11 | [string]$NewModuleName, 12 | 13 | [Parameter( 14 | Position = 1, 15 | Mandatory, 16 | HelpMessage = "What is the parent path for the new module? It must already exist." 17 | )] 18 | [ValidateNotNullOrEmpty()] 19 | [ValidateScript({Test-Path $_ })] 20 | [string]$ParentPath, 21 | 22 | [Parameter( 23 | Mandatory, 24 | HelpMessage = "Enter an module description." 25 | )] 26 | [string]$Description, 27 | 28 | [Parameter( 29 | Mandatory, 30 | HelpMessage = "Enter the paths to PowerShell script files with functions to export." 31 | )] 32 | [ValidateNotNullOrEmpty()] 33 | [ValidateScript({Test-Path $_ })] 34 | [string[]]$Files, 35 | 36 | [Parameter( 37 | Mandatory, 38 | HelpMessage = "Specify the module layout json file created with Export-ModuleLayout." 39 | )] 40 | [ValidateScript({Test-Path $_ })] 41 | [ValidatePattern("\.json$")] 42 | [string]$Layout, 43 | 44 | [Parameter(HelpMessage = "Specify the relative path for the exported functions.")] 45 | [ValidateNotNullOrEmpty()] 46 | [string]$FunctionPath = "functions" 47 | ) 48 | DynamicParam { 49 | $paramDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary 50 | If (Get-Command -name New-MarkdownHelp) { 51 | #CreateHelp 52 | if (-not $paramDictionary.ContainsKey("CreateHelp")) { 53 | 54 | $attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute] 55 | $attributes = New-Object System.Management.Automation.ParameterAttribute 56 | $attributes.ParameterSetName = '__AllParameterSets' 57 | $attributes.HelpMessage = 'Create help documentation using the Platyps module' 58 | $attributeCollection.Add($attributes) 59 | 60 | $dynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('CreateHelp', [Switch], $attributeCollection) 61 | $paramDictionary.Add('CreateHelp', $dynParam1) 62 | } 63 | 64 | #MarkdownPath 65 | if (-not $paramDictionary.ContainsKey("MarkdownPath")) { 66 | 67 | $attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute] 68 | $attributes = New-Object System.Management.Automation.ParameterAttribute 69 | $attributes.ParameterSetName = '__AllParameterSets' 70 | $attributes.HelpMessage = 'Specify the path for the markdown help files.' 71 | 72 | $v = New-Object System.Management.Automation.ValidateNotNullOrEmptyAttribute 73 | $AttributeCollection.Add($v) 74 | $attributeCollection.Add($attributes) 75 | 76 | $dynParam2 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('MarkdownPath', [String], $attributeCollection) 77 | $dynParam2.value = "docs" 78 | $paramDictionary.Add('MarkdownPath', $dynParam2) 79 | 80 | } 81 | } # end if 82 | If (Get-Command git -ErrorAction SilentlyContinue) { 83 | 84 | if (-not $paramDictionary.ContainsKey("InitializeGit")) { 85 | #InitializeGit 86 | $attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute] 87 | $attributes = New-Object System.Management.Automation.ParameterAttribute 88 | $attributes.ParameterSetName = '__AllParameterSets' 89 | $attributes.HelpMessage = 'Initialize the new module as a git repository' 90 | $attributeCollection.Add($attributes) 91 | 92 | $dynParam3 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('InitializeGit', [Switch], $attributeCollection) 93 | $paramDictionary.Add('InitializeGit', $dynParam3) 94 | 95 | } 96 | } 97 | return $paramDictionary 98 | } #end DynamicParam 99 | 100 | Begin { 101 | Write-Verbose "Starting $($MyInvocation.MyCommand)" 102 | $export = [System.Collections.Generic.list[object]]::New() 103 | $aliases = @() 104 | } 105 | Process { 106 | Write-Verbose "Processing dynamic parameters" 107 | $dp = $PSCmdlet.GetDynamicParameters() 108 | if ( $PSBoundParameters.ContainsKey("CreateHelp") -AND (-Not ($PSBoundParameters.ContainsKey("MarkdownPath")))) { 109 | #add the default value to bound parameters if CreateHelp is detected 110 | $PSBoundParameters.Add("MarkdownPath", $dp["MarkdownPath"].value) 111 | } 112 | Write-Verbose "Using these bound parameters" 113 | $PSBoundParameters | Out-String | Write-Verbose 114 | 115 | #the new module location 116 | $path = Join-Path -Path $ParentPath -ChildPath $NewModuleName 117 | Write-Verbose "Creating the module structure" 118 | Import-ModuleLayout -Name $NewModuleName -ParentPath $ParentPath -Layout $layout 119 | $functionFiles = $files | ForEach-Object { 120 | Write-Verbose "Processing $_" 121 | #Export standard functions only. 122 | Export-FunctionFromFile -Path $_ -OutputPath (Join-Path -Path $Path -ChildPath $FunctionPath) -PassThru 123 | #get aliases 124 | if ($PSCmdlet.ShouldProcess($_, "Getting function aliases")) { 125 | $aliases += Get-FunctionAlias -path $_ | Select-Object -ExpandProperty alias 126 | } 127 | } 128 | 129 | if ($functionFiles) { 130 | Write-Verbose "Adding file(s) $($functionFiles.basename -join ',')" 131 | if ($functionFiles.count -gt 1) { 132 | $export.AddRange($functionFiles.baseName) 133 | } 134 | else { 135 | $export.Add($functionFiles.baseName) 136 | } 137 | } 138 | 139 | #create the root module 140 | Write-Verbose "Creating root module $path\$NewModuleName.psm1" 141 | $psm1 = @" 142 | 143 | Get-ChildItem `$PSScriptRoot\$functionPath\*.ps1 -recurse | 144 | Foreach-Object { 145 | . `$_.FullName 146 | } 147 | 148 | "@ 149 | $psm1 | Out-File "$path\$NewModuleName.psm1" 150 | 151 | #create the module manifest 152 | $splat = @{ 153 | Path = "$path\$NewModuleName.psd1" 154 | RootModule = "$NewModuleName.psm1" 155 | ModuleVersion = "0.1.0" 156 | Description = $Description 157 | CmdletsToExport = @() 158 | VariablesToExport = @() 159 | FunctionsToExport = $Export 160 | AliasesToExport = $aliases 161 | PowerShellVersion = "5.1" 162 | CompatiblePSEditions = "Desktop" 163 | } 164 | Write-Verbose "Creating module manifest $($splat.path)" 165 | New-ModuleManifest @splat 166 | 167 | if ($PSBoundParameters.ContainsKey("CreateHelp")) { 168 | $mdPath = Join-Path -Path $path -ChildPath $PSBoundParameters["MarkdownPath"] 169 | $xmlPath = Join-Path -Path $path -ChildPath $(Get-Culture).name 170 | Write-Verbose "Creating module help files" 171 | if ($PSCmdlet.ShouldProcess($mdPath, "create markdown help files")) { 172 | if (Test-Path $mdPath) { 173 | Write-Verbose "Creating markdown files in $mdPath" 174 | _mkHelp -ModulePath $splat.path -MarkdownPath $mdPath -OutputPath $xmlpath 175 | } 176 | else { 177 | Write-Warning "Could not find $mdPath." 178 | } 179 | } 180 | } #if create help 181 | 182 | if ($PSBoundParameters.ContainsKey("InitializeGit")) { 183 | Write-Verbose "Initializing git" 184 | if ($PSCmdlet.ShouldProcess($path, "git initialize")) { 185 | Push-Location 186 | Set-Location $path 187 | git init 188 | git add . 189 | git commit -m "initial files" 190 | git checkout -b $splat.ModuleVersion 191 | Pop-Location 192 | } 193 | } 194 | } #process 195 | End { 196 | Write-Verbose "Ending $($MyInvocation.MyCommand)" 197 | } 198 | } #end function 199 | 200 | -------------------------------------------------------------------------------- /functions/public/New-ModuleFromLayout.ps1: -------------------------------------------------------------------------------- 1 | Function New-ModuleFromLayout { 2 | [cmdletbinding(SupportsShouldProcess)] 3 | [OutputType("System.IO.FileInfo","System.IO.DirectoryInfo")] 4 | Param( 5 | [Parameter( 6 | Position = 0, 7 | Mandatory, 8 | HelpMessage = "What is the name of the new module?" 9 | )] 10 | [ValidateNotNullOrEmpty()] 11 | [string]$NewModuleName, 12 | 13 | [Parameter( 14 | Position = 1, 15 | Mandatory, 16 | HelpMessage = "What is the parent path for the new module? It must already exist." 17 | )] 18 | [ValidateNotNullOrEmpty()] 19 | [ValidateScript({Test-Path $_ })] 20 | [string]$ParentPath, 21 | 22 | [Parameter( 23 | Mandatory, 24 | HelpMessage = "Enter an module description." 25 | )] 26 | [string]$Description, 27 | 28 | [Parameter( 29 | Mandatory, 30 | HelpMessage = "Specify the module layout json file created with Export-ModuleLayout." 31 | )] 32 | [ValidateScript( { Test-Path $_ })] 33 | [ValidatePattern("\.json$")] 34 | [string]$Layout, 35 | 36 | [Parameter(HelpMessage = "Specify the relative path where your functions will be created.")] 37 | [ValidateNotNullOrEmpty()] 38 | [string]$FunctionPath = "functions" 39 | 40 | ) 41 | DynamicParam { 42 | # Add parameter if git.exe is detected 43 | If (Get-Command git -ErrorAction SilentlyContinue) { 44 | $paramDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary 45 | 46 | #InitializeGit 47 | $attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute] 48 | $attributes = New-Object System.Management.Automation.ParameterAttribute 49 | $attributes.ParameterSetName = '__AllParameterSets' 50 | $attributes.HelpMessage = 'Initialize the new module as a git repository' 51 | $attributeCollection.Add($attributes) 52 | 53 | $dynParam = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('InitializeGit', [Switch], $attributeCollection) 54 | $paramDictionary.Add('InitializeGit', $dynParam) 55 | 56 | return $paramDictionary 57 | } 58 | 59 | } #end DynamicParam 60 | 61 | Begin { 62 | Write-Verbose "Starting $($MyInvocation.MyCommand)" 63 | } 64 | Process { 65 | 66 | Write-Verbose "Using these bound parameters" 67 | $PSBoundParameters | Out-String | Write-Verbose 68 | 69 | #the new module location 70 | $path = Join-Path -Path $ParentPath -ChildPath $NewModuleName 71 | Write-Verbose "Creating the module structure" 72 | Import-ModuleLayout -Name $NewModuleName -ParentPath $ParentPath -Layout $layout 73 | 74 | #create the root module 75 | $psm1 = @" 76 | 77 | Get-ChildItem `$PSScriptRoot\$FunctionPath\*.ps1 -recurse | 78 | Foreach-Object { 79 | . `$_.FullName 80 | } 81 | 82 | "@ 83 | Write-Verbose "Creating root module $path\$NewModuleName.psm1" 84 | $psm1 | Out-File "$path\$NewModuleName.psm1" 85 | 86 | #create the module manifest 87 | $splat = @{ 88 | Path = "$path\$NewModuleName.psd1" 89 | RootModule = "$NewModuleName.psm1" 90 | ModuleVersion = "0.1.0" 91 | Description = $Description 92 | PowerShellVersion = "5.1" 93 | CompatiblePSEditions = "Desktop" 94 | } 95 | Write-Verbose "Creating module manifest $($splat.path)" 96 | New-ModuleManifest @splat 97 | 98 | if ($PSBoundParameters.ContainsKey("InitializeGit")) { 99 | Write-Verbose "Initializing git" 100 | if ($PSCmdlet.ShouldProcess($path, "git initialize")) { 101 | Push-Location 102 | Set-Location $path 103 | git init 104 | git add . 105 | git commit -m "initial files" 106 | git checkout -b $splat.ModuleVersion 107 | Pop-Location 108 | } 109 | } 110 | } #process 111 | End { 112 | Write-Verbose "Ending $($MyInvocation.MyCommand)" 113 | } 114 | } #end function -------------------------------------------------------------------------------- /functions/public/Open-PSFunctionToolsSamples.ps1: -------------------------------------------------------------------------------- 1 | Function Open-PSFunctionToolsSamples { 2 | [cmdletbinding()] 3 | [OutputType('System.IO.FileInfo')] 4 | 5 | Param( ) 6 | 7 | Begin { 8 | Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Starting $($MyInvocation.MyCommand)" 9 | Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Running under PowerShell version $($PSVersionTable.PSVersion)" 10 | $SamplePath = "$PSScriptRoot\..\..\samples" 11 | } #begin 12 | 13 | Process { 14 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Changing location to $SamplePath" 15 | Set-Location -Path $SamplePath 16 | Get-ChildItem 17 | } #process 18 | 19 | End { 20 | Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)" 21 | } #end 22 | 23 | } #close Open-PSFunctionToolsSamples -------------------------------------------------------------------------------- /functions/public/Open-README.ps1: -------------------------------------------------------------------------------- 1 | Function Open-PSFunctionToolsHelp { 2 | [CmdletBinding()] 3 | [OutputType('None','String')] 4 | Param( 5 | [Parameter(HelpMessage = 'Open the help file as markdown.')] 6 | [Alias('md')] 7 | [switch]$AsMarkdown 8 | ) 9 | 10 | Begin { 11 | Write-Verbose "Starting $($MyInvocation.MyCommand)" 12 | 13 | if ($AsMarkdown) { 14 | $docPath = "$PSScriptRoot\..\..\README.md" 15 | } 16 | else { 17 | $docPath = "$PSScriptRoot\..\..\PSFunctionTools-Help.pdf" 18 | } 19 | 20 | } #begin 21 | Process { 22 | Write-Verbose "Testing for $docPath" 23 | If (Test-Path -Path $docPath) { 24 | if ($AsMarkdown) { 25 | Write-Verbose "Opening $docPath as markdown." 26 | Show-Markdown -Path $docPath 27 | } 28 | else { 29 | Try { 30 | Write-Verbose "Opening $docPath as a PDF file" 31 | Invoke-Item -Path $docPath -ErrorAction Stop 32 | } 33 | Catch { 34 | Write-Warning "Failed to open $docPath" 35 | } 36 | } 37 | } #if Test-Path 38 | else { 39 | Throw "Cannot find the file $docPath" 40 | } 41 | } #process 42 | End { 43 | Write-Verbose "Ending $($MyInvocation.MyCommand)" 44 | } #end 45 | } -------------------------------------------------------------------------------- /functions/public/Test-FunctionName.ps1: -------------------------------------------------------------------------------- 1 | Function Test-FunctionName { 2 | [CmdletBinding()] 3 | [alias('tfn')] 4 | [OutputType("boolean", "string")] 5 | Param( 6 | [Parameter( 7 | Position = 0, 8 | Mandatory, 9 | ValueFromPipeline, 10 | HelpMessage = "Specify a function name." 11 | )] 12 | [ValidateNotNullOrEmpty()] 13 | [string]$Name, 14 | [Parameter(HelpMessage = "Get a boolean test result.")] 15 | [switch]$Quiet 16 | ) 17 | 18 | Begin { 19 | Write-Verbose "Starting $($MyInvocation.MyCommand)" 20 | $VerbList = (Get-Verb).Verb 21 | } #begin 22 | Process { 23 | Write-Verbose "Validating function name $Name" 24 | #Function name must first follow Verb-Noun pattern 25 | if ($Name -match "^\w+-\w+$") { 26 | #validate the standard verb 27 | $verb = ($Name -split "-")[0] 28 | Write-Verbose "Validating detected verb $verb" 29 | if ($VerbList -contains $verb ) { 30 | if ($Quiet) { 31 | $True 32 | } 33 | else { 34 | $Name 35 | } 36 | } 37 | else { 38 | Write-Verbose "$name contains a non-standard verb." 39 | if ($Quiet) { 40 | $false 41 | } 42 | } 43 | } #if name matches word-word 44 | elseif ($quiet) { 45 | $False 46 | } 47 | } #process 48 | End { 49 | Write-Verbose "Ending $($MyInvocation.MyCommand)" 50 | } #end 51 | } 52 | -------------------------------------------------------------------------------- /images/export-modulelayout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhitsolutions/PSFunctionTools/7406fa1a1026f0a899316584bc95fa7626937312/images/export-modulelayout.png -------------------------------------------------------------------------------- /images/get-functionprofile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhitsolutions/PSFunctionTools/7406fa1a1026f0a899316584bc95fa7626937312/images/get-functionprofile.png -------------------------------------------------------------------------------- /images/get-functionprofile2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhitsolutions/PSFunctionTools/7406fa1a1026f0a899316584bc95fa7626937312/images/get-functionprofile2.png -------------------------------------------------------------------------------- /images/get-modulelayout-source.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhitsolutions/PSFunctionTools/7406fa1a1026f0a899316584bc95fa7626937312/images/get-modulelayout-source.png -------------------------------------------------------------------------------- /images/get-modulelayout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhitsolutions/PSFunctionTools/7406fa1a1026f0a899316584bc95fa7626937312/images/get-modulelayout.png -------------------------------------------------------------------------------- /images/get-psfunctiontools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhitsolutions/PSFunctionTools/7406fa1a1026f0a899316584bc95fa7626937312/images/get-psfunctiontools.png -------------------------------------------------------------------------------- /images/get-relativepath.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhitsolutions/PSFunctionTools/7406fa1a1026f0a899316584bc95fa7626937312/images/get-relativepath.png -------------------------------------------------------------------------------- /images/import-modulelayout-whatif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhitsolutions/PSFunctionTools/7406fa1a1026f0a899316584bc95fa7626937312/images/import-modulelayout-whatif.png -------------------------------------------------------------------------------- /images/import-modulelayout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhitsolutions/PSFunctionTools/7406fa1a1026f0a899316584bc95fa7626937312/images/import-modulelayout.png -------------------------------------------------------------------------------- /images/layout-metadata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhitsolutions/PSFunctionTools/7406fa1a1026f0a899316584bc95fa7626937312/images/layout-metadata.png -------------------------------------------------------------------------------- /images/psrobot-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhitsolutions/PSFunctionTools/7406fa1a1026f0a899316584bc95fa7626937312/images/psrobot-icon.png -------------------------------------------------------------------------------- /images/sample-module-layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhitsolutions/PSFunctionTools/7406fa1a1026f0a899316584bc95fa7626937312/images/sample-module-layout.png -------------------------------------------------------------------------------- /samples/BuildModule.ps1: -------------------------------------------------------------------------------- 1 | #requires -version 7.4 2 | 3 | #build a new module from files 4 | $files = "$PSScriptRoot\tools.psm1","$PSScriptRoot\Get-ZeroSize.ps1" 5 | & "$PSScriptRoot\POC-NewModule2.ps1" -files $files 6 | -------------------------------------------------------------------------------- /samples/Demo-ExportFunctions.ps1: -------------------------------------------------------------------------------- 1 | #requires -version 7.4 2 | 3 | #export functions from a single file to separate files 4 | Import-Module PSFunctionTools 5 | 6 | Export-FunctionFromFile -Path $PSScriptRoot\tools.psm1 -OutputPath $env:temp -PassThru 7 | -------------------------------------------------------------------------------- /samples/Demo-NewModuleFromFiles.ps1: -------------------------------------------------------------------------------- 1 | #requires -version 7.4 2 | #this demo assumes you have the Platyps module and git installed 3 | 4 | [CmdletBinding(SupportsShouldProcess)] 5 | Param() 6 | 7 | $splat = @{ 8 | Description = "Demo exported module" 9 | Files = "$PSScriptRoot\tools.psm1" 10 | Layout = "$PSScriptRoot\ModuleLayout.json" 11 | NewModuleName = "PSFooExport" 12 | ParentPath = $env:temp 13 | CreateHelp = $True 14 | FunctionPath = "functions\public" 15 | InitializeGit = $True 16 | } 17 | Clear-Host 18 | Write-Host "Using these parameters" -ForegroundColor yellow 19 | $splat | Out-String | Write-Host -ForegroundColor yellow 20 | Write-Host "WhatIf = $WhatIfPreference" -ForegroundColor yellow 21 | pause 22 | Write-Host "Creating new module from files" -ForegroundColor Green 23 | New-ModuleFromFiles @splat 24 | $newModulePath = Join-Path -Path $splat.ParentPath -ChildPath $splat.NewModuleName 25 | Write-Host "New module created in newModulePath" -ForegroundColor Green 26 | if (-Not $WhatIfPreference) { 27 | Get-ChildItem -Path $newModulePath -Recurse 28 | } 29 | -------------------------------------------------------------------------------- /samples/Get-ZeroSize.ps1: -------------------------------------------------------------------------------- 1 | #requires -module CIMCmdlets 2 | 3 | Function Get-ZeroLengthFiles { 4 | [CmdletBinding()] 5 | [alias('gzf', 'zombie')] 6 | Param( 7 | [Parameter(Position = 0, HelpMessage = 'Specify a path to search.')] 8 | [ValidateScript( { Test-Path -Path $_ })] 9 | [String]$Path = '.', 10 | [Switch]$Recurse 11 | ) 12 | Begin { 13 | Write-Verbose "[$((Get-Date).TimeOfDay) BEGIN ] Starting $($MyInvocation.MyCommand)" 14 | #select a subset of properties which speeds things up 15 | $get = 'Name', 'CreationDate', 'LastModified', 'FileSize' 16 | 17 | $cimParams = @{ 18 | Classname = 'CIM_DATAFILE' 19 | Property = $get 20 | ErrorAction = 'Stop' 21 | Filter = '' 22 | } 23 | } #begin 24 | Process { 25 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Using specified path $Path" 26 | #test if folder is using a link or reparse point 27 | if ( (Get-Item -Path $Path).Target) { 28 | $target = (Get-Item -Path $Path).Target 29 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] A reparse point was detected pointing towards $target" 30 | #re-define $path to use the target 31 | $Path = $Target 32 | } 33 | #convert the path to a file system path 34 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Converting $Path" 35 | $cPath = Convert-Path $Path 36 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Converted to $cPath" 37 | 38 | #trim off any trailing \ if cPath is other than a drive root like C:\ 39 | if ($cPath.Length -gt 3 -AND $cPath -match '\\$') { 40 | $cPath = $cPath -replace '\\$', '' 41 | } 42 | 43 | #parse out the drive 44 | $drive = $cPath.Substring(0, 2) 45 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Using Drive $drive" 46 | 47 | #get the folder path from the first \ 48 | $folder = $cPath.Substring($cPath.IndexOf('\')).replace('\', '\\') 49 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Using folder $folder (escaped)" 50 | 51 | if ($folder -match '\w+' -AND $PSBoundParameters.ContainsKey('Recurse')) { 52 | #create the filter to use the wildcard for recursing 53 | $filter = "Drive='$drive' AND Path LIKE '$folder\\%' AND FileSize=0" 54 | } 55 | elseif ($folder -match '\w+') { 56 | #create an exact path pattern 57 | $filter = "Drive='$drive' AND Path='$folder\\' AND FileSize=0" 58 | } 59 | else { 60 | #create a root drive filter for a path like C:\ 61 | $filter = "Drive='$drive' AND Path LIKE '\\%' AND FileSize=0" 62 | } 63 | 64 | #add the filter to the parameter hashtable 65 | $cimParams.filter = $filter 66 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Looking for zero length files with filter $filter" 67 | 68 | #initialize a counter to keep track of the number of files found 69 | $i = 0 70 | Try { 71 | Write-Host "Searching for zero length files in $cPath. This might take a few minutes..." -ForegroundColor magenta 72 | #find files matching the query and create a custom object for each 73 | Get-CimInstance @cimParams | ForEach-Object { 74 | #increment the counter 75 | $i++ 76 | 77 | #create a custom object 78 | [PSCustomObject]@{ 79 | PSTypeName = 'cimZeroLengthFile' 80 | Path = $_.Name 81 | Size = $_.FileSize 82 | Created = $_.CreationDate 83 | LastModified = $_.LastModified 84 | } 85 | } 86 | } 87 | Catch { 88 | Write-Warning "Failed to run query. $($_.exception.message)" 89 | } 90 | if ($i -eq 0) { 91 | #display a message if no files were found 92 | Write-Host "No zero length files were found in $cPath." -ForegroundColor yellow 93 | } 94 | else { 95 | Write-Verbose "[$((Get-Date).TimeOfDay) PROCESS] Found $i matching files" 96 | } 97 | } #process 98 | End { 99 | Write-Verbose "[$((Get-Date).TimeOfDay) END ] Ending $($MyInvocation.MyCommand)" 100 | } #end 101 | } 102 | -------------------------------------------------------------------------------- /samples/ModuleLayout.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhitsolutions/PSFunctionTools/7406fa1a1026f0a899316584bc95fa7626937312/samples/ModuleLayout.json -------------------------------------------------------------------------------- /samples/POC-NewModule.ps1: -------------------------------------------------------------------------------- 1 | #requires -version 7.4 2 | 3 | #a proof of concept to convert scripts to a new module 4 | 5 | Import-Module PSFunctionTools -Force 6 | 7 | $NewModuleName = "PSMagic" 8 | $Description = "A sample PowerShell module" 9 | $ParentPath = $env:TEMP 10 | $path = New-Item -Name $NewModuleName -Path $ParentPath -ItemType Directory -Force 11 | 12 | #create the module structure 13 | "docs", "functions", $(Get-Culture).name, "formats" | 14 | ForEach-Object { New-Item -Path $path -Name $_ -ItemType Directory } 15 | 16 | #file data 17 | $data = @" 18 | "Path","Name" 19 | "$PSScriptRoot\SampleScript.ps1","Get-Foo" 20 | "$PSScriptRoot\SampleScript2.ps1","Set-Foo" 21 | "$PSScriptRoot\SampleScript3.ps1","Invoke-Foo" 22 | "$PSScriptRoot\SampleScript4.ps1","Remove-Foo" 23 | "$PSScriptRoot\SampleScript5.ps1","Test-Foo" 24 | "@ 25 | 26 | $csv = $data | ConvertFrom-Csv 27 | foreach ($item in $csv) { 28 | $out = Join-Path $path\functions "$($item.name).ps1" 29 | $item | Convert-ScriptToFunction | Out-File -FilePath $out 30 | Get-Item $out 31 | 32 | } #foreach item 33 | 34 | #create the root module 35 | $psm1 = @" 36 | 37 | Get-ChildItem `$PSScriptRoot\functions\*.ps1 | 38 | ForEach-Object { 39 | . `$_.FullName 40 | } 41 | 42 | "@ 43 | 44 | $psm1 | Out-File "$path\$NewModuleName.psm1" 45 | 46 | #create the module manifest 47 | $splat = @{ 48 | Path = "$path\$NewModuleName.psd1" 49 | RootModule = "$NewModuleName.psm1" 50 | ModuleVersion = "0.1.0" 51 | Author = $env:USERNAME 52 | Description = $Description 53 | FunctionsToExport = $csv.name 54 | PowerShellVersion = "5.1" 55 | CompatiblePSEditions = "Desktop" 56 | } 57 | New-ModuleManifest @splat 58 | 59 | Get-ChildItem $path 60 | 61 | -------------------------------------------------------------------------------- /samples/POC-NewModule2.ps1: -------------------------------------------------------------------------------- 1 | #requires -version 7.4 2 | #requires -module Platyps 3 | 4 | #this is a proof of concept script file 5 | 6 | #Export functions from files and create a new module 7 | 8 | [CmdletBinding(SupportsShouldProcess)] 9 | Param( 10 | [Parameter(position = 0, HelpMessage = 'What is the name of the new module?')] 11 | [ValidateNotNullOrEmpty()] 12 | [String]$NewModuleName = 'PSTools', 13 | 14 | [Parameter(Position = 1, HelpMessage = 'What is the parent path for the new module?')] 15 | [ValidateNotNullOrEmpty()] 16 | [ValidateScript({ Test-Path $_ })] 17 | [String]$ParentPath = $env:temp, 18 | 19 | [Parameter(HelpMessage = 'Enter an module description.')] 20 | [String]$Description = 'A set of PowerShell-based tools.', 21 | 22 | [Parameter(Mandatory, HelpMessage = 'PowerShell script files with functions to export.')] 23 | [ValidateNotNullOrEmpty()] 24 | [ValidateScript({ Test-Path $_ })] 25 | [string[]]$Files 26 | ) 27 | 28 | Write-Verbose "Starting $($MyInvocation.MyCommand)" 29 | 30 | #the new module location 31 | $path = Join-Path -Path $ParentPath -ChildPath $NewModuleName 32 | $export = [System.Collections.Generic.list[object]]::New() 33 | $aliases = @() 34 | #the layout was created using Export-ModuleLayout 35 | $layout = "$PSScriptRoot\ModuleLayout.json" 36 | Write-Verbose 'Creating the module structure' 37 | Import-ModuleLayout -Name $NewModuleName -ParentPath $ParentPath -Layout $layout 38 | 39 | #I removed the parameter validation on the target path 40 | $functionFiles = $files | ForEach-Object { 41 | Write-Verbose "Processing $_" 42 | Export-FunctionFromFile -Path $_ -OutputPath $Path\functions\public -All -PassThru 43 | #get aliases 44 | if ($PSCmdlet.ShouldProcess($_, 'Getting function aliases')) { 45 | $aliases += Get-FunctionAlias -Path $_ | Select-Object -ExpandProperty alias 46 | } 47 | } 48 | 49 | if ($functionFiles) { 50 | $export.AddRange($functionFiles.baseName) 51 | } 52 | 53 | #create the root module 54 | $psm1 = @" 55 | 56 | Get-ChildItem `$PSScriptRoot\functions\*.ps1 -recurse | 57 | ForEach-Object { 58 | . `$_.FullName 59 | } 60 | 61 | "@ 62 | Write-Verbose "Creating root module $path\$NewModuleName.psm1" 63 | $psm1 | Out-File "$path\$NewModuleName.psm1" 64 | 65 | #create the module manifest 66 | $splat = @{ 67 | Path = "$path\$NewModuleName.psd1" 68 | RootModule = "$NewModuleName.psm1" 69 | ModuleVersion = '0.1.0' 70 | Author = 'Jeff Hicks' 71 | CompanyName = 'JDH Information Technology Solutions, Inc.' 72 | Copyright = '(c) 2023 JDH Information Technology Solutions, Inc.' 73 | Description = $Description 74 | CmdletsToExport = @() 75 | VariablesToExport = @() 76 | FunctionsToExport = $Export 77 | AliasesToExport = $aliases 78 | PowerShellVersion = '5.1' 79 | CompatiblePSEditions = 'Desktop', 'Core' 80 | } 81 | Write-Verbose "Creating module manifest $($splat.path)" 82 | New-ModuleManifest @splat 83 | 84 | <# 85 | this requires the Platyps module which you should be using to 86 | create external module help documentation. 87 | Install-Module Platyps 88 | #> 89 | 90 | Write-Verbose 'Creating module help files' 91 | if ($PSCmdlet.ShouldProcess('docs', 'create markdown help files')) { 92 | Import-Module $splat.path 93 | New-MarkdownHelp -Module $NewModuleName -OutputFolder $path\docs 94 | New-ExternalHelp -Path $path\docs -OutputPath $path\en-us 95 | } 96 | 97 | Try { 98 | [void](Get-Command git -ErrorAction stop) 99 | Write-Verbose 'Initializing git' 100 | if ($PSCmdlet.ShouldProcess($path, 'git initialize')) { 101 | Set-Location $path 102 | git init 103 | git add . 104 | git commit -m 'initial files' 105 | git checkout -b $splat.ModuleVersion 106 | } 107 | } 108 | Catch { 109 | Write-Host 'Skipping git init' -ForegroundColor yellow 110 | } 111 | if (-not $WhatIfPreference) { 112 | Get-ChildItem $path -Recurse 113 | Try { 114 | [void](Get-Command -Name code.cmd -ErrorAction stop) 115 | Write-Verbose 'Opening module in VSCode' 116 | code $path 117 | } 118 | Catch { 119 | Write-Warning 'VS Code not found.' 120 | } 121 | } 122 | 123 | Write-Verbose "Ending $($MyInvocation.MyCommand)" 124 | -------------------------------------------------------------------------------- /samples/SampleScript.ps1: -------------------------------------------------------------------------------- 1 | #requires -version 4.0 2 | 3 | #this is a sample script 4 | 5 | Write-Host "this is a sample script that doesn't do anything but write a random number" -ForegroundColor Yellow 6 | 7 | Get-Random -Minimum 1 -Maximum 1000 8 | -------------------------------------------------------------------------------- /samples/SampleScript2.ps1: -------------------------------------------------------------------------------- 1 | #requires -version 3.0 2 | 3 | #this is a sample script 4 | <# 5 | .Synopsis 6 | Sample script 7 | .Description 8 | This is a sample 9 | .Parameter Count 10 | How many numbers do you want? 11 | #> 12 | 13 | Param ([Int]$Count = 1,[String]$Name = "Foo") 14 | 15 | Begin { 16 | Write-Host "this is a sample script that doesn't do anything but write a random number" -ForegroundColor Yellow 17 | Write-Host $Foo -ForegroundColor Green 18 | } 19 | Process { 20 | #get numbers 21 | 1..$count | ForEach-Object { 22 | Get-Random -Minimum 1 -Maximum 1000 23 | } 24 | } 25 | End { 26 | Write-Host "Ending script" -ForegroundColor yellow 27 | } 28 | #eof 29 | -------------------------------------------------------------------------------- /samples/SampleScript3.ps1: -------------------------------------------------------------------------------- 1 | #requires -version 5.0 2 | #requires -RunAsAdministrator 3 | 4 | #this is a sample script 5 | 6 | Param ( 7 | [Parameter(Position = 0, HelpMessage = "How many numbers do you want?")] 8 | [Int]$Count = 1, 9 | [String]$Name, 10 | [Switch]$Demo 11 | ) 12 | 13 | Write-Host "this is a sample script that doesn't do anything but write a random number" -ForegroundColor Yellow 14 | 15 | #get numbers 16 | 1..$count | ForEach-Object { 17 | Get-Random -Minimum 1 -Maximum 1000 18 | } 19 | 20 | Write-Host "Ending script" -ForegroundColor yellow 21 | 22 | #eof 23 | -------------------------------------------------------------------------------- /samples/SampleScript4.ps1: -------------------------------------------------------------------------------- 1 | #requires -version 4.0 2 | #requires -RunAsAdministrator 3 | 4 | #this is a sample script 5 | 6 | Param ( 7 | [Parameter(Position = 0, HelpMessage = "How many numbers do you want?")] 8 | [ValidateRange(1, 100)] 9 | [Int]$Count = 1 10 | ) 11 | DynamicParam { 12 | #this is a sample dynamic parameter 13 | If ($True) { 14 | 15 | $paramDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary 16 | 17 | # Defining parameter attributes 18 | $attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute] 19 | $attributes = New-Object System.Management.Automation.ParameterAttribute 20 | $attributes.ParameterSetName = '__AllParameterSets' 21 | $attributeCollection.Add($attributes) 22 | 23 | # Defining the runtime parameter 24 | $dynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('Demo', [String], $attributeCollection) 25 | $paramDictionary.Add('Demo', $dynParam1) 26 | 27 | return $paramDictionary 28 | } # end if 29 | } #end DynamicParam 30 | 31 | Begin { 32 | Write-Host "this is a sample script that doesn't do anything but write a random number" -ForegroundColor Yellow 33 | } 34 | Process { 35 | #get numbers 36 | 1..$count | ForEach-Object { 37 | Get-Random -Minimum 1 -Maximum 1000 38 | } 39 | } 40 | End { 41 | Write-Host "Ending script" -ForegroundColor yellow 42 | } 43 | #eof 44 | -------------------------------------------------------------------------------- /samples/SampleScript5.ps1: -------------------------------------------------------------------------------- 1 | #requires -version 5.1 2 | #requires -RunAsAdministrator 3 | 4 | #This function can be used for analysis and testing. It 5 | #isn't something that will run without error or make any sense. 6 | #The use of aliases is intentional for testing purposes. 7 | 8 | Function Get-Result { 9 | <# 10 | .Synopsis 11 | Sample function 12 | .Description 13 | This is a sample 14 | .Parameter Count 15 | How many numbers do you want? 16 | #> 17 | [CmdletBinding()] 18 | [alias('grx')] 19 | Param ( 20 | [Parameter(Position=0)] 21 | [ValidateRange(1,100)] 22 | [Int]$Count = 1, 23 | [ValidateNotNullOrEmpty] 24 | [String]$Name = "Foo" 25 | ) 26 | 27 | Begin { 28 | Write-Host "this is a sample script that doesn't do anything but write a random number" -ForegroundColor Yellow 29 | #this is an undefined alias 30 | w -msg "Processing $Name" 31 | $a = [System.DateTime]::Now 32 | Write-Host $a 33 | $os = gcim Win32_OperatingSystem 34 | Write-Verbose "Running in $($PSVersionTable.PSVersion) on $($os.caption)" 35 | $f = Join-Path $([system.environment]::GetEnvironmentVariable("TEMP") "r.txt" 36 | } 37 | Process { 38 | #get numbers 39 | 1..$count | ForEach { 40 | Get-Random -Minimum 1 -Maximum 1000 41 | } | tee -FilePath $f 42 | } 43 | End { 44 | Write-Host "Ending script" -ForegroundColor yellow 45 | $b = [System.DateTime]::now 46 | $c = New-TimeSpan $a $b 47 | Write-Verbose "Runtime: $c" 48 | notepad.exe $f 49 | #run a clean batch file 50 | c:\scripts\cleanup.bat 51 | } 52 | } #close function 53 | -------------------------------------------------------------------------------- /samples/Tools.psm1: -------------------------------------------------------------------------------- 1 |  2 | Function Get-WindowsVersion { 3 | <# 4 | .SYNOPSIS 5 | Get Windows version information 6 | .DESCRIPTION 7 | This is a PowerShell version of the winver.exe utility. This commands uses PowerShell remoting to query the registry on a remote machine to retrieve Windows version information.The parameters are the same as in Invoke-Command. 8 | .PARAMETER Computername 9 | Specifies the computers on which the command runs. The default is the local computer. 10 | 11 | When you use the ComputerName parameter, Windows PowerShell creates a temporary connection that is used only to run the specified command and is then closed. If you need a persistent connection, use the Session parameter. 12 | 13 | Type the NETBIOS name, IP address, or fully qualified domain name of one or more computers in a comma-separated list. To specify the local computer, type the computer name, localhost, or a dot (.). 14 | 15 | To use an IP address in the value of ComputerName , the command must include the Credential parameter. Also, the computer must be configured for HTTPS transport or the IP address of the remote computer must be included in the WinRM TrustedHosts list on the local computer. For instructions for adding a computer name to the TrustedHosts list, see "How to Add a Computer to the Trusted Host List" in about_Remote_Troubleshooting. 16 | 17 | On Windows Vista and later versions of the Windows operating system, to include the local computer in the value of ComputerName , you must open Windows PowerShell by using the Run as administrator option. 18 | .PARAMETER Credential 19 | Specifies a user account that has permission to perform this action. The default is the current user. 20 | 21 | Type a user name, such as User01 or Domain01\User01. Or, enter a PSCredential object, such as one generated by the Get-Credential cmdlet. If you type a user name, this cmdlet prompts you for a password. 22 | .PARAMETER UseSSL 23 | Indicates that this cmdlet uses the Secure Sockets Layer (SSL) protocol to establish a connection to the remote computer. By default, SSL is not used. 24 | 25 | WS-Management encrypts all Windows PowerShell content transmitted over the network. The UseSSL parameter is an additional protection that sends the data across an HTTPS, instead of HTTP. 26 | 27 | If you use this parameter, but SSL is not available on the port that is used for the command, the command fails. 28 | .PARAMETER ThrottleLimit 29 | Specifies the maximum number of concurrent connections that can be established to run this command. If you omit this parameter or enter a value of 0, the default value, 32, is used. 30 | 31 | The throttle limit applies only to the current command, not to the session or to the computer. 32 | .PARAMETER Authentication 33 | Specifies the mechanism that is used to authenticate the user's credentials. The acceptable values for this 34 | parameter are: 35 | 36 | - Default 37 | - Basic 38 | - Credssp 39 | - Digest 40 | - Kerberos 41 | - Negotiate 42 | - NegotiateWithImplicitCredential 43 | 44 | The default value is Default. 45 | 46 | CredSSP authentication is available only in Windows Vista, Windows Server 2008, and later versions of the Windows operating system. 47 | 48 | For information about the values of this parameter, see the description of the AuthenticationMechanismEnumeration (http://go.microsoft.com/fwlink/?LinkID=144382) in theMicrosoft Developer Network (MSDN) library. 49 | 50 | CAUTION: Credential Security Support Provider (CredSSP) authentication, in which the user's credentials are passed to a remote computer to be authenticated, is designed for commands that require authentication on more than one resource, such as accessing a remote network share. This mechanism increases the security risk of the remote operation. If the remote computer is compromised, the credentials that are passed to it can be used to control the 51 | network session. 52 | .EXAMPLE 53 | PS C:\> Get-WindowsVersion 54 | 55 | ProductName : Windows 10 Pro 56 | EditionID : Professional 57 | ReleaseId : 1809 58 | Build : 17763.195 59 | InstalledUTC : 12/17/2018 2:18:37 PM 60 | Computername : BOVINE320 61 | 62 | Query the local host. 63 | .EXAMPLE 64 | PS C:\scripts> get-windowsversion -Computername srv1,srv2,win10 -Credential company\artd | format-table 65 | 66 | 67 | ProductName EditionID ReleaseId Build InstalledUTC Computername 68 | ----------- --------- --------- ----- ------------ ------------ 69 | Windows Server 2016 Standard Evaluation ServerStandardEval 1607 14393.2273 12/26/2018 4:07:25 PM SRV1 70 | Windows Server 2016 Standard Evaluation ServerStandardEval 1607 14393.2273 12/26/2018 4:08:07 PM SRV2 71 | Windows 10 Enterprise Evaluation EnterpriseEval 1703 15063.1387 12/26/2018 4:08:11 PM WIN10 72 | 73 | 74 | Get windows version information from remote computers using an alternate credential. 75 | 76 | .Example 77 | PS C:\> Get-WindowsVersion -Computername win10 -AsString 78 | Windows 10 Enterprise Evaluation Version 1703 (OS Build 15063.1387) 79 | 80 | Get a string 81 | .INPUTS 82 | System.String 83 | .OUTPUTS 84 | Custom object 85 | .NOTES 86 | .LINK 87 | WinVer.exe 88 | .LINK 89 | Invoke-Command 90 | #> 91 | 92 | [cmdletbinding()] 93 | [OutputType("custom object")] 94 | [alias('wver')] 95 | 96 | Param ( 97 | [Parameter( 98 | Position = 0, 99 | ValueFromPipeline, 100 | ValueFromPipelineByPropertyName 101 | )] 102 | [ValidateNotNullOrEmpty()] 103 | [string[]]$Computername = $env:COMPUTERNAME, 104 | [PSCredential]$Credential, 105 | [switch]$UseSSL, 106 | [Int32]$ThrottleLimit, 107 | [ValidateSet('Default', 'Basic', 'Credssp', 'Digest', 'Kerberos', 'Negotiate', 'NegotiateWithImplicitCredential')] 108 | [ValidateNotNullOrEmpty()] 109 | [string]$Authentication = "Default" 110 | ) 111 | 112 | Begin { 113 | Write-Verbose "Starting $($MyInvocation.MyCommand)" 114 | 115 | $sb = { 116 | $RegPath = 'HKLM:\SOFTWARE\Microsoft\Windows nt\CurrentVersion\' 117 | 118 | Get-ItemProperty -Path $RegPath | Select-Object -Property ProductName, EditionID, ReleaseID, 119 | @{Name = "Build"; Expression = { "$($_.CurrentBuild).$($_.UBR)" } }, 120 | @{Name = "InstalledUTC"; Expression = { ([datetime]"1/1/1601").AddTicks($_.InstallTime) } }, 121 | @{Name = "Computername"; Expression = { $env:computername } } 122 | 123 | } #close scriptblock 124 | 125 | #update PSBoundParameters so it can be splatted to Invoke-Command 126 | $PSBoundParameters.Add("ScriptBlock", $sb) | Out-Null 127 | $PSBoundParameters.add("HideComputername", $True) | Out-Null 128 | } #begin 129 | 130 | Process { 131 | if (-Not $PSBoundParameters.ContainsKey("Computername")) { 132 | #add the default value if nothing was specified 133 | $PSBoundParameters.Add("Computername", $Computername) | Out-Null 134 | } 135 | $PSBoundParameters | Out-String | Write-Verbose 136 | $results = Invoke-Command @PSBoundParameters | Select-Object -Property * -ExcludeProperty RunspaceID, PS* 137 | if ($AsString) { 138 | #write a version string for each computer 139 | foreach ($result in $results) { 140 | "{0} Version {1} (OS Build {2})" -f $result.ProductName, $result.releaseID, $result.build 141 | } 142 | } 143 | else { 144 | $results 145 | } 146 | } #process 147 | 148 | End { 149 | Write-Verbose "Ending $($MyInvocation.MyCommand)" 150 | 151 | } #end 152 | } #close function 153 | 154 | 155 | Function Get-WindowsVersionString { 156 | <# 157 | .SYNOPSIS 158 | Get Windows version information 159 | .DESCRIPTION 160 | This is a PowerShell version of the winver.exe utility. This commands uses PowerShell remoting to query the registry on a remote machine to retrieve Windows version information.The parameters are the same as in Invoke-Command. The command writes a string of version information. 161 | .PARAMETER Computername 162 | Specifies the computers on which the command runs. The default is the local computer. 163 | 164 | When you use the ComputerName parameter, Windows PowerShell creates a temporary connection that is used only to run the specified command and is then closed. If you need a persistent connection, use the Session parameter. 165 | 166 | Type the NETBIOS name, IP address, or fully qualified domain name of one or more computers in a comma-separated list. To specify the local computer, type the computer name, localhost, or a dot (.). 167 | 168 | To use an IP address in the value of ComputerName , the command must include the Credential parameter. Also, the computer must be configured for HTTPS transport or the IP address of the remote computer must be included in the WinRM TrustedHosts list on the local computer. For instructions for adding a computer name to the TrustedHosts list, see "How to Add a Computer to the Trusted Host List" in about_Remote_Troubleshooting. 169 | 170 | On Windows Vista and later versions of the Windows operating system, to include the local computer in the value of ComputerName , you must open Windows PowerShell by using the Run as administrator option. 171 | .PARAMETER Credential 172 | Specifies a user account that has permission to perform this action. The default is the current user. 173 | 174 | Type a user name, such as User01 or Domain01\User01. Or, enter a PSCredential object, such as one generated by the Get-Credential cmdlet. If you type a user name, this cmdlet prompts you for a password. 175 | .PARAMETER UseSSL 176 | Indicates that this cmdlet uses the Secure Sockets Layer (SSL) protocol to establish a connection to the remote computer. By default, SSL is not used. 177 | 178 | WS-Management encrypts all Windows PowerShell content transmitted over the network. The UseSSL parameter is an additional protection that sends the data across an HTTPS, instead of HTTP. 179 | 180 | If you use this parameter, but SSL is not available on the port that is used for the command, the command fails. 181 | .PARAMETER ThrottleLimit 182 | Specifies the maximum number of concurrent connections that can be established to run this command. If you omit this parameter or enter a value of 0, the default value, 32, is used. 183 | 184 | The throttle limit applies only to the current command, not to the session or to the computer. 185 | .PARAMETER Authentication 186 | Specifies the mechanism that is used to authenticate the user's credentials. The acceptable values for this 187 | parameter are: 188 | 189 | - Default 190 | - Basic 191 | - Credssp 192 | - Digest 193 | - Kerberos 194 | - Negotiate 195 | - NegotiateWithImplicitCredential 196 | 197 | The default value is Default. 198 | 199 | CredSSP authentication is available only in Windows Vista, Windows Server 2008, and later versions of the Windows operating system. 200 | 201 | For information about the values of this parameter, see the description of the AuthenticationMechanismEnumeration (http://go.microsoft.com/fwlink/?LinkID=144382) in theMicrosoft Developer Network (MSDN) library. 202 | 203 | CAUTION: Credential Security Support Provider (CredSSP) authentication, in which the user's credentials are passed to a remote computer to be authenticated, is designed for commands that require authentication on more than one resource, such as accessing a remote network share. This mechanism increases the security risk of the remote operation. If the remote computer is compromised, the credentials that are passed to it can be used to control the 204 | network session. 205 | .EXAMPLE 206 | PS C:\> Get-WindowsVersionString -Computername win10 -credential company\artd 207 | Windows 10 Enterprise Evaluation Version 1703 (OS Build 15063.1387) 208 | 209 | Get a string version of Windows version information from a remote computer and use an alternate credential. 210 | .EXAMPLE 211 | PS C:\> Get-WindowsVersionString 212 | Windows 10 Pro Version 1809 (OS Build 17763.195) 213 | 214 | Get version information for the current computer. 215 | .EXAMPLE 216 | PS C:\> import-csv .\company.csv | Select Computername,@{Name="Version";Expression={ get-windowsversionstring $_.computername}} 217 | 218 | Computername Version 219 | ------------ ------- 220 | Dom1 Windows Server 2016 Standard Evaluation Version 1607 (OS Build 14393.2273) 221 | Srv1 Windows Server 2016 Standard Evaluation Version 1607 (OS Build 14393.2273) 222 | Srv2 Windows Server 2016 Standard Evaluation Version 1607 (OS Build 14393.2273) 223 | Win10 Windows 10 Enterprise Evaluation Version 1703 (OS Build 15063.1387) 224 | 225 | Import data from a CSV file and display version information. 226 | .INPUTS 227 | System.String 228 | .OUTPUTS 229 | System.String 230 | .NOTES 231 | .LINK 232 | Get-WindowsVersion 233 | .lINK 234 | Winver.exe 235 | 236 | #> 237 | [cmdletbinding()] 238 | [OutputType("system.string")] 239 | 240 | Param ( 241 | [Parameter( 242 | Position = 0, 243 | ValueFromPipeline, 244 | ValueFromPipelineByPropertyName 245 | )] 246 | [ValidateNotNullOrEmpty()] 247 | [string[]]$Computername = $env:COMPUTERNAME, 248 | [PSCredential]$Credential, 249 | [switch]$UseSSL, 250 | [Int32]$ThrottleLimit, 251 | [ValidateSet('Default', 'Basic', 'Credssp', 'Digest', 'Kerberos', 'Negotiate', 'NegotiateWithImplicitCredential')] 252 | [ValidateNotNullOrEmpty()] 253 | [string]$Authentication = "Default" 254 | ) 255 | 256 | Begin { 257 | Write-Verbose "Starting $($MyInvocation.MyCommand)" 258 | } #begin 259 | 260 | Process { 261 | $results = Get-WindowsVersion @PSBoundParameters 262 | 263 | #write a version string for each computer 264 | foreach ($result in $results) { 265 | "{0} Version {1} (OS Build {2})" -f $result.ProductName, $result.releaseID, $result.build 266 | } 267 | } #process 268 | 269 | End { 270 | Write-Verbose "Ending $($MyInvocation.MyCommand)" 271 | } #end 272 | } 273 | function Get-OSInfo { 274 | [CmdletBinding()] 275 | param( 276 | [Parameter(Position = 0, ValueFromPipeline)] 277 | [ValidateNotNullOrEmpty()] 278 | [string[]]$ComputerName = $env:COMPUTERNAME 279 | ) 280 | BEGIN { 281 | Write-Verbose "Starting $($MyInvocation.MyCommand)" 282 | } 283 | PROCESS { 284 | ForEach ($computer in $computername) { 285 | try { 286 | $connected = $True 287 | Write-Verbose "Attempting $computer" 288 | $os = Get-CimInstance -ComputerName $computer -ClassName Win32_OperatingSystem -ErrorAction Stop 289 | } 290 | catch { 291 | $connected = $false 292 | Write-Verbose "Connection to $computer failed. $($_.exception.message)." 293 | } 294 | if ($connected) { 295 | Write-Verbose "Connection to $computer succeeded" 296 | $cs = Get-CimInstance -ComputerName $computer -ClassName Win32_ComputerSystem 297 | $props = @{ 298 | 'ComputerName' = $os.CSName 299 | 'OSVersion' = $os.version 300 | 'Manufacturer' = $cs.manufacturer 301 | 'Model' = $cs.model 302 | } 303 | New-Object -TypeName PSObject -Property $props 304 | } 305 | } 306 | } 307 | END { 308 | Write-Verbose "Ending $($MyInvocation.MyCommand)" 309 | } 310 | } 311 | -------------------------------------------------------------------------------- /samples/samplefunction.ps1: -------------------------------------------------------------------------------- 1 | #requires -version 4.0 2 | #requires -RunAsAdministrator 3 | 4 | #this is a sample script 5 | 6 | Param ( 7 | [Parameter(Position = 0, HelpMessage = "How many numbers do you want?")] 8 | [ValidateRange(1, 100)] 9 | [Int]$Count = 1 10 | ) 11 | DynamicParam { 12 | #this is a sample dynamic parameter 13 | If ($True) { 14 | 15 | $paramDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary 16 | 17 | # Defining parameter attributes 18 | $attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute] 19 | $attributes = New-Object System.Management.Automation.ParameterAttribute 20 | $attributes.ParameterSetName = '__AllParameterSets' 21 | $attributeCollection.Add($attributes) 22 | 23 | # Defining the runtime parameter 24 | $dynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('Demo', [String], $attributeCollection) 25 | $paramDictionary.Add('Demo', $dynParam1) 26 | 27 | return $paramDictionary 28 | } # end if 29 | } #end DynamicParam 30 | 31 | Begin { 32 | Write-Host "this is a sample script that doesn't do anything but write a random number" -ForegroundColor Yellow 33 | } 34 | Process { 35 | #get numbers 36 | 1..$count | ForEach-Object { 37 | Get-Random -Minimum 1 -Maximum 1000 38 | } 39 | } 40 | End { 41 | Write-Host "Ending script" -ForegroundColor yellow 42 | } 43 | #eof 44 | -------------------------------------------------------------------------------- /tests/runtests.ps1: -------------------------------------------------------------------------------- 1 | #requires -module @{ModuleName = 'Pester';ModuleVersion='5.2'} 2 | 3 | $config = New-PesterConfiguration 4 | $config.Run.Path = $PSScriptRoot 5 | #$config.Run.SkipRun = $true 6 | #$config.run.PassThru = $True 7 | $config.Output.Verbosity = "Detailed" 8 | 9 | Invoke-Pester -Configuration $config -WarningAction SilentlyContinue --------------------------------------------------------------------------------