Exclude results from powershell CSV Exports.

Can
Can used Ask the Experts™
on
Hi All,

I got a script to export a list of local administrators on servers. I would like to exclude certain names and groups.  For example exclude names that starts with "L RG"
Any tips to apply this?

$servers= get-content 'C:\Localdata\5admin.csv'
$output = 'c:\localdata\alladmin.csv' 
$results = @()

foreach($server in $servers)
{
$admins = @()
$group =[ADSI]"WinNT://$server/Administrators" 
$members = @($group.psbase.Invoke("Members"))
$members | foreach {
 $obj = new-object psobject -Property @{
 Server = $Server
 Admin = $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)
 }
 $admins += $obj
 } 
$results += $admins
}
$results| Export-csv $Output -NoTypeInformation

Open in new window


Thanks in advance.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2018
Distinguished Expert 2018
Commented:
Like this?
$servers= Get-Content -Path 'C:\Localdata\5admin.csv'
$output = 'C:\localdata\alladmin.csv' 

$servers | ForEach-Object {
	$server = $_
	Write-Host "Processing $($server)"
	$group = [ADSI]"WinNT://$($server)/Administrators" 
	$group.psbase.Invoke('Members') | ForEach-Object {
		New-Object PSObject -Property ([ordered]@{
			Server = $server
			Admin = $_.GetType().InvokeMember('Name', 'GetProperty', $null, $_, $null)
		})
	}
} |
	Where-Object {$_.Admin -notlike "L RG*"} |
	Export-csv $Output -NoTypeInformation

Open in new window

Qlemo"Batchelor", Developer and EE Topic Advisor
Top Expert 2015

Commented:
There are a lot of ways to do that. E.g. you can replace line 17 with
$results += $admins | ? { $_.Admin -notlike 'L RG *' }

Open in new window

If you have multiple conditions, it is probably better to use -notmatch with a regular expression.
CanSystem Administrator

Author

Commented:
Thanks you both, that worked for me. Another thing: how can i add multiple objects to the -notlike parameter? I now got this:

Where-Object {$_.Admin -notlike "L RG*" -and $_.Admin -notlike "LocalAdmin" -and $_.Admin -notlike "Domain Admins"} |

Is there an easier way to add exclusions instead of adding -notlike everytime?
OWASP: Forgery and Phishing

Learn the techniques to avoid forgery and phishing attacks and the types of attacks an application or network may face.

Qlemo"Batchelor", Developer and EE Topic Advisor
Top Expert 2015
Commented:
No, that is where -notmatch comes into play:
Where-Object {$_.Admin -not match '^(L RG.*|LocalAdmin|Domain Admins)$'} 

Open in new window

Note the more complex regular expression syntax:
  ^ means start of string, $ end
  .* arbitrary amount of characters
  | alternative Pattons
  () groups patterns together
Most Valuable Expert 2018
Distinguished Expert 2018

Commented:
This will allow you to use a list with * or ? as wildcards; it will turn that into a regex:
$servers= Get-Content -Path 'C:\Localdata\5admin.csv'
$output = 'C:\localdata\alladmin.csv' 
$exclude = @(
	"L RG*"
	"LocalAdmin"
	"Domain Admins"
)

$pattern = '^(' + (($exclude | ForEach-Object {"($(($_.Replace('*', '.*').Replace('?', '.'))))"}) -join '|') + ')$'
$servers | ForEach-Object {
	$server = $_
	Write-Host "Processing $($server)"
	$group = [ADSI]"WinNT://$($server)/Administrators" 
	$group.psbase.Invoke('Members') | ForEach-Object {
		New-Object PSObject -Property ([ordered]@{
			Server = $server
			Admin = $_.GetType().InvokeMember('Name', 'GetProperty', $null, $_, $null)
		})
	}
} |
	Where-Object {$_.Admin -notmatch $pattern} |
	Export-Csv -Path $Output -NoTypeInformation

Open in new window

CanSystem Administrator

Author

Commented:
And the last: Is there an option to filter out domain accounts? I would like to retrieve only local accounts
Most Valuable Expert 2018
Distinguished Expert 2018

Commented:
This adds a property "AdminRealm" with the member's domain (or the computer name in case of a local account)
$servers= Get-Content -Path 'C:\Localdata\5admin.csv'
$output = 'C:\localdata\alladmin.csv' 
$exclude = @(
	"L RG*"
	"LocalAdmin"
	"Domain Admins"
)

$pattern = '^(' + (($exclude | ForEach-Object {"($(($_.Replace('*', '.*').Replace('?', '.'))))"}) -join '|') + ')$'
$servers | ForEach-Object {
	$server = $_
	Write-Host "Processing $($server)"
	$group = [ADSI]"WinNT://$($server)/Administrators" 
	$group.psbase.Invoke('Members') | ForEach-Object {
		$adsPath = $_.GetType().InvokeMember('AdsPath', 'GetProperty', $null, $_, $null).Split('/', [StringSplitOptions]::RemoveEmptyEntries)
		New-Object PSObject -Property ([ordered]@{
			Server = $server
			Admin = $adsPath[-1]
			AdminRealm = $adsPath[-2]
		})
	}
} |
	Where-Object {($_.AdminRealm -eq $_.Server) -and ($_.Admin -notmatch $pattern)} |
	Export-Csv -Path $Output -NoTypeInformation

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial