What needs to exist in a PowerShell script to assure Get-WMIObject works?

Hello Expert,

My goal is to export the desktop computer names from active directory, place the output into a text file and loop the names through the script to determine the administrator accounts on over 700 desktops.  When I tested the script I received an error:

"Get-WmiObject: The RPC is unavailable
     $AllLocalAccounts = Get-WmiObject -Class ...
   + CategoryInfo: Invalid Operation: (:) ... "

What is the script missing the 'AllLocalAccounts' variable? What is the best syntax?
Set-StrictMode -Version Latest
Set-ExecutionPolicy remotesigned -Force
import-module activedirectory

Get-ADComputer -Filter '*' -SearchBase "OU=Computers,DC=company,DC=com" -Properties Name | Select Name |  Out-File C:\Scripts\DesktopAccounts.txt


Param
(
	[Parameter(Position=0,Mandatory=$false)]
	[ValidateNotNullorEmpty()]
	[Alias('cn')][String[]]$ComputerName=(get-content c:\Scripts\DesktopAccounts.txt),
	[Parameter(Position=1,Mandatory=$false)]
	[Alias('un')][String[]]$AccountName,
	[Parameter(Position=2,Mandatory=$false)]
	[Alias('cred')][System.Management.Automation.PsCredential]$Credential
)
	
$Obj = @()

Foreach ($Computer in $ComputerName)
{
	If($Credential)
	{
		$AllLocalAccounts = Get-WmiObject -Class Win32_UserAccount -Namespace "root\cimv2" `
		-Filter "LocalAccount='$True'" -ComputerName $Computer -Credential $Credential -ErrorAction Stop
	}
	else
	{
		$AllLocalAccounts = Get-WmiObject -Class Win32_UserAccount -Namespace "root\cimv2" `
		-Filter "LocalAccount='$True'" -ComputerName $Computer -ErrorAction Stop
	}
	
	Foreach($LocalAccount in $AllLocalAccounts)
	{
		
        Set-ExecutionPolicy remotesigned -Force
        Import-Module activedirectory

        Set-StrictMode -Version Latest

        $Object = New-Object -TypeName PSObject
		
		$Object|Add-Member -MemberType NoteProperty -Name "User Name" -Value $LocalAccount.Name
		$Object|Add-Member -MemberType NoteProperty -Name "Full Name" -Value $LocalAccount.FullName
		$Object|Add-Member -MemberType NoteProperty -Name "Logon Account Caption" -Value $LocalAccount.Caption
      	$Object|Add-Member -MemberType NoteProperty -Name "Disabled" -Value $LocalAccount.Disabled
		$Object|Add-Member -MemberType NoteProperty -Name "Status" -Value $LocalAccount.Status
		$Object|Add-Member -MemberType NoteProperty -Name "LockOut" -Value $LocalAccount.LockOut
		$Object|Add-Member -MemberType NoteProperty -Name "Password Changeable" -Value $LocalAccount.PasswordChangeable
		$Object|Add-Member -MemberType NoteProperty -Name "Password Expires" -Value $LocalAccount.PasswordExpires
		$Object|Add-Member -MemberType NoteProperty -Name "Password Required" -Value $LocalAccount.PasswordRequired
		$Object|Add-Member -MemberType NoteProperty -Name "Domain" -Value $LocalAccount.Domain
		$Object|Add-Member -MemberType NoteProperty -Name "Description" -Value $LocalAccount.Description
		
		$Obj+=$Object
	}
	
	If($AccountName)
	{
		Foreach($Account in $AccountName)
		{
		    $Obj| Where-Object{$psitem.Name -like "$Account"} 
		}
	}
	else
	{
		    $Obj | Export-csv c:\Scripts\DesktopAccounts.csv
	}
}

Open in new window

CuriousMAUserAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
The issue is that you do not check for reachability of the remote machines. Get-WMIObject times out and throws that error at you.
0
Will SzymkowskiSenior Solution ArchitectCommented:
Get-WmiObject: The RPC is unavailable
WMI uses the RPC service to get the information you are querying. You can receive the above message for the following reasons...
- computer is not pingable
- computer is powered off
- firewall on computer
- RPC service is stopped/disabled.

Will.
0
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
I've changed that part, inserting a ping and doing nothing if no success.
But note that in your line 68 you will write to a single CSV file, and do that in a loop - this will always replace the file, and not append info!
Set-StrictMode -Version Latest
Set-ExecutionPolicy remotesigned -Force
import-module activedirectory

Get-ADComputer -Filter '*' -SearchBase "OU=Computers,DC=company,DC=com" -Properties Name | Select Name |  Out-File C:\Scripts\DesktopAccounts.txt


Param
(
  [Parameter(Position=0,Mandatory=$false)]
  [ValidateNotNullorEmpty()]
  [Alias('cn')][String[]]$ComputerName=(get-content c:\Scripts\DesktopAccounts.txt),
  [Parameter(Position=1,Mandatory=$false)]
  [Alias('un')][String[]]$AccountName,
  [Parameter(Position=2,Mandatory=$false)]
  [Alias('cred')][System.Management.Automation.PsCredential]$Credential
)
  
