Skip to content

Instantly share code, notes, and snippets.

@jdhitsolutions
Last active March 10, 2022 02:42
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jdhitsolutions/6d26c983a13efae93363e0f9a9e2996b to your computer and use it in GitHub Desktop.
Save jdhitsolutions/6d26c983a13efae93363e0f9a9e2996b to your computer and use it in GitHub Desktop.
My module generation code from my Chicago PowerShell presentation on July 31, 2020.
#requires -version 5.1
#requires -module PowerShellGet
<#
The function assumes you have git installed and use it for source control
This code contains hard-coded references for my environment. This file
is offered as educational and reference material. It will not run for you
without revision.
#>
Function New-ModuleBase {
[cmdletbinding(SupportsShouldProcess)]
Param(
[Parameter(Mandatory, Position = 0)]
[ValidateNotNullorEmpty()]
[string]$ModuleName,
[Parameter(Mandatory)]
[ValidateNotNullorEmpty()]
[string]$Description,
[Parameter(HelpMessage = "Enter a list of function names you plan to write")]
[string[]]$Functions,
[ValidateSet("Desktop", "Core")]
[string[]]$Compatible = @("Desktop", "Core"),
[alias("gh")]
[switch]$GitHub
)
Write-Verbose "Provisioning a new module called $ModuleName"
$Base = "C:\Scripts"
$Path = Join-Path -Path $Base -ChildPath $ModuleName
if (Test-Path -Path $path) {
Write-Warning "A module already exists at $Path"
}
else {
New-Item -Path $base -Name $ModuleName -ItemType Directory
Write-Verbose "Creating folder structure"
"docs", "en-us", "images", "tests", ".vscode", "functions", "formats" |
ForEach-Object {
New-Item -Path $path -Name $_ -ItemType Directory
}
Write-Verbose "Creating README.md"
$readme = @"
# $ModuleName
$Description
This module is under development.
Last updated $(Get-Date -format u)
"@
Set-Content -Value $readme -Path (Join-Path -Path $path -ChildPath "README.md")
Write-Verbose "Copy my .vscode files"
#you might have a standard settings.json or dictionary files
Copy-Item -Path C:\scripts\tasks.json -Destination (Join-Path -path $Path -childpath .vscode) -PassThru
Copy-Item -Path C:\scripts\.markdownlint.json -Destination (Join-Path -path $Path -childpath .vscode) -PassThru
Write-Verbose "Creating license"
#update your licensing info
$lic = @"
MIT License
Copyright (c) $((Get-Date).Year) JDH Information Technology Solutions, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"@
Set-Content -Value $lic -Path (Join-Path -Path $path -ChildPath "license.txt")
Write-Verbose "Creating module files"
#you can also set defaults using $PSDefaultParameterValues
$psd1 = @{
Path = "$path\$modulename.psd1"
Author = "Jeff Hicks"
CompanyName = "JDH Information Technology Solutions, Inc."
CompatiblePSEditions = $Compatible
Copyright = "2020 JDH Information Technology Solutions, Inc."
Description = $description
FunctionsToExport = $functions
RootModule = "$modulename.psm1"
ModuleVersion = "0.0.1"
PowerShellVersion = "5.1"
}
New-ModuleManifest @psd1
$psm1 = @"
#enable verbose messaging in the psm1 file
if (`$myinvocation.line -match "-verbose") {
`$VerbosePreference = "continue"
}
Write-Verbose "Loading public functions"
#dot source functions
Get-ChildItem .\functions\*.ps1 |
ForEach-Object {
Write-Verbose `$_.fullname
. `$_.fullname
}
"@
Set-Content -Value $psm1 -Path (Join-Path -Path $path -ChildPath "$modulename.psm1")
if ($Functions) {
$txt = @"
# functions for $modulename
"@
foreach ($f in $Functions) {
$txt += @"
#region $F
Function $f {
[cmdletbinding()]
Param()
Begin {
Write-Verbose "[BEGIN ] Starting `$(`$myinvocation.mycommand)"
}
Process {
Write-Verbose "[PROCESS] Processing"
}
End {
Write-Verbose "[END ] Ending `$(`$myinvocation.mycommand)"
}
}
#endregion
"@
}
Set-Content -Value $txt -Path "$path\functions\functions.ps1"
}
Write-Verbose "Creating changelog.md"
$change = @"
# Changelog for $ModuleName
## v$($psd1.moduleVersion)
+ initial file commit
"@
Set-Content -Value $change -Path (Join-Path -Path $path -ChildPath "changelog.md")
Write-Verbose "Inititalizing git"
#my git configuration is already configured with global settings and excludes
if ($pscmdlet.ShouldProcess($path, "Initialize git")) {
git init $Path
Set-Location $Path
git add .
git commit -m "Initial git commit"
}
if ($GitHub) {
Write-Verbose "Creating private GitHub repo"
#my gittoken is stored in a CMS Mesage
$token = Unprotect-CmsMessage -path C:\scripts\gittoken.txt
#parameters for my New-GitHubRepository function
$new = @{
Name = $ModuleName
Description = $Description
Private = $True
NoWiki = $True
UserToken = $token
}
$repo = New-GitHubRepository @new
Write-Verbose "Updating the module manifest"
$up = @{
Path = "$path\$modulename.psd1"
ProjectURI = $repo.URL
LicenseURI = "$($repo.URL)/blob/master/license.txt"
}
Update-ModuleManifest @up
git add .
git commit -m "manifest update"
if ($pscmdlet.ShouldProcess($repo.url, "Adding remote repo")) {
git remote add origin $repo.clone
git push -u origin master
}
}
#open the project in VSCode
# code $path
} #else path is ok
}
Function New-GitHubRepository {
<#
.Synopsis
Create a GitHub repository
.Description
This command will create a GitHub repository online. The command assumes you have a Github account.
#>
[cmdletbinding(SupportsShouldProcess)]
Param(
[Parameter(Position = 0, Mandatory, HelpMessage = "Enter the new repository name")]
[ValidateNotNullorEmpty()]
# The name for the new repository.
[string]$Name,
# Add a repository description
[string]$Description,
#Make the repository private
[switch]$Private,
#Turn off the repository Wiki
[switch]$NoWiki,
#Turn off Issues
[switch]$NoIssues,
#Disallow downloads
[switch]$NoDownloads,
#auto setup with a README file
[switch]$AutoInitialize,
#license templates found at https://github.com/github/choosealicense.com/tree/gh-pages/_licenses
[ValidateSet("MIT", "apache-2.0", "gpl-3.0", "ms-pl", "unlicense")]
#specify what type of license to use
[string]$LicenseTemplate,
[Alias("token")]
[ValidateNotNullorEmpty()]
#Specify your user token
[string]$UserToken = $gitToken,
#write full native response to the pipeline
[switch]$Raw
)
Write-Verbose "[BEGIN ] Starting: $($MyInvocation.Mycommand)"
#display PSBoundparameters formatted nicely for Verbose output
[string]$pb = ($PSBoundParameters | Format-Table -AutoSize | Out-String).TrimEnd()
Write-Verbose "[BEGIN ] PSBoundparameters: `n$($pb.split("`n").Foreach({"$("`t"*2)$_"}) | Out-String) `n"
#create the header
$head = @{
Accept = 'application/vnd.github.v3+json'
Authorization = "token $UserToken"
}
#create a hashtable from properties
$hash = @{
name = $Name
description = $Description
private = $Private -as [boolean]
has_wiki = (-Not $NoWiki)
has_issues = (-Not $NoIssues)
has_downloads = (-Not $NoDownloads)
auto_init = $AutoInitialize -as [boolean]
}
if ($LicenseTemplate) {
$hash.add("license_template", $LicenseTemplate)
}
$body = $hash | ConvertTo-Json
Write-Verbose "[PROCESS] Sending json"
Write-Verbose $body
#define parameter hashtable for Invoke-RestMethod
$paramHash = @{
Uri = "https://api.github.com/user/repos"
Method = "Post"
body = $body
ContentType = "application/json"
Headers = $head
UseBasicParsing = $True
DisableKeepAlive = $True
}
#should process
if ($PSCmdlet.ShouldProcess("$name [$description]")) {
$r = Invoke-RestMethod @paramHash
if ($r.id -AND $Raw) {
Write-Verbose "[PROCESS] Raw result"
$r
}
elseif ($r.id) {
Write-Verbose "[PROCESS] Formatted results"
$r | Select-Object @{Name = "Name"; Expression = { $_.name } },
@{Name = "Description"; Expression = { $_.description } },
@{Name = "Private"; Expression = { $_.private } },
@{Name = "Issues"; Expression = { $_.has_issues } },
@{Name = "Wiki"; Expression = { $_.has_wiki } },
@{Name = "URL"; Expression = { $_.html_url } },
@{Name = "Clone"; Expression = { $_.clone_url } }
}
else {
Write-Warning "Something went wrong with this process"
}
if ($r.clone_url) {
$msg = @"
To push an existing local repository to Github run these commands:
-> git remote add origin $($r.clone_url)"
-> git push -u origin master
"@
Write-Host $msg -ForegroundColor Green
}
}
Write-Verbose "[END ] Ending: $($MyInvocation.Mycommand)"
}
@jdhitsolutions
Copy link
Author

Slide1
Slide2
Slide3
Slide4
Slide5
Slide6
Slide7
Slide8
Slide9
Slide10
Slide11
Slide12

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment