Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x80070 6BA - powershell

I have what should be a simple script that will connect to all the servers in a domain and build a table of all the services running on each server. However, when I try to automate the script to grab all the servers in a foreach loop I get an RPC error. If the $name variable is replaced with the server DNS name everything works as expected. I've checked the firewall and DCOM services on my system (win7) and the servers (2000 - 2008R2) and these are all enabled or disabled appropriately. So, I'm thinking something in the script is broke. I'm still learning powershell, so any tips are appreciated.
Here is the script so far.
$servernames = get-adobject -Filter 'ObjectClass -eq "Computer" ' -Searchbase "OU=Servers,DC=E,DC=BENEFIS,DC=ORG"
foreach ($name in $servernames) {
Get-WMIObject win32_service -computername $name -Property SystemName,Name,StartName,StartMode |
Format-table SystemName, Name, Startname >c:\serverservices.txt }

Each object you get back have a name property so you need to pass its value to the ComputerName parameter. In addition, to get computer object use the Get-ADComputer cmdlet, you also need to specify the Append switch when you export to the file otherwise content will be overwritten and what you'll see finally is the output of the last computer only.
$servernames = Get-ADComputer -SearchBase "OU=Servers,DC=E,DC=BENEFIS,DC=ORG" -Filter *
foreach ($name in $servernames)
{
Get-WMIObject win32_service -computername $name.Name -Property SystemName,Name,StartName,StartMode |
Format-table SystemName, Name, Startname | Out-File c:\serverservices.txt -Append
}

Related

Powershell - Get a List of all Computers with their IP Address and Last Logged On User

