-
Notifications
You must be signed in to change notification settings - Fork 8
Cut 4862 status reporting v2 #235
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…Cloud/jumpcloud-ADMU into CUT-4862_statusReportingV2
…Cloud/jumpcloud-ADMU into CUT-4862_statusReportingV2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds support for remote migration status tracking via JumpCloud system description fields, enabling administrators to track migration progress without relying on CSV files.
Changes:
- Introduces device description-based migration status reporting
- Adds
DeviceQuery.ps1script for tracking AD user migration states - Updates ADMU module to version 2.12.0 with enhanced status reporting capabilities
Reviewed changes
Copilot reviewed 22 out of 23 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| ModuleChangelog.md | Version 2.12.0 release notes documenting new features |
| JumpCloud.ADMU.psd1 | Module version bump to 2.12.0 and generation date update |
| 3_ADMU_Invoke.ps1 | Refactored to support Description data source alongside CSV |
| DeviceQuery.ps1 | New script for querying and updating AD user migration status |
| Start-Migration.ps1 | Enhanced with device description status reporting |
| Start-Reversion.ps1 | Parameter name standardization and improved error handling |
| Build-MigrationDescription.ps1 | New function to build/update migration description objects |
| Invoke-SystemContextAPI.ps1 | Attribute merging logic for non-destructive updates |
| Invoke-SystemAPI.ps1 | Function renamed and enhanced with GET method support |
| Form.ps1, ProgressForm.ps1 | Version string updated to 2.12.0 |
| Write-ToProgress.ps1 | Updated to use Build-MigrationDescription function |
| deviceQuery.tests.ps1 | Comprehensive test suite for DeviceQuery functionality |
| invokeMigration.Tests.ps1 | Updated test suite with new function names and error messages |
| Start-Reversion.Acceptance.Tests.ps1 | Test updates for parameter changes |
| Start-Migration.Acceptance.Tests.ps1 | Tests for description-based status reporting |
| Invoke-SystemContextAPI.Acceptance.Tests.ps1 | Tests for attribute CRUD operations |
| Invoke-SystemAPI.Acceptance.Tests.ps1 | Updated tests for renamed function |
| Build-MigrationDescription.Acceptance.Tests.ps1 | Acceptance tests for new function |
| Initialize-TestUser.ps1 | Added Reversion parameter for test scenarios |
| JumpCloud.ADMU-help.xml | Help documentation for Start-Reversion function |
| Start-Reversion.md | Documentation for Start-Reversion function |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="none"> | ||
| <maml:name>form</maml:name> | ||
| <maml:description> | ||
| <maml:para>{{ Fill form Description }}</maml:para> |
Copilot
AI
Jan 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple parameter descriptions contain placeholder text '{{ Fill ... Description }}' that should be replaced with actual documentation. These placeholders indicate incomplete documentation for the 'form', 'UserName', 'ProfileSize', and 'LocalPath' parameters.
| <command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="none"> | ||
| <maml:name>form</maml:name> | ||
| <maml:description> | ||
| <maml:para>{{ Fill form Description }}</maml:para> |
Copilot
AI
Jan 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple parameter descriptions contain placeholder text '{{ Fill ... Description }}' that should be replaced with actual documentation. These placeholders indicate incomplete documentation for the 'form', 'UserName', 'ProfileSize', and 'LocalPath' parameters.
| <command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="none"> | ||
| <maml:name>UserName</maml:name> | ||
| <maml:description> | ||
| <maml:para>{{ Fill UserName Description }}</maml:para> |
Copilot
AI
Jan 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple parameter descriptions contain placeholder text '{{ Fill ... Description }}' that should be replaced with actual documentation. These placeholders indicate incomplete documentation for the 'form', 'UserName', 'ProfileSize', and 'LocalPath' parameters.
| <command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="none"> | ||
| <maml:name>ProfileSize</maml:name> | ||
| <maml:description> | ||
| <maml:para>{{ Fill ProfileSize Description }}</maml:para> |
Copilot
AI
Jan 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple parameter descriptions contain placeholder text '{{ Fill ... Description }}' that should be replaced with actual documentation. These placeholders indicate incomplete documentation for the 'form', 'UserName', 'ProfileSize', and 'LocalPath' parameters.
| <command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="none"> | ||
| <maml:name>LocalPath</maml:name> | ||
| <maml:description> | ||
| <maml:para>{{ Fill LocalPath Description }}</maml:para> |
Copilot
AI
Jan 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple parameter descriptions contain placeholder text '{{ Fill ... Description }}' that should be replaced with actual documentation. These placeholders indicate incomplete documentation for the 'form', 'UserName', 'ProfileSize', and 'LocalPath' parameters.
| ``` | ||
| ### -form | ||
| {{ Fill form Description }} |
Copilot
AI
Jan 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parameter descriptions contain placeholder text '{{ Fill ... Description }}' that should be replaced with actual documentation for the 'form', 'UserName', and 'ProfileSize' parameters.
| {{ Fill form Description }} | |
| Indicates that the cmdlet is being invoked from a form or UI context and suppresses additional interactive prompts. |
| ``` | ||
| ### -UserName | ||
| {{ Fill UserName Description }} |
Copilot
AI
Jan 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parameter descriptions contain placeholder text '{{ Fill ... Description }}' that should be replaced with actual documentation for the 'form', 'UserName', and 'ProfileSize' parameters.
| ``` | ||
| ### -ProfileSize | ||
| {{ Fill ProfileSize Description }} |
Copilot
AI
Jan 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parameter descriptions contain placeholder text '{{ Fill ... Description }}' that should be replaced with actual documentation for the 'form', 'UserName', and 'ProfileSize' parameters.
jumpcloud-ADMU-Advanced-Deployment/InvokeFromJCAgent/DeviceInit/DeviceQuery.ps1
Outdated
Show resolved
Hide resolved
jumpcloud-ADMU-Advanced-Deployment/InvokeFromJCAgent/DeviceInit/DeviceQuery.ps1
Outdated
Show resolved
Hide resolved
kmaranionjc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.


Issues
What does this solve?
Updates to support reading/ updating device device description as input source for ADMU migration. There are some significant changes to this branch though the concept is pretty similar to the #194.
This change will only affect remote migrations where the
reportStatusandsystemContextBindingparameters are set to$truein the3_ADMU_Invoke.ps1script.This release supports a migration scenario which is not yet documented but will be documented soon. The short of it is that there's a new way to migrate systems remotely. Instead of relying on the CSV method which is difficult at best to manage, these changes support the future vision of remote migration, for now data about AD users and the corresponding JumpCloud user-to-migrate are stored in a device's description field.
Example device with this data:

Data is stored in a .json format
[ { "st": "Pending", "msg": "Planned", "sid": "S-1-12-1-1616384916-1297768490-51239584-3993624739", "localPath": "C:\\Users\\GeorgeCostanza", "un": "", "uid": "", "lastLogin": "2025-12-05T17:42:22.7950000Z" }, ... ]This data can be set and modified through another method. This release just supports the tools ability to read from the device description and perform migrations when a valid user is defined in the system description field.
Changes to Invoke Script
There is a new directory in the Invoke Script directory containing the
deviceQuery.ps1script — something that's intended to be run on devices in a recurring schedule to get and update data about AD users on the device.The
deviceQuery.ps1script will get the AD users on a device, determine if any of them have been previously migrated and record their status to the device description field in JumpCloud. It will also update a custom attribute on the device itself to calculate the "status" of a device migration. For details please see thedeviceQuery.Tests.ps1included in this PR. In short a device migration state can be:Pending,InProgress,Complete,ErrorDevice custom attributes can drive dynamic device membership. So with this change, we get an automated way to group devices based on their admu status. This can be helpful when tracking overall status of migration.
The invoke script now can take this data as input instead of going through the process to set a CSV. Simply set the
deviceQuery.ps1script to run on all windows devices on a recurring schedule. (It's okay if it runs on the same device multiple times). The invoke script can use "Description" instead of "CSV" to pull data from the device description — the device just has to be eligible to use the system context API for this release, API Key support coming in a future release.Only users that have a valid username (un) and userID (uid) property can be migrated with the invoke script but the invoke script functions exactly the same if the source is CSV/ Description.
Changes to ADMU
For this release the Invoke script needed to be able to support reading from system description for migration. The Start-Migration function needed to work with these changes. There is a new function
Build-MigrationDescription.ps1which gets the current system description and attempts to update it if the user being migrated exists in the device description (using the SID as identifier).The
Write-ToProgressfunction is updated to support this change, basically we are pushing the work to define the user object to the newBuild-MigrationDescription.ps1function.Write-ToProgressjust facilitates the hand off.Invoke-SystemPutrenamed toInvoke-SystemApisince I'm using it to GET data about a system in theBuild-MigrationDescriptionfunction.A few changes to
Invoke-SystemContextAPIto support updating the attribute object instead of wiping out existing attributes.Is there anything particularly tricky?
How should this be tested?
Screenshots