Getty Images/iStockphoto
Using GitHub Copilot to accelerate PowerShell scripting
Learn how to work with GitHub Copilot to write scripts, refactor legacy code and streamline Azure automation with best practices in mind.
GitHub Copilot has evolved from an autocomplete novelty into a capable, chat-assisted development partner that can accelerate day-to-day scripting for IT professionals.
For PowerShell administrators, GitHub Copilot can draft modules and scripts from natural language prompts, refactor legacy Windows PowerShell 5.1 code to PowerShell 7, generate documentation and tests and assist in orchestrating Azure operations.
Still, GitHub Copilot is an assistant -- not an authority. Because it learns from public code and patterns, it can surface outdated APIs or inefficient approaches, so you should verify outputs, require modern module usage and keep security and compliance guardrails in place.
When paired with Visual Studio Code (VS Code), GitHub Copilot becomes particularly effective: you describe the intent in comments or chat, and it proposes context‑aware snippets you can accept, edit or reject as you iterate.
How GitHub Copilot works
Copilot applies generative AI models trained on public source code to predict and propose the next lines, blocks or entire functions based on your current file, project context and prompts.
In VS Code, you can give a descriptive comment or string, such as "what should this script accomplish?", and GitHub Copilot will offer a draft that you can refine. The clearer your intent, constraints and environment details -- PowerShell version, module names and versions, target OS -- the better its suggestions. A grounding in PowerShell helps you steer GitHub Copilot toward correct, efficient scripts and away from deprecated patterns.
GitHubCopilot is responsive to feedback in the flow of work. If it suggests an outdated cmdlet or API and you replace it with the modern equivalent, subsequent completions will typically align with your correction.
For example, when drafting an Azure automation script, GitHub Copilot might initially propose a deprecated AzureRM login cmdlet; using Connect‑AzAccount guides it back to use cmdlets in the current Az module -- also called the Azure PowerShell Account module -- in later suggestions. This adaptability is valuable, but it doesn't eliminate the need for expert review.
A few practical tips to keep in mind:
- Quality varies with the clarity of your prompts. Explicitly state "target PowerShell 7," specify modules, such as Az.Accounts or Az.Compute, and call out required properties to reduce rework.
- Suggestions might draw on patterns that are out of date or suboptimal. Validate correctness, performance and security before adopting them. GitHub Copilot is not a replacement for domain expertise or review processes.
- GitHub Copilot learns general coding conventions from public repositories; it doesn't copy your private code unless you explicitly allow it to use your content for product improvements. You can also control whether suggestions may match public code patterns during setup.
Prepare to use GitHub Copilot
A little upfront configuration significantly improves outcomes, especially in enterprise environments.
Choose your plan and enable GitHub Copilot
- You'll need a GitHub account. Enable Copilot from your GitHub settings (Settings > Copilot). Trial options and pricing are available there. Organizations can provision GitHub Copilot for teams with policy controls; confirm current terms before rollout.
- During sign‑up, you can choose whether to allow suggestions that may match public code and whether to share your snippets for product improvement. Both settings are optional and should align with your organization's policies.
Install and configure in VS Code
- Install the GitHub Copilot extension for VS Code and sign in with your GitHub identity; you'll see a Copilot status indicator in the editor once it's active.
- Add GitHub Copilot Chat to unlock chat‑based workflows: explain and refactor code, request tests and docs and apply multi‑file changes. This chat‑first loop is often the fastest path to high‑quality results.
- Ensure the PowerShell extension for VS Code is installed so GitHub Copilot works with language‑aware syntax, formatting and debugging.
Prepare your PowerShell and Azure environment
- Standardize on a supported PowerShell 7.x runtime and keep core modules updated, such as Az modules for Azure. Ask Copilot for PS7‑compatible code and to avoid deprecated cmdlets such as the legacy AzureRM family; make inline corrections if it suggests otherwise so future completions follow suit. Using a centrally defined and distributed container for local development is a good way to ensure everyone is using the same PowerShell version, cmdlets and tools.
- Adopt basic quality gates in your workspace, such as PSScriptAnalyzer for linting and Pester for testing, so you can quickly validate GitHub Copilot's output as you iterate.
Set security and governance guardrails
- For individual use, review the "public code matching" and "content sharing" toggles during setup and choose the most conservative posture that still enables productivity.
- For organizations, enforce policies centrally, define data boundaries and decide when to enable repository‑ or workspace‑aware assistance. Treat GitHub Copilot output like any code contribution: scan for secrets, review for least‑privilege patterns and check for module or API deprecations before merging.
Prime GitHub Copilot with effective prompts
- State the goal, constraints and environment: PowerShell version, OS, modules and performance or security requirements.
- Ask explicitly for modern patterns: "Use Get‑CimInstance, not Get‑WmiObject," "Target Connect‑AzAccount, not AzureRM," "Return structured objects; avoid Write‑Host" and "Include error handling and -WhatIf support." GitHub Copilot responds best to that level of specificity.
With these preparations, GitHub Copilot becomes a dependable accelerator for PowerShell admins: it drafts the first 80% and you apply expert judgment to refine and solidify the result. The feedback you provide guides its next suggestions without losing sight of correctness, security and maintainability.
How to write PowerShell with GitHub Copilot
GitHub Copilot functions at its best when you provide it with precise intent, a clear execution environment and quality guardrails. Treat it like a junior pair‑programmer: you specify the "what" and the constraints; it drafts the how. And together you review, refine and test. GitHub Copilot needs direction from you to understand how it should proceed. Explicit prompts produce markedly better results.
Work iteratively in VS Code
- Seed with a descriptive comment or a minimal function skeleton -- CmdletBinding, parameters, try/catch, ShouldProcess. GitHub Copilot will propose completions that follow your intent and style.
- If a suggestion is close but not perfect, accept it and edit inline. GitHub Copilot's subsequent completions in that file usually follow your corrections, such as switching from AzureRM to Az, or from WMI to CIM.
- Use GitHub Copilot Chat to:
-
- Explain or refactor a block.
- Add Pester tests and comment‑based help.
- Enforce PSScriptAnalyzer rules.
- Request multi‑file edits, such as update a module and its tests.
Aim for correctness, performance and maintainability
- Return rich objects from the pipeline; avoid Write-Host in library code.
- Prefer a single, well‑scoped query over per‑item lookups. For example, calling a cmdlet inside a loop when you already have the data is unnecessary and inefficient.
- Validate module versions and cmdlet availability. Ask GitHub Copilot to pin or check versions when relevant.
- Add error handling and ShouldProcess so you can run with -WhatIf or -Confirm during testing.
Example: List running services and their logon accounts
Prompt to GitHub Copilot -- as a comment or in chat:
"PowerShell 7. Get all running Windows services and show service name, display name and the account the service runs as. Use Get-CimInstance (not Get-WmiObject). Return objects; no Write-Host."
Resulting approach -- concise, PS7‑compatible:
Query once via CIM and select the properties you need:
$services = Get-CimInstance -ClassName Win32_Service | Where-Object { $_.State -eq 'Running' }
$services | Select-Object Name, DisplayName, State, StartName
This code avoids per‑service WMI calls and relies on Win32_Service.StartName for the logon account. It also avoids implying properties that don't exist on Get-Service in PS 7.x, such as a UserName property.
Use GitHub Copilot to improve code quality
GitHub Copilot helps you implement PowerShell best practices beyond basic functionality. It can refine a script if you request further enhancements by asking for:
- Pester tests covering error conditions.
- Comment‑based help and parameter validation attributes.
- Remediation of PSScriptAnalyzer findings.
- Safer patterns, such as credentials via Get-Credential or managed identity; least‑privilege RBAC.
- Iterate until the script meets your style and reliability standards, then run tests and a -WhatIf dry run before applying changes.
Common pitfalls GitHub Copilot can make and how to fix them:
- Suggesting deprecated cmdlets or modules, such as AzureRM and Get-WmiObject. Correct them and continue; GitHub Copilot will usually follow your lead in later completions.
- Using inefficient loops that re‑query the state on every iteration. Consolidate into a single query and project only the fields you need.
- Emitting strings via Write-Host instead of returning objects. Ask GitHub Copilot to output PSCustomObjects or select specific properties.
By combining clear intent, environment constraints and iterative review, you'll get accurate, PowerShell 7‑friendly and maintainable code from GitHub Copilot: it's much faster than starting from a blank file and safer than accepting the first suggestion at face value.
Examples of PowerShell prompts for GitHub Copilot
Below is a practical "prompt pack" you can paste into GitHub Copilot Chat and adapt. Use placeholders, such as <FILE>, <FUNCTION>, <MODULE>, <RESOURCE_GROUP>, <PS_VERSION>, <RULESET> and <TARGET>.
Here are some quick tips:
- Be explicit about PowerShell version, modules and constraints; GitHub Copilot performs better with clear direction and current APIs, such as PS7, Az modules and CIM instead of WMI.
- If GitHub Copilot suggests deprecated patterns, such as AzureRM or Get-WmiObject, correct it once; subsequent completions typically follow your change.
- Favor single, well-scoped queries and return objects. Avoid per-item re-queries and Write-Host in library code.
Foundation/constraints priming
"You are my PowerShell pair programmer. Constraints: PowerShell 7.x only; cross-platform safe; avoid legacy cmdlets; avoid AzureRM (use Az modules, Connect-AzAccount); return objects (no Write-Host); add error handling (try/catch), parameter validation and ShouldProcess with -WhatIf/-Confirm; follow PSScriptAnalyzer defaults and PowerShell style best practices."
PowerShell 7-only refactor and modernization
"Refactor <FILE> to PowerShell 7-only: replace deprecated cmdlets, ensure cross-platform compatibility, remove Write-Host in favor of pipeline-friendly output, add CmdletBinding and ShouldProcess and include comment-based help. Explain each breaking change and why it's needed for PS7."
PSScriptAnalyzer audit and fixes
"Run PSScriptAnalyzer on <FILE> using default rules (or this custom settings: <RULESET>). List violations with rule IDs and lines, then propose minimal, safe fixes. Apply fixes in an updated version of <FILE>. Where a justified exception is needed, add [Diagnostics.CodeAnalysis.SuppressMessage()] with a rationale in comments."
Generate Pester tests
"Generate Pester v5 tests for <FUNCTION>/<MODULE>: include Arrange/Act/Assert structure, mocks for external calls (filesystem, registry, network, Az cmdlets), tests for -WhatIf/-Confirm, error paths, parameter validation and at least one table-driven test. Target PS7. Output tests in a new file named <FUNCTION>.Tests.ps1 suitable for CI."
Comment-based help and docs
"Add comment-based help to <FUNCTION>: .SYNOPSIS, .DESCRIPTION, .PARAMETER (each), .EXAMPLE (3+ realistic examples), .NOTES, .LINK to docs. Then produce a README snippet describing usage, prerequisites (modules/versions) and examples."
"For <MODULE>, generate a CHANGELOG entry for version <TARGET>, summarizing fixes, features and breaking changes, with links to related functions."
Secure-by-default hardening
"Review <FILE> for security issues: remove plaintext secrets, use Get-Credential or managed identity patterns, validate all external inputs, use least-privilege RBAC in examples, set $ErrorActionPreference = 'Stop' inside critical sections and ensure sensitive data is not logged. Provide a diff-like summary of changes."
Azure script modernization and correctness
"Update this Azure script to current Az modules: authenticate with Connect-AzAccount, select subscription/context, capture resource outputs in variables and use supported parameters for New-AzResourceGroup. Replace any AzureRM usage. Ensure idempotent behavior where practical and include tags. Explain any parameter changes due to module updates."
Performance and efficiency review
"Profile the logic in <FILE> for unnecessary loops and redundant cmdlet calls. Consolidate into single queries where possible (e.g., query services once, then project fields). Replace per-item calls with batched or pipeline operations. Return only required properties and avoid materializing unused data. Provide the optimized version and a short rationale for each change."
Refactor for module quality
"Turn <FILE> into a reusable module function: add [CmdletBinding()], [Parameter()] attributes (Mandatory, ValidateSet/Pattern/Range), supports ShouldProcess, pipeline input where appropriate, structured output (PSCustomObject or typed objects), verbose logging via Write-Verbose and comment-based help. Include a public/private function split if needed."
Documentation from code
"Generate a Markdown README for <MODULE> with: overview, installation, required module versions, usage examples for each public function, configuration and environment variables, troubleshooting and a section on security considerations. Cross-link to comment-based help."
Error handling and resiliency
"Add robust error handling to <FUNCTION>: set $ErrorActionPreference within scope, use try/catch with specific exception types, clean up resources in finally and emit actionable error messages. Ensure all external cmdlets use -ErrorAction Stop where appropriate."
Continuous integration-ready outputs
"Produce a CI checklist for this repo: run PSScriptAnalyzer, run Pester v5, verify no secrets committed, format with PowerShell extension settings and fail on analyzer or test errors. Provide a GitHub Actions workflow yaml that runs on push/PR to main."
Targeted property selection and correctness
"For this task, list running services with their logon accounts in PS7 using CIM (not WMI). Avoid looping and re-querying; return Name, DisplayName, State, StartName as objects. Provide the minimal, efficient snippet and a one-line explanation."
Prompt patterns for iterative editing
"Explain what this function does, identify risks and deprecated APIs and propose a safer, PS7-compatible rewrite. Then apply the rewrite."
"Propose a small, incremental refactor to improve readability and testability (max 10 lines changed), then show a larger refactor that improves structure (max 50 lines)."
House style and formatting
"Reformat <FILE> to match PowerShell style: 2-space indents, PascalCase for functions, singular nouns for functions, approved verbs, consistent parameter ordering (-Name, -Id, -Path, etc.) and one pipeline per line. Do not alter logic; only formatting and naming where safe."
When asking Copilot to modify code, supply the file or selection and say "apply changes to this file" so it proposes an inline edit. If it drifts, restate constraints and correct once. Its next suggestion usually aligns with your guidance.
How to get the most out of GitHub Copilot
GitHub Copilot is now a credible accelerator for PowerShell work. It's capable of drafting scripts from natural language descriptions, refactoring legacy code and stitching together Azure automation -- so long as you keep an expert's hand on the wheel.
For day‑to‑day administration, VS Code combined with GitHub Copilot can collapse hours of boilerplate coding into minutes. Even when GitHub Copilot's first draft isn't perfect, it often gets you most of the way there, translating into meaningful time savings on common tasks.
With precise prompts, careful review and routine testing, GitHub Copilot becomes a reliable force multiplier for scripting, troubleshooting and Azure orchestration when working under deadline pressure.
James Bannan is a principal security consultant with more than 25 years of industry experience, specializing in Microsoft Azure architecture, security and automation. He is a published author and journalist, as well as a former Microsoft MVP and a current Microsoft Certified Trainer.