Skip to content

Conversation

@manas-metron
Copy link

@manas-metron manas-metron commented Jul 3, 2025

Summary by CodeRabbit

  • New Features

    • Added commands to list Intune managed devices and their compliance information.
    • Introduced registry and security analysis for Intune-managed Windows devices, including risk scoring, compliance summaries, and actionable recommendations.
    • Enabled collection and analysis of registry data from Intune devices for enhanced security insights.
    • Integrated detailed device, compliance, and configuration models for Intune assets.
    • Added extensive Intune device management and script execution capabilities, including script deployment validation, execution monitoring, and registry data collection.
    • Introduced comprehensive security data models and BloodHound integration for enhanced security posture assessment.
    • Added filtering options for Intune device compliance by operating system and compliance state.
    • Enhanced streaming and output formatting options for listing Intune devices to improve performance and usability.
  • Chores

    • Updated ignore rules for workflow and script files.
    • Removed a mock client implementation used for testing.

…etron-azurehound-enhancement-metronlabs

Files are causing a conflict because newly created files were added but the deleted files were not removed.
# Test the current implementation

Build the app using:

go build -ldflags="-s -w -X github.com/bloodhoundad/azurehound/v2/constants.Version=dev-intune"

Then test using added JWT token after these commands:

./azurehound list intune-devices --jwt JWT_TOKEN
./azurehound list intune-data --jwt JWT_TOKEN
./azurehound list intune-compliance --jwt JWT_TOKEN
Add
1. client id
2. client secret &
3. tenant id
for the script to work.
This reverts commit fd673c1.
This reverts commit 160a712.
@coderabbitai
Copy link

coderabbitai bot commented Jul 3, 2025

Walkthrough

This update introduces comprehensive Microsoft Intune device management and security analysis capabilities. New models, enums, and client methods enable listing Intune devices, collecting compliance and registry data, executing PowerShell scripts, and analyzing device security. Several new CLI commands provide access to these features. Additionally, a large auto-generated mock client is removed.

Changes

File(s) Change Summary
.gitignore Updated to ignore GitHub workflow files, the entire .github directory, and a PowerShell script.
client/client.go Extended interfaces with methods for Intune device management, script execution, and compliance/configuration retrieval.
client/intune_devices.go Added methods to list Intune managed devices and retrieve device compliance/configuration states.
client/intune_registry.go Implemented registry data collection, script execution, and Intune device management logic.
client/mocks/client.go Deleted the auto-generated GoMock implementation for the AzureClient interface.
cmd/list-intune-compliance.go Added a CLI command to list Intune device compliance, supporting detailed and filtered output.
cmd/list-intune-devices.go Added a CLI command to list Intune managed devices with streaming and multiple output formats.
cmd/list-intune-registry-analysis.go Added a CLI command for registry-based security analysis and reporting on Intune-managed Windows devices.
enums/intune.go Introduced enums for Intune device kinds, compliance states, enrollment types, management agents, and OS types.
models/azure/intune.go Defined models for Intune devices, script executions, compliance/configuration, registry data, and BloodHound integration.
models/azure/intune_security.go Added comprehensive security analysis, configuration, compliance, and BloodHound data models for Intune.
models/intune/models.go Defined Intune data models for managed devices, compliance, and configuration states.

Sequence Diagram(s)

Intune Device Registry Data Collection Flow

sequenceDiagram
    participant User
    participant CLI
    participant AzureClient
    participant IntuneAPI

    User->>CLI: Run "intune-registry-analysis" command
    CLI->>AzureClient: ListIntuneDevices()
    AzureClient->>IntuneAPI: GET /managedDevices
    IntuneAPI-->>AzureClient: List of devices
    AzureClient-->>CLI: Stream devices

    loop For each device
        CLI->>AzureClient: CollectRegistryDataFromDevice(deviceID)
        AzureClient->>IntuneAPI: ExecuteRegistryCollectionScript(deviceID)
        IntuneAPI-->>AzureClient: ScriptExecution info
        AzureClient->>IntuneAPI: WaitForScriptCompletion(scriptID)
        IntuneAPI-->>AzureClient: ScriptExecutionResult (with registry data)
        AzureClient-->>CLI: RegistryData
    end

    CLI->>CLI: Analyze registry and compliance data
    CLI->>User: Output security analysis/report
