diff --git a/changelogs/fragments/runas-become-system-privileges.yml b/changelogs/fragments/runas-become-system-privileges.yml
new file mode 100644
index 00000000000..37562ca6927
--- /dev/null
+++ b/changelogs/fragments/runas-become-system-privileges.yml
@@ -0,0 +1,2 @@
+bugfixes:
+- runas - create a new token when running as ``SYSTEM`` to ensure it has the full privileges assigned to that account
diff --git a/lib/ansible/module_utils/csharp/Ansible.Become.cs b/lib/ansible/module_utils/csharp/Ansible.Become.cs
index 25233165332..a7434a765e9 100644
--- a/lib/ansible/module_utils/csharp/Ansible.Become.cs
+++ b/lib/ansible/module_utils/csharp/Ansible.Become.cs
@@ -339,7 +339,11 @@ namespace Ansible.Become
 
                 // Try and impersonate a SYSTEM token, we need a SYSTEM token to either become a well known service
                 // account or have administrative rights on the become access token.
-                systemToken = GetPrimaryTokenForUser(new SecurityIdentifier("S-1-5-18"), new List<string>() { "SeTcbPrivilege" });
+                // If we ultimately are becoming the SYSTEM account we want the token with the most privileges available.
+                // https://github.com/ansible/ansible/issues/71453
+                bool mostPrivileges = becomeSid == "S-1-5-18";
+                systemToken = GetPrimaryTokenForUser(new SecurityIdentifier("S-1-5-18"),
+                    new List<string>() { "SeTcbPrivilege" }, mostPrivileges);
                 if (systemToken != null)
                 {
                     try
@@ -425,7 +429,8 @@ namespace Ansible.Become
             return userTokens;
         }
 
-        private static SafeNativeHandle GetPrimaryTokenForUser(SecurityIdentifier sid, List<string> requiredPrivileges = null)
+        private static SafeNativeHandle GetPrimaryTokenForUser(SecurityIdentifier sid,
+            List<string> requiredPrivileges = null, bool mostPrivileges = false)
         {
             // According to CreateProcessWithTokenW we require a token with
             //  TOKEN_QUERY, TOKEN_DUPLICATE and TOKEN_ASSIGN_PRIMARY
@@ -435,6 +440,9 @@ namespace Ansible.Become
                 TokenAccessLevels.AssignPrimary |
                 TokenAccessLevels.Impersonate;
 
+            SafeNativeHandle userToken = null;
+            int privilegeCount = 0;
+
             foreach (SafeNativeHandle hToken in TokenUtil.EnumerateUserTokens(sid, dwAccess))
             {
                 // Filter out any Network logon tokens, using become with that is useless when S4U
@@ -443,10 +451,15 @@ namespace Ansible.Become
                 if (tokenLogonType == NativeHelpers.SECURITY_LOGON_TYPE.Network)
                     continue;
 
+                List<string> actualPrivileges = TokenUtil.GetTokenPrivileges(hToken).Select(x => x.Name).ToList();
+
+                // If the token has less or the same number of privileges than the current token, skip it.
+                if (mostPrivileges && privilegeCount >= actualPrivileges.Count)
+                    continue;
+
                 // Check that the required privileges are on the token
                 if (requiredPrivileges != null)
                 {
-                    List<string> actualPrivileges = TokenUtil.GetTokenPrivileges(hToken).Select(x => x.Name).ToList();
                     int missing = requiredPrivileges.Where(x => !actualPrivileges.Contains(x)).Count();
                     if (missing > 0)
                         continue;
@@ -455,16 +468,22 @@ namespace Ansible.Become
                 // Duplicate the token to convert it to a primary token with the access level required.
                 try
                 {
-                    return TokenUtil.DuplicateToken(hToken, TokenAccessLevels.MaximumAllowed, SecurityImpersonationLevel.Anonymous,
-                        TokenType.Primary);
+                    userToken = TokenUtil.DuplicateToken(hToken, TokenAccessLevels.MaximumAllowed,
+                        SecurityImpersonationLevel.Anonymous, TokenType.Primary);
+                    privilegeCount = actualPrivileges.Count;
                 }
                 catch (Process.Win32Exception)
                 {
                     continue;
                 }
+
+                // If we don't care about getting the token with the most privileges, escape the loop as we already
+                // have a token.
+                if (!mostPrivileges)
+                    break;
             }
 
-            return null;
+            return userToken;
         }
 
         private static SafeNativeHandle GetS4UTokenForUser(SecurityIdentifier sid, LogonType logonType)