What am I missing? Script keeps looping

This topic contains 6 replies, has 4 voices, and was last updated by  cm 1 week, 4 days ago.

  • Author
    Posts
  • #81277

    cm
    Participant

    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.

  • #81278

    Don Jones
    Keymaster

    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.

    • #81280

      cm
      Participant

      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).

  • #81283

    Don Jones
    Keymaster

    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."

  • #81286

    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)}}
    } 
    
    • #81308

      cm
      Participant

      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.

  • #81296

    Richard Siddaway
    Moderator

    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

You must be logged in to reply to this topic.