PS: Moving To Modules Pt. 2
Description:
This is a continuation post of Moving to Modules I posted earlier. Main thing, I just wanted to go over design in this post. Here is a typical module:
A good way to see this is to download one of my Modules off Github. From here you can see the folder structure and how I use the modules in a portable fashion (explained below).
To Resolve:
-
So the modules can be named whatever you want. The first thing you do is create a guid for your template so it can be unique in case you ever post it online. You can use online sites like GUID Generator or just Powershell:
$GUID = [guid]::NewGuid().ToString() |Clip.exe
-
Next you can create and edit your template.psd1 file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
<#######<ModuleManifest>#######> <#######<Header>#######> # Name: Module Manifest # Date: 2017-03-27 # Copyright: Gerry Williams # License: MIT License (https://opensource.org/licenses/MIT) <#######</Header>#######> <#######<Body>#######> @{ # Script module or binary module file associated with this manifest. RootModule = 'Template.psm1' # Version number of this module. ModuleVersion = '1.0' # ID used to uniquely identify this module GUID = '70802a57-92de-4ebb-bf2f-45bd3a819159' # Author of this module Author = 'Gerry.Williams' # Company or vendor of this module #CompanyName = 'Unknown' # Copyright statement for this module Copyright = '(c) 2017 Gerry Williams. All rights reserved.' # Description of the functionality provided by this module Description = 'Template module with Powershell functions' # Minimum version of the Windows PowerShell engine required by this module PowerShellVersion = '3.0' # Name of the Windows PowerShell host required by this module # PowerShellHostName = '' # Minimum version of the Windows PowerShell host required by this module # PowerShellHostVersion = '' # Minimum version of Microsoft .NET Framework required by this module # DotNetFrameworkVersion = '' # Minimum version of the common language runtime (CLR) required by this module # CLRVersion = '' # Processor architecture (None, X86, Amd64) required by this module # ProcessorArchitecture = '' # Modules that must be imported into the global environment prior to importing this module # RequiredModules = @() # Assemblies that must be loaded prior to importing this module # RequiredAssemblies = @() # Script files (.ps1) that are run in the caller's environment prior to importing this module. # ScriptsToProcess = @() # Type files (.ps1xml) to be loaded when importing this module # TypesToProcess = @() # Format files (.ps1xml) to be loaded when importing this module # FormatsToProcess = '' # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess # NestedModules = @() # Functions to export from this module FunctionsToExport = '*' # Cmdlets to export from this module CmdletsToExport = '*' # Variables to export from this module VariablesToExport = '*' # Aliases to export from this module AliasesToExport = '*' # DSC resources to export from this module # DscResourcesToExport = @() # List of all modules packaged with this module # ModuleList = @() # List of all files packaged with this module # FileList = @() # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. PrivateData = @{ PSData = @{ # Tags applied to this module. These help with module discovery in online galleries. # Tags = @() # A URL to the license for this module. # LicenseUri = '' # A URL to the main website for this project. # ProjectUri = '' # A URL to an icon representing this module. # IconUri = '' # ReleaseNotes of this module # ReleaseNotes = '' } # End of PSData hashtable } # End of PrivateData hashtable # HelpInfo URI of this module # HelpInfoURI = '' # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. # DefaultCommandPrefix = '' } <#######</Body>#######> <#######</ModuleManifest>#######>
-
Next you want to create and edit your template.psm1 file. The good thing about this is that it is the same for any module you create:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
<#######<Module>#######> <#######<Header>#######> # Name: Module # Date: 2018-03-18 # Copyright: Gerry Williams # License: MIT License (https://opensource.org/licenses/MIT) <#######</Header>#######> <#######<Body>#######> $files = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -Recurse -ErrorAction SilentlyContinue) $files | ForEach-Object ` { . $_.fullname } Export-ModuleMember -Function * <#######</Body>#######> <#######</Module>#######>
- Now you create your folders:
- Private => This is where private functions go, this is where my helpers.psm1 file lives with helper functions. These will not be exported by the module.
- Public => This is where all your .ps1 scripts go. If you do like me, you will make them all advanced functions and the way users will use them is:
- They will import your module and then just call the function that way => preferred.
- For one offs, they can navigate to your Public folder in powershell or Windows Explorer and dot source your script and then call the function from within it.
-
Lastly, in the Public folder, you create functions that use a setup like in my current Template script
-
2018-09-22: Just wanted to add that setting them up this way allows me to pull from Github pretty easily:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
# Launching scripts from Github Write-Output "Launching template script" [Net.ServicePointManager]::SecurityProtocol = "Tls12, Tls11, Tls, Ssl3" $Path = "$Env:UserProfile\Downloads" + "\Temp" New-Item -ItemType Directory -Path $Path -Force | Out-Null $PrivatePath = $Path + "\Private" New-Item -ItemType Directory -Path $PrivatePath -Force | Out-Null $Download = "$Path\Private\helpers.psm1" $URI = "https://github.com/gerryw1389/powershell/blob/main/gwConfiguration/Private/helpers.psm1" $Response = Invoke-RestMethod -Method Get -Uri $URI $Response | Out-File $Download -Encoding ASCII $PublicPath = $Path + "\Public" New-Item -ItemType Directory -Path $PublicPath -Force | Out-Null $Download = "$Path\Public\set-template.ps1" $URI = "https://raw.githubusercontent.com/gerryw1389/powershell/main/gwConfiguration/Public/Set-Template.ps1" $Response = Invoke-RestMethod -Method Get -Uri $URI $Response | Out-File $Download -Encoding ASCII $Batch = $PublicPath + "\set-template.bat" $String = @' @ECHO OFF PowerShell.exe -NoProfile ^ -Command "& {Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -Command ". "%~dpn0.ps1"; Set-Template "' -Verb RunAs}" '@ Write-Output $String | Out-File -LiteralPath $Batch -Encoding ASCII Start-Process $Batch -Verb Runas cmd /c "pause"
Comments