Skip to content

Instantly share code, notes, and snippets.

@mhudasch
Created August 31, 2016 15:50
Show Gist options
  • Save mhudasch/ffdc32ff8056d3d6bcff5b3f74af094b to your computer and use it in GitHub Desktop.
Save mhudasch/ffdc32ff8056d3d6bcff5b3f74af094b to your computer and use it in GitHub Desktop.
The New-PSModule command creates a convention based folder structure to develop a new powershell module. In addition the command automatically creates a module manifest file (.psd1).
<#
.SYNOPSIS
The New-PSModule command creates a convention based folder structure to develop a new powershell module. In addition the command automatically creates a module manifest file (.psd1).
.DESCRIPTION
The New-PSModule command creates a convention based folder structure to develop a new powershell module. The folder structure contains a folder for exported functions (public) and a folder for internal functions (private). Furthermore the structure contains a folder for test-scripts (Tests) and a folder with handy scripts to analyze and publish the created module.
In addition the command automatically creates a module manifest file (.psd1). The manifest file will be filled with the given parameters. The parameters of this command do only cover the bare minimum requirements of the manifest file. The file must be changed to complete all metadata.
.PARAMETER ModuleName
The name of the module (without any file extension).
.PARAMETER Description
The description of the new module.
.PARAMETER Author
The author of the new module. This parameter defaults to the current username ($env:USERNAME).
.PARAMETER Version
The version of the new module. The parameter defaults to '0.0.1'.
.PARAMETER PowerShellVersion
The required powershell version for the module. Possible values are: "1.0","2.0","3.0","4.0","5.0","6.0".
#>
Function New-PSModule {
[CmdletBinding(SupportsShouldProcess=$true)]
param (
[Parameter(Mandatory=$true,Position=0)]
[string]$ModuleName,
[Parameter(Mandatory=$true,Position=1)]
[string]$Description,
[Parameter(Mandatory=$false,Position=2)]
[string]$Author = $env:USERNAME,
[Parameter(Mandatory=$false,Position=3)]
[string]$Version = "0.0.1",
[Parameter(Mandatory=$false,Position=4)]
[ValidateSet("1.0","2.0","3.0","4.0","5.0","6.0")]
[string]$PowerShellVersion = "5.0")
Process {
$Path = Get-Location;
# Create the module and private function directories
if($PSCmdlet.ShouldProcess("$Path\$ModuleName", "Create directory.")) {
mkdir "$Path\$ModuleName" | Write-Verbose;
}
if($PSCmdlet.ShouldProcess("$Path\$ModuleName\Private", "Create directory.")) {
mkdir "$Path\$ModuleName\Private" | Write-Verbose;
}
if($PSCmdlet.ShouldProcess("$Path\$ModuleName\Public", "Create directory.")) {
mkdir "$Path\$ModuleName\Public" | Write-Verbose;
}
if($PSCmdlet.ShouldProcess("$Path\$ModuleName\en-US", "Create directory.")) {
mkdir "$Path\$ModuleName\en-US" | Write-Verbose; # For about_Help files
}
if($PSCmdlet.ShouldProcess("$Path\$ModuleName\en-US\about_$ModuleName.help.txt", "Create file.")) {
New-Item "$Path\$ModuleName\en-US\about_$ModuleName.help.txt" -ItemType File | Write-Verbose;
}
if($PSCmdlet.ShouldProcess("$Path\$ModuleName\Tests", "Create directory.")) {
mkdir "$Path\$ModuleName\Tests" | Write-Verbose;
}
if($PSCmdlet.ShouldProcess("$Path\$ModuleName\Tests\$ModuleName.Tests.ps1", "Create file.")) {
New-Item "$Path\$ModuleName\Tests\$ModuleName.Tests.ps1" -ItemType File | Write-Verbose;
}
if($PSCmdlet.ShouldProcess("$Path\$ModuleName\Publish", "Create directory.")) {
mkdir "$Path\$ModuleName\Publish" | Write-Verbose;
}
if($PSCmdlet.ShouldProcess("$Path\$ModuleName\Publish\$ModuleName.Analyze.ps1", "Create and fill analyzer script file.")) {
#Analyze script
New-Item "$Path\$ModuleName\Publish\$ModuleName.Analyze.ps1" -ItemType File | Write-Verbose;
Set-Content -Encoding UTF8 -Path "$Path\$ModuleName\Publish\$ModuleName.Analyze.ps1" -Value "#requires -version 5`r`n`r`n`# We install and run PSScriptAnalyzer against the module to make sure it's not failing any tests.`r`n# Install-Module PSScriptAnalyzer -Force -Repository public-powershell; `r`nGet-ChildItem -Recurse -Path `$PSScriptRoot\.. -Include '*.ps1','*.psm1' -Exclude '*.Tests.ps1','*.Analyze.ps1','*.Publish.ps1' | Invoke-ScriptAnalyzer;";
}
if($PSCmdlet.ShouldProcess("$Path\$ModuleName\publish\$ModuleName.Publish.ps1", "Create and fill publish script file.")) {
#Publish script
New-Item "$Path\$ModuleName\publish\$ModuleName.Publish.ps1" -ItemType File | Write-Verbose;
Set-Content -Encoding UTF8 -Path "$Path\$ModuleName\publish\$ModuleName.Publish.ps1" -Value "#requires -version 5`r`n`r`n`# Set the path to the module root.r`n`$Path = `"`$PSScriptRoot\..\`";`r`n`r`n`#Only publish when no analyzer warnings`r`n`$analysis = `$(. `"`$PSScriptRoot\$ModuleName.Analyze.ps1`");`r`nIf(`$null -eq `$analysis) {`r`n Publish-Module -Path `$Path -NugetApiKey '$($PublishSettings.ApiKey)' -Repository '$($PublishSettings.Repository)';`r`n Find-Module $ModuleName;`r`n} else { `$analysis; }";
}
$PublishSettings = @{
ApiKey="Admin:Admin";
Name=$ModuleName;
Repository="private-powershell";
};
#Create the module and related files
if($PSCmdlet.ShouldProcess("$Path\$ModuleName\$ModuleName.psm1", "Create and fill root module file.")) {
New-Item "$Path\$ModuleName\$ModuleName.psm1" -ItemType File | Write-Verbose;
Set-Content -Encoding UTF8 -Path "$Path\$ModuleName\$ModuleName.psm1" -Value "#Get public and private function definition files.`r`n`r`n`$public = @( Get-ChildItem -Path `$PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue );`r`n`$private = @( Get-ChildItem -Path `$PSScriptRoot\Private\*.ps1 -ErrorAction SilentlyContinue );`r`n`r`n#Dot source the files`r`nForeach(`$import in @( `$public + `$private )) {`r`n Try {`r`n (. `$import.Fullname);`r`n } Catch {`r`n Write-Error `"Failed to import function `$(`$import.Fullname): `$_`";`r`n }`r`n} `r`n";
}
if($PSCmdlet.ShouldProcess("$Path\$ModuleName\$ModuleName.Format.ps1xml", "Create file.")) {
New-Item "$Path\$ModuleName\$ModuleName.Format.ps1xml" -ItemType File | Write-Verbose;
}
New-ModuleManifest -Path $Path\$ModuleName\$ModuleName.psd1 `
-RootModule "$ModuleName.psm1" `
-Description $Description `
-PowerShellVersion $PowerShellVersion `
-Author $Author `
-FormatsToProcess "$ModuleName.Format.ps1xml" `
-CompanyName $env:Company `
-Copyright $env:Copyright `
-ModuleVersion $Version `
-ClrVersion "4.0" `
-DotNetFrameworkVersion "4.5";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment