No one can deny the superior help of AzureAD and MSOL PowerShell modules and how these two made cloud management straightforward. But the end for these two modules is nearby, and the direction is the Graph API.

Let’s start now and learn the migration steps from the old modules to Graph API.

If you’re new to using graphs, consider checking out the “Connecting and Using Microsoft Graph API Using PowerShell” post. It’s a good starting point for learning how to use this tool.

Prerequisites

Read Your Old Script And Get It Ready

Get your old script, locate and understand the AzureAD and the MSOnline cmdlet functionality. So let’s assume that our script contains some cmdlets such as

  • Import-AzureAD
  • Connect-AzureAD
  • Get-AzureADUser
  • Get-MsolAccountSku

So, How to start?!

Importing and connecting to Graph API

The module importing process is still similar to importing the AzureAD and MSOnline modules, that is, by using Import-Module cmdlet

Import-Module Microsoft.Graph

Connecting to Graph API is essential in the script execution by using Connect-MgGraph. But it’s not only using the cmdlet and you are done. Instead, you need to know the connection scope to include. This can be done by using the -Scope parameter.

The Scope is a declaration of which permission the script will use. The scope structure is a Resource.Operation.Constraint.

For example, to read all user data, use User.Read.All, and to write to all user’s data, use User.ReadWrite.All.. But how to find these permissions?

Graph Explorer is a great way to start. Let’s get the required scope to read the user’s profile.

  • Open your favorite browser, Edge, Chrome… whatever
  • Navigate to Microsoft Graph Explorer
  • Click Resource tab
  • scroll down and find the User
  • expand it and select [GET]User or [POST]User
  • Click on Modify Permission,

Select the most relevant permission you need in the connection scope. The permission includes a description of what each one can do.

You can also click on the Code snippets for a PowerShell example with the required cmdlet to run.

Find the scope
Find the scope

Make sure to evaluate all your script and get the required scope for any cmdlet that will use Graph API.

Authentication and Authorization PowerShell and Graph API.

When connecting to Graph API, there are two parts to consider Authentication and Authorization. Starting with the authentication. The authentication support two methods as the following:

  • Delegate Authentication: The person who executes the script must authenticate by typing a valid organization username and password. Usually, this type of authentication opens a browser window for the user to authenticate.
User Authentication
  • Application Authentication: won’t request the user to type any username or password and won’t open any browser windows. It’s perfect for background processes and automation.
    The Azure admin should have previously registered an App in Azure Directory.
    Write down the Client Key, Tenant id, and client credentials as these values are needed to connect.

For authorization, if the delegate authentication is used, the user must consent and accept the list of permissions after the user is connected. This will appear straight after the user login.

Users need to accept the permission.

But if the application authorization is used, there won’t be any message for the user to consent and accept . The registered application is acting on behalf of the users.

Azure admin should assign the registered application the required permission and consent them.

Which one to use?! Whatever you want, make sure always follow the least privileged permission. don’t assign read-write when only read permissions are needed.

Read more about authentication and authorization and how to find the required scope at Connecting and Using Microsoft Graph API Using PowerShell

Ensure that the Graph cmdlet you use in your script supports the used authentication method. Some cmdlet won’t work if application authentication is used like using New-MgChatMessage cmdlet. Such information can only be found on the Microsoft Documentation website.

Reading the Graph API Documentation To Find The Replacement Cmdlets

Microsoft has made a nice map that shows each cmdlet with its replaced cmdlet from the Graph API side. and in most cases, you will find yourself returning to Microsoft Documentation for the Graph cmdlet help. For example, The Get-AzureADUser was replaced by the Get-MgUser.

Check out Find Azure AD and MSOnline cmdlets in Microsoft Graph PowerShell to see the full map. Each cmdlet is linked to its explanation page along with examples.

Finding the Replacement Cmdlets in Microsoft Graph using Get-Comand cmdlet

What about guessing the cmdlet by using Get-Command cmdlet? Let’s try it. Open PowerShell and type the following.

PS C:\> Get-Command Get*User* | where {$_.Source -like "Microsoft.Graph*"} | Select-Object Name

Name
----
Get-MgUserMember
Get-MgUserMemberByRef     
Get-MgUserTransitiveMember
Get-MgUserTransitiveMemberByRef
Get-MgUser
Get-MgUserCreatedObject
Get-MgUserCreatedObjectByRef
Get-MgUserDirectReport
Get-MgUserDirectReportByRef
Get-MgUserExtension
Get-MgUserLicenseDetail.
.
. Output trimmed

This can be a good start to see any cmdlet that might help in doing a similar task of Get-AzureADUser.

Using Get-Help is another way of knowing what the cmdlet can do, the supported parameters, and each parameter value type. You can use Get-Help Get-MgUser -Full for full help. Keep your help files up to date by running Update-Help.

There is a cmdlet named Get-MgUser. This looks similar to Get-AzureADUser. So let’s take a closer look. run the following line to see the supported parameters.

