Skip to content

Conversation

@w7-mgfcode
Copy link
Owner

@w7-mgfcode w7-mgfcode commented Dec 4, 2025

Summary / Összefoglaló

🇬🇧 English

PowerShell automation scripts for Microsoft 365 administration using Graph API:

Connection Module:

  • OAuth2 authentication with Microsoft Graph
  • Scope-based permission management
  • Connection testing and verification

User Management:

  • Get-M365Users.ps1: Comprehensive user listing
    • Filter support (OData)
    • CSV export capability
    • Sign-in activity tracking
    • Active/inactive statistics

Group Management:

  • Get-M365Groups.ps1: Group enumeration
    • Microsoft 365 vs Security group detection
    • Member count and listing
    • Mail-enabled group identification

License Management:

  • Get-M365Licenses.ps1: License usage reporting
    • Total/assigned/available licenses
    • Usage percentage calculations
    • Low availability warnings
    • Product name mapping for readability

Reports:

  • Get-M365InactiveUsers.ps1: Inactive user detection
    • Configurable inactivity threshold
    • Never-signed-in user identification
    • Account cleanup recommendations

🇭🇺 Magyar

PowerShell automatizálási scriptek Microsoft 365 adminisztrációhoz Graph API használatával.

Features

  • Bilingual documentation (English/Hungarian)
  • Graph API OAuth2 authentication
  • CSV export support
  • Statistics and warnings
  • Professional error handling

Test Plan / Tesztterv

  • PowerShell syntax validated
  • Graph API scopes documented
  • Usage examples included
  • README documentation complete

🤖 Generated with Claude Code

Summary by Sourcery

Add a new suite of PowerShell-based Microsoft 365 admin scripts built on Microsoft Graph for connections, user/group/license reporting, and inactive user analysis, documented in a bilingual README.

New Features:

  • Introduce a reusable Microsoft 365 Graph connection module with connect, test, and disconnect helpers.
  • Add user reporting script to list M365 users with filtering, CSV export, and basic activity statistics.
  • Add group reporting script to enumerate M365 groups, optionally including members and summary statistics.
  • Add license reporting script to summarize M365 license allocation, usage percentages, and low-availability warnings.
  • Add inactive-user reporting script to detect users with no or stale sign-ins, generate CSV exports, and output cleanup recommendations.
  • Document the M365 admin script suite with bilingual (English/Hungarian) usage, examples, and directory structure in a new README.

Summary by CodeRabbit

  • New Features

    • Added Microsoft 365 administration scripts for user management, group querying, license auditing, and inactive user reporting.
    • Included connection management utilities for Microsoft 365 services.
    • Scripts support optional CSV export for reporting and analysis.
  • Documentation

    • Added comprehensive README with prerequisites, usage examples, security considerations, and troubleshooting guidance in bilingual format (Hungarian and English).

✏️ Tip: You can customize this high-level summary in your review settings.

PowerShell scripts for Microsoft 365 administration:

**Connection Module:**
- Connect-M365.ps1: Graph API connection management with OAuth2
- Connection testing and verification
- Scope-based authentication

**User Management:**
- Get-M365Users.ps1: List all users with details, filtering, CSV export
- User statistics (active/inactive)
- Sign-in activity tracking

**Group Management:**
- Get-M365Groups.ps1: List groups with member counts
- M365/Security group type detection
- Optional member enumeration

**License Management:**
- Get-M365Licenses.ps1: License usage report
- Availability warnings
- Usage percentage tracking
- Product name mapping

**Reports:**
- Get-M365InactiveUsers.ps1: Inactive user detection
- Configurable inactivity threshold
- Never-signed-in user identification
- Recommendations for account cleanup

All scripts include bilingual documentation (English/Hungarian).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@sourcery-ai
Copy link

sourcery-ai bot commented Dec 4, 2025

Reviewer's Guide

Adds a modular set of PowerShell scripts for Microsoft 365 administration built on Microsoft Graph, including a shared connection module and specialized scripts for users, groups, licenses, and inactive user reporting, all documented in a bilingual README.

Sequence diagram for running Get-M365InactiveUsers report

