need to export Powershell results to file - powershell

I have the following powershell script, I am unsure how to get it to export all the results to a file. Needs to have $Computer,$Group.Name, $Name preferably in CSV format
here is my query
$Computer = "ChynaSyndrome"
$Computer = [ADSI]"WinNT://$Computer"
$Groups = $Computer.psbase.Children | Where {$_.psbase.schemaClassName -eq "group"}
ForEach ($Group In $Groups)
{
"Group: " + $Group.Name
$Members = #($Group.psbase.Invoke("Members"))
ForEach ($Member In $Members)
{
$Class = $Member.GetType().InvokeMember("Class", 'GetProperty', $Null, $Member, $Null)
$Name = $Member.GetType().InvokeMember("Name", 'GetProperty', $Null, $Member, $Null)
"-- Member: $Name ($Class)"
}
}

This will still give you console output, but it will build a PSObject with each member found in the group, then add those objects to the $results array. Once done, you have the option to show the resulting array in a GridView popup window and/or exporting them to CSV on your Desktop. Comment out either line to not take that action:
** Update: Per comments, I parameterized the script, allowing the calling process to provide an array of computer names (or a single one). Calling this script from a batch file would work like this:
powershell.exe -File "C:\script.ps1" -ComputerName "ChynaSyndrome","ChynaSyndrome2","ChynaSyndrome3"
Script.ps1:
Param
(
[parameter(Mandatory=$true,Position=0)]
[String[]]
$ComputerName
)
Begin {
$results = #()
}
Process {
foreach ($Computer in $ComputerName) {
$ComputerADSI = [ADSI]"WinNT://$Computer"
$Groups = $ComputerADSI.psbase.Children | Where-Object {$_.psbase.schemaClassName -eq "group"}
ForEach ($Group In $Groups) {
"Group: " + $Group.Name
$Members = #($Group.psbase.Invoke("Members"))
ForEach ($Member In $Members) {
$Class = $Member.GetType().InvokeMember("Class", 'GetProperty', $Null, $Member, $Null)
$Name = $Member.GetType().InvokeMember("Name", 'GetProperty', $Null, $Member, $Null)
"-- Member: $Name ($Class)"
$object = New-Object PSObject -Property #{
Computer = $Computer
GroupName = $Group.Name.ToString()
MemberName = $Name.ToString()
MemberClass = $Class
}
$results += $object
}
}
}
}
End {
# Export results to CSV on your Desktop
$results | Export-Csv -NoTypeInformation "$env:USERPROFILE\Desktop\GroupResults.csv" -Force
}

Related

Unable to get the members list from local administrator group through powershell

I am unable to get the list of members from local administrator group after running the following command. its showing the error " missing closing '}' every time. Please help me on it or if have another scripts then please share with me.
function get-localusers {
param (
[Parameter(Mandatory=$true,valuefrompipeline=$true)]
[string]$strComputer
)
begin {}
Process {
$adminlist =""
$powerlist =""
$computer = [ADSI]("WinNT://" + $strComputer + ",computer")
$AdminGroup = $computer.psbase.children.find("Administrators")
$powerGroup = $computer.psbase.children.find("Power Users")
$powerGroup = $computer.psbase.children.find("Power Users")
$Adminmembers= $AdminGroup.psbase.invoke("Members") | % {
$.GetType().InvokeMember("Name", 'GetProperty', $null, $, $null)
}
$Powermembers= $PowerGroup.psbase.invoke("Members") | % {
$.GetType().InvokeMember("Name", 'GetProperty', $null, $, $null)
}
foreach ($admin in $Adminmembers) {
$adminlist = $adminlist + $admin + ","
}
foreach ($poweruser in $Powermembers) {
$powerlist = $powerlist + $poweruser + ","
}
$Computer = New-Object psobject $computer | Add-Member noteproperty ComputerName $strComputer $computer | Add-Member noteproperty Administrators $adminlist $computer | Add-Member noteproperty PowerUsers $powerlist
Write-Output $computer
}
end {}
}
Get-Content C:\temp\server_list.txt | get-localusers | Export-Csv C:\temp\localusers.csv
If you what to reference to the object in a Foreach-Object (%) block you have to use $_
Change the Foreach-Object part in your code to this:
$Adminmembers= $AdminGroup.psbase.invoke("Members") | % {
$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)
}
$Powermembers= $PowerGroup.psbase.invoke("Members") | % {
$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)
}