PS C:\> (Get-Command Get-Mguser).Parameters

Key                        Value
---                        -----
UserId                     System.Management.Automation.ParameterMetadata
InputObject                System.Management.Automation.ParameterMetadata
ExpandProperty             System.Management.Automation.ParameterMetadata
Property                   System.Management.Automation.ParameterMetadata
Filter                     System.Management.Automation.ParameterMetadata
Search                     System.Management.Automation.ParameterMetadata
Skip                       System.Management.Automation.ParameterMetadata
Sort                       System.Management.Automation.ParameterMetadata
Top                        System.Management.Automation.ParameterMetadata
ConsistencyLevel           System.Management.Automation.ParameterMetadata
Break                      System.Management.Automation.ParameterMetadata
HttpPipelineAppend         System.Management.Automation.ParameterMetadata
HttpPipelinePrepend        System.Management.Automation.ParameterMetadata
Proxy                      System.Management.Automation.ParameterMetadata
ProxyCredential            System.Management.Automation.ParameterMetadata
ProxyUseDefaultCredentials System.Management.Automation.ParameterMetadata
PageSize                   System.Management.Automation.ParameterMetadata
All                        System.Management.Automation.ParameterMetadata
CountVariable              System.Management.Automation.ParameterMetadata
Verbose                    System.Management.Automation.ParameterMetadata
Debug                      System.Management.Automation.ParameterMetadata
ErrorAction                System.Management.Automation.ParameterMetadata

There are similar parameters to Get-AzureADUser. Take a look at the table below.

Get-MgUuserGet-AzureADUser
UserIdObjectId
FilterFilter
AllAll
PropertySearchString
ExpandPropertyTop
InputObject
Break
ConsistencyLevel
Search

Why not also check the value type the parameter UserId accept? This helps us know what kind of input should provide to the parameter, whether it is a string, array, hashtable…etc.

(Get-Command Get-MgUser).Parameters.UserID

The UserID in Get-MgUser is a string, so we are good for now and can proceed with the next step.

ParameterType

We can use the UserID parameter with the Get-MgGraph cmdlet and pass the user UPN to get user information. But wait, remember to find the required scope.

Using Find-MgGraphCommand To Find The Required Permission Scope.

Use the Find-MgGraphCommand cmdlet to get a list of all the possible permission to execute the Get-MgUser cmdlet. Read the list to find the most accurate permission that fits your requirement. In this case, it’s User.Read.All.

PS C:\> (Find-MgGraphCommand -Command Get-MgUser -ApiVersion v1.0 ).Permissions  | Select-Object Name,Description

Name                                         Description
----                                         -----------
DeviceManagementApps.Read.All                Read Microsoft Intune apps
DeviceManagementApps.ReadWrite.All           Read and write Microsoft Intune apps
DeviceManagementManagedDevices.Read.All      Read devices Microsoft Intune devices
DeviceManagementManagedDevices.ReadWrite.All Read and write Microsoft Intune devices
DeviceManagementServiceConfig.Read.All       Read Microsoft Intune configuration
Directory.Read.All                           Read directory data
Directory.ReadWrite.All                      Read and write directory data
User.Read.All                                Read all users' full profiles
User.ReadBasic.All                           Read all users' basic profiles
User.ReadWrite.All                           Read and write all users' full profiles

Some permission might not be needed to execute the cmdlet, such as DeviceManagementApps.Read.All, this is part of the Intune apps. all that you need is the most relative one for your use.

Keep Microsoft Documentation in your bookmark as you need to open it to discover other parameters.

Particse is the key, you will remember all these things by trying.

Let’s try it all. As for now, we found that the scope is User.Read.All

$Scope=@('User.Read.All')
Connect-Graph -Scopes $Scope

Try the Get-MgUser cmdlet with the UserID UPN, and let see

PS C:\> Get-MgUser -UserId UserTestOne@PowerShellCenter.com

Id                                   DisplayName         Mail                  UserPrincipalName     UserType
--                                   -----------         ----                  -----------------     --------
616ed1f3-3210-3210-9acd-9acdd9acd92a User Test One     UserTestOne@PowerShellCenter.com           UserTestOne@PowerShellCenter.com

Try the -All parameter

PS C:\> Get-MgUser -all

Id                                   DisplayName                             Mail                                          UserPrincipalName                                                  UserType
--                                   -----------                             ----                                          -----------------                                                  --------
616ed1f3-3210-3210-9acd-9acdd9acd92a User Test One                  UserTestOne@PowerShellCenter.com                       UserTestOne@PowerShellCenter.com
c74d2588-4173-4173-aa1a-7c74d257704a User Test Two                 UserTestTwo@PowerShellCenter.com                        UserTestTwo@PowerShellCenter.com

All working fine, yes. This is cool and straight to the point.

Things Are Not Always Straight To The Point

Let’s see how to replace Set-MsolUserLicense from the Microsoft Graph API module.