sequenceDiagram
    actor Admin
    participant Shell as PowerShell
    participant InactiveScript as Get-M365InactiveUsers.ps1
    participant ConnectModule as Connect-M365.ps1
    participant MgGraph as Microsoft Graph
    participant Dir as Directory service
    participant Reports as Sign-in reports

    Admin->>Shell: Run .\reports\Get-M365InactiveUsers.ps1 -DaysInactive 90 -ExportPath path
    Shell->>InactiveScript: Invoke script with DaysInactive, ExportPath
    InactiveScript->>ConnectModule: Import connection module (dot source)
    InactiveScript->>ConnectModule: Test-M365Connection()
    alt No active connection
        ConnectModule-->>InactiveScript: false
        InactiveScript->>ConnectModule: Connect-M365Services(Scopes=[User.Read.All, AuditLog.Read.All])
        ConnectModule->>MgGraph: Connect-MgGraph(Scopes)
        MgGraph-->>ConnectModule: OAuth2 token and context
        ConnectModule-->>InactiveScript: true
    else Active connection
        ConnectModule-->>InactiveScript: true
    end

    InactiveScript->>Shell: Compute threshold date (Now - DaysInactive)

    InactiveScript->>MgGraph: Get-MgUser(All, Properties including SignInActivity)
    MgGraph->>Dir: Query users with sign-in activity
    Dir-->>MgGraph: User list with SignInActivity
    MgGraph-->>InactiveScript: Users collection

    InactiveScript->>InactiveScript: Filter users with LastSignInDateTime missing or < threshold
    InactiveScript->>InactiveScript: Build PSCustomObject results and statistics

    alt ExportPath provided
        InactiveScript->>Shell: Export-Csv(results, ExportPath)
    end

    InactiveScript->>Shell: Write statistics and recommendations
    InactiveScript-->>Admin: Return results collection
Loading

Sequence diagram for running Get-M365Licenses report

sequenceDiagram
    actor Admin
    participant Shell as PowerShell
    participant LicenseScript as Get-M365Licenses.ps1
    participant ConnectModule as Connect-M365.ps1
    participant MgGraph as Microsoft Graph
    participant LicService as Licensing service

    Admin->>Shell: Run .\licenses\Get-M365Licenses.ps1 -ExportPath path
    Shell->>LicenseScript: Invoke script with ExportPath
    LicenseScript->>ConnectModule: Import connection module (dot source)
    LicenseScript->>ConnectModule: Test-M365Connection()
    alt No active connection
        ConnectModule-->>LicenseScript: false
        LicenseScript->>ConnectModule: Connect-M365Services(Scopes=[Organization.Read.All, Directory.Read.All])
        ConnectModule->>MgGraph: Connect-MgGraph(Scopes)
        MgGraph-->>ConnectModule: OAuth2 token and context
        ConnectModule-->>LicenseScript: true
    else Active connection
        ConnectModule-->>LicenseScript: true
    end

    LicenseScript->>MgGraph: Get-MgSubscribedSku(All)
    MgGraph->>LicService: Query subscribed SKUs
    LicService-->>MgGraph: SKU list with PrepaidUnits and ConsumedUnits
    MgGraph-->>LicenseScript: SKUs collection

    LicenseScript->>LicenseScript: Map SkuPartNumber to friendly names
    LicenseScript->>LicenseScript: Compute totals, availability, UsagePercent

    alt ExportPath provided
        LicenseScript->>Shell: Export-Csv(results, ExportPath)
    end

    LicenseScript->>Shell: Write overall statistics and low-availability warnings
    LicenseScript-->>Admin: Return results collection
Loading

Class diagram for M365 admin script modules and scripts

classDiagram
    class ConnectM365Module {
        <<PowerShellModule>>
        +bool Connect-M365Services(string TenantId, string[] Scopes)
        +void Disconnect-M365Services()
        +bool Test-M365Connection()
    }

    class GetM365UsersScript {
        <<Script>>
        +string Filter
        +string ExportPath
        +Collection Run(string Filter, string ExportPath)
    }

    class GetM365GroupsScript {
        <<Script>>
        +string GroupName
        +bool IncludeMembers
        +Collection Run(string GroupName, bool IncludeMembers)
    }

    class GetM365LicensesScript {
        <<Script>>
        +string ExportPath
        +Collection Run(string ExportPath)
    }

    class GetM365InactiveUsersScript {
        <<Script>>
        +int DaysInactive
        +string ExportPath
        +Collection Run(int DaysInactive, string ExportPath)
    }

    ConnectM365Module <.. GetM365UsersScript : uses
    ConnectM365Module <.. GetM365GroupsScript : uses
    ConnectM365Module <.. GetM365LicensesScript : uses
    ConnectM365Module <.. GetM365InactiveUsersScript : uses
