CuriousMAUser
asked on
Is there an easier way to get Admin user information from remote desktops?
Hello Experts,
Is there an easier way to express the parameters, variables and cmdlets to retrieve Admin user information from desktop computers?
The script below seems verbose and overly complex. Why is there a [ADSI]"WinNT:// syntax and "^Winnt\:\/\/(?<domainName >\S+)\/(?< CompName>\ S+)\/") string within the try-catch syntax?
If you could please add perspective, I'd surely appreciate your insight. Thank you.
************************** ********** ********** ********** ********
Set-ExecutionPolicy remotesigned -Force
Import-Module activedirectory
[CmdletBinding()]
Param(
[Parameter( ValueFromPipeline=$true,
ValueFromPipelineByPropert yName=$tru e
)]
[string[]]
$ComputerName = "get-content c:\Scripts\DesktopComputer s.txt",
[Parameter()]
[string]
$LocalGroupName = "Administrators",
[Parameter()]
[string]
$OutputDir = "c:\Scripts"
)
Begin {
$OutputFile = Join-Path $OutputDir "LocalGroupMembers.csv"
Write-Verbose "Script will write the output to $OutputFile folder"
Add-Content -Path $OutPutFile -Value "ComputerName, LocalGroupName, Status, MemberType, MemberDomain, MemberName"
}
Process {
ForEach($Computer in $ComputerName) {
Write-host "Working on $Computer"
If(!(Test-Connection -ComputerName $Computer -Count 1 -Quiet)) {
Write-Verbose "$Computer is offline. Proceeding with next computer"
Add-Content -Path $OutputFile -Value "$Computer,$LocalGroupName ,Offline"
Continue
} else {
Write-Verbose "Working on $computer"
try {
$group = [ADSI]"WinNT://$Computer/$ LocalGroup Name"
$members = @($group.Invoke("Members") )
Write-Verbose "Successfully queries the members of $computer"
if(!$members) {
Add-Content -Path $OutputFile -Value "$Computer,$LocalGroupName ,NoMembers Found"
Write-Verbose "No members found in the group"
continue
}
}
catch {
Write-Verbose "Failed to query the members of $computer"
Add-Content -Path $OutputFile -Value "$Computer,,FailedToQuery"
Continue
}
foreach($member in $members) {
try {
$MemberName = $member.GetType().Invokeme mber("Name ","GetProp erty",$nul l,$member, $null)
$MemberType = $member.GetType().Invokeme mber("Clas s","GetPro perty",$nu ll,$member ,$null)
$MemberPath = $member.GetType().Invokeme mber("ADSP ath","GetP roperty",$ null,$memb er,$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"
}
Add-Content -Path $OutPutFile -Value "$Computer, $LocalGroupName, SUCCESS, $MemberType, $MemberDomain, $MemberName"
} catch {
Write-Verbose "failed to query details of a member. Details $_"
Add-Content -Path $OutputFile -Value "$Computer,,FailedQueryMem ber"
}
}
}
}
}
End {}
Is there an easier way to express the parameters, variables and cmdlets to retrieve Admin user information from desktop computers?
The script below seems verbose and overly complex. Why is there a [ADSI]"WinNT:// syntax and "^Winnt\:\/\/(?<domainName
If you could please add perspective, I'd surely appreciate your insight. Thank you.
**************************
Set-ExecutionPolicy remotesigned -Force
Import-Module activedirectory
[CmdletBinding()]
Param(
[Parameter( ValueFromPipeline=$true,
ValueFromPipelineByPropert
)]
[string[]]
$ComputerName = "get-content c:\Scripts\DesktopComputer
[Parameter()]
[string]
$LocalGroupName = "Administrators",
[Parameter()]
[string]
$OutputDir = "c:\Scripts"
)
Begin {
$OutputFile = Join-Path $OutputDir "LocalGroupMembers.csv"
Write-Verbose "Script will write the output to $OutputFile folder"
Add-Content -Path $OutPutFile -Value "ComputerName, LocalGroupName, Status, MemberType, MemberDomain, MemberName"
}
Process {
ForEach($Computer in $ComputerName) {
Write-host "Working on $Computer"
If(!(Test-Connection -ComputerName $Computer -Count 1 -Quiet)) {
Write-Verbose "$Computer is offline. Proceeding with next computer"
Add-Content -Path $OutputFile -Value "$Computer,$LocalGroupName
Continue
} else {
Write-Verbose "Working on $computer"
try {
$group = [ADSI]"WinNT://$Computer/$
$members = @($group.Invoke("Members")
Write-Verbose "Successfully queries the members of $computer"
if(!$members) {
Add-Content -Path $OutputFile -Value "$Computer,$LocalGroupName
Write-Verbose "No members found in the group"
continue
}
}
catch {
Write-Verbose "Failed to query the members of $computer"
Add-Content -Path $OutputFile -Value "$Computer,,FailedToQuery"
Continue
}
foreach($member in $members) {
try {
$MemberName = $member.GetType().Invokeme
$MemberType = $member.GetType().Invokeme
$MemberPath = $member.GetType().Invokeme
$MemberDomain = $null
if($MemberPath -match "^Winnt\:\/\/(?<domainName
if($MemberType -eq "User") {
$MemberType = "LocalUser"
} elseif($MemberType -eq "Group"){
$MemberType = "LocalGroup"
}
$MemberDomain = $matches["CompName"]
} elseif($MemberPath -match "^WinNT\:\/\/(?<domainname
if($MemberType -eq "User") {
$MemberType = "DomainUser"
} elseif($MemberType -eq "Group"){
$MemberType = "DomainGroup"
}
$MemberDomain = $matches["domainname"]
} else {
$MemberType = "Unknown"
$MemberDomain = "Unknown"
}
Add-Content -Path $OutPutFile -Value "$Computer, $LocalGroupName, SUCCESS, $MemberType, $MemberDomain, $MemberName"
} catch {
Write-Verbose "failed to query details of a member. Details $_"
Add-Content -Path $OutputFile -Value "$Computer,,FailedQueryMem
}
}
}
}
}
End {}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER