-
Notifications
You must be signed in to change notification settings - Fork 7.1k
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
Get-LocalGroupMember - Failed to compare two elements in the array. #2996
Comments
@ephos This is an interesting issue. Can you please provide $Error[0] | fl * -force as well? |
@mirichmo here you go! > $Error[0] | fl * -Force
writeErrorStream : True
PSMessageDetails :
Exception : System.InvalidOperationException: Failed to compare two elements in the array. --->
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.PowerShell.Commands.GetLocalGroupMemberCommand.<>c.<ProcessesMembership>b_
_20_0(LocalPrincipal p1, LocalPrincipal p2)
at System.Collections.Generic.ArraySortHelper`1.SwapIfGreater(T[] keys, IComparer`1
comparer, Int32 a, Int32 b)
at System.Collections.Generic.ArraySortHelper`1.DepthLimitedQuickSort(T[] keys, Int32
left, Int32 right, IComparer`1 comparer, Int32 depthLimit)
at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32
length, IComparer`1 comparer)
--- End of inner exception stack trace ---
at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32
length, IComparer`1 comparer)
at System.Array.Sort[T](T[] array, Int32 index, Int32 length, IComparer`1 comparer)
at System.Collections.Generic.List`1.Sort(Comparison`1 comparison)
at Microsoft.PowerShell.Commands.GetLocalGroupMemberCommand.ProcessesMembership(IEnumer
able`1 membership)
at Microsoft.PowerShell.Commands.GetLocalGroupMemberCommand.ProcessRecord()
TargetObject :
CategoryInfo : NotSpecified: (:) [Get-LocalGroupMember], InvalidOperationException
FullyQualifiedErrorId : An unspecified error occurred.,Microsoft.PowerShell.Commands.GetLocalGroupMemberCommand
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
ScriptStackTrace : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {0, 1}
|
Thanks for the info |
It's work well on Windows 10 : Name Value
---- -----
CLRVersion
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
GitCommitId v6.0.0-alpha.14-28-geef6ed0584ba62e232f95668ad25d277d2137efc-dirty
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.3
PSEdition Core
WSManStackVersion 3.0
BuildVersion 3.0.0.0
PSVersion 6.0.0-alpha
|
I am also hitting this issue, any workarounds? |
@ssylvan Can you confirm that the problem is on Windows Server 2016 Core server only. |
I'm seeing it on windows 10 on a surface book.
…On Thu, Jan 12, 2017 at 10:46 PM, Ilya ***@***.***> wrote:
@ssylvan <https://github.com/ssylvan> Can you confirm that the problem is
on Windows Server 2016 Core server only.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2996 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABTVpweK9qalpKLeTK1yx5TwZ7csJI-Mks5rRx3ggaJpZM4LhJ0X>
.
--
Sebastian Sylvan
|
@ssylvan Thanks for the clarification. |
Hello, I'm seeing this error raised as well. Windows 10 Pro
|
@itisbrendan Thanks for confirmation! |
Workaround here Same experience in Windows 7 Enterprise and exactly the same Error details as @ephos
|
I'm getting the same on Win10 joined to Azure AD. This PC has never been part of a traditional Active Directory.
|
Same issue on Windows 2008 R2 and 2012 R2. |
I've had a bit of a poke around and a chat and some help from faustonascimento on IRC. This code will reproduce the problem: Import-Module Microsoft.PowerShell.LocalAccounts
Add-Type -ReferencedAssemblies ([PowerShell].Assembly.Location), ([Microsoft.PowerShell.Commands.GetLocalGroupMemberCommand].Assembly.Location) -TypeDefinition '
using System;
using System.Collections.Generic;
using System.Security.Principal;
using Microsoft.PowerShell.Commands;
public class Test
{
public static IEnumerable<LocalPrincipal> Get()
{
List<LocalPrincipal> rv = new List<LocalPrincipal>();
LocalPrincipal principal = new LocalPrincipal(Environment.UserName);
principal.SID = (SecurityIdentifier)(new NTAccount(Environment.UserName)).Translate(typeof(SecurityIdentifier));
rv.Add(principal);
// https://github.com/PowerShell/PowerShell/blob/1462ac300bc5e4a20f0360b428de1cb1de4eaba4/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Sam.cs#L2813
rv.Add(null);
rv.Sort((p1, p2) => string.Compare(p1.Name, p2.Name, StringComparison.CurrentCultureIgnoreCase));
return rv;
}
}
'
[Test]::Get() The problem appears to be caused by the null return from the MakeLocalPrincipalObject method:
The null value is being pushed to MakeLocalPrincipalObject because an invalid SID will cause a name lookup failure from Win32.LookupAccountSid. This method explicitly returns null when the error code ERROR_NONE_MAPPED (1332) is set. This value is not filtered out and ends up being added to the rv collection which subsequently fails on Sort. It can be argued that this value should be filtered out, as the null value is not useful. For example, by inserting: rv = rv.Where(x => x != null).ToList(); Returning the invalid entry is a deep(er) change to the GetGroupMembers method. This would potentially be useful as it may allow these commands to fix the problem (if it is such) rather than just ignoring the condition. Achievable by speculatively replacing the yield return with line with the following: var sid = new SecurityIdentifier(idArray[i]);
AccountInfo info = LookupAccountInfo(sid);
if (info == null)
{
info = new AccountInfo { Sid = sid };
}
yield return MakeLocalPrincipalObject(info); The LookupAccountInfo method is shared by most of the other commands, changing its behaviour would be intrusive. GetGroupMembers only appears to be used by Get-LocalGroupMember. Chris |
I think in general this makes sense. The only other method that calls I'm curious about why we would be getting an invalid SID in the first place. There are two overloads for the |
I only see one overload for GetGroupMembers in the source code? There are two overloads for GetLocalGroupMembers, both call GetGroupMembers with a SID. It seems the only way to recreate this is described in the first post. A machine must be added to the domain, a member added, then the machine removed from the domain. Using a local user is not sufficient to recreate the problem. I'm not at liberty to test such things at the moment although it will need to be tested after the code has been changed. |
Oops. Sorry, you're right. I was looking at an experimental version I'd forgotten about. After re-reading the original description and looking at things again, the whole thing makes more sense to me and I think your solution is the correct one. There would need to be an additional minor change elsewhere to get the SID to be displayed in the output in place of the name, and there would be no way (I think) to correctly determine the ObjectClass. Sorry for the noise. Of course, all this kinda depends on the LocalAccounts cmdlets getting back into the build once they no longer use the SAM API. |
Any update?
Likely due to there being an AzureAD account - this powershell cmdlet always crashes
Diagnostics:
|
/cc @SteveL-MSFT Azure-AD scenario failed. |
I haven't been rushing to make a PR as this will only affect PowerShell 6 builds where it's currently not operational (and I'm rather busy at the moment). It would be rather nice to stream this out as a standalone module, but even if it is, that won't make it immediately available to anyone. |
@Hicsy after we have a fix in PSCore6, we can consider backporting it to Windows PowerShell 5.1. |
@SteveL-MSFT I also would like to see that fix in 5.1 since im running into the same issue. Running windows 2012 R2
|
FFS. |
Are there any updates on this? |
Yes, please fix this if you can.
…On Wed, May 9, 2018, 1:50 PM neomancipator ***@***.***> wrote:
Are there any updates on this?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2996 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AYSeDTlJbiLHL2YvQ5f0k4W_4pNtYqfsks5twyxhgaJpZM4LhJ0X>
.
|
Likely not ever going to be fixed at this point. Some good, creative workarounds from the community tho. 😄
|
I've read the comments and want to say thanks to the community for workarounds. I also want to express my frustration with MSFT at their absurd - if predictable - combination of unwillingness to fix a widespread issue, and complete silence on why. I recommended Office365 and a "cloud-only" approach, and one huge reason was PowerShell. Too often we cannot deploy scripts which conform to PowerShell coding practices via Intune: it targets Windows PowerShell, the native feature does not support parameters, the Mg cmdlets do not support pipeline. Rant over. `
|
@StevieLamb i like your solution, i just updated your code to consider region specific names if OS is not installed en ;) `
} |
@ConfigMgrRSC an excellent addition IMHO, much appreciated |
@StevieLamb Appreciate the candid feedback. I was the person that started the Microsoft Graph PowerShell effort a number of years ago. A number of unfortunate circumstances have prevented us from enabling pipelining in cmdlets without an intermediate steps, for far too long. However, we believe we have removed those blocking issues and pipelining is something that we are going to try and improve this semester. If there are specific pipelining scenarios that you wish were supported that would be valuable feedback for us. |
Firstly, you do your company great credit by owning this issue, my sincere thanks. For my part?
I think the objects returned by Get-MgUser and Get-MgDevice should be accepted as an input object by cmdlets which get specific information about such objects. For example This would allow us to neatly expand on the original example:
I wonder if you would consider enacting a poll on a suitable platform (TBD by MSFT) - to allow you to shortlist some initial proposals based on community feedback? I look forward to enjoying the fruits of your labour :) |
@ConfigMgrRSC I've enhanced this a little bit, thanks to the work of Oliver Kieselbach shown at Combining one of his functions with your revised function, we get this.
|
Just running across this and ended up here. Not fantastic at PS, is there a way to pipe these results straight into something like remove-localgroupmember (even if it's an azure/domain/whatever user) so the group ends up empty? |
|
I'll give this a run. I do want to remove the built in admin (or disable it but that's easy) and the domain admins group if it exists, a full nuke, so i'll try different variations. Can i ask what the -skip 4 does? |
I'd recommend against scripting that element, because better options exist, it'll only work that way as long as nothing else gets broken by incomplete regression testing, and (this one personal) I don't like scripts which mix PowerShell and batch programming. Use Group Policy's Restricted Groups feature if you're in an AD DS environment (a.k.a. "on-premise AD"): If using Intune to manage devices in a pure Azure AD directory environment (no on-premise AD), instead use the option under Endpoint security >> Account protection which does the same thing as the Restricted Groups.
|
Understood but i'm looking for a nuke and pave solution for multiple environments where there may or may not be a local domain, azure/intune in place. Users in the group may be local, domain, azure, or groups and any or all may or may not still exist (and be orphaned with just SIDs). So, looking to make something heavy handed we can deploy to be sure there are no local admins and then we can organize and bring them up to a baseline if required.
|
WTF Microsoft. Can you please fix this blatant issue? It has been so long already |
well this one does not recognize localisation of the administrators group - personally i wrote a function to clean out all except the local admin and testet this in onprem and AAD only environment ( not hybrid) to cleanup. basically i agree, dont like to mix up several techniques and try to be powershell only, but in this case this was the only solution for me..
|
Error is still present on a fresh Win11 joined to a Domain once and never revert to workgroup. PS C:\Users\xxxxxxxxxxx> [System.Environment]::OSVersion.Version
Major Minor Build Revision
----- ----- ----- --------
10 0 22621 0
PS C:\Users\xxxxxxxxxxx> Get-LocalGroupMember -Group 'Administrators'
Get-LocalGroupMember: Failed to compare two elements in the array.
PS C:\Users\xxxxxxxxxxx> $Error[0] | fl * -force
PSMessageDetails :
Exception : System.InvalidOperationException: Failed to compare two elements in the array.
---> System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.PowerShell.Commands.GetLocalGroupMemberCommand.<>c.<ProcessesMembership>b__20_0(LocalPrincipal p1, LocalPrincipal p2)
at System.Collections.Generic.ArraySortHelper`1.InsertionSort(Span`1 keys, Comparison`1 comparer)
at System.Collections.Generic.ArraySortHelper`1.IntroSort(Span`1 keys, Int32 depthLimit, Comparison`1 comparer)
at System.Collections.Generic.ArraySortHelper`1.Sort(Span`1 keys, Comparison`1 comparer)
--- End of inner exception stack trace ---
at System.Collections.Generic.ArraySortHelper`1.Sort(Span`1 keys, Comparison`1 comparer)
at System.Collections.Generic.List`1.Sort(Comparison`1 comparison)
at Microsoft.PowerShell.Commands.GetLocalGroupMemberCommand.ProcessesMembership(IEnumerable`1 membership)
at Microsoft.PowerShell.Commands.GetLocalGroupMemberCommand.ProcessGroup(LocalGroup group)
at Microsoft.PowerShell.Commands.GetLocalGroupMemberCommand.ProcessRecord()
TargetObject :
CategoryInfo : NotSpecified: (:) [Get-LocalGroupMember], InvalidOperationException
FullyQualifiedErrorId : An unspecified error occurred.,Microsoft.PowerShell.Commands.GetLocalGroupMemberCommand
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
ScriptStackTrace : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {0, 1} |
I can't believe it's been almost 7 full years since this was opened, a fix was identified and rejected, and Microsoft still can't be bothered to acknowledge it. Maybe we should start a campaign to submit this thread URL to Jeff Snover and see if he can get a set of eyes on it. |
My workaround to this problem was shifting career out of the Windows ecosystem. |
Snover is working for Google now.
…On Tue, Nov 7, 2023, 6:57 AM GoodThings2Life ***@***.***> wrote:
I can't believe it's been almost 7 full years since this was opened, a fix
was identified and rejected, and Microsoft still can't be bothered to
acknowledge it. Maybe we should start a campaign to submit this thread URL
to Jeff Snover and see if he can get a set of eyes on it.
—
Reply to this email directly, view it on GitHub
<#2996 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABRNERN6RRPC5PSC25KHXATYDJD4NAVCNFSM4C4ETUL2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCNZZHA3TONBXGE4Q>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
This is still issue ! Scenario is little different ( domain membeserver has domain objects in local Admin group, but those domain objects are deleted, so they are not resolved and SID is dispalyed in GUI) . PS fails miserably with same error. |
I think there is a growing issue with hybrid environments as well. I have cloud objects with orphaned SID owners.
Michael J. Martinez Jr.
MBA, CISSP, CEH
***@***.***
***@***.***
Cell: 210-317-9487
http://linkedin.com/in/texasit
…________________________________
From: AndresPae ***@***.***>
Sent: Thursday, December 14, 2023 1:49:02 AM
To: PowerShell/PowerShell ***@***.***>
Cc: Keybonesabi ***@***.***>; Comment ***@***.***>
Subject: Re: [PowerShell/PowerShell] Get-LocalGroupMember - Failed to compare two elements in the array. (#2996)
This is still issue ! Scenario is little different ( domain membeserver has domain objects in local Admin group, but those domain objects are deleted, so they are not resolved and SID is dispalyed in GUI) . PS fails miserably with same error.
—
Reply to this email directly, view it on GitHub<#2996 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AMK42GRCTEKXD22RG4H2TVTYJKVO5AVCNFSM4C4ETUL2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBVGUZTIMRRG44Q>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Ridonkulous that this has been a known problem for so long. I experienced it with Win 11 and a server that always been joined to our main domain (likely because it had admin members from a trusted domain that's no longer present). There's no good reason for the command to fail completely in scenarios like this. |
Is Microsoft even listening to this thread??
Get Outlook for Android<https://aka.ms/AAb9ysg>
…________________________________
From: Jesse Litton ***@***.***>
Sent: Saturday, December 16, 2023 5:49:38 PM
To: PowerShell/PowerShell ***@***.***>
Cc: itsBrendan ***@***.***>; Comment ***@***.***>
Subject: Re: [PowerShell/PowerShell] Get-LocalGroupMember - Failed to compare two elements in the array. (#2996)
Ridonkulous that this has been a known problem for so long. I experienced it with Win 11 and a server that always been joined to our main domain (likely because it had admin members from a trusted domain that's no longer present). There's no good reason for the command to fail completely in scenarios like this.
—
Reply to this email directly, view it on GitHub<#2996 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AHOVIRZTVSWTMVFXNZQUICTYJYQQFAVCNFSM4C4ETUL2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBVHA4TMMBQGQYA>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Attempted to use this in Win11Pro to verify that my script is working properly but it still returns the same error. |
If anyone is looking for a workaround where getting an array of usernames is the goal and are fine with the old "net localgroup administrators", keeping in mind that this won't provide you with the user object, here are a couple of implementations: Get all users in the group: Get all users minus a few matching a regex filter, adding pipe | separated usernames (e.g, "Administrator") or more complex filters (e.g, ".*Domain Admins"): |
IssueI was able to make an workaround for this issue because it's still exists in: OSVersion : 2009
OSEdition : Microsoft Windows 11 Enterprise
OSBuild : 22621.3007
CurrentInstalledUpdate : January 9, 2024 - KB5034123 (OS Builds 22621.3007 and 22631.3007) Example:> Get-LocalGroupMember -Group "Administrators"
Get-LocalGroupMember : Failed to compare two elements in the array.
At line:1 char:1
+ Get-LocalGroupMember -Group "Administrators"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-LocalGroupMember], InvalidOperationException
+ FullyQualifiedErrorId : An unspecified error occurred.,Microsoft.PowerShell.Commands.GetLocalGroupMemberCommand There is an .NET method Workaround Script:param(
[Parameter(Mandatory=$true, Position=0)]
[Alias("g")]
[string]$GroupName
)
function CheckGroupMembership {
param([string]$groupName)
$id = [Security.Principal.WindowsIdentity]::GetCurrent()
$groups = $id.Groups | foreach-object {$_.Translate([Security.Principal.NTAccount])}
$isMember = ($groups.Value | Where-Object { $_.Split('\')[-1] -eq $groupName } | Measure-Object).Count -gt 0
if ($isMember) {
Write-Host "User: `"$($id.Name)`" is a member of a group ending with `"$groupName`"."
} else {
Write-Host "User: `"$($id.Name)`" is not a member of any group ending with `"$groupName`"."
}
}
CheckGroupMembership -groupName $GroupName Examples:Administrators:> .\autosetup\deps\test-group.ps1 -groupName "Administrators"
User: "XXXXXX" is not a member of any group ending with "Administrators". Users:> .\autosetup\deps\test-group.ps1 -groupName "Users"
User: "XXXXXX" is a member of a group ending with "Users". Further reading |
if anyone is still getting this, i found that if an unknown/deleted user exists in the queried group, the command fails. you need to remove the SID of the unknown / non existing user from the group. this resolved the issue for me. |
Yes. I gave up on it and had to go with ADSI instead. I've got thousands of servers with plenty of deleted accounts from retired employees and former contractors that the owners put in local groups over the last 20 years (trying to clean that up separately; I needed something that works now). |
The bug was fixed in PowerShell 7.4+ compatible (unofficial) version of the Microsoft.PowerShell.LocalAccounts module
|
It appears that if you have domain groups added to a local group and then move the server to a workgroup before removing them Get-LocalGroupMember no longer works and instead throws an exception 'Failed to compare two elements in the array.'. I am seeing this on Server 2016 Core, I have not tried on any other editions. I found this while building a server in one domain that needed to move to a different one.
Steps to reproduce
Get-LocalGroupMember -Group Administrators
I've reproduced this on two servers.
Expected behavior
It should return the group members as it would prior to moving to a workgroup and just display the unresolved SIDs for the old domain. Then ideally allow you to reference those unresolved SIDS for Remove-LocalGroupMember.
Actual behavior
Throws an exception.
Environment data
The text was updated successfully, but these errors were encountered: