Jump to content
MetaMSP

Getting Local Admin Users as a CSV via Remote Monitor

Recommended Posts

So I borrowed the operative parts of this from https://4sysops.com/archives/create-a-list-of-local-administrators-with-powershell/

$ComputerName = $env:ComputerName
$LocalGroupName = "Administrators"
$computerCSVResults=""
try {
    $group = [ADSI]"WinNT://$ComputerName/$LocalGroupName"
    $members = @($group.Invoke("Members"))
    if(!$members) {
        $computerCSVResults += $computerCSVResults + "$ComputerName,$LocalGroupName,NoMembersFound" + [environment]::NewLine
        continue
    }
}        
catch {
    $computerCSVResults += $computerCSVResults + "$ComputerName,,FailedToQuery,$_" + [environment]::NewLine
    Continue
}
foreach($member in $members) {
    try {
        $MemberName = $member.GetType().Invokemember("Name","GetProperty",$null,$member,$null)
        $MemberType = $member.GetType().Invokemember("Class","GetProperty",$null,$member,$null)
        $MemberPath = $member.GetType().Invokemember("ADSPath","GetProperty",$null,$member,$null)
        $MemberDomain = $null
        if($MemberPath -match "^Winnt\:\/\/(?<domainName>\S+)\/(?<CompName>\S+)\/") {
            if($MemberType -eq "User") {
                $MemberType = "LocalUser"
            } elseif($MemberType -eq "Group"){
                $MemberType = "LocalGroup"
            }
            $MemberDomain = $matches["CompName"]
 
        } elseif($MemberPath -match "^WinNT\:\/\/(?<domainname>\S+)/") {
            if($MemberType -eq "User") {
                $MemberType = "DomainUser"
            } elseif($MemberType -eq "Group"){
                $MemberType = "DomainGroup"
            }
            $MemberDomain = $matches["domainname"]
 
        } else {
            $MemberType = "Unknown"
            $MemberDomain = "Unknown"
        }
    $computerCSVResults += "$ComputerName, $LocalGroupName, SUCCESS, $MemberType, $MemberDomain, $MemberName" + [environment]::NewLine
    } catch {
        $computerCSVResults += $computerCSVResults + "$ComputerName,,FailedQueryMember,$_" + [environment]::NewLine
    }
}
Write-Host $computerCSVResults

This code golf's down to

$a="Administrators";$b="Name";$c=$env:ComputerName;$d="domain";$e="Query";$f="Failed";$g="GetProperty";$h="Group";$i="Comp";$j="User";$k="Local";$l="";$m="";$n=$null;$o="";$p=[environment]::NewLine;$q="Members";$r="";$s="";$t="";$u="";$v="Unknown";$w="WinNT";try{$m=(([ADSI]"${w}://$c/$a").Invoke($q));if(!$m){$o+="$o$c,$a,No$qFound$p";continue;}}catch{$o+="$o$c,,${f}To$e,$_$p";continue;};foreach($l in $m){try {$r=$l.GetType().Invokemember($b,$g,$n,$l,$n);$s=$l.GetType().Invokemember("Class",$g,$n,$l,$n);$t=$l.GetType().Invokemember("ADSPath",$g,$n,$l,$n);$u=$n;if($t-match"^$w\:\/\/(?<$d$b>\S+)\/(?<$i$b>\S+)\/"){if($s-eq$j){$s="$k$j"}elseif($s-eq$h){$s="$k$h"};$u=$matches["$i$b"];}elseif($t-match"^$w\:\/\/(?<$d$b>\S+)/"){if($s-eq$j){$s="$d$j"}elseif($s-eq$h){$s="$d$h"};$u=$matches["$d$b"];}else{$s=$v;$u=$v;};$o+="$c,$a,SUCCESS,$s,$u,$r$p";}catch{$o+="$o$c,,$f$e$q,$_$p"};};Write-Host $o;

Now to escape it so it can be stuffed in a string to powershell.exe...

Edited by MetaMSP
code highlighting

Share this post


Link to post
Share on other sites

While Base64'ing the above, @Gavsto hit me with this cleaner version!

$Ignore = @("Domain Admins","Enterprise Admins","LocalAdminName")
$Group = "Administrators"
$Result = @(); $Group = [ADSI]"WinNT://$env:COMPUTERNAME/$Group,group"; $Members = @($Group.psbase.Invoke("Members"))
$Members | foreach-object { $Result += $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}
$FinalResult = $Result | Where-Object {$Ignore -notcontains $_}
If ($FinalResult)
{Write-Output (($FinalResult) -join ",")}
else
{Write-Output "No Accounts Found"}

