Powershell Needful Things put that in your pipeline

16Mar/0910

Audit the local Administrators group on a list of remote computers

This is a very basic script which collects a list of server names from a local text file called servers.txt. The script reports the list of users, sorted by server name to a local text file in the root of drive C. I am working on cleaning up the results, as currently the "Adspath" reports to the text file in the following format: WinNT://DOMAIN/COMPUTER/Administrator This was the only true distinction between local or domain users, as "Name" reports only the name of the user or group. So you are never really sure if it is a domain or local entry. Finally I need to enable the script to report its results to Excel or HTML.

$Result = @()

foreach($server in (gc .\servers.txt)){

$computer = [ADSI](”WinNT://” + $server + “,computer”)
$Group = $computer.psbase.children.find(”Administrators”)

function getAdmins
{$members = $Group.psbase.invoke(”Members”) | %{$_.GetType().InvokeMember(”Adspath”, ‘GetProperty’, $null, $_, $null)}
$members}

$Result += $server
$Result += ( getAdmins )
$Result += " "
}

$Result > c:\results.txt
Invoke-Item c:\results.txt

I had a little extra time today, and managed to clean up the members using the -replace parameter, replace "DOMAIN" with your domain name. The updated code looks something like this:

$Result = @()

foreach($server in (gc .\servers.txt)){

$computer = [ADSI](”WinNT://” + $server + “,computer”)
$Group = $computer.psbase.children.find(”Administrators”)

function getAdmins
{$members = ($Group.psbase.invoke(”Members”) | %{$_.GetType().InvokeMember(”Adspath”, ‘GetProperty’, $null, $_, $null)}) -replace ('WinNT://DOMAIN/' + $server + '/'), '' -replace ('WinNT://DOMAIN/', 'DOMAIN\') -replace ('WinNT://', '')
$members}

$Result += Write-Output "SERVER: $server"
$Result += Write-Output ' '
$Result += ( getAdmins )
$Result += Write-Output '____________________________'
$Result += Write-Output ' '
}



$Result > c:\results.txt

Invoke-Item c:\results.txt

You can simply add another -replace ('WinNT://DOMAIN/', 'DOMAIN\') for each domain in the system. I know its a little hack 'n slash but it will do for now.

Comments (10) Trackbacks (0)
  1. Very Good Post, cleanup is below

    $Result = @()

    foreach($server in (gc .\servers.txt)){

    $computer = [ADSI](”WinNT://” + $server + “,computer”)
    $Group = $computer.psbase.children.find(”Administrators”)

    function getAdmins
    {$members = ($Group.psbase.invoke(”Members”) | %{$_.GetType().InvokeMember(”Adspath”, ‘GetProperty’, $null, $_, $null)}) -replace ('WinNT://DOMAIN/' + $server + '/'), '' -replace ('WinNT://DOMAIN/', 'DOMAIN\') -replace ('WinNT://', '')
    $members}

    $Result += Write-Output "SERVER: $server"
    $Result += Write-Output ' '
    $Result += ( getAdmins )
    $Result += Write-Output '____________________________'
    $Result += Write-Output ' '
    }

    $Result > d:\results.txt

    Invoke-Item d:\results.txt

  2. Hi,

    Thanks for your post. It seems my code window added some junk into the code boxes.

    I have resolved that, thanks.

  3. I would like to do this against all groups on remote servers, not just the administrators group. Additionally, I do not know all of the “expected” groups on every server.

    Thank you,

    Jared

  4. Love this script but here’s the problem I see. If the PC is not on or connected to the network and since there is no “if else” clause the results will not be pretty. I must mention that I am a newbie to PS. I tried to use this and it worked great when all the PC’s were available.

    • Michael,

      Thanks for your reply. This is a script I wrote years ago when I started using Powershell. At the time, it did exactly what I needed, and I haven’t needed it since.

      If you want to write a new version, you are welcome, and I will link to your updated version on mmy blog.

      Jean

      • This one will ping the box first and if the ping is good, have a go.

        $Result = @()

        foreach($server in (gc d:\temp\servers.txt)){

        $ipAddress = $pingStatus.ProtocolAddress;
        # Ping the computer
        $pingStatus = Get-WmiObject -Class Win32_PingStatus -Filter “Address = ‘$server'”;
        if($pingStatus.StatusCode -eq 0){

        Write-Host -ForegroundColor Green “Ping Reply received from $server.”;

        $computer = [ADSI](”WinNT://” + $server + “,computer”)
        $Group = “”
        $Group = $computer.psbase.children.find(”Administrators”)

        function getAdmins
        {$members = ($Group.psbase.invoke(”Members”) | %{$_.GetType().InvokeMember(”Adspath”, ‘GetProperty’, $null, $_, $null)}) -replace (‘WinNT://DOMAIN/’ + $server + ‘/’), ” -replace (‘WinNT://DOMAIN/’, ‘DOMAIN\’) -replace (‘WinNT://’, ”)
        $members}

        $Result += Write-Output “SERVER: $server”
        $Result += Write-Output ‘ ‘
        $Result += ( getAdmins )
        $Result += Write-Output ‘____________________________’
        $Result += Write-Output ‘ ‘
        $Result > d:\temp\results.txt
        }

        else

        {
        Write-Host -ForegroundColor Red “No Ping Reply received from $server.”;
        }

        }

  5. Can anyone help to add the functionality of enumerating the members of groups in the local administrators?

  6. Thanks a lot !!! It saved my day ….

  7. Rather old post, but is there a way to alter the script to display all members of all local groups and not just the administrator group?

  8. Marvelous, what a webpage it is! This weblog gives
    useful facts to us, keep it up.


Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

No trackbacks yet.