├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── TemplatePowerShellModule ├── .DS_Store ├── Class │ ├── TemplatePowerShellModule.BaseExample.Class1.psm1 │ ├── TemplatePowerShellModule.Enum1.ps1 │ ├── TemplatePowerShellModule.Overloaded.Class1.psm1 │ └── TemplatePowerShellModule.SingleInstance.Class1.psm1 ├── ModuleName.psd1 ├── ModuleName.psm1 ├── Private │ ├── .gitkeep │ ├── Import-FunctionName3.ps1 │ └── Import-FunctionName4.ps1 └── Public │ ├── Get-FunctionName2.ps1 │ └── New-FunctionName1.ps1 ├── Tests └── TemplatePowerShellModule.Tests.ps1 ├── appveyor.yml ├── build.ps1 ├── docs.ps1 └── install.ps1 /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). 6 | 7 | ## [Unreleased] 8 | 9 | ### Added 10 | 11 | - Documentation scaffolding. -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 First Last 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TemplatePowerShellModule 2 | 3 | [![Build status](https://ci.appveyor.com/api/projects/status/7yb9er834qod0xvw?svg=true)](https://ci.appveyor.com/project/Name/templatepowershellmodule) 4 | 5 | ## TemplatePowerShellModule Title 6 | 7 | {Super High level description} 8 | 9 | ## Synopsis 10 | 11 | A PowerShell Module to 12 | 13 | ## Description 14 | 15 | A PowerShell Module to 16 | 17 | ## Using TemplatePowerShellModule 18 | 19 | To use this module, you will first need to download/clone the repository and import the module: 20 | 21 | ```powershell 22 | Import-Module .\TemplatePowerShellModule.psm1 23 | ``` 24 | 25 | ### How to use 26 | 27 | Explain how to use this module 28 | 29 | ```powershell 30 | New-FunctionName -Parameter1 'C:\Packages' -Parameter2 'C:\NewPackages' 31 | ``` 32 | 33 | ### Using function 2 in TemplatePowerShellModule 34 | 35 | Description on using function 1 in TemplatePowerShellModule 36 | 37 | ```powershell 38 | Get-Function2 -Parameter1 'SomePackageName' -Parameter2 'C:\some\path_to_folder_containing_packages' 39 | ``` 40 | 41 | ## Notes 42 | 43 | ```yaml 44 | Name: TemplatePowerShellModule 45 | Created by: First Last 46 | Created Date: DATE 47 | ``` -------------------------------------------------------------------------------- /TemplatePowerShellModule/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MSAdministrator/TemplatePowerShellModule/8e5510fc2f172c59f06fa91d4c4a754fd521ed0a/TemplatePowerShellModule/.DS_Store -------------------------------------------------------------------------------- /TemplatePowerShellModule/Class/TemplatePowerShellModule.BaseExample.Class1.psm1: -------------------------------------------------------------------------------- 1 | # Base PowerShell 5 Class 2 | 3 | class Class1 { 4 | # Public Properties are exposed and can be {get; set;} 5 | # Public poperties are Instance type properties 6 | [String] $StringProperty 7 | [Int32] $IntegerPropery 8 | 9 | # Static Properties are Class type properties 10 | # Static properties are the same across all instances of the Class 11 | static [String] $StaticProperty = "This is a static property of the class" 12 | 13 | # Hidden Properties are typically hidden 14 | # but can be exposed in PowerShell Classes 15 | hidden [String] $HiddenProperty 16 | 17 | Class1() { 18 | # Empty Class1 Constructor 19 | } 20 | 21 | # Overloaded Constructor 22 | Class1 ([String] $SomeString, [int32] $SomeInteger) { 23 | # $this is used to access or modify the current instance of the Class1 class 24 | $this.StringProperty = $SomeString 25 | $this.IntegerPropery = $SomeInteger 26 | } 27 | 28 | # Overloaded Constructor 29 | Class1([String] $SomeString) { 30 | # Set StringProperty for CLass1 to the passed in $SomeString value 31 | $this.StringProperty = $SomeString 32 | } 33 | 34 | # Instance Method 35 | # An Instance Method will be created for every instance of the Class 36 | [String] getStringProperty() { 37 | return $this.StringProperty 38 | } 39 | 40 | # Static Method 41 | # A static method will be used across all instance of the Class 42 | static [String] getClan() { 43 | return [Class1]::StaticProperty 44 | } 45 | 46 | # VOID Method: Method that changes $Name to the default name 47 | # A VOID method will not return any information 48 | [void] IncreaseIntegerPropertyByOne() { 49 | $this.IntegerPropery += 1 50 | } 51 | } -------------------------------------------------------------------------------- /TemplatePowerShellModule/Class/TemplatePowerShellModule.Enum1.ps1: -------------------------------------------------------------------------------- 1 | # enums are a list of acceptable keys/values to use 2 | 3 | enum EnumExample1 { 4 | Error 5 | Warning 6 | Information 7 | SuccessAudit 8 | FailureAudit 9 | } 10 | 11 | # enums can also have their own static value (key=value pair) 12 | enum EnumExample2 { 13 | Error = 1001 14 | Warning = 1002 15 | Information = 1003 16 | SuccessAudit = 1004 17 | FailureAudit = 1005 18 | } -------------------------------------------------------------------------------- /TemplatePowerShellModule/Class/TemplatePowerShellModule.Overloaded.Class1.psm1: -------------------------------------------------------------------------------- 1 | # Class1 is the parent class 2 | class Class1 { 3 | [string] $Message = "Hello!" 4 | 5 | [string] GetMessage() { 6 | return ("Message: {0}" -f $this.Message) 7 | } 8 | } 9 | 10 | # Class2 extends Class1 and inherits its members 11 | class Class2 : Class1 { 12 | 13 | } 14 | 15 | # Class3 extends Class1 and uses the base (Class1) Constructor 16 | class Class3 : Class1 { 17 | Class3() : base() { 18 | # Since Class3 is extending Class1, it inherits all its members 19 | # Specificying the : base() at the end of the Class3 constructor will 20 | # automatically inherit the Class1 constructor 21 | } 22 | } -------------------------------------------------------------------------------- /TemplatePowerShellModule/Class/TemplatePowerShellModule.SingleInstance.Class1.psm1: -------------------------------------------------------------------------------- 1 | class Class1 { 2 | # Single Instance Property 3 | [string] $SingleInstanceName 4 | 5 | # Static property that does not change between instances 6 | # And used to check if an instance is already created 7 | static [Class1] $StaticInstance 8 | 9 | # Static method to get the instance 10 | static [Class1] GetInstance() { 11 | # if our StaticInstance variable is still set to $null 12 | # then we create a new instance 13 | if ($null -eq [Class1]::StaticInstance) { 14 | [Class1]::StaticInstance = [Class1]::new() 15 | } 16 | # if the instance already exists or not, we return it 17 | return [Class1]::StaticInstance 18 | } 19 | } -------------------------------------------------------------------------------- /TemplatePowerShellModule/ModuleName.psd1: -------------------------------------------------------------------------------- 1 | $TemplatePowerShellModule = 'ModuleName' 2 | $Name = 'First Last' 3 | 4 | # Module manifest for module 'ModuleName' 5 | # 6 | # Generated by: $Name 7 | # 8 | # Generated on: DATE 9 | # 10 | 11 | @{ 12 | 13 | # Script module or binary module file associated with this manifest. 14 | RootModule = "$TemplatePowerShellModule.psm1" 15 | 16 | # Version number of this module. 17 | ModuleVersion = '1.0.0.0' 18 | 19 | # Supported PSEditions 20 | # CompatiblePSEditions = @() 21 | 22 | # ID used to uniquely identify this module 23 | GUID = 'GUID' 24 | 25 | # Author of this module 26 | Author = $Name 27 | 28 | # Company or vendor of this module 29 | CompanyName = '' 30 | 31 | # Copyright statement for this module 32 | Copyright = "(c) 2018 $Name. All rights reserved." 33 | 34 | # Description of the functionality provided by this module 35 | Description = "$TemplatePowerShellModule Description" 36 | 37 | # Minimum version of the Windows PowerShell engine required by this module 38 | # PowerShellVersion = '' 39 | 40 | # Name of the Windows PowerShell host required by this module 41 | # PowerShellHostName = '' 42 | 43 | # Minimum version of the Windows PowerShell host required by this module 44 | # PowerShellHostVersion = '' 45 | 46 | # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 47 | # DotNetFrameworkVersion = '' 48 | 49 | # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 50 | # CLRVersion = '' 51 | 52 | # Processor architecture (None, X86, Amd64) required by this module 53 | # ProcessorArchitecture = '' 54 | 55 | # Modules that must be imported into the global environment prior to importing this module 56 | # RequiredModules = @() 57 | 58 | # Assemblies that must be loaded prior to importing this module 59 | # RequiredAssemblies = @() 60 | 61 | # Script files (.ps1) that are run in the caller's environment prior to importing this module. 62 | # ScriptsToProcess = @() 63 | 64 | # Type files (.ps1xml) to be loaded when importing this module 65 | # TypesToProcess = @() 66 | 67 | # Format files (.ps1xml) to be loaded when importing this module 68 | # FormatsToProcess = @() 69 | 70 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess 71 | # NestedModules = @() 72 | 73 | # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. 74 | FunctionsToExport = @() 75 | 76 | # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. 77 | CmdletsToExport = @() 78 | 79 | # Variables to export from this module 80 | VariablesToExport = '*' 81 | 82 | # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. 83 | AliasesToExport = @() 84 | 85 | # DSC resources to export from this module 86 | # DscResourcesToExport = @() 87 | 88 | # List of all modules packaged with this module 89 | # ModuleList = @() 90 | 91 | # List of all files packaged with this module 92 | # FileList = @() 93 | 94 | # 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. 95 | PrivateData = @{ 96 | 97 | PSData = @{ 98 | 99 | # Tags applied to this module. These help with module discovery in online galleries. 100 | Tags = @('', '') 101 | 102 | # A URL to the license for this module. 103 | LicenseUri = "https://github.com/$Name/$TemplatePowerShellModule/blob/master/LICENSE" 104 | 105 | # A URL to the main website for this project. 106 | ProjectUri = "https://github.com/$Name/$TemplatePowerShellModule" 107 | 108 | # A URL to an icon representing this module.a 109 | # IconUri = '' 110 | 111 | # ReleaseNotes of this module 112 | # ReleaseNotes = '' 113 | 114 | } # End of PSData hashtable 115 | 116 | } # End of PrivateData hashtable 117 | 118 | # HelpInfo URI of this module 119 | # HelpInfoURI = '' 120 | 121 | # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. 122 | # DefaultCommandPrefix = '' 123 | 124 | } 125 | 126 | -------------------------------------------------------------------------------- /TemplatePowerShellModule/ModuleName.psm1: -------------------------------------------------------------------------------- 1 | # using module .\TemplatePowerShellModule\Class\TemplatePowerShellModule.Class1.psm1 2 | # Above needs to remain the first line to import Classes 3 | # remove the comment when using classes 4 | 5 | #requires -Version 2 6 | #Get public and private function definition files. 7 | $Public = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -Recurse -ErrorAction SilentlyContinue ) 8 | $Private = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -Recurse -ErrorAction SilentlyContinue ) 9 | 10 | #Dot source the files 11 | Foreach ($import in @($Public + $Private)) { 12 | Try { 13 | . $import.fullname 14 | } 15 | Catch { 16 | Write-Error -Message "Failed to import function $($import.fullname): $_" 17 | } 18 | } 19 | 20 | Export-ModuleMember -Function $Public.Basename -------------------------------------------------------------------------------- /TemplatePowerShellModule/Private/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MSAdministrator/TemplatePowerShellModule/8e5510fc2f172c59f06fa91d4c4a754fd521ed0a/TemplatePowerShellModule/Private/.gitkeep -------------------------------------------------------------------------------- /TemplatePowerShellModule/Private/Import-FunctionName3.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Import FunctionName3 4 | .DESCRIPTION 5 | FunctionName3 Description 6 | .EXAMPLE New FunctionName3 7 | PS :> Import-FunctionName3 -Parameter1 'SomePackageName' -Parameter2 'C:\some\path_to_folder' 8 | .PARAMETER Parameter1 9 | Parameter1 Description 10 | .PARAMETER Parameter2 11 | Parameter2 Descripton 12 | .NOTES 13 | Name: Import-FunctionName3 14 | Author: First Last 15 | DateCreated: DATE 16 | .FUNCTIONALITY 17 | FunctionName3 Functionality 18 | #> 19 | function Import-FunctionName3 { 20 | [CmdletBinding(DefaultParameterSetName = 'Parameter Set 1', 21 | PositionalBinding = $false, 22 | HelpUri = 'http://www.microsoft.com/', 23 | ConfirmImpact = 'Medium')] 24 | Param ( 25 | # Parameter1 Description 26 | [Parameter(Mandatory = $true, 27 | Position = 0, 28 | ValueFromPipelineByPropertyName = $true, 29 | ParameterSetName = 'Parameter Set 1')] 30 | [ValidateNotNull()] 31 | [ValidateNotNullOrEmpty()] 32 | [string]$Parameter1, 33 | 34 | # Parameter2 Description 35 | [Parameter(Mandatory = $true, 36 | Position = 1, 37 | ValueFromPipelineByPropertyName = $true, 38 | ParameterSetName = 'Parameter Set 1')] 39 | [ValidateNotNull()] 40 | [ValidateNotNullOrEmpty()] 41 | [string]$Parameter2 42 | ) 43 | begin { 44 | Write-Verbose -Message 'Did something' 45 | } 46 | process { 47 | foreach ($pkg in $pkgs) { 48 | Write-Verbose -Message 'Did something' 49 | } 50 | } 51 | end { 52 | Write-Verbose -Message 'Did something' 53 | } 54 | } -------------------------------------------------------------------------------- /TemplatePowerShellModule/Private/Import-FunctionName4.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Import FunctionName4 4 | .DESCRIPTION 5 | FunctionName4 Description 6 | .EXAMPLE New FunctionName4 7 | PS :> Import-FunctionName4 -Parameter1 'SomePackageName' -Parameter2 'C:\some\path_to_folder' 8 | .PARAMETER Parameter1 9 | Parameter1 Description 10 | .PARAMETER Parameter2 11 | Parameter2 Descripton 12 | .NOTES 13 | Name: Import-FunctionName4 14 | Author: First Last 15 | DateCreated: DATE 16 | .FUNCTIONALITY 17 | FunctionName4 Functionality 18 | #> 19 | function Import-FunctionName4 { 20 | [CmdletBinding(DefaultParameterSetName = 'Parameter Set 1', 21 | PositionalBinding = $false, 22 | HelpUri = 'http://www.microsoft.com/', 23 | ConfirmImpact = 'Medium')] 24 | Param ( 25 | # Parameter1 Description 26 | [Parameter(Mandatory = $true, 27 | Position = 0, 28 | ValueFromPipelineByPropertyName = $true, 29 | ParameterSetName = 'Parameter Set 1')] 30 | [ValidateNotNull()] 31 | [ValidateNotNullOrEmpty()] 32 | [string]$Parameter1, 33 | 34 | # Parameter2 Description 35 | [Parameter(Mandatory = $true, 36 | Position = 1, 37 | ValueFromPipelineByPropertyName = $true, 38 | ParameterSetName = 'Parameter Set 1')] 39 | [ValidateNotNull()] 40 | [ValidateNotNullOrEmpty()] 41 | [string]$Parameter2 42 | ) 43 | begin { 44 | Write-Verbose -Message 'Did something' 45 | } 46 | process { 47 | foreach ($pkg in $pkgs) { 48 | Write-Verbose -Message 'Did something' 49 | } 50 | } 51 | end { 52 | Write-Verbose -Message 'Did something' 53 | } 54 | } -------------------------------------------------------------------------------- /TemplatePowerShellModule/Public/Get-FunctionName2.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | New FunctionName2 4 | .DESCRIPTION 5 | FunctionName2 Description 6 | .EXAMPLE New FunctionName2 7 | PS :> New-FunctionName2 -Parameter1 'SomePackageName' -Parameter2 'C:\some\path_to_folder' 8 | .PARAMETER Parameter1 9 | Parameter1 Description 10 | .PARAMETER Parameter2 11 | Parameter2 Descripton 12 | .NOTES 13 | Name: New-FunctionName2 14 | Author: First Last 15 | DateCreated: DATE 16 | .FUNCTIONALITY 17 | FunctionName2 Functionality 18 | #> 19 | function New-FunctionName2 { 20 | [CmdletBinding(DefaultParameterSetName = 'Parameter Set 1', 21 | PositionalBinding = $false, 22 | HelpUri = 'http://www.microsoft.com/', 23 | ConfirmImpact = 'Medium')] 24 | Param ( 25 | # Parameter1 Description 26 | [Parameter(Mandatory = $true, 27 | Position = 0, 28 | ValueFromPipelineByPropertyName = $true, 29 | ParameterSetName = 'Parameter Set 1')] 30 | [ValidateNotNull()] 31 | [ValidateNotNullOrEmpty()] 32 | [string]$Parameter1, 33 | 34 | # Parameter2 Description 35 | [Parameter(Mandatory = $true, 36 | Position = 1, 37 | ValueFromPipelineByPropertyName = $true, 38 | ParameterSetName = 'Parameter Set 1')] 39 | [ValidateNotNull()] 40 | [ValidateNotNullOrEmpty()] 41 | [string]$Parameter2 42 | ) 43 | begin { 44 | Write-Verbose -Message 'Did something' 45 | } 46 | process { 47 | foreach ($pkg in $pkgs) { 48 | Write-Verbose -Message 'Did something' 49 | } 50 | } 51 | end { 52 | Write-Verbose -Message 'Did something' 53 | } 54 | } -------------------------------------------------------------------------------- /TemplatePowerShellModule/Public/New-FunctionName1.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | New FunctionName1 4 | .DESCRIPTION 5 | FunctionName1 Description 6 | .EXAMPLE New FunctionName1 7 | PS :> New-FunctionName1 -Parameter1 'SomePackageName' -Parameter2 'C:\some\path_to_folder' 8 | .PARAMETER Parameter1 9 | Parameter1 Description 10 | .PARAMETER Parameter2 11 | Parameter2 Descripton 12 | .NOTES 13 | Name: New-FunctionName1 14 | Author: First Last 15 | DateCreated: DATE 16 | .FUNCTIONALITY 17 | FunctionName1 Functionality 18 | #> 19 | function New-FunctionName1 { 20 | [CmdletBinding(DefaultParameterSetName = 'Parameter Set 1', 21 | PositionalBinding = $false, 22 | HelpUri = 'http://www.microsoft.com/', 23 | ConfirmImpact = 'Medium')] 24 | Param ( 25 | # Parameter1 Description 26 | [Parameter(Mandatory = $true, 27 | Position = 0, 28 | ValueFromPipelineByPropertyName = $true, 29 | ParameterSetName = 'Parameter Set 1')] 30 | [ValidateNotNull()] 31 | [ValidateNotNullOrEmpty()] 32 | [string]$Parameter1, 33 | 34 | # Parameter2 Description 35 | [Parameter(Mandatory = $true, 36 | Position = 1, 37 | ValueFromPipelineByPropertyName = $true, 38 | ParameterSetName = 'Parameter Set 1')] 39 | [ValidateNotNull()] 40 | [ValidateNotNullOrEmpty()] 41 | [string]$Parameter2 42 | ) 43 | begin { 44 | Write-Verbose -Message 'Did something' 45 | } 46 | process { 47 | foreach ($pkg in $pkgs) { 48 | Write-Verbose -Message 'Did something' 49 | } 50 | } 51 | end { 52 | Write-Verbose -Message 'Did something' 53 | } 54 | } -------------------------------------------------------------------------------- /Tests/TemplatePowerShellModule.Tests.ps1: -------------------------------------------------------------------------------- 1 | $TemplatePowerShellModule = 'ModuleName' 2 | 3 | $here = "$(Split-Path (Split-Path -Parent $MyInvocation.MyCommand.Path) -Parent)\$TemplatePowerShellModule" 4 | 5 | Describe "$TemplatePowerShellModule PowerShell Module Tests" { 6 | Context 'Module Setup' { 7 | It "has the root module $TemplatePowerShellModule.psm1" { 8 | "$here\$TemplatePowerShellModule.psm1" | Should -Exist 9 | } 10 | It "has the manifest file $TemplatePowerShellModule.psd1" { 11 | "$here\$TemplatePowerShellModule.psd1" | should exist 12 | } 13 | It "$TemplatePowerShellModule has functions" { 14 | "$here\Public\*.ps1" | Should exist 15 | "$here\Private\*.ps1" | should exist 16 | } 17 | It "$TemplatePowerShellModule is valid PowerShell Code" { 18 | $psFile = Get-Content -Path "$here\$TemplatePowerShellModule.psm1" -ErrorAction Stop 19 | $errors = $null 20 | $null = [System.Management.Automation.PSParser]::Tokenize($psFile, [ref]$errors) 21 | $errors.count | Should be 0 22 | } 23 | } 24 | } 25 | 26 | $pubFunctions = ('New-FunctionName1', 'Get-FunctionName2') 27 | $privFunctions = ('Import-FunctionName3','Import-FunctionName4') 28 | 29 | $folders = ( 'Public','Private') 30 | 31 | foreach ($folder in $folders) { 32 | Describe 'Folders Tests' { 33 | It "$folder should exist" { 34 | "$here\$Folder" | Should Exist 35 | } 36 | } 37 | } 38 | 39 | Describe 'Function Tests' { 40 | foreach ($function in $pubFunctions) { 41 | Context 'Public Functions' { 42 | It "$function.ps1 should exist" { 43 | "$here\Public\$function.ps1" | Should Exist 44 | } 45 | It "$function.ps1 should have help block" { 46 | "$here\Public\$function.ps1" | Should -FileContentMatch '<#' 47 | "$here\Public\$function.ps1" | Should -FileContentMatch '#>' 48 | } 49 | It "$function.ps1 should have a SYNOPSIS section in the help block" { 50 | "$here\Public\$function.ps1" | Should -FileContentMatch '.SYNOPSIS' 51 | } 52 | It "$function.ps1 should have a DESCRIPTION section in the help block" { 53 | "$here\Public\$function.ps1" | Should -FileContentMatch '.DESCRIPTION' 54 | } 55 | It "$function.ps1 should have a EXAMPLE section in the help block" { 56 | "$here\Public\$function.ps1" | Should -FileContentMatch '.EXAMPLE' 57 | } 58 | It "$function.ps1 should be an advanced function" { 59 | "$here\Public\$function.ps1" | Should -FileContentMatch 'function' 60 | "$here\Public\$function.ps1" | Should -FileContentMatch 'CmdLetBinding' 61 | "$here\Public\$function.ps1" | Should -FileContentMatch 'param' 62 | } 63 | It "$function.ps1 should contain Write-Verbose blocks" { 64 | "$here\Public\$function.ps1" | Should -FileContentMatch 'Write-Verbose' 65 | } 66 | It "$function.ps1 is valid PowerShell code" { 67 | $psFile = Get-Content -Path "$here\Public\$function.ps1" -ErrorAction Stop 68 | $errors = $null 69 | $null = [System.Management.Automation.PSParser]::Tokenize($psFile, [ref]$errors) 70 | $errors.count | Should be 0 71 | } 72 | }# Context Public Function Tests 73 | } # end of Public function foreach 74 | 75 | foreach ($function in $privFunctions) { 76 | Context 'Private Functions' { 77 | It "$function.ps1 should exist" { 78 | "$here\Private\$function.ps1" | Should Exist 79 | } 80 | It "$function.ps1 should have help block" { 81 | "$here\Private\$function.ps1" | Should -FileContentMatch '<#' 82 | "$here\Private\$function.ps1" | Should -FileContentMatch '#>' 83 | } 84 | It "$function.ps1 should have a SYNOPSIS section in the help block" { 85 | "$here\Private\$function.ps1" | Should -FileContentMatch '.SYNOPSIS' 86 | } 87 | It "$function.ps1 should have a DESCRIPTION section in the help block" { 88 | "$here\Private\$function.ps1" | Should -FileContentMatch '.DESCRIPTION' 89 | } 90 | It "$function.ps1 should have a EXAMPLE section in the help block" { 91 | "$here\Private\$function.ps1" | Should -FileContentMatch '.EXAMPLE' 92 | } 93 | It "$function.ps1 should be an advanced function" { 94 | "$here\Private\$function.ps1" | Should -FileContentMatch 'function' 95 | "$here\Private\$function.ps1" | Should -FileContentMatch 'CmdLetBinding' 96 | "$here\Private\$function.ps1" | Should -FileContentMatch 'param' 97 | } 98 | It "$function.ps1 should contain Write-Verbose blocks" { 99 | "$here\Private\$function.ps1" | Should -FileContentMatch 'Write-Verbose' 100 | } 101 | It "$function.ps1 is valid PowerShell code" { 102 | $psFile = Get-Content -Path "$here\Private\$function.ps1" -ErrorAction Stop 103 | $errors = $null 104 | $null = [System.Management.Automation.PSParser]::Tokenize($psFile, [ref]$errors) 105 | $errors.count | Should be 0 106 | } 107 | } # Context Private Function Tests 108 | } # end of Private function foreach 109 | } # end of describe block -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # YAML Reference Guide: https://www.appveyor.com/docs/appveyor-yml/ 2 | # Environmental Variables Guide: https://www.appveyor.com/docs/environment-variables/ 3 | # YAML Validator: https://ci.appveyor.com/tools/validate-yaml 4 | 5 | # Disable automatic builds 6 | # Without this, the following error shows up: 7 | # "Specify a project or solution file. The directory does not contain a project or solution file." 8 | build: off 9 | 10 | # Version number 11 | version: 1.0.0.{build} 12 | 13 | # Ignore testing a commit if only the README.md file changed 14 | # Or if various strings are found in the commit message: updated readme, update readme, update docs, update version, update appveyor 15 | skip_commits: 16 | files: 17 | - README.md 18 | message: /updated readme.*|update readme.*s|update docs.*|update version.*|update appveyor.*/ 19 | 20 | # There's no need to alter the build number for a Pull Request (PR) since they don't modify anything 21 | pull_requests: 22 | do_not_increment_build_number: true 23 | 24 | #Publish to PowerShell Gallery with this key 25 | environment: 26 | NuGetApiKey: 27 | secure: {NUGETAPIKEY} 28 | GitHubKey: 29 | secure: {GITHUB_PERSONAL_ACCESS_TOKEN} 30 | 31 | # Install NuGet to interact with the PowerShell Gallery 32 | install: 33 | - ps: . .\install.ps1 34 | 35 | # Invoke Pester to run all of the unit tests, then save the results into XML in order to populate the AppVeyor tests section 36 | # If any of the tests fail, consider the pipeline failed 37 | test_script: 38 | - ps: $res = Invoke-Pester -Path ".\Tests" -OutputFormat NUnitXml -OutputFile TestsResults.xml -PassThru 39 | - ps: (New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\TestsResults.xml)) 40 | - ps: if ($res.FailedCount -gt 0) { throw "$($res.FailedCount) tests failed."} 41 | - git config --global credential.helper store 42 | - ps: Add-Content "$env:USERPROFILE\.git-credentials" "https://$($env:GitHubKey):x-oauth-basic@github.com`n" 43 | - git config --global user.email "first.last@domain.com" 44 | - git config --global user.name "First Last" 45 | - git config --global core.autocrlf true 46 | - git config --global core.safecrlf false 47 | - ps: write-host "calling build.ps1" 48 | - ps: . .\build.ps1 -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | $Name = 'First Last' 2 | $TemplatePowerShellModule = 'TemplatePowerShellModule' 3 | 4 | # Line break for readability in AppVeyor console 5 | Write-Host -Object '' 6 | 7 | # Make sure we're using the Master branch and that it's not a pull request 8 | # Environmental Variables Guide: https://www.appveyor.com/docs/environment-variables/ 9 | if ($env:APPVEYOR_REPO_BRANCH -ne 'master') { 10 | Write-Warning -Message "Skipping version increment and publish for branch $env:APPVEYOR_REPO_BRANCH" 11 | } 12 | elseif ($env:APPVEYOR_PULL_REQUEST_NUMBER -gt 0) { 13 | Write-Warning -Message "Skipping version increment and publish for pull request #$env:APPVEYOR_PULL_REQUEST_NUMBER" 14 | } 15 | else { 16 | # We're going to add 1 to the revision value since a new commit has been merged to Master 17 | # This means that the major / minor / build values will be consistent across GitHub and the Gallery 18 | Try { 19 | # This is where the module manifest lives 20 | $manifestPath = ".\$TemplatePowerShellModule\$TemplatePowerShellModule.psd1" 21 | 22 | # Start by importing the manifest to determine the version, then add 1 to the revision 23 | $manifest = Test-ModuleManifest -Path $manifestPath 24 | [System.Version]$version = $manifest.Version 25 | Write-Output "Old Version: $version" 26 | [String]$newVersion = New-Object -TypeName System.Version -ArgumentList ($version.Major, $version.Minor, $version.Build, $env:APPVEYOR_BUILD_NUMBER) 27 | Write-Output "New Version: $newVersion" 28 | 29 | # Update the manifest with the new version value and fix the weird string replace bug 30 | $functionList = ((Get-ChildItem -Path .\$TemplatePowerShellModule\Public).BaseName) 31 | $splat = @{ 32 | 'Path' = $manifestPath 33 | 'ModuleVersion' = $newVersion 34 | 'FunctionsToExport' = $functionList 35 | 'Copyright' = "(c) 2015-$( (Get-Date).Year ) $Name. All rights reserved." 36 | } 37 | Update-ModuleManifest @splat 38 | (Get-Content -Path $manifestPath) -replace "PSGet_$TemplatePowerShellModule", "$TemplatePowerShellModule" | Set-Content -Path $manifestPath 39 | (Get-Content -Path $manifestPath) -replace 'NewManifest', $TemplatePowerShellModule | Set-Content -Path $manifestPath 40 | (Get-Content -Path $manifestPath) -replace 'FunctionsToExport = ', 'FunctionsToExport = @(' | Set-Content -Path $manifestPath -Force 41 | (Get-Content -Path $manifestPath) -replace "$($functionList[-1])'", "$($functionList[-1])')" | Set-Content -Path $manifestPath -Force 42 | } 43 | catch { 44 | throw $_ 45 | } 46 | 47 | # Create new markdown and XML help files 48 | Write-Host "Building new function documentation" -ForegroundColor Yellow 49 | Import-Module -Name "$PSScriptRoot\$TemplatePowerShellModule" -Force 50 | New-MarkdownHelp -Module $TemplatePowerShellModule -OutputFolder '.\docs\' -Force 51 | New-ExternalHelp -Path '.\docs\' -OutputPath ".\$TemplatePowerShellModule\en-US\" -Force 52 | . .\docs.ps1 53 | Write-Host -Object '' 54 | 55 | # Publish the new version to the PowerShell Gallery 56 | Try { 57 | # Build a splat containing the required details and make sure to Stop for errors which will trigger the catch 58 | $PM = @{ 59 | Path = ".\$TemplatePowerShellModule" 60 | NuGetApiKey = $env:NuGetApiKey 61 | ErrorAction = 'Stop' 62 | Tags = @('', '') 63 | LicenseUri = "https://github.com/$Name/$TemplatePowerShellModule/blob/master/LICENSE.md" 64 | ProjectUri = "https://github.com/$Name/$TemplatePowerShellModule" 65 | ReleaseNotes = 'Initial release to the PowerShell Gallery' 66 | } 67 | 68 | Publish-Module @PM 69 | Write-Host "$TemplatePowerShellModule PowerShell Module version $newVersion published to the PowerShell Gallery." -ForegroundColor Cyan 70 | } 71 | Catch { 72 | # Sad panda; it broke 73 | Write-Warning "Publishing update $newVersion to the PowerShell Gallery failed." 74 | throw $_ 75 | } 76 | 77 | # Publish the new version back to Master on GitHub 78 | Try { 79 | # Set up a path to the git.exe cmd, import posh-git to give us control over git, and then push changes to GitHub 80 | # Note that "update version" is included in the appveyor.yml file's "skip a build" regex to avoid a loop 81 | $env:Path += ";$env:ProgramFiles\Git\cmd" 82 | Import-Module posh-git -ErrorAction Stop 83 | git checkout master 84 | git add --all 85 | git status 86 | git commit -s -m "Update version to $newVersion" 87 | git push origin master 88 | Write-Host "$TemplatePowerShellModule PowerShell Module version $newVersion published to GitHub." -ForegroundColor Cyan 89 | } 90 | Catch { 91 | # Sad panda; it broke 92 | Write-Warning "Publishing update $newVersion to GitHub failed." 93 | throw $_ 94 | } 95 | } -------------------------------------------------------------------------------- /docs.ps1: -------------------------------------------------------------------------------- 1 | $StageFolder = '.\compiled_docs' 2 | 3 | # Create a Staging folder and copy items in for compiling 4 | $null = New-Item -Path $StageFolder -ItemType:Directory 5 | Copy-Item -Path '.\*.md' -Destination $StageFolder -Force 6 | Copy-Item -Path '.\docs\*' -Destination $StageFolder -Recurse -Force 7 | 8 | # Build the book 9 | Push-Location -Path $StageFolder 10 | gitbook install 11 | gitbook build 12 | Pop-Location 13 | 14 | # Copy the new book items into the docs folder 15 | Remove-Item -Path '.\docs\' -Include *.html -Recurse -Force 16 | Copy-Item -Path "$StageFolder\_book\*" -Destination '.\docs\' -Recurse -Force 17 | Remove-Item -Path $StageFolder -Recurse -Force -------------------------------------------------------------------------------- /install.ps1: -------------------------------------------------------------------------------- 1 | [string[]]$PowerShellModules = @("Pester", "posh-git", "platyPS", "InvokeBuild") 2 | [string[]]$PackageProviders = @('NuGet', 'PowerShellGet') 3 | [string[]]$ChocolateyPackages = @('nodejs', 'calibre') 4 | [string[]]$NodeModules = @('gitbook-cli', 'gitbook-summary') 5 | 6 | # Line break for readability in AppVeyor console 7 | Write-Host -Object '' 8 | 9 | # Install package providers for PowerShell Modules 10 | ForEach ($Provider in $PackageProviders) { 11 | If (!(Get-PackageProvider $Provider -ErrorAction SilentlyContinue)) { 12 | Install-PackageProvider $Provider -Force -ForceBootstrap -Scope CurrentUser 13 | } 14 | } 15 | 16 | # Install the PowerShell Modules 17 | ForEach ($Module in $PowerShellModules) { 18 | If (!(Get-Module -ListAvailable $Module -ErrorAction SilentlyContinue)) { 19 | Install-Module $Module -Scope CurrentUser -Force -Repository PSGallery 20 | } 21 | Import-Module $Module 22 | } 23 | 24 | # Install Chocolatey 25 | Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) 26 | 27 | # Install Chocolatey packages 28 | ForEach ($Package in $ChocolateyPackages) {choco install $Package -y --no-progress} 29 | 30 | # Install Node packages 31 | ForEach ($Module in $NodeModules) {npm install -g $Module} --------------------------------------------------------------------------------