i would like to get in Powershell a list of all computers (in my domain) with their IP Address and the last logged on user, the output should be something like this:
ComputerName | IpAddress | LastLoggedOnUser
ABC-123 1.2.3.4 Username
DEF-456 5.6.7.8 Username1
GHI-789 9.0.1.2 Username2
I have tried a lot of scripts but none of these worked so far :(
Thank you in advance!
Edit:
i tried this:
$computers = Get-ADComputer -Filter * | select Name
foreach($computer in $computers)
{
Get-WmiObject -ComputerName "$computer" -Class Win32_ComputerSystem | Select-Object UserName
}
but i get the error "The RPC Server is unavailable"
if i run the command
Get-WmiObject -ComputerName "[Computer Name]" -Class Win32_ComputerSystem | Select-Object UserName
it works, but shows me only one Computer.
You can append the scripts you have found to include the lastLoggedOnUser with the following command, but you would need acccess to the computer to retrieve this information.
Get-WinEvent -Computer (computer name) -FilterHashtable #{Logname='Security';ID=4672} -MaxEvents 1 | select #{N='User';E={$_.Properties[1].Value}}

Why am i receiving RPC server is unavailable error when looping?

I have a Powershell script to find specific servers and their corresponding service accounts. If I modify the script to use a single server and a single service account, the results are what I expect. If I loop thru the servers and accounts, I receive the following error:
#################################################################
# Find Service Account(s) used to start Services on a Server(s) #
#################################################################
$accounts = (Get-Content C:\Users\location\Scripts\Service_Accounts.txt)
Remove-Item -path C:\Users\location\Scripts\ServiceAccountFnd.txt -force -erroraction silentlycontinue
Import-Module ActiveDirectory # Imports the Active Directory PowerShell module #
## Retrieves servers in the domain based on the search criteria ##
$servers=Get-ADComputer -Filter {Name -Like "namehere*"} -property *
## For Each Server, find the services running under the user specified in $account ##
ForEach ($server in $servers) {
Write-Host $server
ForEach ($account in $accounts) {
Write-Host $account
Get-WmiObject Win32_Service -ComputerName $server | Where-Object {$_.StartName -like "*$account*"} | Format-Table -HideTableHeaders -property #{n='ServerName';e={$_.__SERVER}}, StartName, Name -AutoSize | Out-File -FilePath C:\Users\location\Scripts\ServiceAccountFnd.txt -append -Width 150
}
}
Your $server variable does not only contain the hostname, but also all attributes of the AD computer object.
Try to change the ComputerName value to $server.name.
If that doesn't help: Can you confirm, that you used the very same computer in the loop as without the loop, as you described? I'd assume that you try to access another computer, which is not configured as expected.
Besided that, I'd recommend you to use Get-CimInstance rather than Get-WmiObject, as it doesn't use RPC, but WinRM by default. WinRM is more firewall friendly, secure and faster.

Get-WmiObject from AD OU

I have a simple problem that I can't seem to work through. I need to know what servers are still running server 2008/R2.
I know that Win32_OperatingSystem's Name property contains the information that I'm looking for. I would like to be able to run Get-WmiObject against a collection of servers in an OU.
There are two problems that I'm having:
I can't figure out how to redirect the output of Get-ADComputer to something that Get-WmiObject -ComputerName can use. I think Get-ADComputer is outputting objects of type Microsoft.ActiveDirectory.Management.ADComputer, and Get-WmiObject is looking for type System.Management.ManagementObject. Here's what I came up with but it doesn't appear to work.
Get-WmiObject Win32_OperatingSystem -ComputerName (Get-ADComputer -filter * -SearchBase "OU=Member Servers,DC=Company,DC=Com" | select #{L="ComputerName";e={$_."name"}}) -Property name, csname | select csname, name | Format-Table -AutoSize
My temp workaround: I was able to create a CSV that contains the list of server names. I was able to use the CSV to run Get-WmiObject against. However, the OU contains "dead" servers. So when I try to run Get-WmiObject using the CSV-list of servers that came from AD there are connection timeouts and PowerShell waits a period of time to see if the dead server will respond. This really slows down the operation & we are working to clean this up. Until that happens, Is there a way to only pass the server names that pass a Test-Connection to Get-WmiObject?
Get-WmiObject win32_operatingsystem -ComputerName (Get-Content C:\Users\user1\Desktop\Servers.csv) -Property name, csname | select csname, name | Format-Table -AutoSize
Pick the name component first then it will pass it to the next pipeline object (select -object)
Get-WmiObject Win32_OperatingSystem -ComputerName ((Get-ADComputer -filter * -SearchBase "OU=Member Servers,DC=Company,DC=Com").Name)
Note: -ComputerName: accepts a string object so you cannot pass a base type object directly to that.

Powershell ForEach-Object {Start-Job -Scriptblock} not populating variables

Here is my code, it works and creates a job for each computer in the OU but does not populate the $Computer variable in my script block causing this to fail.
I am sure I am missing something small since I have never created jobs before in Powershell but after working on this for an hour or two I have been unable to figure out what I am missing.
#Gets all workstations that need to have software installed, if you don't want to uninstall all of the software from you will need to use a text document and Get-Content
$computers = Get-ADComputer -Filter * -SearchBase "OU=Workstation Test,OU=Workstations,OU=Workstations,DC=CONTOSO,DC=COM" | Select DNSHostName -ExpandProperty DNSHostname
$Computer
#Use Get-WMIObject to find the IdentifyingNumber
$Computers | ForEach-Object {Start-Job -Name "$Uninstall" -ScriptBlock {(Get-WmiObject -Class Win32_product -ComputerName $Computer -Filter {IdentifyingNumber LIKE '{CD95F661-A5C4-44F5-A6AA-ECDD91C2410B}'}).uninstall()}}
Instead of $computer you need to use $_.
$_ represents the current item in the pipeline.
Alternatively you could do:
ForEach ($Computer in $Computers) { Invoke-Command -ComputerName $Computer -ScriptBlock {(Get-WmiObject -Class Win32_product -Filter {IdentifyingNumber LIKE '{CD95F661-A5C4-44F5-A6AA-ECDD91C2410B}'}).uninstall()} }
Here you continue to use $Computer inside the foreach as it now gets populated with each item in the collection.
Also FYI your $computer line above the ForEach-Object is currently unnecessary (it's just outputting an empty variable, unless you've already populated it elsewhere).
Edit: per comments I also noticed that the start-job seemed redundant as -computername was being used on the wmi cmdlet. Invoke-command is preferred as it uses winrm, so I've modified it as such in my code above.

Using Powershell to build a list of computer model numbers in our Domain?

As the title states, I am trying to determine every computer model used in our domain. I am new to the company, and have been placed in charge of producing a new encryption solution for all end point devices. By knowing the computer models in our domain, I will be able to determine which machines have a TPM 1.2 chip, and which ones don't (almost 15k devices). I do not need anything to look pretty, but I'm open for ideas. I more or less want a list (text or csv for sorting purposes) so I can quantify models and research.
Here's what I have so far:
Get-ADComputer -Filter {Name -like 'ML*'} | select -expand name |
ForEach {
If (Test-Connection $_ -count 1 -quiet)
{Get-WmiObject -Class Win32_ComputerSystem -ComputerName $_} Select-Object -Property model | Export-Csv "c:\scripts\Models.csv"}
Else { Add-Content -value $_ c:\scripts\not.responding.txt}
I know there are problems with this. Right now I'm having trouble querying AD and passing the computer name variable only. Because of this, the ping test fails, and everything exports to the failed text file. The failed text file indicates that the variable includes a lot more than just the computer name. If I can pull the variable correctly, I'm not sure if the rest would work, but I think it should. Any help would be greatly appreciated.
$ComputerNames = Get-ADComputer -Filter {Name -like 'ML*'} | select -expand name
foreach ($computername in $ComputerNames){
If (Test-Connection $computername -count 1 -quiet){
Get-WmiObject -Class Win32_ComputerSystem -ComputerName $computername | Select-Object -Property model | Export-Csv "c:\scripts\Models.csv"
}
else{
Add-Content -value $computername c:\scripts\not.responding.txt
}
}
there you go.