$Obj = @()

Foreach ($Computer in $ComputerName)
{
  if (Test-Connection $Computer -Count 1 -TimeToLive 5 -Quiet)
  {
    If($Credential)
    {
      $AllLocalAccounts = Get-WmiObject -Class Win32_UserAccount -Namespace "root\cimv2" `
      -Filter "LocalAccount='$True'" -ComputerName $Computer -Credential $Credential -ErrorAction Stop
    }
    else
    {
      $AllLocalAccounts = Get-WmiObject -Class Win32_UserAccount -Namespace "root\cimv2" `
      -Filter "LocalAccount='$True'" -ComputerName $Computer -ErrorAction Stop
    }
    
    Foreach($LocalAccount in $AllLocalAccounts)
    {
      
          Set-ExecutionPolicy remotesigned -Force
          Import-Module activedirectory

          Set-StrictMode -Version Latest

          $Object = New-Object -TypeName PSObject
      
      $Object|Add-Member -MemberType NoteProperty -Name "User Name" -Value $LocalAccount.Name
      $Object|Add-Member -MemberType NoteProperty -Name "Full Name" -Value $LocalAccount.FullName
      $Object|Add-Member -MemberType NoteProperty -Name "Logon Account Caption" -Value $LocalAccount.Caption
          $Object|Add-Member -MemberType NoteProperty -Name "Disabled" -Value $LocalAccount.Disabled
      $Object|Add-Member -MemberType NoteProperty -Name "Status" -Value $LocalAccount.Status
      $Object|Add-Member -MemberType NoteProperty -Name "LockOut" -Value $LocalAccount.LockOut
      $Object|Add-Member -MemberType NoteProperty -Name "Password Changeable" -Value $LocalAccount.PasswordChangeable
      $Object|Add-Member -MemberType NoteProperty -Name "Password Expires" -Value $LocalAccount.PasswordExpires
      $Object|Add-Member -MemberType NoteProperty -Name "Password Required" -Value $LocalAccount.PasswordRequired
      $Object|Add-Member -MemberType NoteProperty -Name "Domain" -Value $LocalAccount.Domain
      $Object|Add-Member -MemberType NoteProperty -Name "Description" -Value $LocalAccount.Description
      
      $Obj+=$Object
    }
    
    If($AccountName)
    {
      Foreach($Account in $AccountName)
      {
          $Obj| Where-Object{$psitem.Name -like "$Account"} 
      }
    }
    else
    {
          $Obj | Export-csv c:\Scripts\DesktopAccounts.csv
    }
  }
}

Open in new window

0
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

Will SzymkowskiSenior Solution ArchitectCommented:
Personally all I would do is use -ErrorAction SilentContinue or Ignore.

Will.
0
CuriousMAUserAuthor Commented:
Hi,

For some reason the script still doesn't work. Are the parameters right?
Error message - Test-Connection: Cannot validate argument for parameter 'ComputerName' , The argument is null or empty ...

Within the DesktopAccounts.txt file there is only one pingable computer name.

Thank you.
*********************************
Set-StrictMode -Version Latest
Set-ExecutionPolicy remotesigned -Force
import-module activedirectory

Get-ADComputer -Filter '*' -SearchBase "OU=Computers,DC=company,DC=com" -Properties Name | Select Name |  Out-File C:\Scripts\DesktopAccounts.txt

Param
(
  [Parameter(Position=0,Mandatory=$false)]
  [ValidateNotNullorEmpty()]
  [Alias('cn')][String[]]$ComputerName=(Get-Content -path c:\Scripts\DesktopAccounts.txt),
  [Parameter(Position=1,Mandatory=$false)]
  [Alias('un')][String[]]$AccountName,
  [Parameter(Position=2,Mandatory=$false)]
  [Alias('cred')][System.Management.Automation.PsCredential]$Credential
)      

$Obj = @()

