I have a script which help me to find all OU computers local admin.
when i run it, instead of computer name i get “System.DirectoryServices.PropertyValueCollection”
code:
Import-Module ActiveDirectory
$Searcher = New-Object DirectoryServices.DirectorySearcher([ADSI]"")
$Searcher.SearchRoot = 'LDAP://OU=Laptops,DC=contoso,DC=com'
$Searcher.Filter = "(objectClass=computer)"
$Computers = ($Searcher.Findall())
$Results = @()
md C:\temp
Foreach ($Computer in $Computers){
$Path=$Computer.Path
$Name=([ADSI]"$Path").Name
write-host $Name
$members =[ADSI]"WinNT://$Name/Administrators"
$members = @($members.psbase.Invoke("Members"))
$members | foreach {
$LocalAdmins = $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null) # Create a new object for the purpose of exporting as a CSV
$pubObject = new-object PSObject
$pubObject | add-member -membertype NoteProperty -name "Server" -Value $Name
$pubObject | add-member -membertype NoteProperty -name "Administrators" -Value $LocalAdmins
# Append this iteration of our for loop to our results array.
$Results += $pubObject
}
}
$Results | Export-Csv -Path "C:\temp\ServerLocalAdmins.csv" -NoTypeInformation
$Results = $Null
Although I agree the code could use some fine tuning, if the OP wants to avoid enabling PSRemoting for some security reason, and or has hosts at a powershell level the does not support Get-LocalGroupMember, I see nothing wrong with using ADSI.
I personally manage systems that meet this criteria.
In my experiences most of the time, those “security reasons” are unsubstantiated vague concerns limitting the managebility without actually increasing security.
Those systems need to be updated as soon as possible.
There is nothing wrong with using ADSI but when you borrow code from others you should do it right.
Understood and I totally agree. However, I do have to maintain a script in an air gapped XP environment where we are contractually bound to leave the systems as is. I had to resort to ADSI … so there are situations where it cant be avoided.