Small scale lab setup using two different VMs meant to demonstrate knowledge and practice of joiner-mover-leaver cycle
Stack: Windows Server 2025 · Windows 11 · Active Directory Domain Services · Active Directory Users and Computers · DNS · Event Viewer · VirtualBox (NAT Network)
This is a small lab demonstration which served as a way to gain knowledge of the core fundamentals of the
joiner-mover-leaver lifecycle inside of a simulated corporation. This documentation serves both as a display
and as practice with ensuring that individuals are located in the correct roles, groups and departments
within an OU and are also appropriately deprovisioned in the event of a department switch, title change or even
termination, ensuring that the user is only able to access the content appropriate to their job expectations. The
joiner-mover-leaver lifecycle is an essential part of the work practiced by an IAM Analyst on a frequent basis.
A cloud counterpart to this lab, running the same joiner-mover-leaver lifecycle in a self-built Microsoft Entra ID tenant, is documented in Entra-ID-Identity-Lab.
This environment was simulated using two different virtual machines. One virtual machine running Windows Server 2025 which is meant to serve as the domain controller (titled DCZeroOne). And another virtual machine running a simple Windows 11 operating system which is designated as the user in this scenario (titled ClientZeroOne). Both virtual machines were attached to a NAT Network during the initial setup process to ensure connectivity back and forth.
To begin, I configured the Windows server to a static IPv4 address (set as 10.0.2.10) in addition to a defined subnet mask (255.255.255.0)
and with a set default gateway (10.0.2.1). I then took a snapshot of the Windows server VM to ensure quick recovery in the event of
any issues past this point. The client VM was subsequently pointed to the (static) Windows server IPv4 address to ensure connectivity.
A domain was then created within the Windows server VM (named "lab.local") and the client VM was added shortly thereafter.
After receiving confirmation of the new client machine joining the domain the critical last step was ensuring connectivity was successful
between the two systems. Two simple commands were executed inside of the user's Windows command line:
ping 10.0.2.10 nslookup lab.local
After confirming connectivity the domain building phase had been completed.
To begin, I created a high-level Organizational Unit (OU) named "Corporation" within the domain. This served as the fictional enterprise for the scenario. Inside of the Corporation OU I created a sub-OU named "Corp"; within the "Corp" OU were a set of different departments used to demonstrate the "Mover" part of this project (departments included: HR, IT, Sales). In addition to the departments a set of other OUs were also placed here for a more accurate rendering of a real enterprise environment (those included: Disabled users, WorkStations and Groups). And lastly a set of security groups were created within the "Groups" department in order to simulate real permissions that users would be assigned to based on their roles/job expectations within the company; these security groups included: "SG-Finance-Share-R0", "SG-HR-Users", "SG-IT-Admins" and "SG-Sales-Users".
After completion of the simulated environment the first step was to "join" the user to a specific department. For the sake of this experiment I named this user "John Smith" with the username of "jsmith" and I subsequently moved him from the default location of the "Users" container to the "Sales" department. In addition to the manual change, I also gave John Smith the security group needed to complete his job (SG-Sales-Users). After confirming the change and logging into the client VM (the VM which John Smith is now logged onto and working out of) the "Joiner" part of the practice was complete.
The "Mover" phase commenced by simulating a situation in which John Smith had changed departments and moved from the "Sales" department to the "IT" department. I completed this first by manually moving his account into the IT department to ensure that he was now located in the correct place. However, a very critical removal was also completed at this step by removing his previously attached security group of "SG-Sales-Users" and replacing it with the appropriate group of "SG-IT-Admins". I did this to demonstrate both least privilege and the privilege creep that occurs when permissions are granted without a corresponding review to remove access a user no longer needs. The "Mover" part had now been completed.
And lastly the "Leaver" stage was demonstrated by simulating the offboarding process of John Smith being terminated from the company. I did this by ensuring that John Smith had no permissions, security groups and was not assigned to any department before his departure. After I manually disabled his account I then placed him within the appropriate location in the company of "Disabled Users". I made this decision deliberately rather than deleting the account to ensure that account information, auditing logs, user history, etc. are retained in the event of necessary retrieval. I confirmed this as successful by logging out of the Client VM, trying to log back in and being met with an "Account disabled, please speak with your IT Administrator for more details" message. The "Leaver" phase was now complete and John Smith had been added, moved and terminated safely within the company.
In order to verify all of the events in the Joiner-Mover-Leaver phase I conducted a brief audit within the Event Viewer on the DCZeroOne VM. By specifying "Windows Logs" and "Security" inside of Event Viewer I was able to locate the appropriate logs associated with this scenario to fully confirm validity. Attached are the "Event IDs" which demonstrate:
After the audit logs were checked and verified the exercise was complete and I closed the lab.
Three issues came up during the build. Each is recorded as symptom, cause, and resolution, since diagnosing them was as much a part of the exercise as the configuration itself.
Client VM would not boot from installation media
Symptom: ClientZeroOne fell through to "No bootable option or device was found" instead of starting the Windows installer.
Cause: The installer only offers a five-second "Press any key to boot from CD" window. VirtualBox had not yet captured keyboard input for that VM, so keystrokes during that window went to the host rather than the guest and the window expired.
Resolution: Click into the VM window first to hand keyboard control to the guest, then reset the VM and press the spacebar immediately as it POSTs.
Domain controller was unreachable on the network
Symptom: The client could not ping or resolve against the server. Checking the server's configuration showed a 169.254.x.x address rather than the intended 10.0.2.10.
Cause: A 169.254.x.x address is APIPA — Windows assigns it when an adapter is set to DHCP and no DHCP server answers. The static IP configuration had not actually committed to the adapter, so it was still requesting an address that never came.
Resolution: Reapplied the static IPv4 configuration (address, subnet mask, default gateway, and the server pointing to itself for DNS) and confirmed it persisted after a reboot.
No response to ping or DNS queries between the two machines
Symptom: Connectivity tests failed even after addressing was corrected.
Cause: The two VMs were being started one at a time. A domain controller cannot answer a query from a client that is not running, and a client cannot resolve lab.local when the only DNS server on the network is powered off.
Resolution: Both VMs now run concurrently, with DCZeroOne started first and given 30–60 seconds for Active Directory Domain Services and DNS to finish initializing before ClientZeroOne is powered on.
This lab is deliberately scoped to identity lifecycle fundamentals. The following are known gaps rather than oversights, and several are the natural next steps.
- Single domain controller. One DC in a single-domain, single-site forest. There is no replication, no FSMO role transfer, and no failure scenario to test against.
- No Group Policy. The OU structure was built to organize objects and scope permissions, but no GPOs are linked to it. Applying policy through those OUs is the most obvious extension of this build.
- Manual lifecycle operations. The joiner-mover-leaver cycle was executed by hand through Active Directory Users and Computers. A production identity program would automate this with PowerShell or an IGA platform, and no automation was written here.
- Single test user, single cycle. One account moved through one full lifecycle. Bulk provisioning, scheduled access reviews, and entitlement drift over time are not represented.
- Logs reviewed locally. Audit events were read directly in Event Viewer on the domain controller. They are not forwarded to a SIEM, so there is no correlation, alerting, or retention beyond the local Security log.
- No hybrid identity. The environment is entirely on-premises. Entra ID Connect, conditional access, and MFA are outside its scope.
- Isolated network. Both machines sit on a VirtualBox NAT Network with no external DNS forwarding, so anything requiring internet-dependent authentication is untestable.
- Redundant OU nesting. A "Corp" sub-OU was created inside the "Corporation" OU during the build. It serves no purpose and was left in place rather than restructured mid-exercise.