Loading

Intune Device Compliance Listing Flow

sequenceDiagram
    participant User
    participant CLI
    participant AzureClient
    participant IntuneAPI

    User->>CLI: Run "list-intune-compliance" command
    CLI->>AzureClient: ListIntuneManagedDevices()
    AzureClient->>IntuneAPI: GET /managedDevices
    IntuneAPI-->>AzureClient: Stream devices
    AzureClient-->>CLI: Stream devices

    CLI->>AzureClient: GetIntuneDeviceCompliance(deviceID)
    AzureClient->>IntuneAPI: GET /managedDevices/{id}/deviceCompliancePolicyStates
    IntuneAPI-->>AzureClient: ComplianceState(s)
    AzureClient-->>CLI: ComplianceState(s)

    CLI->>User: Output compliance info
Loading

Poem

🐇
A hop, a skip, through Intune fields anew,
Devices and compliance now in our view.
Scripts run, registry secrets revealed,
Security findings carefully unsealed.
With models and enums, our warren expands—
BloodHound’s analysis now close at hand!
🥕


📜 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 f2c2b46 and 8eebeac.

📒 Files selected for processing (3)
  • client/client.go (3 hunks)
  • cmd/list-intune-compliance.go (1 hunks)
  • cmd/list-intune-devices.go (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
client/client.go (10)
client/query/params.go (2)
  • GraphParams (109-120)
  • RMParams (50-62)
models/azure/role.go (1)
  • Role (22-69)
models/azure/unified_role_assignment.go (1)
  • UnifiedRoleAssignment (22-76)
models/azure/device.go (1)
  • Device (28-131)
models/azure/role-eligibility-schedule-instance.go (1)
  • UnifiedRoleEligibilityScheduleInstance (20-44)
models/azure/tenant.go (2)
  • Tenant (22-33)
  • TenantList (35-38)
models/intune/models.go (3)
  • ManagedDevice (12-25)
  • ComplianceState (28-36)
  • ConfigurationState (46-54)
models/azure/subscription.go (1)
  • Subscription (24-51)
models/azure/management_group.go (1)
  • ManagementGroup (20-31)
models/azure/descendant-info.go (1)
  • DescendantInfo (39-62)
🔇 Additional comments (2)
cmd/list-intune-compliance.go (1)

46-46: Good implementation of configurable OS filter.

The addition of the --os flag with a default of "Windows" and support for "all" properly addresses the previous concern about hardcoded OS filtering. This provides flexibility while maintaining backward compatibility.

cmd/list-intune-devices.go (1)

83-122: Excellent streaming implementation addressing memory concerns.

The processIntuneDevicesStreaming function properly addresses the previous memory usage concern by processing devices as they arrive without accumulating them in memory. The implementation includes proper context cancellation checks and respects the max device limit.

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 14

🧹 Nitpick comments (8)
cmd/list-intune-devices.go (1)

28-48: Good implementation with minor improvement opportunity

The command implementation follows established patterns and handles errors appropriately. The output formatting provides useful device information.

Consider adding a --count flag to only show the device count without detailed listing for performance in large environments.

client/intune_devices.go (1)

16-20: Consider making default parameters more explicit

The setDefaultParams function modifies parameters in-place, which could be unexpected for callers.

Consider documenting the default behavior or making it more explicit:

+// setDefaultParams sets default pagination parameters if not specified
+// Default Top value is 999 to retrieve most devices in a single request
 func setDefaultParams(params *query.GraphParams) {
     if params.Top == 0 {
         params.Top = 999
     }
 }
cmd/list-intune-compliance.go (1)

24-32: Consider making the compliance state version configurable.

The Version field is hardcoded to 1. Consider making this configurable or documenting the versioning strategy to ensure compatibility with future changes.

Add a version parameter or use a constant:

+const DefaultComplianceStateVersion = 1
+
 func createBasicComplianceState(device intune.ManagedDevice, suffix string) intune.ComplianceState {
     return intune.ComplianceState{
         Id:         device.Id + suffix,
         DeviceId:   device.Id,
         DeviceName: device.DeviceName,
         State:      device.ComplianceState,
-        Version:    1,
+        Version:    DefaultComplianceStateVersion,
     }
 }
client/intune_registry.go (1)

224-226: Consider configurable polling interval with exponential backoff.

The polling interval is hardcoded to 30 seconds. For better efficiency and responsiveness, consider making this configurable and implementing exponential backoff.

-func (s *azureClient) WaitForScriptCompletion(ctx context.Context, scriptID string, maxWaitTime time.Duration) (*azure.RegistryData, error) {
+func (s *azureClient) WaitForScriptCompletion(ctx context.Context, scriptID string, maxWaitTime time.Duration, pollInterval time.Duration) (*azure.RegistryData, error) {
 	timeout := time.After(maxWaitTime)
-	ticker := time.NewTicker(30 * time.Second)
+	if pollInterval <= 0 {
+		pollInterval = 30 * time.Second
+	}
+	ticker := time.NewTicker(pollInterval)
 	defer ticker.Stop()
models/azure/intune.go (1)

30-30: Document handling of sensitive device identifiers.

The UDID field contains sensitive device identifier information. Ensure proper handling, logging policies, and potential redaction requirements are documented.

Consider implementing a redaction interface for sensitive fields to ensure they are not accidentally logged or exposed in non-secure contexts.

cmd/list-intune-registry-analysis.go (3)

361-371: Fix error message formatting.

The error messages are missing newline characters, which will cause output formatting issues.

-	fmt.Printf("Starting device analysis without script execution...")
+	fmt.Printf("Starting device analysis without script execution...\n")

 	// ... later in the code ...
 	if deviceResult.Error != nil {
-		fmt.Printf("Error getting device: %v", deviceResult.Error)
+		fmt.Printf("Error getting device: %v\n", deviceResult.Error)
 		continue
 	}

418-418: Make the sync staleness threshold configurable.

The 7-day threshold for determining stale device sync is hardcoded. This should be configurable to accommodate different organizational policies.

+const DefaultSyncStalenessThresholdDays = 7
+
 // Check for old sync dates
-if time.Since(device.LastSyncDateTime) > 7*24*time.Hour {
+if time.Since(device.LastSyncDateTime) > time.Duration(DefaultSyncStalenessThresholdDays)*24*time.Hour {

444-445: Fix error message formatting in registry analysis function.

Missing newlines in Printf statements will cause output formatting issues.

-	fmt.Printf("Starting real registry security analysis...")
+	fmt.Printf("Starting real registry security analysis...\n")

 	// ... and later ...
-	fmt.Printf("Error collecting registry data: %v", registryResult.Error)
+	fmt.Printf("Error collecting registry data: %v\n", registryResult.Error)

-	fmt.Printf("Analyzed device %s: %d findings, risk score %d",
+	fmt.Printf("Analyzed device %s: %d findings, risk score %d\n",
 		analysis.Device.DeviceName,
 		len(analysis.SecurityFindings),
 		analysis.RiskScore)

-	fmt.Printf("Registry analysis completed: %d successful, %d errors", successCount, errorCount)
+	fmt.Printf("Registry analysis completed: %d successful, %d errors\n", successCount, errorCount)

Also applies to: 465-468

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc3ed0f and 5811b81.

📒 Files selected for processing (12)
  • .gitignore (1 hunks)
  • client/client.go (3 hunks)
  • client/intune_devices.go (1 hunks)
  • client/intune_registry.go (1 hunks)
  • client/mocks/client.go (0 hunks)
  • cmd/list-intune-compliance.go (1 hunks)
  • cmd/list-intune-devices.go (1 hunks)
  • cmd/list-intune-registry-analysis.go (1 hunks)
  • enums/intune.go (1 hunks)
  • models/azure/intune.go (1 hunks)
  • models/azure/intune_security.go (1 hunks)
  • models/intune/models.go (1 hunks)
💤 Files with no reviewable changes (1)
  • client/mocks/client.go
🧰 Additional context used
🧬 Code Graph Analysis (2)
client/intune_devices.go (4)
client/query/params.go (2)
  • GraphParams (109-120)
  • Top (42-42)
client/client.go (1)
  • AzureResult (96-99)
models/intune/models.go (3)
  • ManagedDevice (12-25)
  • ComplianceState (28-36)
  • ConfigurationState (46-54)
constants/misc.go (1)
  • GraphApiVersion (43-43)
enums/intune.go (2)
enums/kind.go (1)
  • Kind (20-20)
models/intune/models.go (1)
  • ComplianceState (28-36)
🔇 Additional comments (15)
.gitignore (1)

235-238: LGTM - Appropriate gitignore additions

The additions properly exclude GitHub workflow files and PowerShell scripts that should not be version controlled.

cmd/list-intune-devices.go (1)

21-26: LGTM - Well-structured command definition

The command uses proper Cobra patterns with clear usage description and appropriate flags.

models/intune/models.go (3)

11-25: Excellent model design

The ManagedDevice struct comprehensively captures all essential device attributes with proper JSON serialization tags and appropriate field types.


27-43: Well-structured compliance models

The ComplianceState and ComplianceSettingState structs properly model the hierarchical compliance information with appropriate nesting and field types.


45-61: Consistent configuration state modeling

The ConfigurationState and ConfigurationSettingState structs follow the same pattern as compliance models, ensuring consistency in the API design.

client/intune_devices.go (3)

22-34: Excellent async implementation

The method properly uses channels for async processing and follows the established pattern with proper path construction and parameter handling.


36-48: Good compliance data retrieval implementation

The method correctly constructs the device-specific API path and follows the same async pattern as the device listing method.


50-62: Consistent configuration data retrieval

The method maintains consistency with the other methods in terms of API patterns and async handling.

enums/intune.go (5)

3-9: Well-defined Kind constants

The Kind constants follow proper naming conventions and provide clear identification for different Intune resource types.


11-21: Comprehensive compliance state enumeration

The ComplianceState type and constants cover all standard Intune compliance states, providing type safety and clear documentation.


23-32: Complete enrollment type coverage

The EnrollmentType enumeration covers the key Windows and general enrollment methods used in Intune deployments.


34-42: Appropriate management agent types

The ManagementAgent enumeration properly represents the different management agents that can be used with Intune.


44-52: Standard operating system enumeration

The OperatingSystem constants cover the primary platforms supported by Intune with proper casing conventions.

cmd/list-intune-compliance.go (1)

171-173: GraphParams does not require initialization

After verifying the GraphParams definition in client/query/params.go, all of its fields are optional query parameters. Passing an empty GraphParams{} to GetIntuneDeviceCompliance simply results in no extra parameters—this is the intended behavior. No changes are needed.

models/azure/intune_security.go (1)

8-18: LGTM!

The DeviceSecurityAnalysis struct is well-structured with appropriate field types and JSON tags.


func collectDeviceCompliance(ctx context.Context, client client.AzureClient, devices <-chan intune.ManagedDevice, out chan<- interface{}) {
var (
streams = pipeline.Demux(ctx.Done(), devices, config.ColStreamCount.Value().(int))
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle type assertion safely to prevent panic.

The type assertion config.ColStreamCount.Value().(int) could panic if the value is not an integer. Use the two-value form to handle this safely.

 var (
-    streams = pipeline.Demux(ctx.Done(), devices, config.ColStreamCount.Value().(int))
+    streamCount, ok := config.ColStreamCount.Value().(int)
+    streams     []<-chan intune.ManagedDevice
     wg      sync.WaitGroup
 )
+
+if !ok || streamCount <= 0 {
+    streamCount = 1 // fallback to sequential processing
+}
+streams = pipeline.Demux(ctx.Done(), devices, streamCount)

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In cmd/list-intune-compliance.go at line 140, the type assertion on
config.ColStreamCount.Value() to int is done unsafely and may cause a panic if
the value is not an int. Change this to use the two-value form of type assertion
to check if the assertion succeeded. If it fails, handle the error or provide a
default integer value before passing it to pipeline.Demux to prevent runtime
panics.

@SpecterOps SpecterOps deleted a comment from github-actions bot Jul 10, 2025
@github-actions
Copy link

CLA Assistant Lite bot:
Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request

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.

2 participants