Loading

File-Level Changes

Change Details Files
Introduce a shared Microsoft Graph connection module with connect/test/disconnect helpers and scope handling.
  • Implement Connect-M365Services to validate Microsoft.Graph installation, connect with optional TenantId and customizable scopes, and print connection context details.
  • Add Disconnect-M365Services wrapper for Disconnect-MgGraph with basic error handling.
  • Add Test-M365Connection helper using Get-MgContext to verify an active session and report status.
  • Export the three helper functions from the module for reuse by other scripts.
4-m365-admin-scripts/common/Connect-M365.ps1
Add user reporting script that lists M365 users with rich metadata, optional OData filtering, CSV export, and basic statistics.
  • Wire the script to the shared connection module and ensure required User.Read.All scope.
  • Use Get-MgUser with an optional -Filter and an explicit property set including SignInActivity.
  • Shape output into a consistent object with identity, contact, org data, and last sign-in, and write as a table.
  • Support optional CSV export and print simple enabled/disabled user counts.
4-m365-admin-scripts/users/Get-M365Users.ps1
Add group reporting script that enumerates M365 groups, optionally expanding members and summarizing group types.
  • Reuse the connection module and request Group.Read.All and GroupMember.Read.All scopes if not already connected.
  • Call Get-MgGroup with an optional displayName filter and a fixed property list to retrieve core group metadata.
  • When IncludeMembers is set, fetch members per group and resolve them to users for display of names and UPNs.
  • Format output differently depending on IncludeMembers and compute basic counts for Microsoft 365 vs security groups.
4-m365-admin-scripts/groups/Get-M365Groups.ps1
Add license usage reporting script that aggregates license SKUs, maps product names, computes utilization, and surfaces low-availability warnings.
  • Leverage the shared connection module and connect with Organization.Read.All and Directory.Read.All scopes if needed.
  • Query subscribed SKUs via Get-MgSubscribedSku and map SkuPartNumber values to friendlier product names where known.
  • Calculate derived fields like available licenses and usage percentage per SKU and display them in a sorted table.
  • Compute overall license totals and usage, and emit warnings for SKUs with fewer than five available licenses; support optional CSV export.
4-m365-admin-scripts/licenses/Get-M365Licenses.ps1
Add inactive user reporting script that identifies accounts with no or stale sign-in activity and generates statistics and recommendations.
  • Use the shared connection module and ensure User.Read.All and AuditLog.Read.All scopes, with a configurable DaysInactive threshold.
  • Fetch users with SignInActivity, compute a threshold date, and filter users whose last sign-in is missing or older than the threshold.
  • Project results into a custom object with profile data, last sign-in, days since sign-in, and creation date; optionally export to CSV.
  • Print summary statistics (enabled vs disabled, never signed in) and emit human-readable recommendations in both languages.
4-m365-admin-scripts/reports/Get-M365InactiveUsers.ps1
Document the M365 admin script suite with bilingual usage instructions, prerequisites, and example workflows.
  • Describe required Microsoft.Graph modules and Graph API permissions.
  • Provide per-script usage sections with common invocations and explanations of outputs.
  • Document directory structure and sample daily, monthly, and license audit scenarios combining the scripts.
  • Include basic security, troubleshooting, and licensing notes in both Hungarian and English where relevant.
4-m365-admin-scripts/README.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link

coderabbitai bot commented Dec 4, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

A new M365 admin scripts module is introduced with core connection functionality and four reporting scripts. The module includes helper functions for Graph API authentication and query scripts for retrieving user, group, license, and inactive user data from Microsoft 365, with optional CSV export capabilities and bilingual console messaging.

Changes

Cohort / File(s) Summary
Documentation
4-m365-admin-scripts/README.md
New README documenting module overview, prerequisites, scripts, directory structure, usage examples, security considerations, and troubleshooting in English and Hungarian.
Core Connection Module
4-m365-admin-scripts/common/Connect-M365.ps1
New module with three exported functions: Connect-M365Services (authenticates to Graph API with configurable scopes), Disconnect-M365Services (disconnects from Graph), and Test-M365Connection (validates active context). Includes validation and bilingual messaging.
Reporting & Query Scripts
4-m365-admin-scripts/users/Get-M365Users.ps1, 4-m365-admin-scripts/groups/Get-M365Groups.ps1, 4-m365-admin-scripts/licenses/Get-M365Licenses.ps1, 4-m365-admin-scripts/reports/Get-M365InactiveUsers.ps1
Four new scripts querying M365 data: users (filterable), groups (with optional member details), license SKUs (with usage metrics and friendly name mapping), and inactive users (threshold-based, default 90 days). Each includes result formatting, statistics aggregation, optional CSV export, and error handling.