Foreach($Computer in $ComputerName)
{
  if (Test-Connection $Computer -Count 1 -TimeToLive 5 -Quiet)
   {
      If($Credential)
      {
            $AllLocalAccounts = Get-WmiObject -Class Win32_UserAccount -Namespace "root\cimv2" `
            -Filter "LocalAccount='$True'" -ComputerName $Computer -Credential $Credential -ErrorAction Stop
      }
      else
      {
            $AllLocalAccounts = Get-WmiObject -Class Win32_UserAccount -Namespace "root\cimv2" `
            -Filter "LocalAccount='$True'" -ComputerName $Computer -ErrorAction Stop
      }
      
      Foreach($LocalAccount in $AllLocalAccounts)
      {
            
        Set-ExecutionPolicy remotesigned -Force
        Import-Module activedirectory

        Set-StrictMode -Version Latest

        $Object = New-Object -TypeName PSObject
            
            $Object|Add-Member -MemberType NoteProperty -Name "User Name" -Value $LocalAccount.Name
            $Object|Add-Member -MemberType NoteProperty -Name "Full Name" -Value $LocalAccount.FullName
            $Object|Add-Member -MemberType NoteProperty -Name "Logon Account Caption" -Value $LocalAccount.Caption
            $Object|Add-Member -MemberType NoteProperty -Name "Disabled" -Value $LocalAccount.Disabled
            $Object|Add-Member -MemberType NoteProperty -Name "Status" -Value $LocalAccount.Status
            $Object|Add-Member -MemberType NoteProperty -Name "LockOut" -Value $LocalAccount.LockOut
            $Object|Add-Member -MemberType NoteProperty -Name "Password Changeable" -Value $LocalAccount.PasswordChangeable
            $Object|Add-Member -MemberType NoteProperty -Name "Password Expires" -Value $LocalAccount.PasswordExpires
            $Object|Add-Member -MemberType NoteProperty -Name "Password Required" -Value $LocalAccount.PasswordRequired
            $Object|Add-Member -MemberType NoteProperty -Name "Domain" -Value $LocalAccount.Domain
            $Object|Add-Member -MemberType NoteProperty -Name "Description" -Value $LocalAccount.Description
            
            $Obj+=$Object
      }
      
      If($AccountName)
      {
            Foreach($Account in $AccountName)
            {
                $Obj| Where-Object{$psitem.Name -like "$Account"}
            }
      }
      else
      {
                $Obj | Export-csv c:\Scripts\SleepMedDesktopGroupMembers.csv -Append -NoTypeInformation
      }
  }
}
0
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
You have empty lines in your file for sure, and that is because you create it the wrong way. You should use this:
Get-ADComputer -Filter '*' -SearchBase "OU=Computers,DC=company,DC=com" -Properties Name | Select -Expand Name |  Out-File C:\Scripts\DesktopAccounts.txt

Open in new window

otherwise the property name ("Name"), additional spacing and some equal signs will appear in the file.

And the code is really bad style, mixing writing into files and into the pipeline, having superfluous code, running a command before PARAM, using cumbersome commands, using fixed file names, etc. pp.
Do you really need the different ways the "command" can be called, according to PARAM definition? If not, the script could be simplified much.
0
CuriousMAUserAuthor Commented:
Hi QLemo,

Would you please create the simplified version so I may compare?

Thank you kindly,
CuriousMAUser
0
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
Set-StrictMode -Version Latest
Set-ExecutionPolicy remotesigned -Force
import-module activedirectory

Get-ADComputer -Filter '*' -SearchBase "OU=Computers,DC=company,DC=com" -Properties Name | % {
  $PC = $_.Name

  if (Tst-Connection $PC -Count 1 -TimeToLive 5 -Quiet)
  {
    Get-WmiObject Win32_UserAccount -ComputerName $PC -Filter "LocalAccount='True' | % {
      New-Object PsObject -Property @{
                 "User Name"             = $_.Name
                 "Full Name"             = $_.FullName
                 "Logon Account Caption" = $_.Caption
                 "Disabled"              = $_.Disabled
                 "Status"                = $_.Status
                 "LockOut"               = $_.LockOut
                 "Password Changeable"   = $_.PasswordChangeable
                 "Password Expires"      = $_.PasswordExpires
                 "Password Required"     = $_.PasswordRequired
                 "Domain"                = $_.Domain
                 "Description"           = $_.Description
      }
   }
} | Export-csv c:\Scripts\SleepMedDesktopGroupMembers.csv -NoTypeInformation

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
CuriousMAUserAuthor Commented:
Thank you! I'm still troubleshooting.
0
CuriousMAUserAuthor Commented:
Hi QLemo,

With the script below I'm trying to loop through over 700 computer names and extract their user account details to determine how many 'Administrators' have local access. This script loops once. Does the script need to use ForEach logic?

Set-StrictMode -Version Latest
Set-ExecutionPolicy remotesigned -Force
import-module activedirectory

Get-ADComputer -Filter '*' -SearchBase "OU=Computers - SleepMed,DC=sleepmed,DC=md" -Properties Name | % {
  $PC = $_.Name}

  if (Test-Connection $PC -Count 1 -TimeToLive 5 -Quiet)
  {
    Get-WmiObject Win32_UserAccount -ComputerName $PC -Filter "LocalAccount='True'" | % {
      New-Object PsObject -Property @{
                 "User Name"             = $_.Name
                 "Full Name"             = $_.FullName
                 "Logon Account Caption" = $_.Caption
                 "Disabled"              = $_.Disabled
                 "Status"                = $_.Status
                 "LockOut"               = $_.LockOut
                 "Password Changeable"   = $_.PasswordChangeable
                 "Password Expires"      = $_.PasswordExpires
                 "Password Required"     = $_.PasswordRequired
                 "Domain"                = $_.Domain
                 "Description"           = $_.Description
      } | Export-csv -path c:\Scripts\DesktopGroupMembers.csv -NoTypeInformation
    }
}
0
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
No, the loop is already there. Everything found by the Get-ADComputer will get process.
0
CuriousMAUserAuthor Commented:
Excellent. Thank you so much.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.