# WinRM Ps1 script to get members of local admin groups
cls
Import-Module ActiveDirectory

function Start_Invoke ($search)
{   	
   $arr = Get-ADComputer -Filter 'Name -like "*"' -SearchBase $search -SearchScope Subtree | Select-Object -Property 'dnsHostName', 'DistinguishedName'  | Sort-Object 'dnsHostName'
   $hosts = @()		
   $hosts2 = @()			
   foreach ($a in $arr)
   {
      $hosts += $a.dnsHostName   						
      $hosts2 += $a.dnsHostName + ";" + $a.DistinguishedName   						
   }         		
   
   $scriptblock = 
   { 				
		
      ############################################
      try
      {				
         $strComputer = "."  		   		   
	 $computer = [ADSI]("WinNT://" + $strComputer + ",computer")

	 # !!! Specify a name of local administrator group in a language of your Microsoft Windows !!!
         #$group = $computer.psbase.children.find("Администраторы") # Russian
         $group = $computer.psbase.children.find("Administrators")  # English

	 $members = $group.psbase.invoke("Members") | %{$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}  
  
	 foreach($user in $members) 
         {                       			  
            $myObj = New-Object Object	 			  
	    $myObj | Add-Member NoteProperty PSComputerName $hosts
	    $myObj | Add-Member NoteProperty UserName $user.ToString()
	
	    $key = Get-Item "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
	    $values = Get-ItemProperty $key.PSPath
   	    foreach ($value in $key.Property) 
   	    { 
	       if ($value -like "ProductName") 
	       {
	          try
		  {				
	             $myObj | Add-Member NoteProperty OS $values.$value		  
		  }
	          catch 
		  {	
		     $myObj | Add-Member NoteProperty OS "Error" 
		  }									
   	       } 				    
            }
    
            $myObj                               
         } 
      }
      catch 
      {	
         $myObj | Add-Member NoteProperty UserName "Error" 
      }									
      ################################################		
   }	


   $Job = invoke-command -computername $hosts -scriptblock $scriptblock -throttle 100 -AsJob | Wait-Job		    			
   $myObj = New-Object Object
   $myObj = receive-job $Job -keep            
   	
   foreach ($h in $hosts) 
   {
      $h = $h.toLower();   
      $myObjOut= New-Object Object	 			   
      if ($myObj | where {$_.PSComputerName -eq $h}) 
      {			   			   			
         $myObjOut = $myObj | where {$_.PSComputerName -eq $h}    
	 $myObjOut | Add-Member NoteProperty State "Ok"
      }
      else 
      {								
         $ping = $false
       	 try
	 {
	    $pingObj = new-object System.Net.NetworkInformation.Ping    
    	    if ($pingObj.send($h).Status -eq "Success" ) 
	    {
	       $ping = $true
	    }    
	 }
	 catch
	 {
	    $ping = $false
	 }			
 	 if ($ping) 
	 {	     
	    $myObjOut | Add-Member NoteProperty State "Error WinRM" 
	 }
	 else 
	 {
	    $myObjOut | Add-Member NoteProperty State "No ping" 				 			     
	 }							
      }      	   			
 		
      $ou = $null
      foreach ($h2 in $hosts2)
      {					
         if ($h -eq $h2.Split(";")[0])
	 {						
	    $arr =  ($h2.Split(";")[1]).Split(",")
	    foreach ($a in $arr)
   	    {
	       $tmp = $a
	       if ($tmp -match "OU=")
	       {
	          $tmp = $tmp -replace "OU=", ""
	       	  if ($ou -eq $null) 
		  {
		     $ou = $tmp
		  }
		  else
		  {
		     $ou += "/" + $tmp 
		  }					
	       }
	    }
	 }
	 if ($ou -ne $null) 
	 {
	    break
	 }
      }	
      $myObjOut | Add-Member NoteProperty PC $h 		
      $myObjOut | Add-Member NoteProperty OU $ou 		
      $myObjOut			  
   }
}
			  

$search = "OU=yourOU, DC=yourdomain, Dc=com"
Start_Invoke $search | Select-Object -Property 'OU', 'PC', 'OS','UserName', 'State'