[Solved]new to powershell - some scripting help for beginners

Hi guys,
my Name is Lev,
first off all i want to thank you that you’ve opened this kind of web site.

i’ve seen all the series of first part of powershell on MVA, to day i’ve started to watch the second one which “Advanced Tools & Scripting with PowerShell 3.0 Jump Start”

i’m in powershell almost 2 weeks now and i can tell you that as an experienced system administrator (over 10+ of experience), i don’t understand how the hell i’ve managedto get to 2018 without the knowledge of the use of powershell ! (shame on me !)

so now i’m starting to play with powershell and i’ve managed to do some stuff and i’m learning very fast, but still need some guidance (don’t want the answer… it’s not fun :slight_smile: )

for now, i’m trying something simple as getting test-connection to all the pc’s in my computers ou

here is the script:

$pc=Get-ADComputer -Filter * -SearchBase "ou=computers,ou=blah,ou=blah,dc=blah,dc=local"

ForEach ($PSItem in $pc) {
  write-host "now testing connection to $pc"
  Test-Connection -ComputerName $pc 
}

 

when i run the script, i’m getting this error

Test-Connection : Testing connection to computer 'CN=LEVL-01,OU=blah,OU=blah,OU=blah,DC=blah,DC=local' failed: No such host is known
At line:7 char:3
+   Test-Connection -ComputerName $pc
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (CN=LEVL-01,OU=C...C=blah,DC=local:String) [Test-Connection], PingException
    + FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand
 

the problem is that if i run test-connection only for one computer it’s working ok (levl-01 is my localhost, the one that i’m writing this message from… so it’s alive :slight_smile: )

thanks alot for your help !

*notes: i didn’t use “-quite” for a reason, i want to see that it working.

does $pc.name give you the individual names of each PC?

I’d be looking at that side send $PC | GM to see the properties and then use the property in the loop

Try it this way…

Get-ADComputer -Filter * -SearchBase 'OU=Machines,OU=IT,DC=local,DC=network,DC=contoso,DC=com' | 
ForEach {
    If (Test-Connection -ComputerName $_.Name -Count 1 -Quiet) 
    {"$($_.Name) is up"} 
    Else 
    {"$($_.Name) is down"}
}

yes it is

Hi Postanote,

thanks alot for your help,

it’s my mistake that i writed the “write-host” command did not mean to use it, i just wanted to see that i’m getting the things that i’ve learned correct and that the script will run and do “test-connection” on each pc in the OU

thanks alot for your help, i have some quastions:

  1. why did you pipe it?
  2. why did you use If?

First of all, you’re not even using $PSItem in the loop. You’d see that $PSItem.tostring() results in the OU, and that’s what test-connection is trying to use. $PSItem.name is what you want. Although $pc.name for the whole list would work with test-connection in this case, and you don’t even need the foreach loop. Sometimes a parameter can be a list, and sometimes it can’t. Sometimes you can get lucky and pipe one command to another without any tweaking, but not in this case.

$pc=Get-ADComputer -Filter * -SearchBase "ou=computers,ou=blah,ou=blah,dc=blah,dc=local"

ForEach ($PSItem in $pc) {
  write-host "now testing connection to " + $PSItem.name
  Test-Connection -ComputerName $PSItem.name 
}
$pc=Get-ADComputer -Filter * -SearchBase "ou=computers,ou=blah,ou=blah,dc=blah,dc=local"

write-host "now testing connection to " + $pc.name
Test-Connection -ComputerName $pc.name

Hi Lev

What I would suggest to you to try is run the first line of code on its own, then type in $pc and take a look at what is stored there.

Next type in get-adcomputer and press enter

You will see a prompt like filter:

Type in !? for Help and take a look at the help that will be displayed.

So hopefully going by that you will be able to know what to filter on the first line to have just the computer names stored in the variable pc

Then for line 3, I find sometimes to read your code out loud it makes sense than just reading it.

On MVA there is a video called Using Powershell for Active Directory which in one chapter on querying AD Data, they talk about filtering which should point you in the right direction.

Hope that helps and good luck!

thanks alot for your help !!

i’ll try that and update

update:

i’ve change abit the code, so now it looks like that:

$pc=Get-ADComputer -Filter * -SearchBase "ou=computers,ou=blah,ou=blah,dc=blah,dc=local" |Select-Object name 
|ForEach-Object {Test-Connection $_.name}

now when i check what is in the $pc i get the correct resolve of the variable, which is the property “name”

it shows all the computers in the relevant ou.

but still when i run the “test-connection” i get

Test-Connection : Testing connection to computer 'levl-01' failed: No such host is known
At line:1 char:128
+ ... orEach-Object {Test-Connection $_.name}
+                    ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (levl-01:String) [Test-Connection], PingException
    + FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand

when i type !? in the prompt, i get the help alright and i’ve read about the “-filter” parameter but probably because absence of knowledge in powershell i don’t understand what i should do

Hello,

Here is some lazy stuff in, like using * too much, but in small environment and in testing it is ok.

To achieve your goal I would do it somewhat like this:

$ou = 'OU=Domain Controllers,DC=blah,DC=com'

$pcs =Get-ADComputer -Filter * -SearchBase $ou 

foreach ($pc in $pcs.name) {

 write-output "$pc ping $(Test-Connection $pc -Count 1 -quiet)"

 }

But actually, I would like to get some more information (and still keep the script in readable form).

$ou = 'OU=Domain Controllers,DC=blah,DC=com'

$pcs = Get-ADComputer -Filter * -SearchBase $ou -properties *

foreach ($pc in $pcs) {

  $pingTest = Test-Connection $pc.name -Count 1

 [PSCustomObject]@{
    'Computername'    = $pc.name 
    'ResponseTime'    = $pingTest.ResponseTime
    'IPv4'            = $pingTest.IPV4Address
    'OperatingSystem' = $pc.OperatingSystem
    }
 }

Or to go with a oneliner

Get-ADComputer -Filter * -SearchBase 'OU=Domain Controllers,DC=blah,DC=com' -properties * | select name, operatingsystem, @{N='PingTest';E={$(Test-Connection $_.name -Count 1 -Quiet)}}

Fixed the oneliner from $pc.name to $_.name. copypaste mistake from me

I think you want $_.name instead of $pc.name in the one-liner.

Here’s another way to pipe it together, since test-connection wants a computername property piped in:

Get-ADComputer -Filter * -SearchBase "ou=computers,ou=blah,ou=blah,dc=blah,dc=local" | 
  select @{n='computername';e={$_.name}} | 
  test-connection -count 1

Source        Destination     IPV4Address      IPV6Address                           Bytes    Time(ms)
------        -----------     -----------      -----------                           -----    --------
BOGUS         BOGUS           198.6.1.1                                              32       0

thanks! :slight_smile:

Hi Aapeli Hietikko,
thanks alot for your help,

i’m looking in to your first code (in the second code you have the “@” sign, and i still didn’t figure out what is this thing do, same about the “PSCustomObject”)

$ou = 'OU=Domain Controllers,DC=blah,DC=com'

$pcs =Get-ADComputer -Filter * -SearchBase $ou 

foreach ($pc in $pcs.name) {

 write-output "$pc ping $(Test-Connection $pc -Count 1 -quiet)"

 }

this is my original code that i’ve posted

$pc=Get-ADComputer -Filter * -SearchBase "ou=computers,ou=blah,ou=blah,dc=blah,dc=local"

ForEach ($PSItem in $pc) {
  write-host "now testing connection to $pc"
  Test-Connection -ComputerName $pc 
}

and it looks almost the same (probably i miss something).

beside the two different variables that you’ve signed

first the $ou

and second the $pc

i asignd only one variable (in the original post)

can you explain why you did it that way please?

Hi,

Look in to the foreach loops. First is mine, second is yours. Try to think that as row in excel spreadsheet. You filled the excel by computer objects and then in the foreach loop you go through it row by row.

In my case row is $pc and in your case it is $psitem. Your mistake was to call the $pc (spreadsheet) within the loop, where you should have used the $psitem (row)

foreach ($pc in $pcs.name)

ForEach ($PSItem in $pc)

finally you can close the post !!!

it’s 1:35 am local time and i can say that I’ve died out how the loop is working !!!

i just did another script and it worked like a magic !!

i had a problem to understand which variable in looping !!!

now i do !!

when i run “foreach”, i’am getting the out put for the first variable and not the one that coming after the “in”

that’s why in your scrip $pc was at the loop and in the “write-host”

example that will work:

$ou=Get-ADUser -filter * -SearchBase "OU=Users,OU=blah,OU=blah,DC=blah,DC=local"

foreach ($user in $ou) {

Write-Host "$user is the best"

}

example that won’t work:

$ou=Get-ADUser -filter * -SearchBase "OU=Users,OU=blah,OU=blah,DC=blah,DC=local"

foreach ($user in $ou) {

Write-Host "$ou is the best"

}

Apologies I did not have follow up replies turned on.

The reason that bit levl-01 failed was because in your test-connection you referenced $_.name when you did not need to.

Your first line of code filtered all of the computers by name contained in $pc.

Basically you are running a filter where it was not needed. :slight_smile:

Now if you get the same error, most likely that computer is offline.