Sequence Diagram

sequenceDiagram
    actor Admin
    participant Script as M365 Admin Script
    participant Graph as Microsoft Graph API
    participant M365 as Microsoft 365 Backend

    Admin->>Script: Execute script (with optional parameters)
    Script->>Script: Import Connect-M365.ps1
    Script->>Script: Test-M365Connection
    
    alt No Active Context
        Script->>Graph: Connect-MgGraph (with scopes)
        Graph->>M365: Authenticate & validate
        M365-->>Graph: Auth token
        Graph-->>Script: Connection established
    end
    
    Script->>Graph: Query data (Get-MgUser/Group/SubscribedSku)
    Graph->>M365: Fetch data
    M365-->>Graph: Return dataset
    Graph-->>Script: Data results
    
    Script->>Script: Process & format results
    Script->>Script: Calculate metrics/statistics
    
    alt Export Requested
        Script->>Script: Format as CSV
        Script->>Admin: Export to file
    end
    
    Script->>Admin: Display formatted table & summary
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Connect-M365.ps1: Verify Microsoft.Graph module validation, error handling for failed authentication, and scope parameter defaults
  • Get-M365Groups.ps1: Validate member resolution logic (nested loops fetching member details), accuracy of GroupTypes classification, and null-handling for groups without members
  • Get-M365Licenses.ps1: Review SkuPartNumber-to-friendly-name mapping completeness, division-by-zero handling in percentage calculations, and warning threshold logic (< 5 available licenses)
  • Get-M365InactiveUsers.ps1: Verify date threshold calculation (90-day default), proper filtering of users with null SignInActivity, and enabled/disabled account statistics accuracy
  • CSV export paths: Ensure consistent error handling for invalid or inaccessible export paths across all scripts

Poem

🐰 A rabbit hops through M365 lands,
With scripts to query and help admin hands,
Users, groups, and licenses align,
Inactive accounts now clearly shine,
Connection flows smooth, exports run fine! 🎉

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/phase-6-m365-admin-scripts

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9de275c and a53d421.

📒 Files selected for processing (6)
  • 4-m365-admin-scripts/README.md (1 hunks)
  • 4-m365-admin-scripts/common/Connect-M365.ps1 (1 hunks)
  • 4-m365-admin-scripts/groups/Get-M365Groups.ps1 (1 hunks)
  • 4-m365-admin-scripts/licenses/Get-M365Licenses.ps1 (1 hunks)
  • 4-m365-admin-scripts/reports/Get-M365InactiveUsers.ps1 (1 hunks)
  • 4-m365-admin-scripts/users/Get-M365Users.ps1 (1 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@w7-mgfcode w7-mgfcode merged commit 099bd35 into main Dec 4, 2025
4 of 12 checks passed
@w7-mgfcode w7-mgfcode deleted the feature/phase-6-m365-admin-scripts branch December 4, 2025 14:33
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes and found some issues that need to be addressed.

  • Connect-M365.ps1 is dot-sourced as a plain script, so using Export-ModuleMember at the end will fail because it only works in module (.psm1) context; consider removing it or converting this into a proper module.
  • In Get-M365Groups.ps1, when -IncludeMembers is used you call Get-MgUser for each Get-MgGroupMember result, which will be slow for large groups and can fail for non-user members (e.g., groups, service principals); consider either selecting properties directly from the member objects or branching based on object type to avoid unnecessary per-member lookups.
  • Both user and inactive-user scripts rely on the SignInActivity property, which is only available via the beta profile in Microsoft Graph PowerShell; consider explicitly switching to the beta profile (e.g., Select-MgProfile -Name 'beta') or documenting/enforcing the required profile in the connection logic to avoid runtime property errors.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Connect-M365.ps1 is dot-sourced as a plain script, so using `Export-ModuleMember` at the end will fail because it only works in module (.psm1) context; consider removing it or converting this into a proper module.
- In Get-M365Groups.ps1, when `-IncludeMembers` is used you call `Get-MgUser` for each `Get-MgGroupMember` result, which will be slow for large groups and can fail for non-user members (e.g., groups, service principals); consider either selecting properties directly from the member objects or branching based on object type to avoid unnecessary per-member lookups.
- Both user and inactive-user scripts rely on the `SignInActivity` property, which is only available via the beta profile in Microsoft Graph PowerShell; consider explicitly switching to the beta profile (e.g., `Select-MgProfile -Name 'beta'`) or documenting/enforcing the required profile in the connection logic to avoid runtime property errors.

## Individual Comments

### Comment 1
<location> `4-m365-admin-scripts/common/Connect-M365.ps1:116-117` </location>
<code_context>
+    }
+}
+
+# Export functions
+Export-ModuleMember -Function Connect-M365Services, Disconnect-M365Services, Test-M365Connection
</code_context>

