About the Author
About This Book
- PowerShell version
- Roadmap
- Part 1
- Part 2
- Part 3
- Part 4
- Bonus
Feedback
Typographic Conventions
- Asides
Dedication
Introduction
- IPart 1 - Modules Primer
1Module Basics
- You will learn
- 1.1What is a module
- You are already using modules
- 1.2Why build modules
- 1.2.1Organizing related functionality
- 1.2.2Code sharing
- 1.2.3Code reuse
- 1.2.4Versioning
- 1.3Terminology
- 1.4Module types
- 1.4.1Script modules
- 1.4.2Binary modules
- 1.4.3Manifest
- 1.4.4What is a manifest
- 1.5Summary
- Key Points
2Working with Modules
- You will learn
- 2.1Module locations
- 2.1.1$env:PSModulePath
- Cross-platform code
- 2.2PowerShellGet
- 2.2.1Finding modules online
- 2.2.2Installing a module
- 2.2.3Updating modules
- 2.2.4Uninstalling modules
- 2.3Discovering module information
- 2.3.1Listing installed modules
- 2.3.2Getting module commands
- 2.3.3Exploring a module
- 2.4Installing modules
- 2.4.1Creating a hello world module
- 2.4.2Manual installation
- Module locations
- 2.4.3PowerShellGet
- Default installation scope with PowerShellGet
- 2.5Saving modules
- 2.6Importing modules
- 2.6.1Modules are single-instance
- 2.6.2Module prefixes
- 2.7Being specific with module specifications
- 2.8Module auto-loading
- 2.8.1Controlling auto-loading behavior
- 2.9Removing modules
- 2.9.1Removing a module by name
- 2.9.2Removing a module by using a module specification
- 2.9.3Removing a module by PSModuleInfo
- 2.9.4Caveats
- 2.10Summary
- Key points
3Authoring a Module
- You will learn
- 3.1Basic structure of a module
- 3.1.1Rules and conventions for module files
- Always include a manifest
- 3.1.2Exceptions to the rules
- 3.2Creating a script module
- 3.2.1Creating a basic script
- 3.2.2Turning a script into a module
- Default script module versioning
- 3.3Manifests
- 3.3.1Manifest structure
- Restricted language support in manifests
- 3.3.2Creating a module manifest
- An evolving manifest
- 3.3.3Elements of a manifest
- Make sure your module IDs are unique
- Manifest “gotchas”
- 3.3.4Updating a manifest
- 3.3.5Testing a manifest
- 3.4Summary
- Key points
4Dealing with Module Dependencies
- You will learn
- 4.1Module dependencies
- 4.1.1Implicit dependencies
- Beware of implicit dependencies
- Built-in modules can differ across platforms
- 4.1.2Explicit dependencies
- 4.1.3Focusing our efforts
- 4.1.4Defining dependencies to other modules
- Options for RequiredModules
- 4.1.5Installing dependencies
- Taking advantage of what is already available
- 4.2Summary
- Key points
5Distributing Modules
- You will learn
- 5.1PowerShell repositories
- 5.1.1The default repository
- 5.1.2Trusting repositories
- 5.1.3Repository types
- 5.2Creating a local repository
- 5.2.1Registering a repository
- 5.3Publishing a module locally
- 5.3.1Publishing a module by name
- 5.3.2Publishing a module by file path
- When publishing modules, be specific
- 5.4The PowerShell Gallery, a tour
- 5.4.1Navigating the Gallery
- 5.4.2Registering on the Gallery
- Enable 2FA
- 5.4.3Managing API keys
- 5.5Summary
- Key points
- IIPart 2 - Project and Module Design
6Choosing a Module Layout
- 6.1Monolithic PSM1
- 6.1.1Module structure
- 6.2Category submodules
- 6.2.1Grouping by domain
- 6.3Dot-sourced functions from PSM1
- 6.3.1What happens during import
- 6.3.2Advantages and disadvantages
- 6.4Final verdict
- 6.5Summary
- Key points
7Keeping Some Module Contents Private
- You will learn
- 7.1Determining the public functions
- Approved Powershell verbs for CRUD operations
- 7.1.1The role of private functions
- 7.1.2Candidates for private functions
- 7.1.3Controlling the visibility of variables and aliases
- 7.2Summary
- Key points
8Using Classes in a Module
- You will learn
- Class bonus chapter
- 8.1Importing classes
- Having import trouble?
- 8.1.1The using statement
- Confusion with
$using: - Module resolution with
using module - 8.1.2Differences from Import-Module
- 8.1.3Differences from #requires
- 8.2Using classes internally in a module
- 8.2.1Trying to dot-source classes
- 8.3Ordering classes
- 8.4Extending classes from other modules
- 8.4.1Having a module reference classes from another module
- RequiredModules looks for modules in $env:PSModulePath
- 8.5The user experience of classes
- 8.5.1Providing functions to create class instances
- 8.6Summary
- Key points
9Building a Module From Many Files
- You will learn
- 9.1Benefits of a monolithic PSM1
- Code signing
- 9.2Benefits of dot-sourced functions
- Simple is good
- 9.3Creating a dot-sourced module
- Creating flexible modules
- 9.4Building a module - E pluribus enum (out of many, one)
- Are we really “compiling” a module?
- 9.4.1Creating a project directory
- Builds scripts are the entry point for projects
- 9.4.2Creating a build script
- PowerShell-based build frameworks
- 9.4.3Running the build script
- 9.4.4Exporting functions in the manifest
- 9.5Summary
- Key points
10Versioning a Module
- You will learn
- 10.1What is a software version
- Sometimes versions are just marketing
- 10.1.1Examples of versioning schemes
- 10.2Semantic Versioning
- SemVer v1.0.0
- 10.2.1SemVer rules
- Version 0 doesn’t replace proper planning
- 10.2.2Why SemVer is useful
- Not everyone follows SemVer
- 10.3Automating module versioning
- 10.3.1Avoid auto-incrementing
- 10.3.2Incrementing a module version
- 10.4Pre-release versioning
- Pre-release is for v1.0.0 and above
- 10.4.1Adding a pre-release moniker
- 10.4.2Publishing a pre-release module
- 10.4.3Finding and installing a pre-release module
- Updating a pre-release version replaces the existing version
- 10.5Tips for avoiding breaking changes
- PowerShell is consistent, except when it isn’t
- 10.6Handling deprecation
- Don’t pull the rug out from under your users
- 10.6.1Communication avenues
- 10.7Specifying compatible operating systems and PowerShell editions
- Finding the edition of PowerShell
- 10.7.1The CompatiblePSEditions module manifest field
- 10.8Summary
- Key points
11Building Better Functions
- You will learn
- 11.1Plan your dive, dive your plan
- 11.1.1Planning your functions
- 11.1.2Think about the experience
- 11.2Functions should do one thing
- 11.3Creating testable functions
- 11.4Self-contained functions
- 11.5Writing defensive functions
- 11.5.1Enforce mandatory parameters
- 11.5.2Explicitly define parameter types
- Beware of strings
- 11.5.3Use validation attributes
- 11.6Document your functions
- 11.7Adhere to approved verbs
- Avoid the Invoke verb
- 11.8Use proper parameter names
- 11.9Use advanced functions
- Don’t replicate advanced function features
- Alternate way to create advanced functions
- 11.10Support the pipeline
- 11.11Create safe functions
- 11.11.1Adding -WhatIf and
-Confirmto your functions - ShouldContinue breaks non-interactive scripts
- 11.11.2Using the -Force
- 11.12Sensible error handling
- 11.12.1Creating terminating errors
- 11.12.2Creating non-terminating errors
- 11.13Write with cross-platform in mind
- 11.13.1Working with the PATH environment variable
- Supporting older PowerShell versions
- 11.13.2File paths and delimiters
- 11.14Summary
- Key points
12Creating a Quality GitHub Project
- You will learn
- 12.1The README
- What happens when there is no README?
- 12.1.1Elements of the README
- 12.1.2Jazzing up the README with badges
- 12.2Choosing a license
- 12.3Keeping track of what changed
- 12.4The Code of Conduct
- 12.5Tell folks how to contribute
- 12.6Issue and pull request templates
- 12.6.1Template front matter and Markdown
- 12.6.2Pull request template
- 12.7Divvying up the work with CODEOWNERS
- 12.7.1CODEOWNERS Syntax
- 12.8Project sponsors and funding
- 12.9Summary
- Key points
13Documenting a Project
- IIIPart 3 - The Build and Test Loop
- IVPart 4 - Creating a Quality Community Project
- VBonus Chapters
14PowerShell Classes Explained
- You will learn
- 14.1What is a PowerShell Class
- 14.2Why use classes
- 14.3Defining and creating a class
- Creating a class using New-Object
- 14.4Adding class properties
- Type constrained properties
- 14.5Defining class methods
- Returning data from methods
- 14.6Initializing class properties
- 14.7Validating properties by using attributes
- 14.8Accessing the class members with $this
- 14.9Passing input to methods
- Parameters in class methods are mandatory
- 14.10Method overloading and signatures
- Passing method parameters
- 14.11Making properties and methods static
- 14.11.1Accessing static properties
- Common static properties
- 14.11.2Calling static methods
- Static methods only access static members
- 14.12Initializing a class instance with constructors
- Defining constructors removes the default constructor
- 14.13Inheritance
- 14.13.1Creating a derived class
- 14.13.2Overriding methods
- 14.13.3Calling base methods
- 14.13.4Calling constructors
- 14.14Hiding properties and methods
- Hidden class members are not protected
- 14.15Enumerations
- 14.15.1Using an enumeration
- 14.15.2Using enumerations in parameters
- Enumerations are everywhere
- 14.15.3Creating an enumeration
- 14.15.4Flag enumerations
- Flag values
- 14.16Summary
- Key points