本文へ移動
購読
GUIDE#saas更新 2026.09.24

Microsoft Graph PowerShellでMicrosoft 365のユーザー・ライセンスを一括管理する

Microsoft Graph PowerShell 2.40.0のインストール、スコープの決め方、ユーザー棚卸しのCSV出力、ライセンス一括割り当てスクリプト、退職者処理までを検証した手順です。

level
中級
time
約40分
stack
PowerShell 7.5 / Microsoft.Graph 2.40.0(Authentication・Users・Users.Actions・Identity.DirectoryManagement・Groups)
author
@ryoma_t
// 前提条件
Microsoft 365テナントのユーザー管理者またはライセンス管理者ロール / PowerShellの基本操作
Microsoft Graph PowerShellのモジュールを確認し、Find-MgGraphCommandでライセンス割り当てAPIに対応するコマンドを調べたターミナル
画像:nagoya.dev(実際の画面・実行結果をもとに作成)

Microsoft Graph PowerShellとは、Microsoft 365とEntra IDをGraph API経由で管理する、Microsoft公式のPowerShellモジュール群です。ユーザーの作成、ライセンスの割り当て、退職者のサインイン停止といった定型作業を、管理センターのクリックではなくスクリプトでまとめて処理できます。

ここでは執筆時点の最新版であるMicrosoft.Graph 2.40.0(2026年9月16日公開)を、PowerShell 7.5のコンテナに入れて確認した内容をもとに、インストール、接続と権限の決め方、ユーザーとライセンスの棚卸し、CSVからの一括割り当て、退職時の処理までを手順にしています。一括割り当てのスクリプトは、テナントに接続する代わりにGraphのコマンドを同名の関数で置き換え、-WhatIf と本実行の両方の動きを確かめたものです。

この記事でわかること

  • MSOnline・AzureADモジュールとの違いと、必要なサブモジュールだけを入れる方法(オフライン環境を含む)
  • Connect-MgGraphのスコープの決め方と、Find-MgGraphCommandで必要な権限を調べる手順
  • ユーザーとライセンスの一覧をExcelで文字化けしないCSVに出す方法
  • CSVからライセンスを一括で割り当てるスクリプト(WhatIf対応・空き数チェック付き)
  • 退職者のサインイン停止とライセンス回収、実際に出たエラーと対処

Microsoft Graph PowerShellとは:MSOnline・AzureADとの違い

以前のMicrosoft 365管理では、MSOnlineモジュール(Connect-MsolService)やAzureADモジュール(Connect-AzureAD)が使われていました。これらは廃止が決まり、MSOnlineは2025年に動作を停止しています。後継がMicrosoft Graph PowerShellで、Graph APIの定義から自動生成されているため、APIのURLとコマンド名が規則的に対応します。GET /users は Get-MgUser、POST /users/{id}/assignLicense は Set-MgUserLicense という具合です。

古い記事を読むときの注意点が2つあります。1つは、バージョン2でv1.0とbetaのAPIが別モジュールに分かれ、Select-MgProfile が削除されたことです。2.40.0でも Get-Command Select-MgProfile は見つかりません。betaのAPIを使うときは Microsoft.Graph.Beta.Users のようなモジュールを入れ、Get-MgBetaUser のように名前に Beta が付いたコマンドを使います。もう1つは、MSOnlineの Set-MsolUserLicense -AddLicenses "contoso:ENTERPRISEPACK" のような文字列指定はできず、ライセンスはGUID(SkuId)で指定する点です。

作業MSOnline / AzureAD(廃止)Microsoft Graph PowerShell
接続Connect-MsolService / Connect-AzureADConnect-MgGraph -Scopes ...
ユーザー一覧Get-MsolUser -AllGet-MgUser -All -Property ...
ライセンス一覧Get-MsolAccountSkuGet-MgSubscribedSku
ライセンス割り当てSet-MsolUserLicenseSet-MgUserLicense
サインイン停止Set-MsolUser -BlockCredential $trueUpdate-MgUser -AccountEnabled:$false

インストール:必要なサブモジュールだけを入れる

Install-Module Microsoft.Graph で入るのはメタモジュールで、2.40.0では39個のサブモジュールに依存しています。全部入れるとディスクも読み込み時間もかさむため、使う分だけを入れるのがおすすめです。ユーザーとライセンスの管理に必要なのは次の5つです。

