Author Posts

October 21, 2013 at 7:31 am

I have this little script which will provide me username and computer name

$computerlist = Get-ADComputer -Filter * | select -expand name
icm -ComputerName $computerlist {Get-WmiObject win32_computersystem -ComputerName 'localhost' |select username, name | ft
}

My result set looks like this

username : domain\user Name : TABLET-PC

Is there a way that I can include an exception to ignore computers that are off so I dont get a bloody mess on my screen , lol.

October 21, 2013 at 7:35 am

I suggest you try to use a for each loop to ping each machine prior to pulling the information.

That way, if the machine doesn't respond to the ping, you can skip it.

October 21, 2013 at 8:00 am

Depends on how "correct" you want to be with how you handle it. Ideally, you'd handle all of the errors, and only suppress the ones that involve a computer that can't be contacted, but still display any other errors that might be of interest to you. I don't have the exception type handy, but the code can look something like this:

$computerlist = Get-ADComputer -Filter * | select -expand name

# Use -ErrorAction SilentlyContinue and -ErrorVariable to temporarily suppress all non-terminating errors, and store them for later review in the $err collection.
Invoke-Command -ErrorAction SilentlyContinue -ErrorVariable err -ComputerName $computerlist { Get-WmiObject win32_computersystem -ComputerName 'localhost' | select username, name | ft }

# Loop to output only the errors that you want to see.
foreach ($record in $err)
{
    if ($record.Exception -isnot [SomeExceptionTypeThatYouWantToIgnore])
    {
        Write-Error -ErrorRecord $record
    }
}

Then there's the "sweep them all under the rug" approach... it's not really a good practice, but if you really don't care about the errors and just want to display the successful output, you can just add "-ErrorAction SilentlyContinue" to your call to Invoke-Command, and not bother to look at the errors later

$computerlist = Get-ADComputer -Filter * | select -expand name
Invoke-Command -ErrorAction SilentlyContinue -ComputerName $computerlist { Get-WmiObject win32_computersystem -ComputerName 'localhost' | select username, name | ft }

October 21, 2013 at 8:49 am

thanks for your help all, I like the idea using the for-each cmdlet

I rewrote as foollows, am I in the ball park (i'm a newbie)

$computerlist = Get-ADComputer -Filter * | select -expand name | ForEach-Object {$pingme = Test-Connection -Quiet -count 1}
if ($pingme -eq "true")
{icm {Get-WmiObject win32_computersystem |select username, name | ft }}

else

{Write-Host "computer is offline"}

October 21, 2013 at 8:59 am

You're on the right track, but your braces are in the wrong places. It helps to use a consistent style of indenting and line breaks when writing code, to make it easier to read. I've revised the code a bit. In particular, I moved the call to Format-Table out of the loop, and piped objects to it at the end. You might find that this produces cleaner output; give it a try:

Get-ADComputer -Filter * |
Select-Object -ExpandProperty name |
ForEach-Object {
    $computer = $_

    $pingme = Test-Connection -ComputerName $computer -Quiet -count 1
    
    if ($pingme -eq $true)
    {
        Invoke-Command -ComputerName $computer -ScriptBlock { Get-WmiObject win32_computersystem | Select-Object username, name }
    }
    else
    {
        Write-Host "computer '$computer' is offline"
    }
} |
Format-Table

October 21, 2013 at 11:07 am

dave that is a beatiful looking output 🙂

I have a question regarding the variable you declared " $computer = $_"
is that storing the values from get-adcomputers ?

October 21, 2013 at 11:29 am

Basically, yes. When you use ForEach-Object, the current object is stored in the automatic $_ variable inside the -Process script block. (Normally, as in my example, this is the only script block passed to ForEach-Object, and it's passed by position, not name.)

Because the $_ automatic variable is used by all sorts of things, sometimes you can run into problems with it being "hijacked" by some other code inside the block (such as inside a Catch block, where $_ refers to the error that was caught.) For that reason, I'm in the habit of assigning the contents of $_ to another variable as the first statement in any ForEach-Object block. This way, the object will be stored in the $computer variable, regardless of what may happen with $_ later. It's not always absolutely required, but it's a good habit to have; you'll avoid some irritating bugs this way.