Author Posts

October 4, 2017 at 9:55 pm

import-module Activedirectory
$Servers = $null
$ErrorActionPreference = "SilentlyContinue"

$Servers = Get-ADComputer -Filter 'name -like "*_*"' -SearchBase "OU=,OU=,OU=,OU=,DC=,DC=,DC=,DC=" -SearchScope Subtree -Properties Name | Sort Name

foreach ($objItem in $Servers) {
$Server = $objItem.Name
Write-Host "Checking uptime on servers..."

Get-WmiObject -ComputerName $Servers.name -ClassName win32_operatingsystem | select csname, @{LABEL='LastBootUpTime';EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}}
}

I have no issues with it running.

October 4, 2017 at 9:59 pm

Ah, Hungarian notation. Brings back memories of my youth.

First, the $ErrorActionPreference you're doing is an Incredibly Poor Idea. There's also zero need to make $Servers null at the top. I'd strongly urge deleting those two lines – this isn't VBScript :).

How many objects are in $Servers?

Your main error is that you've lost track of your variables. In Get-WmiObject, you're passing "$Servers.name" as the computer name. That's going to query EVERY SINGLE ONE OF THE SERVERS, and it will do that once for however many objects are in $Servers. So if you have 100 servers, it's going to do it 100×100 times. 10,000 times. It's not looping forever – just give it a few years to finish ;).

You probably meant to just use "$Server" instead, since you've taken the trouble of pulling $objItem.Name into $Server already.

October 4, 2017 at 10:04 pm

Ugh, that really sucks. When I use just $servers, I get that the RPC server unavailable.

When I did $servers.name without ErrorAction, it gave me RPC server unavailable on a few servers, even if I did a test-connection. Back to the drawing board I guess... 'cause it's probably a firewall issue blocking (I'm guessing).

October 4, 2017 at 10:07 pm

Nope, you missed my point – use $server, singular, not $servers. Or, use "-ComputerName $objItem.Name" if you prefer. See where you defined $server to be the same as $objItem.Name?

$servers has many objects. You don't want to use that. You're enumerating it in a ForEach loop.

And RPC will be unavailable for anything running 2012R2 or later by default – MS has moved away from WMI and prefers Get-CimInstance now, which can speak both RPC and WS-MAN. And yeah, it could also be a firewall. But WMI is deprecated and on the way out – CIM rules, now. Test-Connection is a ping – it doesn't test for RPC connectivity or availability.

The proper way to handle that error is described in our free ebook, "The Big Book of PowerShell Error Handling."

October 4, 2017 at 10:50 pm

I think, this is what Don meant:

import-module Activedirectory
$Servers = $null
$ErrorActionPreference = "SilentlyContinue"

$Servers = Get-ADComputer -Filter 'name -like "*_*"' -SearchBase "OU=,OU=,OU=,OU=,DC=,DC=,DC=,DC=" -SearchScope Subtree -Properties Name | Sort Name

#You might wanna take this link out of the ForEach as well
Write-Host "Checking uptime on servers..."

foreach ($objItem in $Servers) {
$Server = $objItem.Name

#Your line:
#Get-WmiObject -ComputerName $Servers.name -ClassName win32_operatingsystem | select csname, @{LABEL='LastBootUpTime';EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}}

#Recommeded line:
Get-CimInstance -ComputerName $Server -ClassName win32_operatingsystem | select csname, @{LABEL='LastBootUpTime';EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}}
} 

October 5, 2017 at 9:43 am

If you use Get-CimInstance the date is automatically converted to human format – don't need the conversion just:

Get-CimInstance -ComputerName $Server -ClassName win32_operatingsystem | select csname, lastbootuptime

October 5, 2017 at 12:43 pm

Ah, with your help and Leandro it worked! I'm going to have to read on Get-CimInstance vs Get-WMIObject and when/where each are applicable. Thanks.