PowerShell 7
Install-PSResource -Name Microsoft.Graph.Authentication, Microsoft.Graph.Users, Microsoft.Graph.Users.Actions, Microsoft.Graph.Identity.DirectoryManagement, Microsoft.Graph.Groups -Scope CurrentUser -TrustRepository
Get-InstalledPSResource Microsoft.Graph.* | Format-Table Name, Version

Install-PSResource はPowerShell 7.4以降に同梱されている新しいモジュール管理コマンド(PSResourceGet)で、検証に使った7.5.0ではバージョン1.1.0が入っていました。従来の Install-Module でも同じモジュールが入ります。5つのサイズは、Authenticationが41MB、Usersが30MB、Identity.DirectoryManagementが29MB、Groupsが26MB、Users.Actionsが7.9MBでした。どのモジュールに何のコマンドがあるかは、Users(ユーザーの取得・更新)、Users.Actions(ライセンス割り当て、セッション失効)、Identity.DirectoryManagement(Get-MgSubscribedSku)、Groups(グループとグループのライセンス)という分担です。

インターネットに出られない管理端末に入れる場合は、接続できる端末で Save-PSResource を使って保存し、フォルダーごとコピーします。保存先のフォルダーは先に作っておかないと「Cannot find path ... because it does not exist.」で失敗します。検証では、Microsoft.Graph.Users を保存すると依存するAuthenticationも一緒に モジュール名/バージョン の階層で保存され、合計は69MBでした。この階層のまま、オフライン端末の $env:PSModulePath に含まれるフォルダー(Windowsなら ドキュメント\PowerShell\Modules)に置けば読み込めます。

PowerShell 7(オンライン端末で実行)
New-Item -ItemType Directory -Path C:\graph-offline
Save-PSResource -Name Microsoft.Graph.Users, Microsoft.Graph.Users.Actions, Microsoft.Graph.Identity.DirectoryManagement -Path C:\graph-offline -TrustRepository

サブモジュールのバージョンは必ずそろえてください。検証で2.39.0と2.40.0を混在させたところ、先に2.39.0のAuthenticationが読み込まれたセッションで2.40.0のUsersを読み込もうとして「Could not load file or assembly 'Microsoft.Graph.Authentication, Version=2.40.0.0, ...' Assembly with same name is already loaded」で失敗しました。更新するときは全サブモジュールを同じバージョンに上げ、古いバージョンは Uninstall-PSResource -Name <モジュール名> -Version <古い版> で消します。依存関係のあるモジュールから先に消そうとすると「This package is a dependency for: 'Microsoft.Graph.Users'」と止められるので、Users系を先に、Authenticationを最後に消します。

接続する:Connect-MgGraphと権限(スコープ)の決め方

対話的に使う場合は、必要な権限(スコープ)を指定して接続します。ユーザーの読み書きとライセンスの割り当てなら次のとおりです。

PowerShell 7
Connect-MgGraph -Scopes "User.ReadWrite.All", "LicenseAssignment.ReadWrite.All", "Organization.Read.All" -NoWelcome
Get-MgContext | Format-List Account, TenantId, Scopes

初回は、Microsoftが用意しているエンタープライズアプリ「Microsoft Graph Command Line Tools」への同意を求められます。スコープはこのアプリに付与される権限で、一度同意したスコープは残り続けます。そのため、接続のたびに -Scopes を最小限にしても、過去に同意した強い権限は外れません。グローバル管理者で広いスコープに同意する前に、日常の作業に必要な範囲を決めておきます。サインインするアカウント自体にも、ユーザー管理者やライセンス管理者などのロールが必要です。グローバル管理者で日常作業をしない運用はEntra IDの条件付きアクセス入門の管理者保護の考え方と同じです。

どの権限が必要かは、テナントに接続しなくても Find-MgGraphCommand で調べられます。検証環境で /users/{id}/assignLicense を調べると、対応するコマンドは Set-MgUserLicense(Users.Actions、POST)で、権限の候補に LicenseAssignment.ReadWrite.All、User.ReadWrite.All、Directory.ReadWrite.All などが並びました。候補のうち最も狭いものを選ぶのが原則で、この場合は LicenseAssignment.ReadWrite.All です。

PowerShell 7
Find-MgGraphCommand -Uri '/users/{id}/assignLicense' -ApiVersion v1.0 | Format-List Command, Module, Method, Permissions
Find-MgGraphCommand -Command Get-MgSubscribedSku | Format-Table Command, Method, URI