<issue_to_address>
**issue (bug_risk):** Export-ModuleMember in a dot-sourced .ps1 will fail; this should only be used in a .psm1 module.

Because this file is dot-sourced (e.g. `. (Join-Path ... 'common\Connect-M365.ps1')`), `Export-ModuleMember` will always fail with `The Export-ModuleMember cmdlet can only be called from inside a script module`. Please either remove this call or convert the script to a `.psm1` module and load it via `Import-Module` instead of dot-sourcing.
</issue_to_address>

### Comment 2
<location> `4-m365-admin-scripts/groups/Get-M365Groups.ps1:108-110` </location>
<code_context>
+        }
+
+        # Statisztikák / Statistics
+        $m365Groups = ($results | Where-Object { $_.Type -eq "Microsoft 365" }).Count
+        $securityGroups = ($results | Where-Object { $_.SecurityEnabled }).Count
+
+        Write-Host "`nStatisztikák / Statistics:" -ForegroundColor Cyan
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Security group statistics may double-count Microsoft 365 groups that are also security-enabled.

Because `Type` is set to `"Microsoft 365"` when `GroupTypes` contains `"Unified"`, but `securityGroups` is counted solely via `SecurityEnabled`, unified security-enabled groups are included in both stats. If these statistics are meant to be mutually exclusive, consider basing `securityGroups` on something like `Type -ne "Microsoft 365" -and $_.SecurityEnabled`, or introduce a dedicated type for pure security groups and count against that.

```suggestion
        # Statisztikák / Statistics
        # Microsoft 365 csoportok (Unified) / Microsoft 365 groups (Unified)
        $m365Groups = ($results | Where-Object { $_.Type -eq "Microsoft 365" }).Count

        # Biztonsági csoportok, M365 csoportok nélkül / Security groups excluding M365 groups
        # Így a statisztikák kölcsönösen kizáróak maradnak / Keeps the statistics mutually exclusive
        $securityGroups = ($results | Where-Object { $_.SecurityEnabled -and $_.Type -ne "Microsoft 365" }).Count
```
</issue_to_address>

### Comment 3
<location> `4-m365-admin-scripts/users/Get-M365Users.ps1:108-109` </location>
<code_context>
+        }
+
+        # Statisztikák / Statistics
+        $enabledCount = ($users | Where-Object { $_.AccountEnabled }).Count
+        $disabledCount = $users.Count - $enabledCount
+
+        Write-Host "`nStatisztikák / Statistics:" -ForegroundColor Cyan
</code_context>

<issue_to_address>
**suggestion (bug_risk):** The statistics label 'Inactive users' is actually counting disabled accounts, which can be misleading.

Here `disabledCount` is based on `AccountEnabled`, but the label is `Inaktív felhasználók / Inactive users`. Elsewhere, “inactive” means no recent sign-ins, not disabled accounts. Please either rename this label (e.g., `Letiltott felhasználók / Disabled users`) or change the logic to reflect sign-in inactivity, so terminology stays consistent across reports.

```suggestion
        Write-Host "  Aktív felhasználók / Active users: $enabledCount" -ForegroundColor Green
        Write-Host "  Letiltott felhasználók / Disabled users: $disabledCount" -ForegroundColor Yellow
```
</issue_to_address>

