What is PowerShell
PowerShell is a cross-platform task automation solution made up of a command-line shell, a scripting language, and a configuration management framework. PowerShell runs on Windows, Linux, and macOS. [1]
Commands for PowerShell are known as cmdlets (pronounced command-lets). In addition to cmdlets, PowerShell allows you to run any command available on your system. [2]
-
Cmdlets are native PowerShell commands, not stand-alone executables.
-
Cmdlets are collected into PowerShell modules that can be loaded on demand.
-
Cmdlets can be written in any compiled .NET language or in the PowerShell scripting language itself.
-
PowerShell uses a Verb-Noun name pair to name cmdlets.
PowerShell includes cmdlets that help you discover PowerShell. Using these three cmdlets, you can discover what commands available, what they do, and what types they operate on. [3]
-
Get-Verb
. Running this command returns a list of verbs that most commands adhere to. The response includes a description of what these verbs do. Since most commands follow this naming convention, it sets expectations on what a command does. This helps you select the appropriate command and what to name a command, should you be creating one. -
Get-Command
. This command retrieves a list of all commands installed on your machine. -
Get-Member
. It operates on object based output and is able to discover what object, properties and methods are available for a command. -
Get-Help
. Invoking this command with the name of a command as an argument displays a help page describing various parts of a command.
Using these commands, you can discover almost anything you need to know about PowerShell.
Get-Command -Name Get-Process
Get-Command -Name *-Process | Select-Object -First 2
Get-Command -Verb Get | Select-Object -First 2
Get-Command -Noun Process | Select-Object -First 2
Get-Process | Get-Member | Select-Object -First 3
Get-Process | Get-Member -MemberType Method | Select-Object -First 3
Get-Command -ParameterType Process | Select-Object -First 3
Get-Help -Name Get-Command -Full
Get-Help -Name Get-Command -Detailed
Get-Help -Name Get-Command -Examples
Get-Help -Name Get-Command -Online
Get-Help -Name Get-Command -Parameter Noun
Get-Help -Name Get-Command -ShowWindow
- 1. Getting Started with PowerShell
- 2. The PowerShellGet module
- 3. Scripting language
- 4. Manage Microsoft 365 with PowerShell
- 4.1. Azure Active Directory PowerShell for Graph
- 4.2. Azure Active Directory Module (MSOnline) for Windows PowerShell
- 4.3. Microsoft Graph PowerShell SDK
- 4.3.1. Installation
- 4.3.2. Use PowerShell SDK
- 4.3.3. Using authentication cmdlets
- 4.3.4. Using Find-MgGraphCommand cmdlet
- 4.3.5. Using Find-MgGraphPermission cmdlet
- 4.3.6. View Microsoft 365 licenses and services with PowerShell
- 4.3.7. View licensed and unlicensed Microsoft 365 users with PowerShell
- 4.3.8. Assign Microsoft 365 licenses to user accounts with PowerShell
- 4.3.9. View Microsoft 365 account license and service details with PowerShell
- 4.3.10. Remove Microsoft 365 licenses from user accounts with PowerShell
- 4.3.11. Disable access to Microsoft 365 services with PowerShell
- 4.4. Exchange Online PowerShell
- 5. Azure PowerShell
- References
1. Getting Started with PowerShell
All modern versions of Windows operating systems ship with PowerShell installed. If you’re running a version older than 5.1, you should install the latest version.
-
To upgrade to Windows PowerShell 5.1, see Upgrading existing Windows PowerShell
-
To install the latest version of PowerShell, see Installing PowerShell
1.1. What version of PowerShell am I running?
There are a number of automatic variables in PowerShell that store state information. One of these variables is $PSVersionTable
, which contains a hashtable that can be used to display the relevant PowerShell version information:
PS C:\> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.19041.3031
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.19041.3031
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
1.2. Execution Policy
Contrary to popular belief, the execution policy in PowerShell is not a security boundary. It’s designed to prevent a user from unknowingly running a script.
Regardless of the execution policy setting, any PowerShell command can be run interactively. The execution policy only affects commands running in a script.
The Get-ExecutionPolicy
cmdlet is used to determine what the current execution policy setting is and the Set-ExecutionPolicy
cmdlet is used to change the execution policy.
PS C:\> Get-ExecutionPolicy
RemoteSigned
PS C:\> Get-ExecutionPolicy -List
Scope ExecutionPolicy
----- ---------------
MachinePolicy Undefined
UserPolicy Undefined
Process Undefined
CurrentUser RemoteSigned
LocalMachine Undefined
It’s recommended to use the RemoteSigned policy, which requires downloaded scripts to be signed by a trusted publisher in order to be run.
PowerShell scripts can’t be run at all when the execution policy is set to Restricted. This is the default setting on all Windows client operating systems.
PS C:\> Set-ExecutionPolicy -Scope CurrentUser Restricted
PS C:\> Get-Service -Name W32Time | Stop-Service -PassThru
Status Name DisplayName
------ ---- -----------
Stopped W32Time Windows Time
PS C:\> echo 'Get-Service -Name W32Time | Stop-Service -PassThru' > Stop-TimeService.ps1
PS C:\> .\Stop-TimeService.ps1
.\Stop-TimeService.ps1 : File C:\Stop-TimeService.ps1 cannot be loaded because running scripts is disabled on this system. For more
information, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.
At line:1 char:1
+ .\Stop-TimeService.ps1
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : SecurityError: (:) [], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess
PS C:\> Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
PS C:\> .\Stop-TimeService.ps1
Status Name DisplayName
------ ---- -----------
Stopped W32Time Windows Time
1.3. The Help System
Compiled commands in PowerShell are called cmdlets. Cmdlet is pronounced "command-let" (not CMD-let). Cmdlets names have the form of singular "Verb-Noun" commands to make them easily discoverable.
1.3.1. Get-Help
Get-Help
is a multipurpose command. Get-Help
helps you learn how to use commands once you find them. Get-Help
can also be used to help locate commands, but in a different and more indirect way when compared to Get-Command
.
When Get-Help
is used to locate commands, it first searches for wildcard matches of command names based on the provided input. If it doesn’t find a match, it searches through the help topics themselves, and if no match is found an error is returned. Contrary to popular belief, Get-Help
can be used to find commands that don’t have help topics.
Get-Help -Name Get-Help
Help
is a function that pipes Get-Help
to a function named more
, which is a wrapper for the more.com
executable file in Windows.
Get-Help -Name Get-Help -Full
help -Name Get-Help -Full
help Get-Help -Full
Get-Help -Name Get-Command -Full
Get-Help -Name Get-Command -Detailed
Get-Help -Name Get-Command -Examples
Get-Help -Name Get-Command -Online
Get-Help -Name Get-Command -Parameter Noun
Get-Help -Name Get-Command -ShowWindow
1.3.2. Get-Command
Get-Command
is designed to help you locate commands. Running Get-Command
without any parameters returns a list of all the commands on your system.
Get-Command -Name *service* -CommandType Cmdlet, Function, Alias
Use Get-Command
with the Module parameter to determine what commands were added as part of the ActiveDirectory PowerShell module when the remote server administration tools were installed.
Get-Command -Module ActiveDirectory
1.3.3. Get-Member
Get-Member
helps you discover what objects, properties, and methods are available for commands. Any command that produces object-based output can be piped to Get-Member
.
Get-Service -Name w32time
Get-Service -Name w32time | Get-Member
Get-Command -ParameterType ServiceController
Get-Service -Name w32time | Select-Object -Property *
Get-Service -Name w32time | Select-Object -Property Status, Name, DisplayName, ServiceType
Get-Service -Name w32time | Select-Object -Property Status, DisplayName, Can*
Get-Service -Name w32time | Get-Member -MemberType Method
(Get-Service -Name w32time).Stop()
1.4. Formatting, aliases, providers, comparison
The most common format commands are Format-Table
and Format-List
. Format-Wide
and Format-Custom
can also be used, but are less common.
PS C:\> Get-Service -Name w32time | Select-Object -Property Status, DisplayName, Can*
Status : Running
DisplayName : Windows Time
CanPauseAndContinue : False
CanShutdown : True
CanStop : True
PS C:\> Get-Service -Name w32time | Select-Object -Property Status, DisplayName, Can* | Format-Table
Status DisplayName CanPauseAndContinue CanShutdown CanStop
------ ----------- ------------------- ----------- -------
Running Windows Time False True True
PS C:\> Get-Service -Name w32time | Format-List
Name : w32time
DisplayName : Windows Time
Status : Running
DependentServices : {}
ServicesDependedOn : {}
CanPauseAndContinue : False
CanShutdown : True
CanStop : True
ServiceType : Win32OwnProcess, Win32ShareProcess
An alias in PowerShell is a shorter name for a command. PowerShell includes a set of built-in aliases and you can also define your own aliases.
The Get-Alias
cmdlet is used to find aliases. If you already know the alias for a command, the Name parameter is used to determine what command the alias is associated with.
PS C:\> Get-Alias -Name gcm
CommandType Name Version Source
----------- ---- ------- ------
Alias gcm -> Get-Command
PS C:\> Get-Alias -Name gcm, gm
CommandType Name Version Source
----------- ---- ------- ------
Alias gcm -> Get-Command
Alias gm -> Get-Member
A provider in PowerShell is an interface that allows file system like access to a datastore. There are a number of built-in providers in PowerShell.
PS C:\> Get-PSProvider
Name Capabilities Drives
---- ------------ ------
Registry ShouldProcess, Transactions {HKLM, HKCU}
Alias ShouldProcess {Alias}
Environment ShouldProcess {Env}
FileSystem Filter, ShouldProcess, Credentials {C, D}
Function ShouldProcess {Function}
Variable ShouldProcess {Variable}
Certificate ShouldProcess {Cert}
WSMan Credentials {WSMan}
The actual drives that these providers use to expose their datastore can be determined with the Get-PSDrive
cmdlet. The Get-PSDrive
cmdlet not only displays drives exposed by providers, but it also displays Windows logical drives including drives mapped to network shares.
PS C:\> Get-PSDrive
Name Used (GB) Free (GB) Provider Root CurrentLocation
---- --------- --------- -------- ---- ---------------
Alias Alias
C 138.14 131.16 FileSystem C:\
Cert Certificate \
D 205.78 0.33 FileSystem D:\
Env Environment
Function Function
HKCU Registry HKEY_CURRENT_USER
HKLM Registry HKEY_LOCAL_MACHINE
Variable Variable
WSMan WSMan
Third-party modules such as the Active Directory PowerShell module and the SQLServer PowerShell module both add their own PowerShell provider and PSDrive.
PS C:\> Import-Module SqlServer
PS C:\> Get-PSProvider
Name Capabilities Drives
---- ------------ ------
Registry ShouldProcess {HKLM, HKCU}
Alias ShouldProcess {Alias}
Environment ShouldProcess {Env}
FileSystem Filter, ShouldProcess, Credentials {C, D, Temp}
Function ShouldProcess {Function}
Variable ShouldProcess {Variable}
SqlServer Credentials {SQLSERVER}
Certificate ShouldProcess {Cert}
WSMan Credentials {WSMan}
PS C:\> Get-PSDrive
Name Used (GB) Free (GB) Provider Root CurrentLocation
---- --------- --------- -------- ---- ---------------
Alias Alias
C 138.14 131.16 FileSystem C:\
Cert Certificate \
D 205.78 0.33 FileSystem D:\
Env Environment
Function Function
HKCU Registry HKEY_CURRENT_USER
HKLM Registry HKEY_LOCAL_MACHINE
SQLSERVER SqlServer SQLSERVER:\
Temp 138.14 131.16 FileSystem C:\Users\xuqiang3\AppData\Local\Te…
Variable Variable
WSMan WSMan
PSDrives can be accessed just like a traditional file system.
PS C:\> Get-ChildItem -Path Cert:\LocalMachine\CA
PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\CA
Thumbprint Subject EnhancedKeyUsageList
---------- ------- --------------------
FEE449EE0E3965A5246F000E87FDE2A065FD89D4 CN=Root Agency
D559A586669B08F46A30A133F8A9ED3D038E2EA8 OU=www.verisign.com… {Server Authentication, Client Authentication, $null, $null}
D4FFDB19BA590FFFAA34DB5F4B568706A2978436 CN=Microsoft TPM Ro…
5E94211AC5D477F157230E6E316AA923E521AF2C CN=NCU-INTC-KEYID-B… {$null, Attestation Identity Key Certificate}
109F1CAED645BB78B3EA2B94C0697C740733031C CN=Microsoft Window… {Code Signing, Windows Hardware Driver Verification}
PowerShell contains a number of comparison operators that are used to compare values or find values that match certain patterns. Table 5-1 contains a list of comparison operators in PowerShell.
Operator | Definition |
---|---|
-eq |
Equal to |
-ne |
Not equal to |
-gt |
Greater than |
-ge |
Greater than or equal to |
-lt |
Less than |
-le |
Less than or equal to |
-Like |
Match using the * wildcard character |
-NotLike |
Does not match using the * wildcard character |
-Match |
Matches the specified regular expression |
-NotMatch |
Does not match the specified regular expression |
-Contains |
Determines if a collection contains a specified value |
-NotContains |
Determines if a collection does not contain a specific value |
-In |
Determines if a specified value is in a collection |
-NotIn |
Determines if a specified value is not in a collection |
-Replace |
Replaces the specified value |
2. The PowerShellGet module
The PowerShellGet module contains cmdlets for discovering, installing, updating, and publishing PowerShell packages from the PowerShell Gallery. These packages can contain artifacts such as Modules, DSC Resources, and Scripts.
Use the following command to see what version is installed.
PS C:\> Get-Module PowerShellGet, PackageManagement
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Binary 1.0.0.1 PackageManagement {Find-Package, Find-PackageProvider, Get-Package, Get-PackageProvider...}
Script 1.0.0.1 PowerShellGet {Find-Command, Find-DscResource, Find-Module, Find-RoleCapability...}
To install the latest versions of these modules run the following:
Install-Module PowerShellGet -Force -AllowClobber
Windows PowerShell 5.1 comes with version 1.0.0.1 of the PowerShellGet and PackageManagement preinstalled. This version of PowerShellGet has a limited features and must be updated to work with the PowerShell Gallery. To be supported, you must update to the latest version.
Windows PowerShell 5.1 comes with PowerShellGet version 1.0.0.1, which doesn’t include the NuGet provider. The provider is required by PowerShellGet when working with the PowerShell Gallery.
There are two ways to install the NuGet provider:
-
Use
Install-PackageProvider
to install NuGet before installing other modulesRun the following command to install the NuGet provider.
Install-PackageProvider -Name NuGet -Force
After you have installed the provider you should be able to use any of the PowerShellGet cmdlets with the PowerShell Gallery.
-
Let
Install-Module
prompt you to install the NuGet providerThe following command attempts to install the updated PowerShellGet module without the NuGet provider.
Install-Module PowerShellGet -AllowClobber -Force
After you have installed the new version of PowerShellGet, you should open a new PowerShell session. PowerShell automatically loads the newest version of the module when you use a PowerShellGet cmdlet.
It’s also recommended to register the PowerShell Gallery as a trusted repository. Use the following command:
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
3. Scripting language
As a scripting language, PowerShell is commonly used for automating the management of systems. It’s also used to build, test, and deploy solutions, often in CI/CD environments. PowerShell is built on the .NET Common Language Runtime (CLR). All inputs and outputs are .NET objects. No need to parse text output to extract information from output. The PowerShell scripting language includes the following features:
-
Extensible through functions, classes, scripts, and modules
-
Extensible formatting system for easy output
-
Extensible type system for creating dynamic types
-
Built-in support for common data formats like CSV, JSON, and XML
3.1. How to run a script
Before you can run a script on Windows, you need to change the default PowerShell execution policy. Execution policy does not apply to PowerShell running on non-Windows platforms.
The default execution policy, Restricted, prevents all scripts from running, including scripts that you write on the local computer. For more information, see about_Execution_Policies.
The execution policy is saved in the registry, so you need to change it only once on each computer.
To change the execution policy, use the following procedure.
At the command prompt, type:
Set-ExecutionPolicy AllSigned
or
Set-ExecutionPolicy RemoteSigned
The change is effective immediately.
To run a script, type the full name and the full path to the script file.
For example, to run the Get-ServiceLog.ps1 script in the C:\Scripts
directory, type:
C:\Scripts\Get-ServiceLog.ps1
To run a script in the current directory, type the path to the current directory, or use a dot to represent the current directory, followed by a path backslash (.\
).
For example, to run the ServicesLog.ps1 script in the local directory, type: PowerShell
.\Get-ServiceLog.ps1
If the script has parameters, type the parameters and parameter values after the script filename.
For example, the following command uses the ServiceName parameter of the Get-ServiceLog script to request a log of WinRM service activity.
.\Get-ServiceLog.ps1 -ServiceName WinRM
As a security feature, PowerShell does not run scripts when you double-click the script icon in File Explorer or when you type the script name without a full path, even when the script is in the current directory.
Beginning in PowerShell 3.0, you can run scripts from File Explorer.
-
To use the "Run with PowerShell" feature: Run File Explorer, right-click the script filename and then select "Run with PowerShell".
-
The "Run with PowerShell" feature is designed to run scripts that do not have required parameters and do not return output to the command prompt.
3.2. How to write a script
A script can contain any valid PowerShell commands, including single commands, commands that use the pipeline, functions, and control structures such as If statements and For loops.
To write a script, open a new file in a text editor, type the commands, and save them in a file with a valid filename with the .ps1
file extension.
To define parameters in a script, use a Param
statement. The Param
statement must be the first statement in a script, except for comments and any #Require
statements.
Script parameters work like function parameters. The parameter values are available to all of the commands in the script. All of the features of function parameters, including the Parameter attribute and its named arguments, are also valid in scripts.
# Test-Remote.ps1
param ($ComputerName = $(throw "ComputerName parameter is required."))
function CanPing {
$error.clear()
$tmp = test-connection $computername -erroraction SilentlyContinue
if (!$?)
{write-host "Ping failed: $ComputerName."; return $false}
else
{write-host "Ping succeeded: $ComputerName"; return $true}
}
function CanRemote {
$s = new-pssession $computername -erroraction SilentlyContinue
if ($s -is [System.Management.Automation.Runspaces.PSSession])
{write-host "Remote test succeeded: $ComputerName."}
else
{write-host "Remote test failed: $ComputerName."}
}
if (CanPing $computername) {CanRemote $computername}
3.3. Functions
A function is a list of PowerShell statements that has a name that you assign. When you run a function, you type the function name. The statements in the list run as if you had typed them at the command prompt.
Functions can be as simple as:
function Get-PowerShellProcess { Get-Process PowerShell }
Like cmdlets, functions can have parameters. The parameters can be named, positional, switch, or dynamic parameters. Function parameters can be read from the command line or from the pipeline.
Functions can return values that can be displayed, assigned to variables, or passed to other functions or cmdlets. You can also specify a return value using the return
keyword. The return
keyword doesn’t affect or suppress other output returned from your function. However, the return
keyword exits the function at that line.
The function’s statement list can contain different types of statement lists with the keywords begin
, process
, end
, and clean
. These statement lists handle input from the pipeline differently.
The filter
keyword is used to create a type of function that runs on each object in the pipeline. A filter resembles a function with all its statements in a process block.
The following are the syntax for a function:
function [<scope:>]<name> [([type]$parameter1[,[type]$parameter2])]
{
begin {<statement list>}
process {<statement list>}
end {<statement list>}
clean {<statement list>}
}
function [<scope:>]<name>
{
param([type]$parameter1 [,[type]$parameter2])
dynamicparam {<statement list>}
begin {<statement list>}
process {<statement list>}
end {<statement list>}
clean {<statement list>}
}
A function includes the following items:
-
A
function
keyword -
A scope (optional)
-
A name that you select
-
Any number of named parameters (optional)
-
One or more PowerShell commands enclosed in braces {}
Functions don’t have to be complicated to be useful. The simplest functions have the following format:
function <function-name> {statements}
For example, the following function starts PowerShell with the Run as Administrator option.
function Start-PSAdmin {Start-Process PowerShell -Verb RunAs}
4. Manage Microsoft 365 with PowerShell
PowerShell for Microsoft 365 enables you to manage your Microsoft 365 settings from the command line. To connect to PowerShell, just install the required software and then connect to your Microsoft 365 organization. [4]
There are two versions of the PowerShell module that you can use to connect to Microsoft 365 and administer user accounts, groups, and licenses:
-
Azure Active Directory PowerShell for Graph, whose cmdlets include AzureAD in their name
-
Microsoft Azure Active Directory Module for Windows PowerShell, whose cmdlets include Msol in their name
Currently, the Azure Active Directory PowerShell for Graph module doesn’t completely replace the functionality of the Microsoft Azure Active Directory Module for Windows PowerShell module for user, group, and license administration. In some cases, you need to use both versions. You can safely install both versions on the same computer.
The Azure Active Directory Module is being replaced by the Microsoft Graph PowerShell SDK. You can use the Microsoft Graph PowerShell SDK to access all Microsoft Graph APIs. |
4.1. Azure Active Directory PowerShell for Graph
Azure AD Powershell is planned for deprecation on March 30, 2024. For more details on the deprecation plans, see the deprecation update. We encourage you to continue migrating to Microsoft Graph PowerShell, which is the recommended module for interacting with Azure AD. In addition, Microsoft Graph PowerShell allows you access to all Microsoft Graph APIs and is available on PowerShell 7. For answers to frequent migration queries, see the Migration FAQ. |
You can use the Azure Active Directory PowerShell module version for Graph for Azure AD administrative tasks such as user management, domain management and for configuring single sign-on.
The Azure AD PowerShell module is not compatible with PowerShell 7. It is only supported in PowerShell 5.1. |
To install the General Availability version of the module, run:
Install-Module AzureAD
To connect to Azure Active Directory (Azure AD) for your Microsoft 365 subscription with an account name and password or with multi-factor authentication, run one of these commands from a Windows PowerShell command prompt. [4]
Office 365 cloud | Command |
---|---|
Office 365 Worldwide (+GCC) |
|
Office 365 operated by 21 Vianet |
|
Office 365 Germany |
|
Office 365 U.S. Government DoD and Office 365 U.S. Government GCC High |
|
4.2. Azure Active Directory Module (MSOnline) for Windows PowerShell
MSOnline is planned for deprecation on March 30, 2024. For more details on the deprecation plans, see the deprecation update. We encourage you to continue migrating to Microsoft Graph PowerShell, which is the recommended module for interacting with Azure AD. In addition, Microsoft Graph PowerShell allows you access to all Microsoft Graph APIs and is available on PowerShell 7. For answers to frequent migration queries, see the Migration FAQ. |
Follow these steps to install and import the Microsoft Azure Active Directory Module for Windows PowerShell:
-
Open an elevated Windows PowerShell command prompt (run Windows PowerShell as an administrator).
-
Run the Install-Module MSOnline command.
-
If you’re prompted to install the NuGet provider, type Y and press Enter.
-
If you’re prompted to install the module from PSGallery, type Y and press Enter.
-
Run the Import-Module MSOnline command to import the module.
To connect to Azure AD for your Microsoft 365 subscription with an account name and password or with multi-factor authentication, run one of these commands from a Windows PowerShell command prompt. (It doesn’t have to be elevated.)
Office 365 cloud | Command |
---|---|
Office 365 Worldwide (+GCC) |
|
Office 365 operated by 21 Vianet |
|
Office 365 Germany |
|
Office 365 U.S. Government DoD and Office 365 U.S. Government GCC High |
|
4.3. Microsoft Graph PowerShell SDK
The Microsoft Graph PowerShell SDK acts as an API wrapper for the Microsoft Graph APIs, exposing the entire API set for use in PowerShell. It contains a set of cmdlets that helps you manage identities at scale from automating tasks to managing users in bulk using Azure Active Directory (Azure AD). It will help administer every Azure AD feature that has an API in Microsoft Graph. [5]
The Microsoft Graph PowerShell SDK provides the following benefits:
-
Access to all Microsoft Graph APIs: Microsoft Graph PowerShell is based on Microsoft Graph API. In addition to Azure AD, the Microsoft Graph API includes APIs from other Microsoft services like SharePoint, Exchange, and Outlook, all accessed through a single endpoint with a single access token.
-
Supports PowerShell 7: Microsoft Graph PowerShell works with PowerShell 7 and later. It’s also compatible with Windows PowerShell 5.1.
-
Cross-platform support: Microsoft Graph PowerShell works on all platforms including Windows, macOS, and Linux.
-
Supports modern authentication: Microsoft Graph PowerShell supports the Microsoft Authentication Library (MSAL) which offers more security. For example, you can use passwordless sign-in experiences.
-
Supports external identities: Users from other Azure AD tenants can authenticate to services in your tenant with Microsoft Graph PowerShell.
-
Uses least privilege: Microsoft Graph PowerShell permissions are not pre-authorized and users must perform one-time request for app permissions depending on their needs.
-
Advanced queries: Microsoft Graph PowerShell supports rich, advanced queries via eventual consistency. For example, you can get a near-instant count of all users using advanced queries.
-
Open source: Feature teams and the community can create great PowerShell experiences and share them with everyone.
-
Receives regular updates: Microsoft Graph PowerShell commands are updated regularly to support the latest Graph API updates.
4.3.1. Installation
The Microsoft Graph PowerShell SDK comes in 2 modules, Microsoft.Graph and Microsoft.Graph.Beta, that you will install separately. These modules call the Microsoft Graph v1.0 and Microsoft Graph beta endpoints, respectively. You can install the 2 modules on the same PowerShell version.
Using the Install-Module cmdlet is the preferred installation method for the Microsoft Graph PowerShell modules.
To install the v1 module of the SDK in PowerShell Core or Windows PowerShell, run the following command.
Install-Module Microsoft.Graph -Scope CurrentUser
Optionally, you can change the scope of the installation using the -Scope
parameter. This requires admin permissions.
Install-Module Microsoft.Graph -Scope AllUsers
To install the beta module, run the following command.
Install-Module Microsoft.Graph.Beta
After the installation is completed, you can verify the installed version with the following command.
Get-InstalledModule Microsoft.Graph
To verify the installed sub-modules and their versions, run:
Get-InstalledModule
The version in the output should match the latest version published on the PowerShell Gallery. Now you’re ready to use the SDK.
4.3.2. Use PowerShell SDK
The PowerShell SDK supports two types of authentication: delegated access, and app-only access.
Each API in the Microsoft Graph is protected by one or more permission scopes. The user logging in must consent to one of the required scopes for the APIs you plan to use.
The Find-MgGraphCommand
cmdlet can be used to discover the required permissions for another cmdlet. For example, to see all permissions that can be used to call Get-MgUser
, run;
Find-MgGraphCommand -command Get-MgUser | Select -First 1 -ExpandProperty Permissions
PS C:\> Find-MgGraphCommand -Command Get-MgUser
APIVersion: v1.0
Command Module Method URI OutputType Permissions
------- ------ ------ --- ---------- -----------
Get-MgUser Users GET /users IMicrosoftGraphUser {DeviceManagementApps.Read.All, DeviceManagementApps.ReadWrite.All, DeviceMana...
Get-MgUser Users GET /users/{user-id} IMicrosoftGraphUser {DeviceManagementApps.Read.All, DeviceManagementApps.ReadWrite.All, DeviceMana...
PS C:\> Find-MgGraphCommand -Command Get-MgUser | Select -First 1 -ExpandProperty Permissions
Name IsAdmin Description FullDescription
---- ------- ----------- ---------------
DeviceManagementApps.Read.All True Read Microsoft Intune apps Allows the app to rea...
DeviceManagementApps.ReadWrite.All True Read and write Microsoft Intune apps Allows the app to rea...
DeviceManagementConfiguration.Read.All True Read Microsoft Intune Device Configuration and Policies Allows the app to rea...
DeviceManagementConfiguration.ReadWrite.All True Read and write Microsoft Intune Device Configuration and Policies Allows the app to rea...
DeviceManagementManagedDevices.Read.All True Read devices Microsoft Intune devices Allows the app to rea...
DeviceManagementManagedDevices.ReadWrite.All True Read and write Microsoft Intune devices Allows the app to rea...
DeviceManagementServiceConfig.Read.All True Read Microsoft Intune configuration Allows the app to rea...
DeviceManagementServiceConfig.ReadWrite.All True Read and write Microsoft Intune configuration Allows the app to rea...
Directory.Read.All True Read directory data Allows the app to rea...
Directory.ReadWrite.All True Read and write directory data Allows the app to rea...
User.Read.All True Read all users' full profiles Allows the app to rea...
User.ReadBasic.All False Read all users' basic profiles Allows the app to rea...
User.ReadWrite.All True Read and write all users' full profiles Allows the app to rea...
Use the Connect-MgGraph
command to sign in with the required scopes. You’ll need to sign in with an admin account to consent to the required scopes.
Connect-MgGraph -Scopes "User.Read.All","Group.ReadWrite.All"
The command prompts you to go to a web page to sign in with your credentials. Once you’ve done that, the command indicates success with a Welcome To Microsoft Graph!
message. You only need to sign in once per session.
You can add additional permissions by repeating the Connect-MgGraph command with the new permission scopes.
|
Use the Disconnect-MgGraph command to sign out.
Disconnect-MgGraph
4.3.3. Using authentication cmdlets
Microsoft Graph PowerShell supports two types of authentication: delegated and app-only access. There are a number of cmdlets that can be used to manage the different parameters required during authentication, for example, environment, application ID, and certificate. [6]
4.3.3.1. Using Connect-MgGraph
You must invoke Connect-MgGraph
before any commands that access Microsoft Graph. This cmdlet gets the access token using the Microsoft Authentication Library.
-
Delegated access
There are three ways to allow delegated access using
Connect-MgGraph
:-
Using interactive authentication, where you provide the scopes that you require during your session:
Connect-MgGraph -Scopes "User.Read.All", "Group.ReadWrite.All"
-
Using device code flow:
Connect-MgGraph -Scopes "User.Read.All", "Group.ReadWrite.All" -UseDeviceAuthentication
-
Using your own access token:
Connect-MgGraph -AccessToken $AccessToken
-
-
App-only access
-
Using client credential with a certificate
To use app-only access, the certificate is loaded from either
Cert:\CurrentUser\My\
orCert:\LocalMachine\My\
when-CertificateThumbprint
or-CertificateName
is specified. Make sure that the certificate you’re using is present in either certificate store before callingConnect-MgGraph
.-
Using Certificate Thumbprint:
Connect-MgGraph -ClientId "YOUR_APP_ID" -TenantId "YOUR_TENANT_ID" -CertificateThumbprint "YOUR_CERT_THUMBPRINT"
-
Using Certificate name:
Connect-MgGraph -ClientId "YOUR_APP_ID" -TenantId "YOUR_TENANT_ID" -CertificateName "YOUR_CERT_SUBJECT"
-
Using a certificate:
$Cert = Get-ChildItem Cert:\LocalMachine\My\$CertThumbprint Connect-MgGraph -ClientId "YOUR_APP_ID" -TenantId "YOUR_TENANT_ID" -Certificate $Cert
To use a certificate stored in your machine’s certificate store or another location when connecting to Microsoft Graph, specify the certificate’s location.
-
-
Using client secret credentials
If you need interactions in the background, without a user to sign in, this type of grant will help you. Support for client secret credentials was added by adding
-ClientSecretCredential
parameter toConnect-MgGraph
.$ClientSecretCredential = Get-Credential -Username "Client_Id" # Enter client_secret in the password prompt. Connect-MgGraph -TenantId "Tenant_Id" -ClientSecretCredential $ClientSecretCredential
-
Using managed identity
A common challenge when writing automation scripts is the management of secrets, credentials, certificates, and keys used to secure communication between services. Eliminate the need to manage credentials by allowing the module to obtain access tokens for Azure resources that are protected by Azure AD. The identity is managed by the Azure platform and does not require you to provision or rotate any secrets.
-
System-assigned managed identity:
Uses an automatically managed identity on a service instance. The identity is tied to the lifecycle of a service instance.
Connect-MgGraph -Identity
-
User-assigned managed identity:
Uses a user created managed identity as a standalone Azure resource.
Connect-MgGraph -Identity -ClientId "User_Assigned_Managed_identity_Client_Id"
-
-
4.3.3.2. Using Get-MgEnvironment: Connecting to an environment or cloud
When you use Connect-MgGraph
, you can choose to target other environments. By default, Connect-MgGraph
targets the global public cloud.
To get a list of all clouds that you can choose from, run:
Get-MgEnvironment
Name AzureADEndpoint GraphEndpoint Type
---- --------------- ------------- ----
China https://login.chinacloudapi.cn https://microsoftgraph.chinacloudapi.cn Built-in
Global https://login.microsoftonline.com https://graph.microsoft.com Built-in
USGov https://login.microsoftonline.us https://graph.microsoft.us Built-in
USGovDoD https://login.microsoftonline.us https://dod-graph.microsoft.us Built-in
Germany https://login.microsoftonline.de https://graph.microsoft.de Built-in
To explicitly target other clouds, for example, US Government and Azure China, use the -Environment
parameter.
Connect-MgGraph -Environment USGov
Globally registered apps don’t replicate to Azure China. You’ll need to register your own applications in Azure China and use them when connecting to Microsoft Graph. |
4.3.3.3. Connecting to an environment as a different identity
To connect as a different identity other than CurrentUser, specify the -ContextScope
parameter with the value Process.
Connect-MgGraph -ContextScope Process -ForceRefresh
4.3.3.4. Using Disconnect-MgGraph
Once you’re signed in, you’ll remain signed in until you invoke Disconnect-MgGraph
. Microsoft Graph PowerShell automatically refreshes the access token for you and sign-in persists across PowerShell sessions because Microsoft Graph PowerShell securely caches the token.
Use Disconnect-MgGraph
to sign out.
Disconnect-MgGraph
4.3.3.5. Using Get-MgContext
Get-MgContext
is used to retrieve the details about your current session, which include:
-
ClientID
-
TenantID
-
Certificate Thumbprint
-
Scopes consented to
-
AuthType: Delegated or app-only
-
AuthProviderType
-
CertificateName
-
Account
-
AppName
-
ContextScope
-
Certificate
-
PSHostVersion
-
ClientTimeOut.
To retrieve the session details, run:
Get-MgContext
To retrieve all the scopes that you’ve consented to, expand the Scopes property using the -ExpandProperty parameter.
Get-MgContext | Select -ExpandProperty Scopes
4.3.3.6. Using Invoke-MgGraphRequest
Invoke-MgGraphRequest
issues REST API requests to the Graph API. It works for any Graph API if you know the REST URI, method and optional body parameter. This command is especially useful for accessing APIs for which there isn’t an equivalent cmdlet yet.
To retrieve the details of the signed-in user, run:
Invoke-MgGraphRequest -Method GET https://graph.microsoft.com/v1.0/me
4.3.4. Using Find-MgGraphCommand cmdlet
Find-MgGraphCommand aims to make it easier for you to discover which API path a command calls, by providing a URI or a command name.
The Find-MgGraphCommand allows to:
-
Pass a Microsoft Graph URL (relative and absolute) and get an equivalent Microsoft Graph PowerShell command.
-
Pass a command and get the URL it calls.
-
Pass a command or URI wildcard (.*) to find all commands that match it.
Find-MgGraphCommand -Uri <String[]> [-Method <String>] [-ApiVersion <String>] [<CommonParameters>]
Find-MgGraphCommand -Uri .*searchstring.* [-ApiVersion <String>] [<CommonParameters>] [-Method <String>]
Find-MgGraphCommand -Command <String[]> [-ApiVersion <String>] [<CommonParameters>]
Find-MgGraphCommand -Command .*searchstring.* [-ApiVersion <String>] [<CommonParameters>]
# Use a URI to get all related cmdlets
Find-MgGraphCommand -Uri '/users/{id}'
# Search for commands using URI wildcard
Find-MgGraphCommand -Uri ".*users.*" -Method 'Get' -ApiVersion 'v1.0'
# Pass a command and get the URI it calls
Find-MgGraphCommand -Command 'Get-MgUser'
# Pass a command and get the permissions required
Find-MgGraphCommand -command Get-MgUser | Select -First 1 -ExpandProperty Permissions
# Search for commands using a command wildcard
Find-MgGraphCommand -Command .*UserToDo.* -APIVersion 'v1.0'
4.3.5. Using Find-MgGraphPermission cmdlet
The Microsoft Graph PowerShell SDK application requires users to have domain knowledge of both the semantics and syntax of Microsoft Graph API permissions used to authorize access to the API. This cmdlet helps to answer the following questions:
-
How do I find the values to supply to the permission-related parameters of commands like
New-MgApplication
and other application and consent related commands? -
What permissions are applicable to a certain domain, for example, application, directory? To use Microsoft Graph PowerShell SDK to access Microsoft Graph, users must sign in to an Azure AD application using the
Connect-MgGraph
command.
# Find permissions related to a given domain
Find-MgGraphPermission application
# Find the identifier for a specific permission
Find-MgGraphPermission application.Read | Format-List
# Pass a command and get the permissions required
Find-MgGraphCommand New-MgApplication | Select -ExpandProperty Permissions
4.3.6. View Microsoft 365 licenses and services with PowerShell
Every Microsoft 365 subscription consists of the following elements: [7]
-
Licensing plans These are also known as license plans or Microsoft 365 plans. Licensing plans define the Microsoft 365 services that are available to users. Your Microsoft 365 subscription may contain multiple licensing plans. An example licensing plan would be Microsoft 365 E3.
-
Services These are also known as service plans. Services are the Microsoft 365 products, features, and capabilities that are available in each licensing plan, for example, Exchange Online and Microsoft 365 Apps for enterprise (previously named Office 365 ProPlus). Users can have multiple licenses assigned to them from different licensing plans that grant access to different services.
-
Licenses Each licensing plan contains the number of licenses that you purchased. You assign licenses to users so they can use the Microsoft 365 services that are defined by the licensing plan. Every user account requires at least one license from one licensing plan so they can log on to Microsoft 365 and use the services.
Reading subscription license plans requires the Organization.Read.All
permission scope or one of the other permissions listed in the 'List subscribedSkus' Graph API reference page.
Connect-Graph -Scopes Organization.Read.All
-
To view summary information about your current licensing plans and the available licenses for each plan, run this command:
Get-MgSubscribedSku | Select -Property Sku*, ConsumedUnits -ExpandProperty PrepaidUnits | Format-List
The results contain:
-
SkuPartNumber: Shows the available licensing plans for your organization. For example,
ENTERPRISEPACK
is the license plan name for Office 365 Enterprise E3. -
Enabled: Number of licenses that you’ve purchased for a specific licensing plan.
-
ConsumedUnits: Number of licenses that you’ve assigned to users from a specific licensing plan.
-
-
To view details about the Microsoft 365 services that are available in all of your license plans, first display a list of your license plans.
Get-MgSubscribedSku
Next, store the license plans information in a variable.
$licenses = Get-MgSubscribedSku
Next, display the services in a specific license plan.
$licenses[<index>].ServicePlans
<index>
is an integer that specifies the row number of the license plan from the display of theGet-MgSubscribedSku | Select SkuPartNumber
command, minus 1.For example, if the display of the
Get-MgSubscribedSku | Select SkuPartNumber
command is this:SkuPartNumber ------------- WIN10_VDA_E5 EMSPREMIUM ENTERPRISEPREMIUM FLOW_FREE -------------
Then the command to display the services for the
ENTERPRISEPREMIUM
license plan is this:$licenses[2].ServicePlans
ENTERPRISEPREMIUM
is the third row. Therefore, the index value is (3 - 1), or 2.For a complete list of license plans (also known as product names), their included service plans, and their corresponding friendly names, see Product names and service plan identifiers for licensing.
4.3.7. View licensed and unlicensed Microsoft 365 users with PowerShell
User accounts in your Microsoft 365 organization may have some, all, or none of the available licenses assigned to them from the licensing plans that are available in your organization. [8]
Reading user properties including license details requires the User.Read.All permission scope or one of the other permissions listed in the 'Get a user' Graph API reference page.
The Organization.Read.All permission scope is required to read the licenses available in the tenant.
Connect-Graph -Scopes User.Read.All, Organization.Read.All
-
To view the license details of a specific user account, run the following command:
Get-MgUserLicenseDetail -UserId "<user sign-in name (UPN)>"
-
To view the list of all user accounts in your organization that have NOT been assigned any of your licensing plans (unlicensed users), run the following command:
Get-MgUser -Filter 'assignedLicenses/$count eq 0' -ConsistencyLevel eventual -CountVariable unlicensedUserCount -All Write-Host "Found $unlicensedUserCount unlicensed users."
-
To view the list of all member user accounts (excluding guests) in your organization that have NOT been assigned any of your licensing plans (unlicensed users), run the following command:
Get-MgUser -Filter "assignedLicenses/`$count eq 0 and userType eq 'Member'" -ConsistencyLevel eventual -CountVariable unlicensedUserCount -All Write-Host "Found $unlicensedUserCount unlicensed users (excluding guests)."
-
To view the list of all user accounts in your organization that have been assigned any of your licensing plans (licensed users), run the following command:
Get-MgUser -Filter 'assignedLicenses/$count ne 0' -ConsistencyLevel eventual -CountVariable licensedUserCount -All -Select UserPrincipalName,DisplayName,AssignedLicenses | Format-Table -Property UserPrincipalName,DisplayName,AssignedLicenses Write-Host "Found $licensedUserCount licensed users."
-
To view the list of all user accounts in your organization that have an E5 license assigned, run the following command:
$e5Sku = Get-MgSubscribedSku -All | Where SkuPartNumber -eq 'SPE_E5' Get-MgUser -Filter "assignedLicenses/any(x:x/skuId eq $($e5sku.SkuId) )" -ConsistencyLevel eventual -CountVariable e5licensedUserCount -All Write-Host "Found $e5licensedUserCount E5 licensed users."
4.3.8. Assign Microsoft 365 licenses to user accounts with PowerShell
Users can’t use any Microsoft 365 services until their account has been assigned a license from a licensing plan. You can use PowerShell to quickly assign licenses to unlicensed accounts. [9]
User accounts must first be assigned a location. Specifying a location is a required part of creating a new user account in the Microsoft 365 admin center.
Accounts synchronized from your on-premises Active Directory Domain Services do not by default have a location specified. You can configure a location for these accounts from:
-
The Microsoft 365 admin center
-
The Azure portal
Assigning and removing licenses for a user requires the User.ReadWrite.All permission scope or one of the other permissions listed in the 'Assign license' Microsoft Graph API reference page.
The Organization.Read.All permission scope is required to read the licenses available in the tenant.
Connect-MgGraph -Scopes User.ReadWrite.All, Organization.Read.All
Run the Get-MgSubscribedSku
command to view the available licensing plans and the number of available licenses in each plan in your organization. The number of available licenses in each plan is ActiveUnits - WarningUnits - ConsumedUnits.
-
To find the unlicensed accounts in your organization, run this command.
Get-MgUser -Filter 'assignedLicenses/$count eq 0' -ConsistencyLevel eventual -CountVariable unlicensedUserCount -All
-
To find the unlicensed synchronized users in your organization, run this command.
Get-MgUser -Filter 'assignedLicenses/$count eq 0 and OnPremisesSyncEnabled eq true' -ConsistencyLevel eventual -CountVariable unlicensedUserCount -All -Select UserPrincipalName
You can only assign licenses to user accounts that have the UsageLocation property set to a valid ISO 3166-1 alpha-2 country code. For example, US for the United States, and FR for France. Some Microsoft 365 services aren’t available in certain countries.
-
To find accounts that don’t have a UsageLocation value, run this command.
Get-MgUser -Select Id,DisplayName,Mail,UserPrincipalName,UsageLocation,UserType | where { $_.UsageLocation -eq $null -and $_.UserType -eq 'Member' }
-
To set the UsageLocation value on an account, run this command.
$userUPN="<user sign-in name (UPN)>" $userLoc="<ISO 3166-1 alpha-2 country code>" Update-MgUser -UserId $userUPN -UsageLocation $userLoc
For example:
Update-MgUser -UserId "belindan@litwareinc.com" -UsageLocation US
If you use the
Get-MgUser
cmdlet without using the -All parameter, only the first 100 accounts are returned. -
To assign a license to a user, use the following command in PowerShell.
Set-MgUserLicense -UserId $userUPN -AddLicenses @{SkuId = "<SkuId>"} -RemoveLicenses @()
This example assigns a license from the SPE_E5 (Microsoft 365 E5) licensing plan to the unlicensed user belindan@litwareinc.com:
$e5Sku = Get-MgSubscribedSku -All | Where SkuPartNumber -eq 'SPE_E5' Set-MgUserLicense -UserId "belindan@litwareinc.com" -AddLicenses @{SkuId = $e5Sku.SkuId} -RemoveLicenses @()
This example assigns SPE_E5 (Microsoft 365 E5) and EMSPREMIUM (ENTERPRISE MOBILITY + SECURITY E5) to the user belindan@litwareinc.com:
$e5Sku = Get-MgSubscribedSku -All | Where SkuPartNumber -eq 'SPE_E5' $e5EmsSku = Get-MgSubscribedSku -All | Where SkuPartNumber -eq 'EMSPREMIUM' $addLicenses = @( @{SkuId = $e5Sku.SkuId}, @{SkuId = $e5EmsSku.SkuId} ) Set-MgUserLicense -UserId "belinda@litwareinc.com" -AddLicenses $addLicenses -RemoveLicenses @()
This example assigns SPE_E5 (Microsoft 365 E5) with the MICROSOFTBOOKINGS (Microsoft Bookings) and LOCKBOX_ENTERPRISE (Customer Lockbox) services turned off:
$e5Sku = Get-MgSubscribedSku -All | Where SkuPartNumber -eq 'SPE_E5' $disabledPlans = $e5Sku.ServicePlans | ` Where ServicePlanName -in ("LOCKBOX_ENTERPRISE", "MICROSOFTBOOKINGS") | ` Select -ExpandProperty ServicePlanId $addLicenses = @( @{ SkuId = $e5Sku.SkuId DisabledPlans = $disabledPlans } ) Set-MgUserLicense -UserId "belinda@litwareinc.com" -AddLicenses $addLicenses -RemoveLicenses @()
This example updates a user with SPE_E5 (Microsoft 365 E5) and turns off the Sway and Forms service plans while leaving the user’s existing disabled plans in their current state:
$userLicense = Get-MgUserLicenseDetail -UserId "belinda@litwareinc.com" $userDisabledPlans = $userLicense.ServicePlans | ` Where ProvisioningStatus -eq "Disabled" | ` Select -ExpandProperty ServicePlanId $e5Sku = Get-MgSubscribedSku -All | Where SkuPartNumber -eq 'SPE_E5' $newDisabledPlans = $e5Sku.ServicePlans | ` Where ServicePlanName -in ("SWAY", "FORMS_PLAN_E5") | ` Select -ExpandProperty ServicePlanId $disabledPlans = ($userDisabledPlans + $newDisabledPlans) | Select -Unique $addLicenses = @( @{ SkuId = $e5Sku.SkuId DisabledPlans = $disabledPlans } ) Set-MgUserLicense -UserId "belinda@litwareinc.com" -AddLicenses $addLicenses -RemoveLicenses @()
This example updates a user with SPE_E5 (Microsoft 365 E5) and turns off the Sway and Forms service plans while leaving the user’s existing disabled plans in all other subscriptions in their current state:
$userLicense = Get-MgUserLicenseDetail -UserId belinda@litwareinc.com $userDisabledPlans = $userLicense.ServicePlans | Where-Object ProvisioningStatus -eq "Disabled" | Select -ExpandProperty ServicePlanId $e5Sku = Get-MgSubscribedSku -All | Where SkuPartNumber -eq 'SPE_E5' $newDisabledPlans = $e5Sku.ServicePlans | Where ServicePlanName -in ("SWAY", "FORMS_PLAN_E5") | Select -ExpandProperty ServicePlanId $disabledPlans = ($userDisabledPlans + $newDisabledPlans) | Select -Unique $result=@() $allPlans = $e5Sku.ServicePlans | Select -ExpandProperty ServicePlanId foreach($disabledPlan in $disabledPlans) { foreach($allPlan in $allPlans) { if($disabledPlan -eq $allPlan) { $property = @{ Disabled = $disabledPlan } } } $result += New-Object psobject -Property $property } $finalDisabled = $result | Select-Object -ExpandProperty Disabled $addLicenses = @( @{ SkuId = $e5Sku.SkuId DisabledPlans = $finalDisabled } ) Set-MgUserLicense -UserId belinda@litwareinc.com -AddLicenses $addLicenses -RemoveLicenses @()
-
Assign licenses to a user by copying the license assignment from another user
This example assigns jamesp@litwareinc.com with the same licensing plan that has been applied to belindan@litwareinc.com:
$mgUser = Get-MgUser -UserId "belindan@litwareinc.com" -Property AssignedLicenses Set-MgUserLicense -UserId "jamesp@litwareinc.com" -AddLicenses $mgUser.AssignedLicenses -RemoveLicenses @()
-
Move a user to a different subscription (license plan)
-
This example upgrades a user from the SPE_E3 (Microsoft 365 E3) licensing plan to the SPE_E5 (Microsoft 365 E5) licensing plan:
$e3Sku = Get-MgSubscribedSku -All | Where SkuPartNumber -eq 'SPE_E3' $e5Sku = Get-MgSubscribedSku -All | Where SkuPartNumber -eq 'SPE_E5' # Unassign E3 Set-MgUserLicense -UserId "belindan@litwareinc.com" -AddLicenses @{} -RemoveLicenses @($e3Sku.SkuId) # Assign E5 Set-MgUserLicense -UserId "belindan@litwareinc.com" -AddLicenses @{SkuId = $e5Sku.SkuId} -RemoveLicenses @()
You can verify the change in subscription for the user account with this command.
Get-MgUserLicenseDetail -UserId "belindan@litwareinc.com"
-
This example upgrades all users from TEAMS_EXPLORATORY (Microsoft Teams Exploratory) to STANDARDPACK (Office 365 E1):
Connect-MgGraph -Scopes Organization.Read.All,User.ReadWrite.All $teamsExploratorySku = Get-MgSubscribedSku | Where SkuPartNumber -eq 'TEAMS_EXPLORATORY' $e1Sku = Get-MgSubscribedSku | Where SkuPartNumber -eq 'STANDARDPACK' $disabledPlans = $e1Sku.ServicePlans | Where ServicePlanName -in ("EXCHANGE_S_STANDARD") | Select -ExpandProperty ServicePlanId $addLicenses = @( @{ SkuId = $e1Sku.SkuId DisabledPlans = $disabledPlans } ) $removeLicenses = @($teamsExploratorySku.SkuId) $filter = "assignedLicenses/any(u:u/skuId eq $($teamsExploratorySku.SkuId))" $teamsExploratoryUserIds = Get-MgUser -Property UserPrincipalName -Filter $filter | Select -Property UserPrincipalName Write-Host $teamsExploratoryUserIds.Count foreach ($userId in $teamsExploratoryUserIds) { Set-MgUserLicense -UserId $userId.UserPrincipalName -AddLicenses $addLicenses -RemoveLicenses $removeLicenses }
-
4.3.9. View Microsoft 365 account license and service details with PowerShell
In Microsoft 365, licenses from licensing plans (also called SKUs or Microsoft 365 plans) give users access to the Microsoft 365 services that are defined for those plans. However, a user might not have access to all the services that are available in a license that’s currently assigned to them. You can use PowerShell for Microsoft 365 to view the status of services on user accounts. [10]
Reading user properties including license details requires the User.Read.All permission scope or one of the other permissions listed in the 'Get a user' Graph API reference page.
The Organization.Read.All permission scope is required to read the licenses available in the tenant.
Connect-Graph -Scopes User.ReadWrite.All, Organization.Read.All
Next, list the license plans for your tenant with this command.
Get-MgSubscribedSku
-
Use these commands to list the services that are available in each licensing plan.
$allSKUs = Get-MgSubscribedSku -Property SkuPartNumber, ServicePlans $allSKUs | ForEach-Object { Write-Host "Service Plan:" $_.SkuPartNumber $_.ServicePlans | ForEach-Object {$_} }
-
Use these commands to list the licenses that are assigned to a user account.
Get-MgUserLicenseDetail -UserId "<user sign-in name (UPN)>"
For example:
Get-MgUserLicenseDetail -UserId "belindan@litwareinc.com"
-
To view all the Microsoft 365 services that a user has access to, use the following syntax:
(Get-MgUserLicenseDetail -UserId <user account UPN> -Property ServicePlans)[<LicenseIndexNumber>].ServicePlans
This example shows the services to which the user BelindaN@litwareinc.com has access. This shows the services that are associated with all licenses that are assigned to her account.
(Get-MgUserLicenseDetail -UserId belindan@litwareinc.com -Property ServicePlans).ServicePlans
This example shows the services that user BelindaN@litwareinc.com has access to from the first license that’s assigned to her account (the index number is 0).
(Get-MgUserLicenseDetail -UserId belindan@litwareinc.com -Property ServicePlans)[0].ServicePlans
-
To view all the services for a user who has been assigned multiple licenses, use the following syntax:
$userUPN="<user account UPN>" $allLicenses = Get-MgUserLicenseDetail -UserId $userUPN -Property SkuPartNumber, ServicePlans $allLicenses | ForEach-Object { Write-Host "License:" $_.SkuPartNumber $_.ServicePlans | ForEach-Object {$_} }
4.3.10. Remove Microsoft 365 licenses from user accounts with PowerShell
Assigning and removing licenses for a user requires the User.ReadWrite.All permission scope or one of the other permissions listed in the 'Assign license' Graph API reference page. [11]
The Organization.Read.All permission scope is required to read the licenses available in the tenant.
Connect-Graph -Scopes User.ReadWrite.All, Organization.Read.All
-
To remove licenses from an existing user account, use the following syntax:
Set-MgUserLicense -UserId "<Account>" -RemoveLicenses @("<AccountSkuId1>") -AddLicenses @{}
This example removes the SPE_E5 (Microsoft 365 E5) licensing plan from the user BelindaN@litwareinc.com:
$e5Sku = Get-MgSubscribedSku -All | Where SkuPartNumber -eq 'SPE_E5' Set-MgUserLicense -UserId "belindan@litwareinc.com" -RemoveLicenses @($e5Sku.SkuId) -AddLicenses @{}
-
To remove all licenses from a group of existing licensed users, use the following syntax:
$licensedUsers = Get-MgUser -Filter 'assignedLicenses/$count ne 0' ` -ConsistencyLevel eventual -CountVariable licensedUserCount -All ` -Select UserPrincipalName,DisplayName,AssignedLicenses foreach($user in $licensedUsers) { $licencesToRemove = $user.AssignedLicenses | Select -ExpandProperty SkuId $user = Set-MgUserLicense -UserId $user.UserPrincipalName -RemoveLicenses $licencesToRemove -AddLicenses @{} }
Another way to free up a license is by deleting the user account.
4.3.11. Disable access to Microsoft 365 services with PowerShell
When a Microsoft 365 account is assigned a license from a licensing plan, Microsoft 365 services are made available to the user from that license. However, you can control the Microsoft 365 services that the user can access. For example, even though the license allows access to the SharePoint Online service, you can disable access to it. You can use PowerShell to disable access to any number of services for a specific licensing plan for:
-
An individual account.
-
A group of accounts.
-
All accounts in your organization.
Assigning and removing licenses for a user requires the User.ReadWrite.All permission scope or one of the other permissions listed in the 'Assign license' Graph API reference page.
The Organization.Read.All permission scope is required to read the licenses available in the tenant.
Connect-Graph -Scopes User.ReadWrite.All, Organization.Read.All
Next, use this command to view your available licensing plans, also known as SkuPartNumber:
Get-MgSubscribedSku | Select SkuId, SkuPartNumber, ServicePlans | Sort SkuPartNumber
-
Disable specific Microsoft 365 services for specific users for a specific licensing plan
First list the licensing plans available in your tenant using the following command.
Get-MgSubscribedSku | Select SkuPartNumber
Next, use the SkuPartNumber from the command above, list the service plans available for a given license plan (Sku).
Get-MgSubscribedSku -All | Where SkuPartNumber -eq 'SPE_E5' | select -ExpandProperty ServicePlans
The following example assigns SPE_E5 (Microsoft 365 E5) with the MICROSOFTBOOKINGS (Microsoft Bookings) and LOCKBOX_ENTERPRISE (Customer Lockbox) services turned off:
$e5Sku = Get-MgSubscribedSku -All | Where SkuPartNumber -eq 'SPE_E5' $disabledPlans = $e5Sku.ServicePlans | ` Where ServicePlanName -in ("LOCKBOX_ENTERPRISE", "MICROSOFTBOOKINGS") | ` Select -ExpandProperty ServicePlanId $addLicenses = @( @{ SkuId = $e5Sku.SkuId DisabledPlans = $disabledPlans } ) Set-MgUserLicense -UserId "belinda@litwareinc.com" -AddLicenses $addLicenses -RemoveLicenses @()
The DisabledPlans property of the AddLicenses parameter in
Set-MgUserLicense
will overwrite the user’s existing DisabledPlans value. To preserve the state of existing service plans, the user’s current state of service plans must be merged with the new plans that are going to be disabled.Failing to include the existing DisabledPlans will result in the user’s previously disabled plan being enabled.
The following example updates a user with SPE_E5 (Microsoft 365 E5) and turns off the Sway and Forms service plans while leaving the user’s existing disabled plans in their current state:
## Get the services that have already been disabled for the user. $userLicense = Get-MgUserLicenseDetail -UserId "belinda@fdoau.onmicrosoft.com" $userDisabledPlans = $userLicense.ServicePlans | ` Where ProvisioningStatus -eq "Disabled" | ` Select -ExpandProperty ServicePlanId ## Get the new service plans that are going to be disabled $e5Sku = Get-MgSubscribedSku -All | Where SkuPartNumber -eq 'SPE_E5' $newDisabledPlans = $e5Sku.ServicePlans | ` Where ServicePlanName -in ("SWAY", "FORMS_PLAN_E5") | ` Select -ExpandProperty ServicePlanId ## Merge the new plans that are to be disabled with the user's current state of disabled plans $disabledPlans = ($userDisabledPlans + $newDisabledPlans) | Select -Unique $addLicenses = @( @{ SkuId = $e5Sku.SkuId DisabledPlans = $disabledPlans } ) ## Update user's license Set-MgUserLicense -UserId "belinda@litwareinc.onmicrosoft.com" -AddLicenses $addLicenses -RemoveLicenses @()
4.4. Exchange Online PowerShell
Exchange Online PowerShell is the administrative interface that enables you to manage your Microsoft Exchange Online organization from the command line. For example, you can use Exchange Online PowerShell to configure mail flow rules (also known as transport rules) and connectors. [9]
The Exchange Online PowerShell module uses modern authentication and works with multi-factor authentication (MFA) for connecting to all Exchange-related PowerShell environments in Microsoft 365: Exchange Online PowerShell, Security & Compliance PowerShell, and standalone Exchange Online Protection (EOP) PowerShell.
To install the latest public version of the module, run one of the the following commands:
-
In an elevated PowerShell window (all users):
Install-Module -Name ExchangeOnlineManagement
-
Only for the current user account:
Install-Module -Name ExchangeOnlineManagement -Scope CurrentUser
After you’ve installed the module, open a PowerShell window and load the module by running the following command:
Import-Module ExchangeOnlineManagement
If the module is already installed, you can typically skip this step and run Connect-ExchangeOnline without manually loading the module first.
|
Use the Connect-ExchangeOnline
command to sign in.
Connect-ExchangeOnline -UserPrincipalName <UPN> [-UseRPSSession] [-ExchangeEnvironmentName <Value>] [-ShowBanner:$false] [-DelegatedOrganization <String>] [-PSSessionOption $ProxyOptions]
Be sure to disconnect the session when you’re finished. If you close the PowerShell window without disconnecting the session, you could use up all the sessions available to you, and you need to wait for the sessions to expire. To disconnect the session, run the following command:
Disconnect-ExchangeOnline
To silently disconnect without a confirmation prompt, run the following command:
Disconnect-ExchangeOnline -Confirm:$false
4.4.1. AutoDiscover of Outlook, Exchange, and Exchange Online (EXO)
Autodiscover is a feature that simplifies the configuration process for email clients like Outlook by automatically discovering the required settings for connecting to Exchange mailboxes, whether they are hosted on-premises (Exchange Server) or in the cloud (Exchange Online).
Here’s a summary of Autodiscover for Outlook, Exchange, and Exchange Online (EXO):
-
Outlook: When configuring an email account in Outlook, it uses the Autodiscover process to find the appropriate settings for the user’s mailbox. Outlook first attempts to connect to Exchange Online by querying the default Office 365 Autodiscover endpoint. If it fails to find an Exchange Online mailbox, Outlook will try to discover settings for an on-premises Exchange mailbox using various methods, such as querying custom Autodiscover URLs or performing an SCP (Service Connection Point) lookup in Active Directory.
-
Exchange (On-premises): For on-premises Exchange environments, the Autodiscover service is hosted on the Exchange server. You need to configure Autodiscover DNS records (such as an "A" or "CNAME" record for
autodiscover.yourdomain.com
) that point to your Exchange server’s IP address or hostname. This will enable Outlook to discover the on-premises mailbox settings automatically when it fails to find an Exchange Online mailbox. -
Exchange Online (EXO): In Office 365, the Autodiscover service is automatically configured for Exchange Online. Outlook can discover Exchange Online mailboxes using the default Office 365 Autodiscover endpoint. However, it’s a good practice to configure the recommended DNS records for your domain, including the Autodiscover CNAME record that points to
autodiscover.outlook.com
. This ensures optimal performance, compatibility, and helps avoid potential issues in the future.If you haven’t configured an Autodiscover DNS record for your domain, but Outlook still connects to Exchange Online (EXO) automatically, it’s likely due to Outlook’s built-in capability to find the Exchange Online mailbox using the default Office 365 Autodiscover service.
Outlook has a pre-defined list of endpoints it checks during the Autodiscover process. If Outlook is unable to find a custom Autodiscover DNS record for your domain, it will try the default Office 365 Autodiscover endpoint at
https://autodiscover-s.outlook.com/autodiscover/autodiscover.xml
.Since Exchange Online is part of Office 365, its Autodiscover information is already available at this default endpoint. When Outlook queries this URL, it will receive the necessary configuration settings to connect to the Exchange Online mailbox automatically.
By properly configuring Autodiscover for both on-premises Exchange and Exchange Online environments, you can ensure a seamless user experience and simplify the process of connecting to mailboxes using Outlook and other email clients.
Here’s the order of the Autodiscover process in Outlook:
-
Outlook first checks for an Office 365 mailbox (Exchange Online) by querying the Office 365 Autodiscover service at “https://autodiscover-s.outlook.com/autodiscover/autodiscover.xml”;.
-
the mailbox is not found in Office 365, Outlook will then try to discover the mailbox settings from the on-premises Exchange server using the following methods:
-
Querying the “https://autodiscover.yourdomain.com/autodiscover/autodiscover.xml”; URL, where "yourdomain.com" is the user’s email domain.
-
Performing an SCP (Service Connection Point) lookup in Active Directory (only applicable for domain-joined computers in the same AD forest as the Exchange server).
-
Querying the “https://yourdomain.com/autodiscover/autodiscover.xml”; URL.
-
-
If the on-premises Exchange server is discovered and the mailbox settings are retrieved, Outlook will connect to the on-premises Exchange server.
It is important to ensure that your organization’s Autodiscover DNS records and configuration are set up correctly for both Exchange Online and on-premises Exchange server. This will allow Outlook to discover the correct mailbox settings and ensure a seamless user experience.
4.4.2. How to bypass the Autodiscover process in Outlook
Disabling Autodiscover in Office 365 (Microsoft 365) Exchange Online is not recommended, as it is an essential service for automatically configuring email clients and maintaining connections with Exchange Online mailboxes. However, if you want to prevent Outlook from automatically connecting to Exchange Online, you can use a registry modification on the client-side to bypass the Autodiscover process.
Please note that modifying the registry can cause issues if not done correctly, so proceed with caution and create a backup of your registry before making any changes.
To bypass the Autodiscover process in Outlook:
-
Press
Win + R
to open the Run dialog box, type regedit, and press Enter. -
Navigate to the following registry key, depending on your version of Outlook:
-
Outlook 2016, 2019, or Outlook for Office 365:
HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Outlook\AutoDiscover
-
Outlook 2013:
HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook\AutoDiscover
If the
AutoDiscover
key does not exist, you can create it by right-clicking on theOutlook
key, selecting "New" > "Key," and naming it "AutoDiscover." -
-
Right-click on the
AutoDiscover
key, choose "New" > "DWORD (32-bit) Value," and name it "ExcludeExplicitO365Endpoint." -
Double-click the "ExcludeExplicitO365Endpoint" value, set the "Value data" to 1, and click "OK."
-
Close the Registry Editor and restart Outlook.
This registry modification tells Outlook to bypass the Office 365 Autodiscover process, allowing you to manually configure your email clients to connect to other Exchange servers, such as on-premises deployments.
Please keep in mind that this method disables the Autodiscover process for Office 365 on the client-side and may lead to issues with email client configuration and connectivity. Use this approach only if you understand the risks and potential consequences.
Here’s a PowerShell script and a batch script that will automatically detect the operating system version, Outlook version, and add or update the necessary registry key to bypass the Office 365 Autodiscover process.
# Detect the Outlook version
$OutlookVersion = (Get-ItemProperty -Path "HKLM:\Software\Microsoft\Office\ClickToRun\Configuration" -Name "ClientVersionToReport" -ErrorAction SilentlyContinue) -replace '[^\d\.]'
if (-not $OutlookVersion) { $OutlookVersion = (Get-ItemProperty -Path "HKLM:\Software\Microsoft\Office\16.0\Common\InstallRoot" -Name "Path" -ErrorAction SilentlyContinue) }
if (-not $OutlookVersion) { $OutlookVersion = (Get-ItemProperty -Path "HKLM:\Software\Microsoft\Office\15.0\Common\InstallRoot" -Name "Path" -ErrorAction SilentlyContinue) }
# Set the registry key based on the Outlook version
if ($OutlookVersion) {
$AutoDiscoverPath = "HKCU:\Software\Microsoft\Office\$($OutlookVersion.Split('.')[0]).0\Outlook\AutoDiscover"
if (-not (Test-Path $AutoDiscoverPath)) { New-Item -Path $AutoDiscoverPath -Force }
Set-ItemProperty -Path $AutoDiscoverPath -Name "ExcludeExplicitO365Endpoint" -Value 1 -Type DWord
}
To run the PowerShell script:
-
Save the script as
AutodiscoverBypass.ps1
. -
Open PowerShell as Administrator.
-
Execute the script:
.\AutodiscoverBypass.ps1
@echo off
setlocal enabledelayedexpansion
rem Detect the Outlook version
for /f "tokens=2*" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Office\ClickToRun\Configuration" /v "ClientVersionToReport" 2^>nul') do set OutlookVersion=%%b
if not defined OutlookVersion for /f "tokens=2*" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Office\16.0\Common\InstallRoot" /v "Path" 2^>nul') do set OutlookVersion=16
if not defined OutlookVersion for /f "tokens=2*" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Office\15.0\Common\InstallRoot" /v "Path" 2^>nul') do set OutlookVersion=15
rem Set the registry key based on the Outlook version
if defined OutlookVersion (
set MajorVersion=!OutlookVersion:~0,2!
reg add "HKCU\Software\Microsoft\Office\!MajorVersion!.0\Outlook\AutoDiscover" /v "ExcludeExplicitO365Endpoint" /t REG_DWORD /d 1 /f
)
To run the batch script:
-
Save the script as
AutodiscoverBypass.bat
. -
Right-click the file and select "Run as Administrator".
Both scripts will detect the operating system and Outlook version, and then add or update the ExcludeExplicitO365Endpoint
registry key accordingly.
5. Azure PowerShell
Azure PowerShell is a set of cmdlets for managing Azure resources directly from PowerShell. Azure PowerShell is designed to make it easy to learn and get started with, but provides powerful features for automation. [10]
The Az PowerShell module is the replacement of AzureRM and is the recommended version to use for interacting with Azure.
5.1. Install Azure PowerShell on Windows
The Azure PowerShell Az module is a rollup module. Installing the Az PowerShell module downloads the generally available modules and makes their cmdlets available for use. [11]
The recommended installation method and PowerShell version for the Az PowerShell module:
-
Install from the PowerShell Gallery
-
Use with PowerShell version 7 or higher
5.1.1. Prerequisites
-
Run the following command from PowerShell to determine your PowerShell version:
$PSVersionTable.PSVersion
-
Determine if you have the AzureRM PowerShell module installed:
Get-Module -Name AzureRM -ListAvailable
If you have the AzureRM PowerShell module installed, see Az and AzureRM coexistence before proceeding. |
Windows PowerShell
|
-
Set the PowerShell execution policy to remote signed or less restrictive
-
Check the PowerShell execution policy:
Get-ExecutionPolicy -List
-
Set the PowerShell execution policy to remote signed:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
-
5.1.2. Installation
-
Use the
Install-Module
cmdlet to install the Az PowerShell module:Install-Module -Name Az -Repository PSGallery -Force
-
Use Update-Module to update to the latest version of the Az PowerShell module:
Update-Module -Name Az -Force
Updating the Az PowerShell module using
Update-Module
doesn’t remove old versions of the Az PowerShell module from your system.
5.1.3. Sign in with Azure PowerShell
Azure PowerShell supports several authentication methods. [12]
-
The easiest way to get started is with Azure Cloud Shell, which automatically logs you in.
-
With a local install, you can sign in interactively through your browser.
-
When writing scripts for automation, the recommended approach is to use a service principal with the necessary permissions.
When you restrict sign-in permissions as much as possible for your use case, you help keep your Azure resources secure.
Initially, you’re signed into the first subscription Azure returns if you have access to more than one subscription. Commands are run against this subscription by default.
-
To change your active subscription for a session, use the
Set-AzContext
cmdlet. -
To change your active subscription and have it persist between sessions on the same system, use the
Select-AzContext
cmdlet.
5.1.3.1. Sign in interactively
-
To sign in interactively, use the
Connect-AzAccount
cmdlet.Connect-AzAccount
This cmdlet presents an interactive browser based login prompt by default.
5.1.3.2. Device code authentication
-
You can specify the
UseDeviceAuthentication
parameter to use device code authentication instead of a browser control.Connect-AzAccount -UseDeviceAuthentication
5.1.3.3. Sign in using a managed identity
Managed identities are a feature of Azure Active Directory. Managed identities are service principals assigned to resources that run in Azure. You can use a managed identity service principal for sign-in, and an app-only access token to access other resources. Managed identities are only available on resources running in an Azure cloud.
This example connects using a system-assigned managed identity of the host environment. For example, if executed on a VirtualMachine with an assigned Managed Service Identity, this allows the code to sign in using that assigned identity.
Connect-AzAccount -Identity
5.1.3.4. Sign in with a non-default tenant or as a Cloud Solution Provider (CSP)
If your account is associated with more than one tenant, sign-in requires the Tenant
parameter to be specified when connecting. This parameter works with any sign-in method. When logging in, this parameter value can either be the Azure object ID of the tenant (Tenant ID) or the fully qualified domain name of the tenant.
If you’re a Cloud Solution Provider (CSP), the value for the Tenant parameter must be a tenant ID.
Connect-AzAccount -Tenant '00000000-0000-0000-0000-000000000000'
5.1.3.5. Sign in to another Cloud
Azure cloud services offer environments compliant with regional data-handling laws. For accounts in a regional cloud, set the environment when you sign in with the Environment
parameter. This parameter works with any sign-in method. For example, if your account is in Azure China 21Vianet:
Connect-AzAccount -Environment AzureChinaCloud
The following command returns a list of available environments:
Get-AzEnvironment | Select-Object -Property Name
5.1.4. Credential contexts
Azure PowerShell uses Azure PowerShell context objects (Azure contexts) to hold subscription and authentication information. If you have more than one subscription, Azure contexts let you select the subscription to run Azure PowerShell cmdlets on. Azure contexts are also used to store sign-in information across multiple PowerShell sessions and run background tasks.
Azure contexts are PowerShell objects representing your active subscription to run commands against, and the authentication information needed to connect to an Azure cloud. With Azure contexts, Azure PowerShell doesn’t need to reauthenticate your account each time you switch subscriptions. An Azure context consists of:
-
The account that was used to sign in to Azure with
Connect-AzAccount
. Azure contexts treat users, application IDs, and service principals the same from an account perspective. -
The active subscription, a service agreement with Microsoft to create and run Azure resources, which are associated with a tenant. Tenants are often referred to as organizations in documentation or when working with Active Directory.
-
A reference to a token cache, a stored authentication token for accessing an Azure cloud. Where this token is stored and how long it persists for is determined by the context autosave settings.
# List the available contexts
Get-AzContext -ListAvailable
# Or get a context by name
Get-AzContext -Name 'mycontext'
5.1.4.1. Change the active Azure context
Both Set-AzContext
and Select-AzContext
can be used to change the active Azure context.
Set-AzContext
creates a new Azure context for a subscription if one doesn’t exist, and then switches the active context to that one.
Select-AzContext
is meant to be used only with existing Azure contexts and works similarly to using Set-AzContext -Context
, but is designed for use with piping:
Set-AzContext -Context $(Get-AzContext -Name 'mycontext') # Set a context with an inline Azure context object
Get-AzContext -Name 'mycontext' | Select-AzContext # Set a context with a piped Azure context object
Like many other account and context management commands in Azure PowerShell, Set-AzContext
and Select-AzContext
support the Scope parameter so that you can control how long the context is active. Scope lets you change a single session’s active context without changing your default:
Get-AzContext -Name 'mycontext' | Select-AzContext -Scope Process
To avoid switching contexts for a whole PowerShell session, Azure PowerShell commands with an AzContext parameter can be run against a given context:
$context = Get-AzContext -Name "mycontext"
New-AzVM -Name ExampleVM -AzContext $context
In order to change subscriptions associated with your current Azure session, you use the Set-AzContext
cmdlet to change the current context.
Set-AzContext -Subscription <subscription name or id>
You can use the Get-AzSubscription
cmdlet to retrieve a list of your Azure subscriptions.
5.1.4.2. Save Azure contexts across PowerShell sessions
By default, Azure contexts are saved for use between PowerShell sessions. You change this behavior in the following ways:
-
Sign in using -Scope Process with Connect-AzAccount.
Connect-AzAccount -Scope Process
The Azure context returned as part of this sign in is valid for the current session only and won’t be saved automatically, regardless of the Azure PowerShell context autosave setting.
-
Disable context autosave in Azure PowerShell with the
Disable-AzContextAutosave
cmdlet. Disabling context autosave doesn’t clear any stored tokens.To remove stored information, use the Clear-AzContext
cmdlet. -
Explicitly enable Azure context autosave can be enabled with the
Enable-AzContextAutosave
cmdlet. With autosave enabled, a user’s contexts are stored locally for later PowerShell sessions. -
Manually save contexts with
Save-AzContext
to be used in future PowerShell sessions, where they can be loaded withImport-AzContext
:Save-AzContext -Path current-context.json # Save the current context Save-AzContext -Profile $profileObject -Path other-context.json # Save a context object Import-AzContext -Path other-context.json # Load the context from a file and set it to the current context
5.1.4.3. Remove Azure contexts and stored credentials
To clear Azure contexts and credentials:
-
Sign out of an account with
Disconnect-AzAccount
. You can sign out of any account either by account or context:Disconnect-AzAccount # Disconnect active account Disconnect-AzAccount -Username 'user@contoso.com' # Disconnect by account name Disconnect-AzAccount -ContextName 'subscription2' # Disconnect by context name Disconnect-AzAccount -AzureContext $contextObject # Disconnect using context object information
Disconnecting always removes stored authentication tokens and clears saved contexts associated with the disconnected user or context.
-
Use
Clear-AzContext
. This cmdlet always removes stored contexts, authentication tokens, and signs you out. -
Remove a context with
Remove-AzContext
:Remove-AzContext -Name 'mycontext' # Remove by name Get-AzContext -Name 'mycontext' | Remove-AzContext # Remove by piping Azure context object
If you remove the active context, you’ll be disconnected from Azure and need to reauthenticate with
Connect-AzAccount
.
5.2. Find commands
Azure PowerShell cmdlets follow a standard naming convention for PowerShell, Verb-Noun
. The verb describes the action (examples include New
, Get
, Set
, Remove
) and the noun describes the resource type (examples include AzVM
, AzKeyVaultCertificate
, AzFirewall
, AzVirtualNetworkGateway
). Nouns in Azure PowerShell always start with the prefix Az
.
Knowing the nouns, verbs, and the Azure PowerShell modules available helps you find commands with the Get-Command
cmdlet. For example, to find all VM-related commands that use the Get
verb:
Get-Command -Verb Get -Noun AzVM* -Module Az.Compute
References
-
[1] https://learn.microsoft.com/en-us/powershell/scripting/overview?view=powershell-7.3
-
[2] https://learn.microsoft.com/en-us/powershell/scripting/powershell-commands?view=powershell-7.3
-
[3] https://learn.microsoft.com/en-us/powershell/scripting/discover-powershell?view=powershell-7.3
-
[4] https://learn.microsoft.com/en-us/microsoft-365/enterprise/connect-to-microsoft-365-powershell?view=o365-worldwide
-
[5] https://learn.microsoft.com/en-us/powershell/microsoftgraph/overview?view=graph-powershell-1.0
-
[6] https://learn.microsoft.com/en-us/powershell/microsoftgraph/authentication-commands?view=graph-powershell-1.0
-
[7] https://learn.microsoft.com/en-us/microsoft-365/enterprise/view-licenses-and-services-with-microsoft-365-powershell?view=o365-worldwide
-
[8] https://learn.microsoft.com/en-us/microsoft-365/enterprise/view-licensed-and-unlicensed-users-with-microsoft-365-powershell?view=o365-worldwide
-
[9] https://learn.microsoft.com/en-us/microsoft-365/enterprise/assign-licenses-to-user-accounts-with-microsoft-365-powershell?view=o365-worldwide
-
[10] https://learn.microsoft.com/en-us/microsoft-365/enterprise/view-account-license-and-service-details-with-microsoft-365-powershell?view=o365-worldwide
-
[11] https://learn.microsoft.com/en-us/microsoft-365/enterprise/remove-licenses-from-user-accounts-with-microsoft-365-powershell?view=o365-worldwide
-
[9] https://learn.microsoft.com/en-us/powershell/exchange/exchange-online-powershell?view=exchange-ps
-
[10] https://learn.microsoft.com/en-us/powershell/azure/what-is-azure-powershell?view=azps-10.1.0
-
[11] https://learn.microsoft.com/en-us/powershell/azure/install-azps-windows?view=azps-10.1.0&tabs=windowspowershell&pivots=windows-psgallery
-
[12] https://learn.microsoft.com/en-us/powershell/azure/authenticate-azureps?view=azps-10.1.0