権限の名前から検索する Find-MgGraphPermission は、未接続だとモジュールに同梱された一覧を使います。検証では User.Read は見つかった一方で、license での検索は何も返しませんでした。-Online を付けると最新の一覧を引きに行きますが、未接続では「Authentication needed. Please call Connect-MgGraph.」になります。権限を調べるときは Find-MgGraphCommand のほうが確実です。

画面のない端末では -UseDeviceCode を付けると、表示されたコードを別の端末のブラウザーで入力してサインインできます(-UseDeviceAuthentication や -DeviceCode という別名でも同じです)。ただしデバイスコードによるサインインはフィッシングに悪用されやすく、条件付きアクセスの「認証フロー」条件でブロックしている組織では使えません。共用の作業用サーバーで接続する場合は -ContextScope Process を付けると、認証情報がそのPowerShellのプロセスの中だけに限られ、他のセッションに残りません。

夜間の定期処理のように人がサインインできない用途は、Entra IDにアプリを登録して証明書で認証する「アプリのみ」の接続(Connect-MgGraph -ClientId <アプリID> -TenantId <テナントID> -CertificateThumbprint <拇印>)にします。この場合の権限はアプリケーション権限として管理者が同意するもので、ユーザーのロールによる制限がかからないため、付与する権限はさらに絞ります。

ユーザーとライセンスの一覧をCSVに出す

最初の作業は棚卸しです。Get-MgUser は既定では一部のプロパティしか返さないため、部署やアカウントの有効・無効、ライセンスは -Property で明示しないと空欄になります。ライセンスはGUIDで返るので、Get-MgSubscribedSku で製品名(SkuPartNumber)との対応表を作って置き換えます。

PowerShell 7
$skuMap = @{}
Get-MgSubscribedSku | ForEach-Object { $skuMap[$_.SkuId] = $_.SkuPartNumber }

Get-MgUser -All -Property Id, DisplayName, UserPrincipalName, Department, AccountEnabled, UsageLocation, AssignedLicenses |
    Select-Object DisplayName, UserPrincipalName, Department, AccountEnabled, UsageLocation,
        @{ n = 'Licenses'; e = { ($_.AssignedLicenses.SkuId | ForEach-Object { $skuMap[$_] }) -join ';' } } |
    Export-Csv ./m365-users.csv -Encoding utf8BOM -NoTypeInformation