### Comment 4
<location> `4-m365-admin-scripts/README.md:145` </location>
<code_context>
+```
+
+**Statisztikák / Statistics:**
+- Inaktív aktív fiókok / Inactive enabled accounts
+- Letiltott fiókok / Disabled accounts
+- Soha nem bejelentkezett / Never signed in
</code_context>

<issue_to_address>
**suggestion (typo):** Clarify the Hungarian wording "Inaktív aktív fiókok", which reads contradictory.

Since "inaktív" and "aktív" contradict each other, consider aligning more closely with the English "Inactive enabled accounts", e.g. "Inaktív, engedélyezett fiókok", to convey that the accounts are enabled but currently inactive.

```suggestion
- Inaktív, engedélyezett fiókok / Inactive enabled accounts
```
</issue_to_address>

### Comment 5
<location> `4-m365-admin-scripts/README.md:245` </location>
<code_context>
+
+### Kapcsolódási Hiba / Connection Error
+```powershell
+# Module ellenőrzés / Check module
+Get-Module Microsoft.Graph -ListAvailable
+
</code_context>

<issue_to_address>
**nitpick (typo):** Align the Hungarian comment with the rest by using "Modul" instead of "Module".

This seems like a minor consistency issue with the Hungarian terminology. Please change it to "Modul ellenőrzés" to match the rest of the Hungarian text.

```suggestion
# Modul ellenőrzés / Check module
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +116 to +117
# Export functions
Export-ModuleMember -Function Connect-M365Services, Disconnect-M365Services, Test-M365Connection
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Export-ModuleMember in a dot-sourced .ps1 will fail; this should only be used in a .psm1 module.

Because this file is dot-sourced (e.g. . (Join-Path ... 'common\Connect-M365.ps1')), Export-ModuleMember will always fail with The Export-ModuleMember cmdlet can only be called from inside a script module. Please either remove this call or convert the script to a .psm1 module and load it via Import-Module instead of dot-sourcing.

Comment on lines +108 to +110
# Statisztikák / Statistics
$m365Groups = ($results | Where-Object { $_.Type -eq "Microsoft 365" }).Count
$securityGroups = ($results | Where-Object { $_.SecurityEnabled }).Count
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Security group statistics may double-count Microsoft 365 groups that are also security-enabled.

Because Type is set to "Microsoft 365" when GroupTypes contains "Unified", but securityGroups is counted solely via SecurityEnabled, unified security-enabled groups are included in both stats. If these statistics are meant to be mutually exclusive, consider basing securityGroups on something like Type -ne "Microsoft 365" -and $_.SecurityEnabled, or introduce a dedicated type for pure security groups and count against that.

Suggested change
# Statisztikák / Statistics
$m365Groups = ($results | Where-Object { $_.Type -eq "Microsoft 365" }).Count
$securityGroups = ($results | Where-Object { $_.SecurityEnabled }).Count
# Statisztikák / Statistics
# Microsoft 365 csoportok (Unified) / Microsoft 365 groups (Unified)
$m365Groups = ($results | Where-Object { $_.Type -eq "Microsoft 365" }).Count
# Biztonsági csoportok, M365 csoportok nélkül / Security groups excluding M365 groups
# Így a statisztikák kölcsönösen kizáróak maradnak / Keeps the statistics mutually exclusive
$securityGroups = ($results | Where-Object { $_.SecurityEnabled -and $_.Type -ne "Microsoft 365" }).Count

Comment on lines +108 to +109
Write-Host " Aktív felhasználók / Active users: $enabledCount" -ForegroundColor Green
Write-Host " Inaktív felhasználók / Inactive users: $disabledCount" -ForegroundColor Yellow
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): The statistics label 'Inactive users' is actually counting disabled accounts, which can be misleading.

Here disabledCount is based on AccountEnabled, but the label is Inaktív felhasználók / Inactive users. Elsewhere, “inactive” means no recent sign-ins, not disabled accounts. Please either rename this label (e.g., Letiltott felhasználók / Disabled users) or change the logic to reflect sign-in inactivity, so terminology stays consistent across reports.

Suggested change
Write-Host " Aktív felhasználók / Active users: $enabledCount" -ForegroundColor Green
Write-Host " Inaktív felhasználók / Inactive users: $disabledCount" -ForegroundColor Yellow
Write-Host " Aktív felhasználók / Active users: $enabledCount" -ForegroundColor Green
Write-Host " Letiltott felhasználók / Disabled users: $disabledCount" -ForegroundColor Yellow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants