2016-06-13 70 views
1

我想在不查詢域的情況下列出本地用戶所屬的所有本地組。這已被證明特別困難,因爲所有WMI變體都會查詢域,而不管您應用的是哪種過濾器。 (這就是爲什麼它們會永久生成並在域上生成數百個(如果不是數千個)安全審覈事件的。)顯然,所有Active Directory命令都會按照它們設計的那樣來查詢域。如何獲取本地用戶所屬的所有本地組

回答

2

非常感謝所有的人都在Pinvoke

[email protected]" 
using System; 
using System.Runtime.InteropServices; 
using System.Collections; 

//LG_INCLUDE_INDIRECT=1 
namespace Netapi32Wrapper { 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
    internal struct LOCALGROUP_USERS_INFO_0 { 
     [MarshalAs(UnmanagedType.LPWStr)] 
     internal string name; 
    } 

    public static class api { 

     [DllImport("Netapi32.dll", SetLastError = true)] 
     public extern static Int64 NetUserGetLocalGroups(
      [MarshalAs(UnmanagedType.LPWStr)] string servername, 
      [MarshalAs(UnmanagedType.LPWStr)] string username, 
      Int64 level, 
      Int64 flags, 
      out IntPtr bufptr, 
      Int64 prefmaxlen, 
      out Int64 entriesread, 
      out Int64 totalentries); 

     [DllImport("Netapi32.dll", SetLastError = true)] 
     public static extern Int64 NetApiBufferFree(IntPtr Buffer); 
    } 

    public class NetUtilWrapper : IDisposable { 

     // Creates a new wrapper for the local machine 
     public NetUtilWrapper() { } 

     // Disposes of this wrapper 
     public void Dispose() { GC.SuppressFinalize(this); } 

     public ArrayList GetUserLocalGroups(string ServerName, string Username, Int64 Flags) { 

      ArrayList myList = new ArrayList(); 
      Int64 EntriesRead; 
      Int64 TotalEntries; 
      IntPtr bufPtr; 
      //int ErrorCode; 
      //string _ErrorMessage; 

      api.NetUserGetLocalGroups(ServerName, Username, 0, Flags, out bufPtr, 1024, out EntriesRead, out TotalEntries); 
      //ErrorCode = api.NetUserGetLocalGroups(ServerName,Username,0,Flags,out bufPtr,1024,out EntriesRead, out TotalEntries); 
      //if (ErrorCode==0) { _ErrorMessage="Successful"; } 
      //else { _ErrorMessage="Username or computer not found"; } 

      //if (Flags>1) _ErrorMessage="Flags can only be 0 or 1"; 

      if (EntriesRead > 0) { 
       LOCALGROUP_USERS_INFO_0[] RetGroups = new LOCALGROUP_USERS_INFO_0[EntriesRead]; 
       IntPtr iter = bufPtr; 
       for (Int64 i = 0; i < EntriesRead; i++) { 
        RetGroups[i] = (LOCALGROUP_USERS_INFO_0)Marshal.PtrToStructure(iter, typeof(LOCALGROUP_USERS_INFO_0)); 
        iter = (IntPtr)((Int64)iter + (Int64)Marshal.SizeOf(typeof(LOCALGROUP_USERS_INFO_0))); 
        myList.Add(RetGroups[i].name); 
       } 

       api.NetApiBufferFree(bufPtr); 
      } 

      return myList; 
     } //GetUserLocalGroups 

     // Occurs on destruction of the Wrapper 
     ~NetUtilWrapper() { Dispose(); } 

    } // wrapper class 
} // namespace 
"@ 
#Failing to perform the line below will result in "arithmetic overflow" on x64 systems 
#Failing to perform the line below will result in a total failure on x86 systems 
if ([IntPtr]::Size -eq 4) { $TypeDefinition=$TypeDefinition.Replace("Int64","Int32") } 
Add-Type -TypeDefinition $TypeDefinition 

function Get-LocalGroupsForLocalUser { 
    [CmdletBinding(SupportsShouldProcess=$true)] 
    Param([Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [string]$Name) 

    Process { 
    $User=[ADSI]"WinNT://$env:COMPUTERNAME/$Name,user" 
    if ($User.Name -ne $null) { 
     $Netapi=new-object Netapi32Wrapper.NetUtilWrapper 
     $Netapi.GetUserLocalGroups($null,$Name,0) 
    } 
    else { Write-Error "ERROR: User $Name does not exist." } 
    } 
} 

Get-LocalGroupsForLocalUser -Name "admin-person" 
相關問題