Which one-lines down to:

$Ignore=@("Domain Admins","Enterprise Admins","LocalAdminName");$Group="Administrators";$Result=@();$Group=[ADSI]"WinNT://$env:COMPUTERNAME/$Group,group";$Members=@($Group.psbase.Invoke("Members"));$Members|foreach-object{$Result +=$_.GetType().InvokeMember("Name",'GetProperty',$null,$_,$null)};$FinalResult=$Result|Where-Object{$Ignore-notcontains$_};If($FinalResult){Write-Output(($FinalResult)-join",")}else{Write-Output "No Accounts Found"};

Which then can be Base64'd like this:

$Command = {$Ignore=@("Domain Admins","Enterprise Admins","LocalAdminName");$Group="Administrators";$Result=@();$Group=[ADSI]"WinNT://$env:COMPUTERNAME/$Group,group";$Members=@($Group.psbase.Invoke("Members"));$Members|foreach-object{$Result +=$_.GetType().InvokeMember("Name",'GetProperty',$null,$_,$null)};$FinalResult=$Result|Where-Object{$Ignore-notcontains$_};If($FinalResult){Write-Output(($FinalResult)-join",")}else{Write-Output "No Accounts Found"};}

$Encoded = [convert]::ToBase64String([System.Text.encoding]::Unicode.GetBytes($command))

$Encoded

JABJAGcAbgBvAHIAZQA9AEAAKAAiAEQAbwBtAGEAaQBuACAAQQBkAG0AaQBuAHMAIgAsACIARQBuAHQA
ZQByAHAAcgBpAHMAZQAgAEEAZABtAGkAbgBzACIALAAiAEwAbwBjAGEAbABBAGQAbQBpAG4ATgBhAG0A
ZQAiACkAOwAkAEcAcgBvAHUAcAA9ACIAQQBkAG0AaQBuAGkAcwB0AHIAYQB0AG8AcgBzACIAOwAkAFIA
ZQBzAHUAbAB0AD0AQAAoACkAOwAkAEcAcgBvAHUAcAA9AFsAQQBEAFMASQBdACIAVwBpAG4ATgBUADoA
LwAvACQAZQBuAHYAOgBDAE8ATQBQAFUAVABFAFIATgBBAE0ARQAvACQARwByAG8AdQBwACwAZwByAG8A
dQBwACIAOwAkAE0AZQBtAGIAZQByAHMAPQBAACgAJABHAHIAbwB1AHAALgBwAHMAYgBhAHMAZQAuAEkA
bgB2AG8AawBlACgAIgBNAGUAbQBiAGUAcgBzACIAKQApADsAJABNAGUAbQBiAGUAcgBzAHwAZgBvAHIA
ZQBhAGMAaAAtAG8AYgBqAGUAYwB0AHsAJABSAGUAcwB1AGwAdAAgACsAPQAkAF8ALgBHAGUAdABUAHkA
cABlACgAKQAuAEkAbgB2AG8AawBlAE0AZQBtAGIAZQByACgAIgBOAGEAbQBlACIALAAnAEcAZQB0AFAA
cgBvAHAAZQByAHQAeQAnACwAJABuAHUAbABsACwAJABfACwAJABuAHUAbABsACkAfQA7ACQARgBpAG4A
YQBsAFIAZQBzAHUAbAB0AD0AJABSAGUAcwB1AGwAdAB8AFcAaABlAHIAZQAtAE8AYgBqAGUAYwB0AHsA
JABJAGcAbgBvAHIAZQAtAG4AbwB0AGMAbwBuAHQAYQBpAG4AcwAkAF8AfQA7AEkAZgAoACQARgBpAG4A
YQBsAFIAZQBzAHUAbAB0ACkAewBXAHIAaQB0AGUALQBPAHUAdABwAHUAdAAoACgAJABGAGkAbgBhAGwA
UgBlAHMAdQBsAHQAKQAtAGoAbwBpAG4AIgAsACIAKQB9AGUAbABzAGUAewBXAHIAaQB0AGUALQBPAHUA
dABwAHUAdAAgACIATgBvACAAQQBjAGMAbwB1AG4AdABzACAARgBvAHUAbgBkACIAfQA7AA==

Taking that Base64-encrypted string (after removing newlines!), it can now be passed into a remote monitor (because, you know, native .ps1 remote monitors are not implemented yet) like this:

