This guide walks you through the complete process of building, validating, and testing the Microsoft Entra PowerShell module on your local machine. Follow these steps to verify your changes before submitting a pull request.
- Quick Start
- Detailed Build Steps
- Safe Testing Practices
- Installing a Test Version Locally
- Validating Documentation Changes
- Complete Build Scripts
- CI/CD Pipeline Expectations
For contributors who want the shortest path to building and testing:
# Clone the repository (use your fork URL if contributing via fork)
git clone https://github.com/microsoftgraph/entra-powershell.git
cd entra-powershell
# Install dependencies
.\build\Install-Dependencies.ps1 -ModuleName Entra
# Install help generation tool
Install-Module -Name PlatyPS -Scope CurrentUser -Force
# Build the module
. .\build\Common-functions.ps1
Create-ModuleHelp -Module Entra
.\build\Create-EntraModule.ps1 -Module 'Entra'
.\build\Create-EntraModule.ps1 -Module 'Entra' -Root
# Import the module
Import-Module .\bin\Microsoft.Entra.psd1 -Force
# Run tests
Invoke-Pester -Path .\test\Entra\ -Output DetailedOption A: Clone directly (recommended)
git clone https://github.com/microsoftgraph/entra-powershell.git
cd entra-powershell
git checkout -b feature/your-change-descriptionOption B: Fork and clone
# Fork via GitHub UI first, then:
git clone https://github.com/<YOUR-USERNAME>/entra-powershell.git
cd entra-powershell
git remote add upstream https://github.com/microsoftgraph/entra-powershell.git
git checkout -b feature/your-change-descriptionNote: PRs from direct clones trigger the CI/CD pipeline automatically. PRs from forks require an internal reviewer to manually trigger the pipeline.
Important: Always use a fresh PowerShell session when building. If a different version of the module dependencies is already loaded in your session, the build will fail.
The module requires specific versions of the Microsoft Graph PowerShell SDK modules (v2.25.x or later).
For the v1.0 module:
.\build\Install-Dependencies.ps1 -ModuleName EntraFor the Beta module:
.\build\Install-Dependencies.ps1 -ModuleName EntraBetaInstall the PlatyPS module (required for generating help documentation):
Install-Module -Name PlatyPS -Scope CurrentUser -ForceTip: If you get an execution policy error, run:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Build help documentation:
. .\build\Common-functions.ps1
Create-ModuleHelp -Module EntraBuild the module:
.\build\Create-EntraModule.ps1 -Module 'Entra'
.\build\Create-EntraModule.ps1 -Module 'Entra' -RootThe built module is output to the ./bin directory.
Import the built module to verify it loads without errors:
Import-Module .\bin\Microsoft.Entra.psd1 -ForceVerify the module is loaded:
Get-Module Microsoft.Entra* | Format-Table Name, Version, ExportedCommandsTest that your cmdlet is available:
Get-Command -Module Microsoft.Entra* -Name <YourCmdletName>PowerShell 5.1 users: If you see
Function capacity 4096 exceeded, run$MaximumFunctionCount = 32768before importing.
Run all unit tests to ensure nothing is broken:
# Run all v1.0 tests
Invoke-Pester -Path .\test\Entra\ -Output Detailed
# Or run tests for a specific sub-module
Invoke-Pester -Path .\test\Entra\Users\ -Output Detailed
# Or run tests for your specific cmdlet
Invoke-Pester -Path .\test\Entra\Users\Get-EntraUser.Tests.ps1 -Output DetailedFor detailed testing instructions, see the Testing Guide.
Run PSScriptAnalyzer on your changed files to catch common issues:
# Analyze a specific file
Invoke-ScriptAnalyzer -Path .\module\Entra\<YourFile>.ps1 -Severity Warning
# Analyze an entire sub-module
Invoke-ScriptAnalyzer -Path .\module\Entra\Users\ -Recurse -Severity WarningWhen testing changes locally, follow these practices to avoid unintended side effects:
The project's unit tests use Pester mocks — they never call the real Microsoft Graph API. This is the safest way to test:
# This is safe — all API calls are mocked
Invoke-Pester -Path .\test\Entra\Users\Get-EntraUser.Tests.ps1If you need to manually test cmdlets against a real environment:
- Use a dedicated test/development tenant — never test against production.
- Use least-privilege scopes — only request the permissions you need:
Connect-Entra -Scopes "User.Read"
- Use read-only operations first — verify with
Get-cmdlets before usingSet-,New-, orRemove-cmdlets. - Use
-WhatIfwhen available — some cmdlets support-WhatIfto preview changes without applying them. - Clean up after testing — remove any test resources you created.
To test the module installation experience without affecting your system:
. .\build\Common-functions.ps1
Create-ModuleFolder
Register-LocalGallery
.\build\Publish-LocalCompatModule.ps1 -Install
# Test with the installed module
Import-Module Microsoft.Entra -Force
# Clean up when done
Unregister-LocalGalleryIf you want to install your locally-built module system-wide (useful for automation testing):
# Set up a local PowerShell gallery
. .\build\Common-functions.ps1
Create-ModuleFolder
Register-LocalGallery
# Publish and install from local gallery
.\build\Publish-LocalCompatModule.ps1 -Install
# Now import without specifying a path
Import-Module Microsoft.Entra -ForceTo clean up:
# Unregister the local gallery
Unregister-LocalGallery
# Uninstall the test module
Uninstall-Module Microsoft.Entra -ForceIf you've updated cmdlet documentation (markdown files in module/docs/):
# Rebuild help files
. .\build\Common-functions.ps1
Create-ModuleHelp -Module Entra
# Import module with updated help
Import-Module .\bin\Microsoft.Entra.psd1 -Force
# Verify your help content
Get-Help <YourCmdletName> -Full
Get-Help <YourCmdletName> -ExamplesEnsure your documentation markdown is properly formatted:
- Examples must include
powershellas the code fence language. - Parameter descriptions must be present for all parameters.
- At least one example must be included per cmdlet.
- See the cmdlet reference template for the expected format.
# Start a fresh PowerShell session before running this script
.\build\Install-Dependencies.ps1 -ModuleName Entra
Install-Module -Name PlatyPS -Scope CurrentUser -Force
. .\build\Common-functions.ps1
Create-ModuleHelp -Module Entra
.\build\Create-EntraModule.ps1 -Module 'Entra'
.\build\Create-EntraModule.ps1 -Module 'Entra' -Root
Import-Module .\bin\Microsoft.Entra.psd1 -Force
# Run all tests
Invoke-Pester -Path .\test\Entra\ -Output Detailed# Start a fresh PowerShell session before running this script
.\build\Install-Dependencies.ps1 -ModuleName EntraBeta
Install-Module -Name PlatyPS -Scope CurrentUser -Force
. .\build\Common-functions.ps1
Create-ModuleHelp -Module EntraBeta
.\build\Create-EntraModule.ps1 -Module 'EntraBeta'
.\build\Create-EntraModule.ps1 -Module 'EntraBeta' -Root
Import-Module .\bin\Microsoft.Entra.Beta.psd1 -Force
# Run all tests
Invoke-Pester -Path .\test\EntraBeta\ -Output DetailedWhen you open a pull request, the PR pipeline automatically:
- Builds the module — using Azure Pipelines on Windows.
- Runs PSScriptAnalyzer — static analysis for code quality.
- Runs credential scanning — ensures no secrets are committed.
To avoid surprises, replicate these checks locally before pushing:
# 1. Build the module (see steps above)
# 2. Run static analysis
Invoke-ScriptAnalyzer -Path .\module\Entra\ -Recurse -Severity Warning
# 3. Run all tests
Invoke-Pester -Path .\test\Entra\ -Output Detailed
# 4. Verify no secrets are in your changes
git diff --cached --name-only # Review staged filesTip: The PR review SLA is three business days. Complete the PR template checklist to avoid delays.
Important: Once your PR is complete and all checks pass, add the Ready For Review label to signal the team for review.
Note: Pull requests from direct branches trigger the CI pipeline automatically. Pull requests from forks require an internal reviewer to manually trigger the pipeline after reviewing the changes. In both cases, ensure all tests pass locally before submitting your PR.