-Encoding utf8BOM は、ExcelでCSVを開いたときの文字化けを防ぐための指定です。理由は既定の文字コードにあり、PowerShell 7の Export-Csv はBOMなしのUTF-8を書き出します。検証でも既定のファイルは先頭が 22 55 73("Us)で始まったのに対し、utf8BOM では EF BB BF が付きました。BOMがないと、日本語の表示名や部署名がExcelで文字化けします。出力例は次のとおりです(値は例)。

m365-users.csv(例)
"DisplayName","UserPrincipalName","Department","AccountEnabled","UsageLocation","Licenses"
"山田 太郎","[email protected]","営業部","True","JP","SPB;EXCHANGESTANDARD"
"佐藤 花子","[email protected]","総務部","True",,

UsageLocation(利用場所)が空のユーザーは、次の一括割り当ての前に埋める必要があります。条件で絞り込む場合、-Filter "accountEnabled eq true" のような単純な条件はそのまま使えますが、endsWith(userPrincipalName,'@example.co.jp') のような高度なクエリは、-ConsistencyLevel eventual と -CountVariable を一緒に指定しないとエラーになります。

ライセンスの空きを確認する

Get-MgSubscribedSku は、テナントが契約しているライセンスごとに、購入数(PrepaidUnits.Enabled)と使用数(ConsumedUnits)を返します。

PowerShell 7
Get-MgSubscribedSku | Select-Object SkuPartNumber, ConsumedUnits,
    @{ n = 'Enabled'; e = { $_.PrepaidUnits.Enabled } },
    @{ n = 'Free'; e = { $_.PrepaidUnits.Enabled - $_.ConsumedUnits } } | Format-Table

SkuPartNumberは管理センターの表示名とは違う内部名で、たとえば SPB がMicrosoft 365 Business Premium、O365_BUSINESS_ESSENTIALS がBusiness Basic、SPE_E3 がMicrosoft 365 E3です(執筆時点)。表示名との正確な対応は、Microsoftが公開している「製品名とサービスプランの識別子」の一覧で確認できます。プランごとの機能の違いはMicrosoft 365のプラン比較で整理しています。

CSVからライセンスを一括で割り当てる

入社や組織変更でまとめてライセンスを付けるときのスクリプトです。CSVには UserPrincipalName と SkuPartNumber の2列を用意します。

users.csv(例)
UserPrincipalName,SkuPartNumber
[email protected],SPB
[email protected],SPB
[email protected],SPB
Set-LicenseFromCsv.ps1
[CmdletBinding(SupportsShouldProcess)]
param(
    [Parameter(Mandatory)] [string] $CsvPath,
    $Encoding = 'utf8BOM',                 # Excelの「CSV(コンマ区切り)」で保存したファイルなら 932
    [string] $DefaultUsageLocation = 'JP'
)
$ErrorActionPreference = 'Stop'

$rows = Import-Csv -Path $CsvPath -Encoding $Encoding
$skus = Get-MgSubscribedSku

$log = foreach ($row in $rows) {
    $r = [ordered]@{ UserPrincipalName = $row.UserPrincipalName; SkuPartNumber = $row.SkuPartNumber; Result = '' }
    try {
        $sku = $skus | Where-Object SkuPartNumber -eq $row.SkuPartNumber
        if (-not $sku) { throw "テナントに $($row.SkuPartNumber) がありません" }
        $user = Get-MgUser -UserId $row.UserPrincipalName -Property Id, UserPrincipalName, UsageLocation, AssignedLicenses

        if ($user.AssignedLicenses.SkuId -contains $sku.SkuId) {
            $r.Result = 'スキップ(割り当て済み)'
        }
        elseif ($sku.PrepaidUnits.Enabled - $sku.ConsumedUnits -le 0) {
            throw "$($sku.SkuPartNumber) の空きがありません"
        }
        elseif ($PSCmdlet.ShouldProcess($user.UserPrincipalName, "$($sku.SkuPartNumber) を割り当て")) {
            if (-not $user.UsageLocation) {
                Update-MgUser -UserId $user.Id -UsageLocation $DefaultUsageLocation
            }
            Set-MgUserLicense -UserId $user.Id -AddLicenses @(@{ SkuId = $sku.SkuId }) -RemoveLicenses @() | Out-Null
            $sku.ConsumedUnits++
            $r.Result = '割り当て完了'
        }
        else {
            $sku.ConsumedUnits++      # WhatIf でも空き数の計算を進める
            $r.Result = '未実行(WhatIf)'
        }
    }
    catch {
        $r.Result = "エラー: $($_.Exception.Message)"
    }
    [pscustomobject]$r
}

$log | Export-Csv -Path ('license-result-{0:yyyyMMdd-HHmm}.csv' -f (Get-Date)) -Encoding utf8BOM -NoTypeInformation -WhatIf:$false
$log | Format-Table -AutoSize

設計上の要点は4つです。1つ目は、割り当て前に UsageLocation を埋めることで、利用場所が空のユーザーにはライセンスを割り当てられません。2つ目は、ライセンスの空きを事前に数えることで、途中で枠が尽きたときに後続の行が中途半端に失敗するのを防ぎます。3つ目は、すでに割り当て済みの人を飛ばすことで、同じCSVを何度流しても結果が変わらないようにしています。4つ目が SupportsShouldProcess による -WhatIf 対応で、本番前に何が起きるかを確認できます。-RemoveLicenses @() は、APIの仕様上「外すライセンス」も必ず渡す必要があるための空配列です。

実行はまず -WhatIf で行います。

PowerShell 7
Connect-MgGraph -Scopes "User.ReadWrite.All", "LicenseAssignment.ReadWrite.All", "Organization.Read.All" -NoWelcome
./Set-LicenseFromCsv.ps1 -CsvPath ./users.csv -WhatIf
./Set-LicenseFromCsv.ps1 -CsvPath ./users.csv

Graphのコマンドを置き換えた検証では、Business Premiumの空きが1つ、Business Basicの空きが0の状態で5行のCSVを流しました。-WhatIf の実行では「What if: Performing the operation "SPB を割り当て" on target "[email protected]".」が表示され、Graphを変更するコマンドは1回も呼ばれませんでした。結果の表は、taroが「未実行(WhatIf)」、割り当て済みのhanakoが「スキップ(割り当て済み)」、3人目のjiroが「エラー: SPB の空きがありません」、存在しないユーザーは「エラー: Resource '[email protected]' does not exist ...」となり、本実行でもtaroへの Update-MgUser(利用場所JPの設定)と Set-MgUserLicense だけが実行されました。結果は license-result-日時.csv にBOM付きで残るので、申請者への報告にそのまま使えます。

人の異動が多い組織では、スクリプトで1人ずつ割り当てるより、Entra IDのグループにライセンスを割り当てる「グループベースのライセンス」のほうが管理が楽です(Set-MgGroupLicense で設定できます)。部署やプランのグループに入れるだけで割り当てと解除が自動で行われ、割り当て漏れが構造的に起きません。利用にはEntra ID P1相当のライセンスが必要です(執筆時点、要件は公式ドキュメントで確認してください)。このスクリプトは、グループ化の前の一括移行や、P1がない環境での運用に使います。

退職者の処理と、使われていないライセンスの回収

退職日には、サインインの停止、発行済みトークンの失効、ライセンスの回収を順に行います。

PowerShell 7
$upn = '[email protected]'
Update-MgUser -UserId $upn -AccountEnabled:$false
Revoke-MgUserSignInSession -UserId $upn
$user = Get-MgUser -UserId $upn -Property Id, AssignedLicenses
Set-MgUserLicense -UserId $user.Id -AddLicenses @() -RemoveLicenses @($user.AssignedLicenses.SkuId)

-AccountEnabled はスイッチ型の引数なので、-AccountEnabled:$false のようにコロンでつなぎます。Revoke-MgUserSignInSession は、すでに発行されたリフレッシュトークンを無効にし、スマホのメールアプリなどに残ったサインイン状態を切ります。ライセンスを外すとメールボックスなどのデータは一定期間後に削除されるため、メールの保管が必要な場合は、ライセンスを外す前に共有メールボックスへの変換や保持ポリシーの確認を済ませます。

使われていないライセンスを探すには、最終サインイン日時(SignInActivity)を使います。取得には AuditLog.Read.All のスコープと、テナントにEntra ID P1以上のライセンスが必要です。

PowerShell 7
Connect-MgGraph -Scopes "User.Read.All", "AuditLog.Read.All" -NoWelcome
$limit = (Get-Date).AddDays(-90)
Get-MgUser -All -Property DisplayName, UserPrincipalName, AccountEnabled, AssignedLicenses, SignInActivity |
    Where-Object { $_.AccountEnabled -and $_.AssignedLicenses.Count -gt 0 -and
        ($null -eq $_.SignInActivity.LastSuccessfulSignInDateTime -or $_.SignInActivity.LastSuccessfulSignInDateTime -lt $limit) } |
    Select-Object DisplayName, UserPrincipalName, @{ n = 'LastSuccess'; e = { $_.SignInActivity.LastSuccessfulSignInDateTime } }

LastSuccessfulSignInDateTime は、失敗したサインインを含まない最終成功日時です。値が空のユーザーは一度もサインインしていないか、記録が始まる前から使われていないことを意味します。90日は目安で、長期休職者や共有アカウントを除外したうえで、四半期の棚卸しで所属長に確認します。棚卸しの運用全体はSaaS管理の始め方で扱っています。

動作確認

テナントに接続しなくても、インストールと権限の調べ方は確認できます。次はLinuxのbash(PowerShell 7.5のコンテナ)から実行した例と、実際の出力です。

terminal
pwsh -NoLogo -NoProfile -c "Get-InstalledPSResource Microsoft.Graph.* | Format-Table Name,Version"
pwsh -NoLogo -NoProfile -c "Find-MgGraphCommand -Uri '/users/{id}/assignLicense' -ApiVersion v1.0 | Format-List Command,Module,Method"
pwsh -NoLogo -NoProfile -c "Find-MgGraphCommand -Command Get-MgSubscribedSku | Format-Table Command,Method,URI"
出力
Name                                         Version
----                                         -------
Microsoft.Graph.Identity.DirectoryManagement 2.40.0
Microsoft.Graph.Authentication               2.40.0
Microsoft.Graph.Groups                       2.40.0
Microsoft.Graph.Users                        2.40.0
Microsoft.Graph.Users.Actions                2.40.0

Command : Set-MgUserLicense
Module  : Users.Actions
Method  : POST

Command             Method URI
-------             ------ ---
Get-MgSubscribedSku GET    /subscribedSkus/{subscribedSku-id}
Get-MgSubscribedSku GET    /subscribedSkus

5つのサブモジュールが同じバージョンで並び、APIのURLから担当コマンドを引ければ、インストールは正常です。テナントに接続した後は、Get-MgContext の Scopes に要求した権限が含まれていること、Get-MgUserLicenseDetail -UserId <UPN> で割り当てたライセンスの SkuPartNumber が表示されることを確認します。一括割り当ては、必ず -WhatIf の結果表を見てから本実行してください。

つまずきポイント

「Authentication needed. Please call Connect-MgGraph.」と表示される

接続せずにGraphのコマンドを実行したときに出ます。スクリプトを別のPowerShellウィンドウで実行した場合や、-ContextScope Process で接続したセッションとは別のプロセスで実行した場合も同じです。Get-MgContext が何も返さなければ未接続なので、Connect-MgGraph から実行し直します。

「Could not load file or assembly 'Microsoft.Graph.Authentication, Version=...' Assembly with same name is already loaded」で読み込めない

異なるバージョンのサブモジュールが混在していると出ます。検証では2.39.0と2.40.0の組み合わせで再現しました。Get-InstalledPSResource Microsoft.Graph.* でバージョンを確認し、すべて同じ版にそろえてから、PowerShellを起動し直します。同じウィンドウのままでは、一度読み込んだアセンブリは入れ替わりません。

「A positional parameter cannot be found that accepts argument 'False'.」でアカウントを無効にできない

Update-MgUser -UserId $upn -AccountEnabled $false のように、スイッチ型の引数に空白区切りで値を渡したときのエラーです。このとき $false は、どの引数にも属さない値として扱われます。-AccountEnabled:$false とコロンでつなぐと、意図どおり無効化されます。有効に戻すときは -AccountEnabled だけで構いません。

CSVの日本語が「��� ���Y」のように文字化けする

Excelで「CSV(コンマ区切り)」として保存したファイルはShift_JIS系(コードページ932)で、PowerShell 7の Import-Csv の既定(UTF-8)で読むと文字化けします。検証でも、932で保存した「鈴木 次郎」がそのまま化けました。-Encoding 932 を付けると正しく読めます。Excelで「CSV UTF-8(コンマ区切り)」を選んで保存したファイルなら、既定のままで読めます。

よくある質問

Microsoft Graph PowerShellとは何ですか?

Microsoft 365やEntra IDを操作するGraph APIを、PowerShellのコマンドとして呼び出せるようにしたMicrosoft公式のモジュール群です。廃止されたMSOnline・AzureADモジュールの後継で、APIの定義から自動生成されているため、新しいAPIにも比較的早く対応します。v1.0とbetaでモジュールが分かれています。

Graph PowerShellのインストール方法は?

おすすめは、PowerShell 7で Install-PSResource -Name Microsoft.Graph.Users -Scope CurrentUser のように、必要なサブモジュールを指定して入れる方法です。全部入りの Microsoft.Graph は39個のモジュールに依存していて重くなります。オフラインの端末には、別の端末で Save-PSResource したフォルダーをコピーします。

Microsoft Graph PowerShellの最新バージョンは?

執筆時点の最新版は2.40.0で、PowerShell Galleryでの公開日は2026年9月16日でした。更新は頻繁なので、Find-PSResource -Name Microsoft.Graph で公開中の最新版を確認し、Get-InstalledPSResource Microsoft.Graph.* で手元のバージョンと比べます。更新時は全サブモジュールを同じ版にそろえます。

PowerShellは無くなるのはいつですか?

なくなるのはPowerShell自体ではありません。Windows PowerShell 5.1もWindowsに同梱され続けています。なくなったのはMicrosoft 365管理用のMSOnline・AzureADモジュールで、MSOnlineは2025年に動作を停止しました。これらを使うスクリプトは、Microsoft Graph PowerShellへの書き換えが必要です。

まとめ

Microsoft Graph PowerShellは、必要なサブモジュールだけを同じバージョンで入れ、Find-MgGraphCommand で調べた最小のスコープで接続するのが基本です。棚卸しのCSVは -Property と -Encoding utf8BOM を指定して出し、ライセンスの一括割り当ては空き数と利用場所を確認するスクリプトを -WhatIf で試してから本実行します。退職時は無効化、セッション失効、ライセンス回収の3つをセットで行ってください。

次に読む

$ subscribe --weekly
毎週月曜、企業ITとホームラボの要点を5分で。