Visual Studio Code for PowerShell and Microsoft 365

For Microsoft 365 administration, Visual Studio Code is the successor to ISE. It is free, runs PowerShell 7, debugs your scripts and warns about mistakes before you press Enter. This guide sets VS Code up for daily work with Graph, PnP and Exchange Online.

Installing

Shell
winget install --id Microsoft.PowerShell --source winget
winget install --id Microsoft.VisualStudioCode --source winget
code --install-extension ms-vscode.powershell

PowerShell 7 as the default

The extension starts its own console, the “PowerShell Extension Terminal”. Pick which PowerShell it uses from the Command Palette (Ctrl+Shift+P) → PowerShell: Show Session Menu. To make it stick, add this to your settings (settings.json):

JSON
{
  "powershell.powerShellDefaultVersion": "PowerShell (x64)",
  "powershell.integratedConsole.focusConsoleOnExecute": false,
  "files.encoding": "utf8bom",
  "[powershell]": { "editor.formatOnSave": true }
}

utf8bom prevents Windows PowerShell 5.1 from misreading characters like é and ë in scripts you still run there.

Working like in ISE

Command Palette → PowerShell: Enable ISE Mode. F5 runs the script, F8 the selection. Variables from a run stay available in the console, just like ISE, so you can keep filtering after an export.

Debugging

Click left of a line number for a breakpoint and press F5. The script stops there and the Variables panel shows what each variable holds, for example the result of Get-PnPListItem. F10 steps line by line. It is the quickest way to see why a filter returns nothing.

A profile with standard connections

VS Code has its own profile file, separate from ISE and the regular console. Open it with:

PowerShell
if (!(Test-Path $PROFILE)) { New-Item -Path $PROFILE -ItemType File -Force }
code $PROFILE

Put short functions there for connections you make often. No passwords or secrets; use interactive sign-in or a certificate.

PowerShell
function Connect-Contoso {
    Connect-MgGraph -Scopes 'User.Read.All','Group.Read.All' -NoWelcome
    Connect-PnPOnline -Url 'https://contoso.sharepoint.com' -Interactive -ClientId '<client id>'
}

Take the warnings seriously

The extension includes PSScriptAnalyzer. Yellow squiggles point at aliases in scripts, unused variables or a plain-text password. That last one is the most common security mistake in Microsoft 365 scripts. Store secrets with the Microsoft.PowerShell.SecretManagement module instead.

Useful habits

  • One folder (workspace) per customer or tenant, with Git for versioning your scripts.
  • The terminal keeps Graph and PnP sessions while you edit the script. Disconnect with Disconnect-MgGraph and Disconnect-PnPOnline before switching tenants.
  • Cmdlet suddenly behaves differently? Check which version is loaded with Get-Module.

See also PowerShell 7 in ISE and Cleaning up PowerShell modules.

Frequent errors and how to fix them

These are the messages people type into search when the module will not start. The exact wording is here so this page can be found.

pwsh is not recognized
PowerShell 7 is not on PATH. Restart after winget install Microsoft.PowerShell.
Cannot run PowerShell 7 in ISE
ISE is 5.1-only. Use the VS Code PowerShell extension in ISE mode.

Questions about this, or need help setting it up? We are happy to think along.

Message on LinkedIn →