[Solved]need help in combine If inside a Foreach statement

Hi Guys,
I can tell that after a whole month of training my mind and learning to work with Power Shell, it’s my second Script that will contribute to my Organization :slight_smile:

the first one went yesterday for production (not something complex, since I new to scripting) and this is the second one, which is half working (lool).

If i use only the first part of the code it’s working great :

$allpc = Get-ADComputer -Filter * -SearchBase 'ou=blah,OU=blah,OU=blah,DC=blah,DC=local'

ForEach($Pc in $allpc.name) {

 Get-WmiObject -class Win32_Printer -ComputerName $Pc |Select-Object SystemName,name |Format-Table -AutoSize
}

it’s working perfect, showing the result that I want with the columns that i need, the only problem that i have, is that for each computer that the Power Shell can’t connect,

It’s showing me this horrible red errors, so I thought that I need to make Powershell something like “can’t reach the pc” or something like that

if ((Get-WmiObject -Class win32_printer -ComputerName $Pc.name ) -eq $false)

{Write-Host "cant reach to $Pc"}

olso i’ve tried to do the IF like that:

if (Get-WmiObject -Class win32_printer -ComputerName $Pc.name -eq "$False" )

{Write-Host "cant reach to $Pc"}

Thanks alot for your help.

I think you are trying to achieve something that you shouldn’t do yet :slight_smile: keep on reading those in a month of lunches and toolmaking books Don have made. Try - Catch is most likely the thing you are after.

I prefer to take the data to variable so that when you hit format-table it actually does it by the longest values.

$allpc = Get-ADComputer -Filter * -SearchBase 'ou=blah,OU=blah,OU=blah,DC=blah,DC=local'

$output = ForEach($Pc in $allpc.name) {
    
    try {
        Get-WmiObject -class Win32_Printer -ComputerName $Pc -ErrorAction stop | Select-Object SystemName,name 
        }
    Catch {
        
        }

    }
$output | ft
$allpc = Get-ADComputer -Filter * -SearchBase 'ou=blah,OU=blah,OU=blah,DC=blah,DC=local'

ForEach($Pc in $allpc.name) {
    if (Test-Connection -ComputerName $Pc -Count 2 -ErrorAction SilentlyContinue) {
        Get-WmiObject -class Win32_Printer -ComputerName $Pc | Select-Object SystemName,name | Format-Table -AutoSize
    } else {
        Write-Host "Computer '$Pc' is offline or cannot be reached"
    } 
}

Hi Aapeli,
thanks alot for your help :).

I will check “try” and “catch” (never saw this before…)

I do read the books but i’m very impulsive person, so i want to know things as fast as i can :slight_smile:

Sam,
Thanks alot for your help,

let me check your code…

updated: i’ve checked it, and it doing actually what i wanted…

Now i need to check about the the “try” “catch” “ErrorAction” “SilentlyContinue”.

Thanks a lot for your help guys, i have to admit that each time that i get answer here, i realise how “flexible” i can be while using Power Shell.

I have to admit that i didn’t thought to use “test-connection” inside the IF

I know the pain :slight_smile: On a basic scripts you basically need to know only. ForEach, While (do-while), if-else, switch and try-catch and you can do anything. You can even replace switch with if-else, but that’s not pretty.

Aapeli,

i’ve read about the “try-catch” blocks and now i have one more question, i’ve noticed that you set the foreach statement into a variable, so that it will out-put all the content,
my question is, why it not working if i do something like that:

isn’t it supposed to take all the content after doing all the loop?

$allpc = Get-ADComputer -Filter * -SearchBase 'ou=Computers,OU=afula,OU=crow,DC=crow,DC=local'

ForEach($Pc in $allpc.name) {

try { 

    Get-WmiObject -class Win32_Printer -ComputerName $Pc -ErrorAction Continue -ErrorVariable x |Select-Object SystemName,name  
    }

   catch { 

 $allpc |out-file c:\err.txt -Append |Format-Table -AutoSize
 Write-Warning "cant reach to $Pc : $X" }

 }

  

Thanks alot for your help

you are setting $allpc content on row1
for each error you are dumping that content from row1 to c:\err.txt and you try to for each (pipe) that to format-table

again this will mess up your pretty console, so I would actually drop the write-warning row away.

$allpc = Get-ADComputer -Filter * -SearchBase 'ou=Computers,OU=plz,DC=change,DC=this'

ForEach($Pc in $allpc.name) {

try { 

    Get-WmiObject -class Win32_Printer -ComputerName $Pc -ErrorAction Continue -ErrorVariable x |Select-Object SystemName,name  
    
}

   catch { 

 Write-Warning "cant reach to $Pc : $X" 
 Write-output "cant reach to $Pc : $X" | out-file c:\err.txt -Append
 }
 
 }

ForEach($Pc in $allpc.name) {

try { 

    $objs = Get-WmiObject -class Win32_Printer -ComputerName $Pc -ErrorAction stop | Select-Object SystemName,name  

    foreach ($obj in $objs) {
        
        [PSCustomObject]@{
            'SystemName' = $obj.systemName
            'Printer'    = $obj.name
            }
        }
    }

catch { 

            [PSCustomObject]@{
            'SystemName' = $PC
            'Printer'    = 'blah no connection'
            }
    
    }

 }