Write action output to csv

Newbie to forum and PS. I am in the process of learning the PS language, so please do not hate on me. I am trying to output an action in a admin removal script i borrowed. I want to append a CSV file for each admin removed by the script in an enterprise environment. “add-content -path and value” is not getting it. Below is the area of the script i want to append a csv file to show that an admin was removed from action $Group.remove(“WinNT://$computerName/$domain/$name”). The list will be extensive (in the hundreds) and in another body of PS script, there are names being skipped due to being offline. So, i can compare the names of those removed from those skipped and rerun a short list the next day (when they are back from time off, etc) until all users are removed… Any help would be appreciated

                   foreach ($name in $names) {
                     Write-Host "Verifying the local admin users on computer $computerName" 
                     $Admins = Get-Content -Path "C:\Temp\script\testusers.txt"
                        foreach ($Admin in $Admins) {
                           if ($name -eq $Admin) {
                               Write-Host "User $Admin found on computer $computerName ... " -NoNewline -ForegroundColor Cyan
                               $group.Remove("WinNT://$computerName/$domain/$name")
                               Write-Host "Removed" -ForegroundColor Cyan }

MATTrimony66

Welcome to the forums.

It’s gonna be hard to recommend something meaningful if you do not share the relevant code.

So here are some general tipps:
If you want to output structured data to a CSV file you should use Export-Csv.

If you want to compare a big amount of object you can use Compare-Object.

Instead of Write-Host you should use Write-Verbose or Write-Debug. :wink:

@Olaf
$computerNames = Get-Content “C:\Temp\script\testComputers.txt”
foreach ($computerName in $computerNames) {
if ( -not(Test-Connection $computerName -Quiet -Count 1 -ErrorAction Continue )) {
Write-Host “Could not connect to computer $computerName - Skipping this computer…” -ForegroundColor Red }
Else { Write-Host “Computer $computerName is online” -ForegroundColor Green
$localGroupName = “Administrators”

      $group = [ADSI]("WinNT://$computerName/$localGroupName,group")
      $group.Members() |
         foreach {
                   $AdsPath = $_.GetType().InvokeMember('Adspath', 'GetProperty', $null, $_, $null)
                   $a = $AdsPath.split('/',[StringSplitOptions]::RemoveEmptyEntries)
                   $names = $a[-1] 
                   $domain = $a[-2]

                   foreach ($name in $names) {
                     Write-Host "Verifying the local admin users on computer $computerName" 
                     $Admins = Get-Content -Path "C:\Temp\script\testusers.txt"
                        foreach ($Admin in $Admins) {
                           if ($name -eq $Admin) {
                               Write-Host "User $Admin found on computer $computerName ... " -NoNewline -ForegroundColor Cyan
                               $group.Remove("WinNT://$computerName/$domain/$name")
                               Write-Host "Removed" -ForegroundColor Cyan }

Before I digg into that code - you know that there are group policies available to maintain the members of the local administrators group on domain joined computers, don’t you? You don’t have to re-invent the wheel. :wink: :smiley:

Thanks Olaf, yes. We do have group policies enabled. However in our enterprise, individual exceptions are made for certain users for varying reasons to have administrative rights. I could tackle this manually, however removing over 500 users manually is not something i relish in any capacity (ha). So it was determined the best way to tackle this is by removing the users outside of GP.

I’m still not really sure what exactly you want to output. I assume the account and the computer name would be helpful, right?

Instead of outputting unhelpful messages to the console using Write-Host you could output what account on what computer you removed and collect these information to a variable you can then export to a CSV file.

Top output it in a re-usable way you should use objects - not text. So you remove all code lines with Write-Host in it and replace the line

Write-Host "Removed" -ForegroundColor Cyan

with the following snippet:

[PSCustomObject]@{
    ComputerName = $computerName
    Domain       = $domain
    Name         = $name
}

At the end you can pipe all the ouptut to an Export-Csv and you’re done. :wink: :+1:t4:

BTW: The code you posted misses at least 5 curly braces and uses some typographic quotation marks and some “normal”. I’d recommend using VSCode to write your PowerShell script as it helps you avoiding a lot of failures.

Thank you for taking the time to help this VERY green newbie :slight_smile:
There are over 10,000 computers at my company. Group Policies are just not a good fit for what we are accomplishing. So we are cleaning up an identified number of individual administrative rights - over 500 to be exact. The script is working fine. We supply the computer names in (for now) testcomputers.txt and the lan id’s of the users to search for in testusers.txt. The script (borrowed, as i do not yet have the skillset to author a complex script such as this) performs this task marvelously. We want to monitor the progress in an active PS window, hence ‘write-host’ cmdlet. We were just wanting to dump into csv all the activity from the PS script, pour over it later showing which machines were inaccessible from those that were accessible but possible host MECM issues to those that actually removed the lan id’s from the machines. Its not that big of a deal, we can just run a sql report from MECM again and compare to those we ran the removal script on. It would be nice to eliminate running the report again from MECM.

You might find this article by Mike F Robbins useful. It introduces the LocalAccounts module that was released with PowerShell 5.1. Might help with simplifying your code a bit.

https://mikefrobbins.com/2019/04/04/audit-membership-of-the-local-admins-group-with-powershell/

2 Likes

That sounds for me even more like a perfect case for the recommendation: do it the right way, use GPOs.

I doubt that a PowerShell script may be the right fit.

If you insist I’d start reading up about PowerShell remoting and continue reading the recommendation of @matt-bloomfield.
Then I’d drop all console output as it’s slowing you script down. Instead you could write log files.

1 Like