Start by finding the cmdlet that can relate to Set-MsolUserLicense, for example, something with Set*UserLicense*. and find the available parameters

#Find the cmdlet
PS C:\> Get-Command Set*UserLicense* | where {$_.Source -like "Microsoft.Graph*"} | Select-Object Name

Name
----
Set-MgUserLicense

#Find the Supported Parameters
PS C:\> (get-command  Set-MgUserLicense).Parameters

Key                        Value
---                        -----
UserId                     System.Management.Automation.ParameterMetadata
InputObject                System.Management.Automation.ParameterMetadata
BodyParameter              System.Management.Automation.ParameterMetadata
AddLicenses                System.Management.Automation.ParameterMetadata
AdditionalProperties       System.Management.Automation.ParameterMetadata
RemoveLicenses             System.Management.Automation.ParameterMetadata
Break                      System.Management.Automation.ParameterMetadata
HttpPipelineAppend         System.Management.Automation.ParameterMetadata
HttpPipelinePrepend        System.Management.Automation.ParameterMetadata
Proxy                      System.Management.Automation.ParameterMetadat

Get the required permission to run the cmdlet.

PS C:\> (Find-MgGraphCommand -Command Set-MgUserLicense -ApiVersion v1.0).permissions | select Name, Description

Name                    Description
----                    -----------
Directory.ReadWrite.All Read and write directory data
User.ReadWrite.All      Read and write all users' full profiles

Comparing the two cmdlets looks good.

Set-MsolUserLicenseSet-MgUserLicense
ObjectIdUserID
AddLicensesAddLicenses
RemoveLicensesRemoveLicenses
There are other parameters, but here I am showing the common one only.

Things seems to be correct, so the code should work as expected if the line is written like the following. Yes ?!

Set-MgUserLicense -UserId 'UserTestOne@PowerShellCenter.com' -AddLicenses "PowerShellCenter:SPE_E5"

The answer is No, as mentioned before. you need to check the value type for these parameters. There are two used parameters used in the Set-MsolUserLicense cmdlet. The UserID, and the AddLicenses.

The parameter type for the UserID is a string, as shown below.

(Get-Command Set-MgUserLicense).Parameters.Userid.ParameterType
UserID Parameter Type

But let’s check the AddLicenses parameter type. The Name is IMicrosoftGraphAssignedLicense[], and the BaseType is System.Array.

(Get-Command Set-MgUserLicense).Parameters.AddLicenses.parametertype
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     IMicrosoftGraphAssignedLicense[]         System.Array

So now what to do?!! The answer is Microsoft Documentation. We need to know what kind of value we need to provide to this parameter to work.

According to Microsoft, the AddLicenses parameter needs the following

ADDLICENSES : <MicrosoftGraphAssignedLicense[]>:.
[DisabledPlans ]: A collection of the unique identifiers for plans that have been disabled.
[SkuId <String>]: The unique identifier for the SKU.

Microsoft.com

So, the structure is Set-MgUserLicense -AddLicenses [SkuId=”SKU Identifier”]. This key and value are hashtable and are written between curly brackets. @{Key=Value}

The AddLicenses parameter value should be AddLicenses @{SkuId="06ebc4ee-1bb5-47dd-8120-11324bc54e06"}

A lot of the Graph API cmdlet value type are hashtables. So its -ParameterName @{Key=Value}. Its also possible for the Key value to be an array, such as -ParameterName @{Key=@(Value1,Value2,Value3)}.

Set-MgUserLicense -UserId 'UserTestOne@PowerShellCenter.com' -AddLicenses @{SkuId="06ebc4ee-1bb5-47dd-8120-11324bc54e06"} -RemoveLicenses @() 

Also, by reviewing the documentation, you need to provide an additional parameter RemoveLicenses. Running the Set-MgUserLicense without the -RemoveLicenses returns the following error.

Set-MgUserLicense_AssignExpanded1: One or more parameters of the function import ‘assignLicense’ are missing from the request payload. The missing parameters are: removeLicenses.

Checklist to Migrate From MSOnline and AzureAD to Graph API

Here is a quick checklist:

  • Evaluate your old script, and see where are all the cmdlets related to MSOnline and AzureAD. Take a note.
  • Authentication and Permissions
    • How the script will be executed using the User context of the application context?
    • Think of the required permission to execute the script, and don’t the least privilege concept. Only assign the user/application the required permission.
    • Use Graph Explorer and Find-MgGraphCommand to find the required scope.
    • Microsoft Documentation is always a great starting point.
  • While evaluating the alternative cmdlet, look at the supported parameter to know how to structure the parameters and the supported value type.
  • It’s okay for things not to work from the first time.
  • Microsoft Documentation is always a great starting point
  • Learn how to use Microsoft Graph Explorer.

Conclusion

There might be some challenges while migrating your script to the Graph API. But once you understand the concept, you find it easy.

Let me know in the comment your method of such migration.

5/5 - (4 votes)