Powershell for retrieve local USB printer details and insert into WMI

I am trying to get USB printer model and serial from the Win32_PnPEntity, then insert these info into a custom WMI namespace, so that I can use the Hardware inventory function in SCCM to collect the info for reporting.
I noticed that the location storing these info varies from one manufacturer to another.
such as the FujiXerox stores in "USB Printing Support" while HP and Brother stores in "USB Composite Device"
what weird is after I somehow got the below code working on my computer, when I try it on other computers, it only returns the first character, such as:
Results on my computer (two USB printers connected)
Model
Serial
HEWLETT-PACKARDHP_LASERJET_400_M401D
VNH3G0XXXX
FUJI_XEROXDOCUPRINT_P355_DB
YWG-50XXXX
Results on other computers (eg. a HP printer with serial no. starting with V)
Model
Serial
H
V
I am a system administrator managing SCCM, occasionally using PowerShell to help on my tasks, I just completely stuck at the moment as I didn't find any hint that will trim the results.
Thanks
Andrew
$ModelInfo = #()
$SerialInfo = #()
$FullInfo = #{}
$Final=#()
$USBPrinterModels = Get-WmiObject Win32_PnPEntity | Where-Object {$_.DeviceID -Match "USBPRINT"}|select DeviceID
$USBPrinterSerials2 = Get-WmiObject Win32_PnPEntity | Where-Object {$_.Description -Match "USB 列印支援" -or $_.Description -Match "USB Printing Support"}|select DeviceID
$USBPrinterSerials = Get-WmiObject Win32_PnPEntity | Where-Object {$_.Description -Match "USB Composite Device"}|select DeviceID
Foreach ($USBPrinterModel in $USBPrinterModels)
{
$ModelFull = $USBPrinterModel.DeviceID
$Model = #{}
$Model.model += ($ModelFull.Split("\"))[1]
$ModelInfo += $Model
}
Foreach ($USBPrinterSerial in $USBPrinterSerials)
{
$SerialFull = $USBPrinterSerial.DeviceID
$Serial = #{}
$Serial.serial += $SerialFull.Split("\")[2]
If($Serial.serial -notmatch "&")
{
$SerialInfo += $Serial
}
}
Foreach ($USBPrinterSerial2 in $USBPrinterSerials2)
{
$SerialFull2 = $USBPrinterSerial2.DeviceID
$Serial2 = #{}
$Serial2.serial += $SerialFull2.Split("\")[2]
If($Serial2.serial -notmatch "&")
{
$SerialInfo += $Serial2
}
}
$MaxLength = [Math]::Max($ModelInfo.Length, $SerialInfo.Length)
for ($loop_index = 0; $loop_index -lt $MaxLength; $loop_index++)
{
$Final += new-object psobject -Property #{
Model=$ModelInfo.model[$loop_index]
Serial=$SerialInfo.serial[$loop_index]
}
# $Final+=$ModelInfo[$loop_index]
# $Final+=$SerialInfo[$loop_index]
}
$Class = Get-WmiObject Win32_USBPrinterDetails -ErrorAction SilentlyContinue
If ($Class) {Remove-WmiObject -Class Win32_USBPrinterDetails}
$WMIClass = New-Object System.Management.ManagementClass("root\cimv2", [String]::Empty, $null);
$WMIClass["__CLASS"] = "Win32_USBPrinterDetails";
$WMIClass.Qualifiers.Add("Static", $true)
$WMIClass.Properties.Add("Model", [System.Management.CimType]::String, $false)
$WMIClass.Properties["Model"].Qualifiers.Add("read", $true)
$WMIClass.Properties.Add("Serial", [System.Management.CimType]::String, $false)
$WMIClass.Properties["Serial"].Qualifiers.Add("key", $true)
$WMIClass.Properties["Serial"].Qualifiers.Add("read", $true)
$WMIClass.Put()
ForEach ($FInfo in $Final) {
[void](Set-WmiInstance -Path \\.\root\cimv2:Win32_USBPrinterDetails -Arguments #{Model=$FInfo.model; Serial=$FInfo.serial})
}
I am so stupid,
When there is only ONE USB printer, the $ModelInfo and $SerialInfo become "String" type and caused the [loop_index] return the first character of the string instead of the first entry of the array.
I added a gettype check on the variables (surely not perfect).
$ModelInfo = #()
$SerialInfo = #()
$FullInfo = #{}
$Final=#()
$USBPrinterModels = Get-WmiObject Win32_PnPEntity | Where-Object {$_.DeviceID -Match "USBPRINT"}|select DeviceID
$USBPrinterSerials2 = Get-WmiObject Win32_PnPEntity | Where-Object {$_.Description -Match "USB 列印支援" -or $_.Description -Match "USB Printing Support"}|select DeviceID
$USBPrinterSerials = Get-WmiObject Win32_PnPEntity | Where-Object {$_.Description -Match "USB Composite Device"}|select DeviceID
Foreach ($USBPrinterModel in $USBPrinterModels)
{
$ModelFull = $USBPrinterModel.DeviceID
$Model = #{}
$Model.model += ($ModelFull.Split("\"))[1]
$ModelInfo += $Model
}
Foreach ($USBPrinterSerial in $USBPrinterSerials)
{
$SerialFull = $USBPrinterSerial.DeviceID
$Serial = #{}
$Serial.serial += $SerialFull.Split("\")[2]
If($Serial.serial -notmatch "&")
{
$SerialInfo += $Serial
}
}
Foreach ($USBPrinterSerial2 in $USBPrinterSerials2)
{
$SerialFull2 = $USBPrinterSerial2.DeviceID
$Serial2 = #{}
$Serial2.serial += $SerialFull2.Split("\")[2]
If($Serial2.serial -notmatch "&")
{
$SerialInfo += $Serial2
}
}
If ($ModelInfo.model.GetType().name -eq "String") {
$Final += new-object psobject -Property #{
Model=$ModelInfo.model
Serial=$SerialInfo.serial
}
}
ElseIf ($ModelInfo.model.GetType().name -ne "String"){
$MaxLength = [Math]::Max($ModelInfo.Length, $SerialInfo.Length)
for ($loop_index = 0; $loop_index -lt $MaxLength; $loop_index++)
{
$Final += new-object psobject -Property #{
Model=$ModelInfo.model[$loop_index]
Serial=$SerialInfo.serial[$loop_index]
}
}
}
$Class = Get-WmiObject Win32_USBPrinterDetails -ErrorAction SilentlyContinue
If ($Class) {Remove-WmiObject -Class Win32_USBPrinterDetails}
$WMIClass = New-Object System.Management.ManagementClass("root\cimv2", [String]::Empty, $null);
$WMIClass["__CLASS"] = "Win32_USBPrinterDetails";
$WMIClass.Qualifiers.Add("Static", $true)
$WMIClass.Properties.Add("Model", [System.Management.CimType]::String, $false)
$WMIClass.Properties["Model"].Qualifiers.Add("read", $true)
$WMIClass.Properties.Add("Serial", [System.Management.CimType]::String, $false)
$WMIClass.Properties["Serial"].Qualifiers.Add("key", $true)
$WMIClass.Properties["Serial"].Qualifiers.Add("read", $true)
$WMIClass.Put()
ForEach ($FInfo in $Final) {
[void](Set-WmiInstance -Path \\.\root\cimv2:Win32_USBPrinterDetails -Arguments #{Model=$FInfo.model; Serial=$FInfo.serial})
}
$final|FT

Using Invoke-Command but get error 'One or more computer names are not valid'

Invoke-Command : One or more computer names are not valid
I'm getting the error when running this command:
Invoke-Command -ComputerName $Targets -ScriptBlock $ScriptBlock
$Targets is an array, which is populated by this command:
Get-ADComputer -Filter "Name -like '$Filter'" -SearchBase $OU |
Select-Object -ExpandProperty Name |
Sort-Object
The computer names usually have - in them, but I tested computers without any special characters and got the same result.
Here is my method:
function Get-FilteredADComputers
{
[CmdletBinding()]
[OutputType([System.String[]])]
param
(
[Parameter(Position = 0, Mandatory)]
[ValidateSet('Site 1', 'Site 2', 'Site 3')]
[String]
$Site,
[Parameter(Position = 1, Mandatory)]
[ValidateSet('Client', 'Server')]
[String]
$ComputerType,
[Parameter(Position = 2, Mandatory)]
[String]
$Filter
)
$siteSecondLevel
switch($Site){
"site 1"{$siteSecondLevel = "LVL 1"}
"site 2"{$siteSecondLevel = "LVL 2"}
"site 3"{$siteSecondLevel = "LVL 3"}
}
$OU = "OU=$ComputerType,OU=Devices,OU=$siteSecondLevel,OU=$Site,OU=MyOU,DC=mydomain,DC=com"
Get-ADComputer -Filter {Name -like $Filter} -SearchBase $OU | Select-Object -ExpandProperty Name | Sort-Object
}
How I declare my list in a test environment:
$temp = Get-FilteredADComputers -Site Site1 -ComputerType Client -Filter
"myfilter"
$target = #()
foreach($t in $temp){
if($t -ne $null -or $t -ne ""){
$target += $t
}
}
I also get the same result by just declaring my array as $Targets = Get-FilteredADComputers
First step is to look to see what's in $targets. I suspect you may have a blank line at the end or some other oddity that Invoke-Command rejects as a computer name
The $Targets is a list right? If not than do this: $Targets2 = #($Targets)
This will make it as a list and probably you will succeed with using this solution.
It should work, however, I would say to use a Foreach instead.
foreach ($Target in $Targets)
{
Invoke-Command -ComputerName $Target -ScriptBlock $ScriptBlock
}
I do it this way most of the time, as it is easier to troubleshoot and find the cause of error.
Give this a try:
$temp = Get-FilteredADComputers
$targets = #()
foreach($t in $temp)
{
if($t -ne $null -and $temp -ne "")
{
$targets += $t
}
}
In one of your comments you said that you do the following:
$temp = Get-FilteredADComputers -Site $site -ComputerType $computerType -Filter $filter
if($temp -ne $null -or $temp -ne ""){ $targets += $temp }
But with the check $temp -ne $null you just check that it's not null, as soon as there is one entry in $temp (even if it is just on the 2nd position) it is not null anymore..
Posting this for google search purposes. My issue was that I was trying to pass a DevOps variable to a powershell script. I had to change my DevOps WebServers variable
From:
server1,server2,server3
to:
#("server1","server2","server3")
and in my powershell I used:
$p = "$(password)";
$sv = $(WebServers); // --> I had to change this line and remove the quotes
$u = "$(username)";

List all local administrator accounts excluding domain admin and local admin

function get-localgroupmember {
[CmdletBinding()]
param(
[parameter(ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[string[]]$computername = $env:COMPUTERNAME
)
BEGIN {
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ctype = [System.DirectoryServices.AccountManagement.ContextType]::Machine
}
PROCESS{
foreach ($computer in $computername) {
$context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ctype, $computer
$idtype = [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName
$group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($context, $idtype, 'Administrators')
$group.Members |
select #{N='Server'; E={$computer}}, #{N='Domain'; E={$_.Context.Name}}, samaccountName
} # end foreach
} # end PROCESS
}
"Win12R2", "W12SUS" | get-localgroupmember
What I want is the output to look like the following and I want to flag the users in the admin group that are NOT part of our standard setup. Really I want to ignore the SAM accounts that are the domain accounts but flagging them for now works. What is happening is there is a looping through the SAM accounts to create this output. However when the machine is offline I need to note that too.
I also do NOT want to use a ValueFromPipeline but rather get a list of PC names from this command $allComputers = Get-ADComputer -Filter 'PasswordLastSet -ge $date' -properties PasswordLastSet | select Name and then use that variable as the source to loop through.
This is my revised code but I'm having issues creating a custom object to add to an array when there seems to be looping in the $group.Members |select #{N='Server'; E={$computer}}, #{N='Domain'; E={$_.Context.Name}}, samaccountName
function get-localgroupmember {
[CmdletBinding()]
param(
[Parameter(Mandatory=$True,HelpMessage="Enter PC")]
[ValidateNotNullorEmpty()]
[object]$computername = $null
)
BEGIN {
$newArray = #();
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ctype = [System.DirectoryServices.AccountManagement.ContextType]::Machine
}
PROCESS{
foreach ($computer in $computername) {
If (Test-Connection -ComputerName $computer.name -Quiet -Count 1) {
try {
$context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ctype, $computer.name
$idtype = [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName
$group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($context, $idtype, 'Administrators')
$group.Members | select #{N='Server'; E={$computer.name}}, #{N='Domain'; E={$_.Context.Name}}, samaccountName
$objComputer = [pscustomobject] #{
Server = $computer.name
Domain = $group.Members | select #{N='Domain'; E={$_.Context.Name}}
Account = $Computer.samaccountName
}
} catch {
$objComputer = [pscustomobject] #{
Server = $computer.name
Domain = "Error"
Account = "Error"
}
}
} else {
$objComputer = [pscustomobject] #{
Server = $computer.name
Domain = "Off-Line"
Account = "Off-Line"
}
} $arrayNew += $objComputer
} # end foreach
} # end PROCESS
return $arrayNew
}
$date = [DateTime]::Today.AddDays(-1)
$allComputers = Get-ADComputer -Filter 'PasswordLastSet -ge $date' -properties PasswordLastSet | select Name
get-localgroupmember -computername $allComputers | Out-GridView
To be honest I would not try to output an array object like you are. There is really no need for it. Just create each object as needed, and let it output directly (you really don't need to use return as the function will pass any output down the pipeline unless you specifically tell it otherwise, with something like Write-Host, or Out-File). Also, it looks like your input wants an object (that's pretty vague), but you are then trying to loop through that object, and use each record as the name of a PC, so what you really want for input is an array of strings. In that case change your type from [object] to [string[]]. Lastly, a good bit of your code can be simplified if you just expand the Name property when creating your $AllComputers variable. Oh, I lied, this is the last thing... Your return statement is not in a valid section of your function. It would need to be something like END{ Return $arrayNew }
Then you just have to add a list of excepted accounts to not flag, or add some logic in, or something. Honestly, your code should do pretty much everything you want it to do with a little syntax fixing. Here's based on your script, where it outputs all members of the group and flags any that arn't a local account with the name 'Administrator', and are not a domain account listed as OK (defined in the BEGIN section, currently "Domain Admins" or "Workstation Admin").
function get-localgroupmember {
[CmdletBinding()]
param(
[Parameter(Mandatory=$True,HelpMessage="Enter PC")]
[string[]]$computername
)
BEGIN {
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ctype = [System.DirectoryServices.AccountManagement.ContextType]::Machine
$OKAccounts = ("Workstation Admin","Domain Admins" | ForEach{[regex]::Escape($_)}) -join "|"
}
PROCESS{
foreach ($computer in $computername) {
If (Test-Connection -ComputerName $computer -Quiet -Count 1) {
try {
$context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ctype, $computer
$idtype = [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName
$group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($context, $idtype, 'Administrators')
$group.Members | select #{N='Server'; E={$computer}}, #{N='Domain'; E={$_.Context.Name}}, samaccountName, #{N='Flag';E={If(!(($_.Context.Name -eq $Computer -and $_.samaccountname -match "Administrator") -or ($_.context.name -ne $Computer -and $_.samaccountname -match $OKAccounts))){"X"}}}
} catch {
[pscustomobject] #{
Server = $computer
Domain = "Error"
SamAccountName = "Error"
Flag = ''
}
}
} else {
[pscustomobject] #{
Server = $computer
Domain = "Off-Line"
SamAccountName = "Off-Line"
Flag = ''
}
}
} # end foreach
} # end PROCESS
}
$date = [DateTime]::Today.AddDays(-1)
$allComputers = Get-ADComputer -Filter 'PasswordLastSet -ge $date' -properties PasswordLastSet | select -Expand Name
#$allComputers = $env:COMPUTERNAME
get-localgroupmember -computername $allComputers | Out-GridView
That should give you output something like:
Server Domain SamAccountName Flag
------ ------ -------------- ----
TMTsLab TMTsLab Administrator
TMTsLab TMTsTacoTruck.com Domain Admins
TMTsLab TMTsTacoTruck.com SomeAcct1 X
TMTsLab TMTsTacoTruck.com SomeAcct2 X
TMTsLab TMTsTacoTruck.com TMTech X
Probably better yet would be to filter out the accounts you don't want, rather than just not flag them. So change the #{N='Flag';E={If(!(($_.Context.Name -eq $Computer -and $_.samaccountname -match "Administrator") -or ($_.context.name -ne $Computer -and $_.samaccountname -match $OKAccounts))){"X"}}} bit to a Where statement, so that line would be:
$group.Members | select #{N='Server'; E={$computer}}, #{N='Domain'; E={$_.Context.Name}}, samaccountName | Where { !(($_.Server -eq $_.Domain -and $_.samaccountname -match "Administrator") -or ($_.Server -ne $_.Domain -and $_.samaccountname -match $OKAccounts)) }
You'll also want to remove the Flag = '' lines from your Catch and Else scriptblocks as well. Which then the code only returns something like:
Server Domain SamAccountName
------ ------ --------------
TMTsLab TMTsTacoTruck.com SomeAcct1
TMTsLab TMTsTacoTruck.com SomeAcct2
TMTsLab TMTsTacoTruck.com TMTech
Full function code at that point:
function get-localgroupmember {
[CmdletBinding()]
param(
[Parameter(Mandatory=$True,HelpMessage="Enter PC")]
[string[]]$computername
)
BEGIN {
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ctype = [System.DirectoryServices.AccountManagement.ContextType]::Machine
$OKAccounts = ("Workstation Admin","Domain Admins" | ForEach{[regex]::Escape($_)}) -join "|"
}
PROCESS{
foreach ($computer in $computername) {
If (Test-Connection -ComputerName $computer -Quiet -Count 1) {
try {
$context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ctype, $computer
$idtype = [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName
$group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($context, $idtype, 'Administrators')
$group.Members | select #{N='Server'; E={$computer}}, #{N='Domain'; E={$_.Context.Name}}, samaccountName | Where{ !(($_.Server -ieq $_.Domain -and $_.samaccountname -match "Administrator") -or ($_.Server -ne $_.Domain -and $_.samaccountname -match $OKAccounts)) }
} catch {
[pscustomobject] #{
Server = $computer
Domain = "Error"
Account = "Error"
}
}
} else {
[pscustomobject] #{
Server = $computer
Domain = "Off-Line"
Account = "Off-Line"
}
}
} # end foreach
} # end PROCESS
}

Only enabled Administrator accounts

I use The below script to get remote administrator account names, I get all the administrator enabled / disabled. I wanted to just get enabled administrator accounts / get the status of the account whether it is enabled / disabeld. Have tried but failed. Can anyone please help.
$Computers = Get-Content "D:\doc\Work\sCRIPTS\servers.txt"
foreach ($Computer in $Computers) {
$strcomputer = [ADSI]("WinNT://" + $Computer + ",computer")
$Group = $strcomputer.psbase.children.find("Administrators")
$members= $Group.psbase.invoke("Members") | %{$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}
$Computer | Add-Content D:\doc\Work\sCRIPTS\export.xls
ForEach($user in $members){
$user | Add-Content D:\doc\Work\sCRIPTS\export.xls
}
Write-Host ""
}
I think you need to change the end of your script by retrieving each user object member of the Administrators group and verify that it is not Disabled in the userFlags property of the object.
$Computers = Get-Content "D:\doc\Work\sCRIPTS\servers.txt"
foreach ($Computer in $Computers) {
$strcomputer = [ADSI]("WinNT://" + $Computer + ",computer")
$Group = $strcomputer.psbase.children.find("Administrators")
$members= $Group.psbase.invoke("Members") | %{$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}
$Computer | Add-Content D:\doc\Work\sCRIPTS\export.xls
ForEach($user in $members)
{
$userObj = [ADSI]("WinNT://" +$computer+"/"+ $user)
if ($userObj.UserFlags -ne $null)
{
$flags = $userObj.UserFlags[0]
if ($flags -band 512) # 512 = enabled, 2 = disabled
{
$user | Add-Content D:\doc\Work\sCRIPTS\export.xls
}
}
}
}