I have an issue with a function I've wrote to return members of local groups when it is run against a remote machine. We use secondary domain accounts for admin privileges so I've used Invoke-Command so we can run the script block with that account, however, when I do this as opposed to running a new PowerShell window with my admin credentials, it can't enumerate members of the local group that aren't local users.
$computers = "blah"
$creds = Get-Credential
$sb = {
param($c)
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ctype = [System.DirectoryServices.AccountManagement.ContextType]::Machine
$context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ctype,$c
$idtype = [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName
$lg = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($context,$idtype,"administrators")
$members = $lg.Members
return $members
}
foreach ($c in $computers) {
if ($c -eq $env:COMPUTERNAME) { & $sb -c $c }
else {
Invoke-Command -ComputerName $c -Credential $creds -ScriptBlock $sb -ArgumentList $c
}
}
When run against a machine that I'm logged in to locally it returns all members of the local group. It also works if I start a new console with my second account. If credentials are passed with Invoke-Command though, I receive errors pertaining to a lack of network access and it appears to happen after successfully listing the two local accounts on a machine first.
Information returned for lg variable when failing:
PSComputerName : blah
RunspaceId : hex...
IsSecurityGroup : True
GroupScope : Local
Members : {local_admin, local_user}
Context : System.DirectoryServices.AccountManagement.PrincipalContext
ContextType : Machine
Description : Administrators have complete and unrestricted access to the computer/domain
DisplayName :
SamAccountName : Administrators
UserPrincipalName :
Sid : SID...
Guid :
DistinguishedName :
StructuralObjectClass :
Name : Administrators
When it's successful, the Members section includes domain groups and users too (identical results if remotely with shell run as second account or locally on the server logged on as second account):
IsSecurityGroup : True
GroupScope : Local
Members : {local_admin, local_user, domain_group, domain_group, domain_user...}
Context : System.DirectoryServices.AccountManagement.PrincipalContext
ContextType : Machine
Description : Administrators have complete and unrestricted access to the computer/domain
DisplayName :
SamAccountName : Administrators
UserPrincipalName :
Sid : SID...
Guid :
DistinguishedName :
StructuralObjectClass :
Name : Administrators
Two different errors received with slightly different approaches:
An error occurred while enumerating through a collection: The network path was not found.
.
+ CategoryInfo : InvalidOperation: (System.Director...ctionEnumerator:PrincipalCollectionEnumerator) [], RuntimeException
+ FullyQualifiedErrorId : BadEnumeration
+ PSComputerName : blah
Cannot convert value "System.DirectoryServices.AccountManagement.PrincipalCollection" to type "System.Array". Error: "The network path was not found.
"
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
+ PSComputerName : blah
The first message is from just trying to return the members variable, the second one was when I tried to make that variable an array. I think they essentially have the same root cause. I tried adding the -EnableNetworkAccess switch to Invoke-Command, but this doesn't change the error received.
I appreciate that I already know a way to make this work, but we'd like to see if there is any way around running the shell with admin credentials and only introducing them when they need to be passed for remote servers. It doesn't appear to be an authentication issue because we can run more simple commands using Invoke-Command i.e. ipconfig or whoami.
I'm using PowerShell 5.1
Thanks.