"%windir%\System32\WindowsPowerShell\v1.0\powershell.exe" -noprofile -encodedCommand "JABJAGcAbgBvAHIAZQA9AEAAKAAiAEQAbwBtAGEAaQBuACAAQQBkAG0AaQBuAHMAIgAsACIARQBuAHQAZQByAHAAcgBpAHMAZQAgAEEAZABtAGkAbgBzACIALAAiAEwAbwBjAGEAbABBAGQAbQBpAG4ATgBhAG0AZQAiACkAOwAkAEcAcgBvAHUAcAA9ACIAQQBkAG0AaQBuAGkAcwB0AHIAYQB0AG8AcgBzACIAOwAkAFIAZQBzAHUAbAB0AD0AQAAoACkAOwAkAEcAcgBvAHUAcAA9AFsAQQBEAFMASQBdACIAVwBpAG4ATgBUADoALwAvACQAZQBuAHYAOgBDAE8ATQBQAFUAVABFAFIATgBBAE0ARQAvACQARwByAG8AdQBwACwAZwByAG8AdQBwACIAOwAkAE0AZQBtAGIAZQByAHMAPQBAACgAJABHAHIAbwB1AHAALgBwAHMAYgBhAHMAZQAuAEkAbgB2AG8AawBlACgAIgBNAGUAbQBiAGUAcgBzACIAKQApADsAJABNAGUAbQBiAGUAcgBzAHwAZgBvAHIAZQBhAGMAaAAtAG8AYgBqAGUAYwB0AHsAJABSAGUAcwB1AGwAdAAgACsAPQAkAF8ALgBHAGUAdABUAHkAcABlACgAKQAuAEkAbgB2AG8AawBlAE0AZQBtAGIAZQByACgAIgBOAGEAbQBlACIALAAnAEcAZQB0AFAAcgBvAHAAZQByAHQAeQAnACwAJABuAHUAbABsACwAJABfACwAJABuAHUAbABsACkAfQA7ACQARgBpAG4AYQBsAFIAZQBzAHUAbAB0AD0AJABSAGUAcwB1AGwAdAB8AFcAaABlAHIAZQAtAE8AYgBqAGUAYwB0AHsAJABJAGcAbgBvAHIAZQAtAG4AbwB0AGMAbwBuAHQAYQBpAG4AcwAkAF8AfQA7AEkAZgAoACQARgBpAG4AYQBsAFIAZQBzAHUAbAB0ACkAewBXAHIAaQB0AGUALQBPAHUAdABwAHUAdAAoACgAJABGAGkAbgBhAGwAUgBlAHMAdQBsAHQAKQAtAGoAbwBpAG4AIgAsACIAKQB9AGUAbABzAGUAewBXAHIAaQB0AGUALQBPAHUAdABwAHUAdAAgACIATgBvACAAQQBjAGMAbwB1AG4AdABzACAARgBvAHUAbgBkACIAfQA7AA=="

However, after plugging all that in to a remote monitor, sometimes you get interesting PowerShell objects embedded in the result:

#< CLIXML
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04"><Obj S="progress" RefId="0"><TN RefId="0"><T>System.Management.Automation.PSCustomObject</T><T>System.Object</T></TN><MS><I64 N="SourceId">1</I64><PR N="Record"><AV>Preparing modules for first use.</AV><AI>0</AI><Nil /><PI>-1</PI><PC>-1</PC><T>Completed</T><SR>-1</SR><SD> </SD></PR></MS></Obj></Objs>Administrator,Internal 

But you can filter that out in a remote monitor by using this RegEx:

(?<=:^|\/Objs>)(.*)

Which yields this result:

Administrator,Internal

 

Edited by MetaMSP
Adding RegEx

Share this post


Link to post
Share on other sites

Here's @MartynKeigher's contribution!

Quote

This one spits out all LOCAL accounts on a machine, and capitalizes those that are admin.... be sure to test it though! :slightly_smiling_face:

(Get-WmiObject -Class Win32_UserAccount -Namespace "root\cimv2" -Filter "LocalAccount='$True'"|?{ $_.Caption -notmatch 'HomeGroup|ASPNET|VMWare' } | Select @{Name = "Name"; Expression = {$localAdmins = Get-WmiObject -Class win32_groupuser |?{ $_.GroupComponent -match 'administrators' } |%{ [wmi]$_.PartComponent };if($_.Name -in $localAdmins.Name){$_.Name.ToUpper()}else{$_.Name}}}).Name -join ', ' -replace ',([^,]+)$',' and$1.'

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...