Skip to main content

Windows 10 Autologin - Full Book

This page is a dynamically generated collection of other pages in this book. If you want to focus on one topic at a time, you will see them in the Book Navigation menu to the left (below the Page Navigation tree). Attached files for any given section can be found on the page for that particular section. You will not find them attached here.

Summary

This is a potential process for managing Windows 10 computers with autologin configured (Microsoft calls it Autologon, but I don't care). This scenario could be considered a security risk in a business environment if proper care is not taken.

Before we begin, there are a few prerequisites:

  • All computers involved should be members of Active Directory (AD)
  • Remote Server Administration Tools (RSAT) for AD should be installed on a management host
  • You need to be able to import the AD PowerShell module (comes with the RSAT AD feature)
  • You need an account with administrator privileges for all target computers

You should only do this if there is a need for such accounts. Additionally, AD joined devices with autologin configured should be in secure areas where random people can't just walk in and start using the computer.

Configuring Autologin (Single Host)

This section only applies to a single computer. See the Group Policy section below to deploy at scale.

Microsoft already has an article here. I've attached a PDF copy of the page in case it ever goes down/goes missing. If you read the Microsoft page, you'll see that there are multiple ways to configure autologin. Unfortunately, the Sysinternals tool doesn't work well with AD group policy, so we'll be covering the normal registry edit method.

Be aware that we will be storing passwords in plaintext. Make sure you enforce harsh limits on the autologin account to ensure no end users are able to query the registry.

The whole process is very straightforward. Go to HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\ in the registry and set the following values:

  • AutoAdminLogon: 1
  • DefaultUserName: Username to be used to automatically log in
  • DefaultPassword: Password associated with the aforementioned username
  • DefaultDomainName: Fully Qualified Domain Name (FQDN) for your domain

If any of the above values do not exist, create them with a type of string.

That's it! All done!

Creating Users and Computers

This is a very simplified example. A production AD environment will look much different.

We need to create some users, computers, and groups in Active Directory. For the sake of testing, I'm going to stick to simple naming conventions. Open up Active Directory Users and Computers (ADUC) and create the following objects.

Users

  • AutologinUser01
  • AutologinUser02
  • AutologinUser03

Computers

  • AutologinPC01
  • AutologinPC02
  • AutologinPC03

Groups

  • Autologin Users
  • Autologin Computers

I'm going to leave everything in the default containers, but you should move objects to more appropriate locations in a production environment.

image.png

image.png

You can add descriptions if you want, but we're going to automate that later on as part of a PowerShell script when we examine how to handle password updates.

Add the autologin users and computers to their corresponding groups as shown below.

image.png image.png

Group Policy

I'm not going to cover all the various ways to lock these accounts and computers down, but they should be restricted as much as possible without crippling them and making them useless.

Objectives

Before we configure anything, let's review what we are trying to achieve with group policy. We want to:

  • Configure the Windows registry to enable autologin using one of our autologin user accounts
  • Ensure target computers are always available for use
  • Ensure password changes do not negatively impact computer availability

To accomplish these goals, we need to configure a new group policy object (GPO). I'll explain settings as we go.

User Configuration

Open up Group Policy Management and create a new GPO called Windows 10 Autologin.

image.png

In the new GPO, go to User Configuration\Preferences\Windows Settings\Registry\ and add a new registry value with the following properties:

  • Hive: HKEY_LOCAL_MACHINE
  • Key Path: SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\
  • Value Name: DefaultUserName
  • Value Type: REG_SZ
  • Value Data: %USERNAME%

image.png

We don't want a new GPO for every autologin account, so we're using the %USERNAME% environment variable to insert the name of the currently logged-in user. This change will take effect after the account logs in for the first time.

Make sure you add this to the User Configuration section of the GPO. If you add it under Computer Configuration, %USERNAME% will resolve to the hostname of the computer instead of the desired account.

Computer Configuration

Autologin

Go to Computer Configuration\Preferences\Windows Settings\Registry\ and add the remaining registry values specified in Configuring Autologin (Single Host). It should look similar to the example image below. Please use a better password in production.

image.png

It's worth explaining why the autologin password is in the computer configuration. It makes intuitive sense that it should be in the user configuration, but if you do that, autologin will break the next time you update the password (which you should absolutely do on a regular schedule). With the password in the user configuration, you will invariably end up in a Catch-22 situation in which the user has a new password but can not log in until the user's policy updates, and the policy can't update until the user logs in.

Next, we need to make sure the computer does not time out and lock because that would very quickly defeat the purpose of logging in automatically. Go to Computer Configuration\Policies\Administrative Templates\System\Power Management\Sleep Settings\ and disable Require a password when a computer wakes (plugged in) and Require a password when a computer wakes (on battery).

This is the simplest way to achieve the desired goal but may conflict with your own computer/session locking policies. This setting also applies to all users on this computer. Please consult your own policies before doing this.

image.png

Finally, we need to make sure the computer does not attempt to log in until after it has had a chance to process policies. This will ensure the computer is always aware of the current password configured in the GPO before it logs in. Go to Computer Configuration\Administrative Templates\System\Logon\ and enable Always wait for the network at computer startup and logon.

image.png

Remote Management

As you'll see in Password Changes, we're going to need to run some remote commands against our autologin computers. We could do most of this by running Enable-PSRemoting, but that cmdlet doesn't set things up in quite the way I want, so we're doing this the hard way (>' ')>

Windows Remote Management Service (WinRM)

First, we need to allow the WinRM service to listen for network connections. Go to Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Remote Management (WinRM)\WinRM Service\ and enable Allow remote server management through WinRM. Add a * to the IPv4 filter field. This will tell the computer to listen on all available IP addresses.

image.png

We're going to define a small startup script a little later that depends on the WinRM service. If the WinRM service isn't running, the script won't finish executing and policy processing will hang. We can get around this problem by changing the service startup type from Automatic (Delayed Start) to Automatic. Go to Computer Configuration\Preferences\Control Panel Settings\Services\ and define a new service.

image.png

Select the following options:

  • Startup: Automatic
  • Service Name: WinRM
  • Service Action: Start Service

image.png

Windows Firewall

Next, we need to allow remote management traffic through the firewall. Go to Computer Configuration\Policies\Windows Settings\Security Settings\Windows Defender Firewall with Advanced Security\Windows Defender Firewall with Advanced Security\ and create a new inbound rule.

image.png

Select the Predefined radio button and select Windows Remote Management from the dropdown menu.

image.png

We only want this to be allowed on the domain network, so uncheck the Public rule before continuing.

You may have noticed that the predefined rules are for HTTP and not HTTPS. This does not mean that commands are sent in cleartext. WinRM uses Kerberos authentication in an AD environment and uses message-level encryption for ongoing communication. You can read more about it here: Security Considerations for PowerShell Remoting using WinRM

image.png

Select the Allow the connection radio button and click Finish.

image.png

We're not quite finished with the firewall yet. Right-click on the new rule and open the Properties window.

image.png

Go to the Advanced tab and uncheck the Private checkbox. This will ensure that only domain network traffic is allowed to pass.

image.png

Go to the Local Principals tab, check the Only allow connections from these users box, and add BUILTIN\Administrators. This will restrict the use of this rule to members of the built-in administrators group.

You can do this with other groups, but the additional configuration necessary is out of scope for this topic.

image.png

Startup Script

This step isn't necessary for managing Windows Server machines, but Windows 10 adds an extra barrier to remote management by denying remote PowerShell connections by default. To get around this, we need to (somewhat ironically) add a short script to run at startup.

Create a PowerShell script file in your NETLOGON share folder (at \\your-domain.whatever\NETLOGON\) and add the following command to it. We'll call it Set PSSessionConfig AccessMode Remote.ps1 because-well-that's what it does.

# Allows remote use of the Microsoft.Powershell session configuration
Set-PSSessionConfiguration -Name Microsoft.Powershell -AccessMode Remote

image.png

Now we need to add our script to the GPO. Go to Computer Configuration\Policies\Windows Settings\Scripts\ and double-click on Startup to open the Startup Properties box. Select the PowerShell Scripts tab and click Add.

image.png

Browse to the NETLOGON folder and select the script file we just saved. When you're done, click OK until the Startup Properties box is closed.

image.png

Applying Policies

Before we link/enable our new GPO, we need to configure it to filter based on the security groups we added in Creating Users and Computers. Add the Autologin Users and Autologin Computers groups to the Security Filtering section of the GPO.

We also need to remove the Authenticated Users group. This will prevent other users in the linked OU from applying the registry changes.

Only remove the Authenticated Users group from the Security Filtering section. Computers will fail to process the policy if you remove the same group from the Delegation tab.

image.png

Now that we have our GPO configured, we can link it to an appropriate OU. For testing purposes, I'm just going to link it to the domain.

image.png

If you want the changes to take effect immediately, run a group policy update on the computer(s) using gpupdate /force from an administrator command line window. Run gpresult /r /scope:computerto confirm the new GPO has been applied. If it has not, reboot the computer and check again.

At this point, you just need to log in to each computer with the corresponding account and reboot. The next time Windows boots, it will automatically log in to the configured account.

Password Changes

Now that we have everything deployed, let's look toward the future. You should plan to update the password for your autologin users at some point. This probably wouldn't be much of a hassle if you only have a few of them, but for the sake of argument, let's assume you have at least 100 such devices and accounts. Changing the password in the GPO is easy enough, but do you really want to manually reset the password for every account? Of course not! Let's do things the fun way and write a script to handle the tedious manual tasks for us!

Considerations and Planning

Before we write our script, let's look at what we are trying to accomplish and what a successful autologin password change would look like. We need to:

  • Update the password in the GPO
  • Reset account passwords using the password in the GPO
  • Add descriptions to AD objects (users and computers) for easier troubleshooting and documentation

Additional considerations might include:

  • Autologin accounts and computers may be segmented into different groups with different policies based on use case and environment
  • You may not be able to update all accounts at once, so you might need different AD groups, GPOs, and/or OUs for the new password. This allows devices using the old password and devices using the new password to coexist during the transition
  • How frequently should the autologin password(s) be updated?

With all of that in mind, let's lay out a scenario. Let's say we have 100 autologin users and computers that we can't update all at once because they are in constant use, but we can do them in smaller batches of 25 at a time. We have decided that the password(s) need to be updated twice a year.

We won't complicate the scenario by adding segmented use cases because it shouldn't significantly change how we approach the problem.

Here's the plan:

  • Copy the exiting GPO and call the copy Windows 10 Autologin 2024 H1. Please avoid using names like "Windows 10 Autologin NEW" because the word "NEW" becomes ambiguous and unhelpful over time. Including 2024 H1 in the name makes it clear that this policy is intended for the first half of the year for 2024
  • Create a corresponding group named Autologin Computers 2024 H1 that we can move computers to as we run through batches. We'll tie this and the Autologin Users group to the new GPO. This change will be transparent to our autologin users, so we do not need to create a new group for them
  • Write and run a PowerShell script to automatically handle manual changes

Implementation

Active Directory Prep Work

We're not going to script this part. We absolutely could, but there is much less value in doing so because we only need to perform these particular tasks once every 6 months per our scenario.

Create the new Autologin Computers 2024 H1 group in AD

image.png

Make a copy of the Windows 10 Autologin GPO and name the copy Windows 10 Autologin 2024 H1. Select Preserve the existing permissions in the Copy GPO box.

image.png

image.png

Open the GPO and go to Computer Configuration\Preferences\Windows Settings\Registry\ and change the DefaultPassword to reflect the new password.

image.png

Replace the Autologin Computers group with the new Autologin Computers 2024 H1 group in the Security Filtering section of the GPO.

image.png

image.png

User Update Script

Update-AutologinUsers.ps1 (click to expand)
<#
	.SYNOPSIS
	Updates autologin account on Windows PCs
 
	.DESCRIPTION
	Brings autologin user accounts in line with the specified group policy object (GPO) in Active Directory (AD)
	
	This is accomplished by doing the following:
	- Resetting the account password in AD using the password found in the GPO
	- Optionally moving the associated computer to a new/different AD OU
	- Optionally moving the associated computer to a new/different AD group
	
	Usage Notes
	- The script always requires an argument for the GPO and target computers
	- You can't use both the MoveComputer and UpdateComputerGroup switches at the same time
	
	Most values are not hardcoded. This provides flexibility and avoids leakage of sensitive information.
	
	Author	: Newb
	Date	: 04/23/2024
 
	.EXAMPLE
	Update-AutologinUsers.ps1 -GPOName 'Dummy GPO' -TargetComputers 'DummyPC'
	- Resets the autologin user account's password for the target computer using the password found in the specified GPO
	- Updates user and computer object descriptions in AD
	
	.EXAMPLE
	Update-AutologinUsers.ps1 -GPOName 'Dummy GPO' -TargetComputers (Get-Content .\Dummy PC List)
	- Same as the previous example but the target computers are stored in a text file
	
	.EXAMPLE
	Update-AutologinUsers.ps1 -GPOName 'Dummy GPO' -TargetComputers 'DummyPC' -UpdateComputerGroup -OldGroup 'Old Dummy Group' -NewGroup 'New Dummy Group'
	- Resets the autologin user account's password for the target computer using the password found in the specified GPO
	- Updates user and computer object descriptions in AD
	- Removes computer from old AD group
	- Adds computer to new AD group
 
	.EXAMPLE
	Update-AutologinUsers.ps1 -GPOName 'Dummy GPO' -TargetComputers 'DummyPC' -MoveComputer -ComputerDestinationPath 'OU=Dummy OU,DC=dummy,DC=com'
	- Resets the autologin user account's password for the target computer using the password found in the specified GPO
	- Updates user and computer object descriptions in AD
	- Moves computer to a new AD OU
#>

########---------- Define Script Scope Parameters -----------------------------########
#
#
#

[CmdletBinding(DefaultParameterSetName='None')]param
(
	[Parameter(Mandatory)][String]$GPOName, # GPO from which to pull the autologin account password
	[Parameter(Mandatory)][String[]]$TargetComputers, # Can be a single string or an array of strings
	
	[Parameter(ParameterSetName='MoveComputer')][Switch]$MoveComputer, # Set if you want to move the computer to a new AD OU
	[Parameter(ParameterSetName='MoveComputer',Mandatory=$True)][String]$ComputerDestinationPath, # Distinguished name for new OU. Only used if MoveComputer switch is set
	
	[Parameter(ParameterSetName='UpdateComputerGroup')][Switch]$UpdateComputerGroup, # Set if you want to change the AD group the computer belongs to
	[Parameter(ParameterSetName='UpdateComputerGroup',Mandatory=$True)][String]$OldGroup, # AD Group to remove computer from
	[Parameter(ParameterSetName='UpdateComputerGroup',Mandatory=$True)][String]$NewGroup # AD group to add computer to
)

#
#
#
########---------- Define Script Scope Variables ------------------------------########
#
#
#

$Date = Get-Date -Format "yyyy-MM-dd" # For logs
$RegPath = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\' # Where autologin values live
$Results = [ordered]@{} # Dictionary for tracking progress
$Tasks = # Functions to run through
@(
'Move-Computer',
'Update-ComputerGroup',
'Reset-UserPassword',
'Update-UserDescription',
'Update-ComputerDescription'
)

#
#
#
########---------- Define Script Scope Functions ------------------------------########
#
#
#

##----- Work Functions: Functions doing actual work

function Move-Computer # Move computer to new AD OU
{
	## Notes
	# Function doesn't run unless the MoveComputer switch is set
	
	if ($MoveComputer) # If MoveComputer switch is on
	{
		## Define Function Scope Variables
		# $Computer and $ComputerDestinationPath inherited from parent scope(s)
		$ComputerCurrentDN = (Get-ADComputer -Identity $Computer -ErrorAction Stop).DistinguishedName # Computer's distinguished name
		$ComputerCurrentPath = $ComputerCurrentDN.Substring($ComputerCurrentDN.IndexOf(",")+1) # LDAP path to computer
		
		## Actions
		if ($ComputerDestinationPath -eq $ComputerCurrentPath)
		{
			return "$Computer is already at $ComputerDestinationPath"
		}
		else
		{
			Move-ADObject -Identity $ComputerCurrentDN -TargetPath $ComputerDestinationPath -ErrorAction Stop
			return 'Completed'
		}
	}
	else
	{
		return 'Not indicated'
	}
}

function Update-ComputerGroup # Removes from old group, adds to new group
{
	## Notes
	# Function doesn't run unless the UpdateComputerGroup switch is set
	
	if ($UpdateComputerGroup) # If UpdateComputerGroup switch is on
	{
		## Define Function Scope Variables
		# $Computer, $OldGroup, and $NewGroup inherited from paarent scope(s)
		$ComputerCurrentDN = (Get-ADComputer -Identity $Computer -ErrorAction Stop).DistinguishedName # Computer's distinguished name
		$IsAlreadyInGroup = (Get-ADGroupMember -Identity $NewGroup).Name -match $Computer
	
		## Actions
		if ($IsAlreadyInGroup)
		{
			return "$Computer is already a member of $NewGroup"
		}
		else
		{
			try # Remove-ADGroupMember throws an exception if the group doesn't exist
			{
				Remove-ADGroupMember -Identity $OldGroup -Members $ComputerCurrentDN -Confirm:$False
			}
			catch # We don't need to stop the script over this, so just warn the user
			{
				Write-Warning $_.exception.message
			}
			
			Add-ADGroupMember -Identity $NewGroup -members $ComputerCurrentDN
			return 'Completed'
		}
	}
	else
	{
		return 'Not Indicated'
	}
}

function Reset-UserPassword # Reset password... duh
{
	# $User and $GPOPassword inherited from parent scope(s)
	Set-ADAccountPassword -Identity $User -Reset -NewPassword (ConvertTo-SecureString -AsPlainText $GPOPassword -Force) -ErrorAction Stop
	return 'Completed'
}

function Update-UserDescription # Add associated computer to account description
{
	# $User and $Computer inherited from parent scope(s)
	Set-ADUser -Identity $User -Description "Autologin account for $Computer" -ErrorAction Stop
	return 'Completed'
}

function Update-ComputerDescription # Add associated account to computer description
{
	# $User and $Computer inherited from parent scope(s)
	Set-ADComputer -Identity $Computer -Description "Autologin Account: $User" -ErrorAction Stop
	return 'Completed'
}

##----- Support Functions: Functions that provide input data, reporting, etc

function Get-GPOPassword # Get autologin password from GPO
{
	# $GPOName and $RegPath inherited from parent scope(s)
	(Get-GPPrefRegistryValue -Name $GPOName -Context Computer -Key $RegPath.Replace(':', '') -ValueName 'DefaultPassword' -ErrorAction Stop).Value
}

function Get-Users # Get autologin usernames from target computers
{
	# $TargetComputers and $RegPath inherited from parent scope(s)
	$Users = Invoke-Command -ComputerName $TargetComputers {(Get-ItemProperty -Path $Using:RegPath -Name DefaultUserName).DefaultUserName}
	return $Users | Sort-Object -Property PSComputerName # Sort results
}

function Fail-RemainingTasks # Adds status to update tasks that were not executed
{
	## Define Function Scope Parameters
	param ([Parameter(Mandatory)]$Message)
	
	## Define Function Scope Variables
	# $Results, $Computer, $Tasks, and $Task inherited from parents scope(s)
	# $RemainingTasks gets an index range
	$RemainingTasks = ($Tasks.IndexOf($Task)+1)..($Tasks.GetUpperBound(0))
	
	foreach ($Task in $Tasks[$RemainingTasks])
	{
		$script:Results[$Computer] += @{$Task = $Message}
	}
}

function Print-Summary # Output results summary for all tasks run
{
	Write-Host -BackgroundColor White -ForegroundColor Black "`nResults Summary`n"
	foreach ($Computer in $Results.Keys)
	{
		Write-Host -BackgroundColor DarkBlue -ForegroundColor White "$($Computer)"
		foreach ($Record in $Results.$Computer)
		{
			$Record | Format-Table -Autosize
		}
	}
}

#
#
#
########---------- Run Script -------------------------------------------------########
#
#
#

# Start log
Start-Transcript -Append -Path .\Update-Autologins-$Date.log

# Collect data
$GPOPassword = Get-GPOPassword
$Users = Get-Users

:UserLoop foreach ($User in $Users)
{
	$Computer = $User.PSComputerName
	
	try # Confirm user exists. 
	{
		Get-ADUser -Identity $User -ErrorAction Stop | Out-Null
	}
	catch # Skip tasks for this user if it doesn't exist in AD
	{
		Write-Host -ForegroundColor Red "$($Computer): $($_.exception.message)"
		Fail-RemainingTasks -Message $_.exception.message
		continue
	}
	
	Write-Host -BackgroundColor DarkBlue "`n Applying changes to user $User on $Computer"
	:TaskLoop foreach ($Task in $Tasks)
	{		
		try
		{
			$Results[$Computer] += @{$Task = & $Task} # Call task and add output to $Results
			Write-Host -ForegroundColor Green "$($Computer): $Task - $($Results.$Computer.$Task)"
		}
		catch # Skip remaining tasks in current loop if exception occurs
		{
			Write-Host -ForegroundColor Red "$($Computer): $Task - $($_.exception.message)"
			$Results[$Computer] += @{$Task = $_.exception.message}
			Fail-RemainingTasks -Message "Process failed at $Task"
			Write-Host "$($Computer): Skipping reboot because of unsuccessful task(s)"
			continue UserLoop # Point back to top of user loop
		}
	}
	
	Write-Host "$($Computer): Rebooting"
	Invoke-Command -ComputerName $Computer {Restart-Computer -Force}
}

Print-Summary

# End log
Stop-Transcript

I'll do my very best not to overexplain the above script, but I do want to briefly run through what it does and how it works.

Script Structure and Explanation

If you open it up, you'll see plenty of comment-based help right at the top. The script itself is broken down into a few sections with parameters and variables at the top, functions in the middle, and the actual execution portion down at the bottom.

The execution portion of the script starts by collecting information. It gets the current autologin password from the GPO and gets usernames from each respective computer in a list of target computers. Once it has that information, it iterates through two main loops, one inside the other. The outer loops goes through each username while the inner loop goes through each of 5 tasks (two of which are optional). These tasks:

  • Move the computer to a new AD OU (optional)
  • Update the computer's AD group memberships (optional)
  • Reset the autologin account password
  • Update the user object description in AD
  • Update the computer object description in AD

Once all indicated tasks for a given user have been successfully completed, the computer is rebooted. If the script encounters an error for a given user, the inner loop starts over with the next user in line and the computer is not rebooted. Once the outer loop has iterated through all of the users in the list, it will print a summary of completed tasks, including any errors encountered. The script also creates a log file which includes the same output you see at the command line.

Script Execution

Now that we've done our prep work and understand how our update script works, let's run through our scenario. 

First, let's do a quick dry run to make sure the script works as expected. In the example below, you can see that only one of the computers has been targeted and that the script is pointing to the current GPO.

.\Update-AutologinUsers.ps1 -GPOName 'Windows 10 Autologin' -TargetComputers 'AUTOLOGINPC01'

The output will look like the below image. Output is divided into two sections, one for tracking current progress, and another for displaying the final Results Summary. Because we didn't specify a group change or OU move, those tasks are listed as Not Indicated.

image.png

If we list the files in our current directory, we'll see that our log file has been created.

image.png

Having had a successful test, let's move forward with the actual update. We'll target the new Windows 10 Autologin 2024 H1 GPO and move the target computers out of the old Autologin Computers group and into Autologin Computers 2024 H1. I have added the three target computers (pretend we have a full batch of 25) to a text file called computers.txt.

.\Update-AutologinUsers.ps1 -GPOName 'Windows 10 Autologin 2024 H1' -TargetComputers (Get-Content .\computers.txt) -UpdateComputerGroup -OldGroup 'Autologin Computers' -NewGroup 'Autologin Computers 2024 H1'

You should see similar output as with the test run. Here's our progress tracker

image.png

and our results summary

image.png

Let's confirm our success by looking at one of our computers. We can see that it's in the new AD group

image.png

and the password in the registry has been updated

image.png

If we check the rest of our computers, we'll see the same success!

Additional

Alternative Scenario

My preferred approach to managing autologin is to use AD groups, but you can certainly manage the same policies in a similar fashion using OUs instead. For example, we can set up two GPOs and OUs with these names:

  • Windows 10 Autologin H1
  • Windows 10 Autologin H2

Every 6 months, we just need to change the password for the unused GPO and move all of the computers to the vacant OU. To do this, just use the same script with the MoveComputer switch.

.\Update-AutologinUsers.ps1 -GPOName 'Windows 10 Autologin H1' -TargetComputers (Get-Content .\computers.txt) -MoveComputer -ComputerDestinationPath 'OU=Windows 10 Autologin H1,DC=newbadmin,DC=test'

The MoveComputer and UpdateComputerGroup switches are mutually exclusive.

Failure Scenarios

You won't always be running the script in ideal conditions. With that in mind, I have included some sample failure scenarios with corresponding expected output.

Computer Already in New Group

This isn't really a failure because the script will continue without any issues, but it is considered nonstandard output.

image.png

Username not in Registry

The script will throw an error for the affected computer and continue forward with all unaffected computers. Note the hostname of the affected computer at the bottom of the message.

image.png

Old Group Not in AD

This is another scenario where there is no impact to the completion of tasks, but you will see a warning message pop up in the output.

image.png

Autologin User Not in AD

This will cause all tasks for the affected computer to fail with the same error message.

image.png

Password in GPO Not Compliant with Password Policy

To demonstrate, I've added a value of badpassword to the GPO. When we run the script, the computer group change task runs, but the password reset fails with an expected error message. All subsequent tasks will fail with the message that the process failed at the password reset.

image.png

There are some additional protections that could be added to the script to prevent it from executing at all in this scenario, but my assumption is that the admin responsible for the GPO should be fully aware of current standards and that the new password has been tested and confirmed to be working ahead of time.