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

This topic contains 14 replies, has 6 voices, and was last updated by  Ben 2 months ago.

  • Author
    Posts
  • #95283

    Lev Leiderman
    Participant

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

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

    thanks alot for your help !

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

  • #95289

    Andy
    Participant

    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

  • #95290

    postanote
    Participant

    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"}
    }
    
    • #95314

      Lev Leiderman
      Participant

      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?

  • #95335

    js
    Participant

    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
    
  • #95344

    Ben
    Participant

    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!

    • #95353

      Lev Leiderman
      Participant

      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

    • #96404

      Ben
      Participant

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

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

  • #95451

    Aapeli Hietikko
    Participant

    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

    • #95457

      js
      Participant

      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
      
      
    • #95463

      Aapeli Hietikko
      Participant

      thanks! 🙂

    • #95465

      Lev Leiderman
      Participant

      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?

    • #95468

      Aapeli Hietikko
      Participant

      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)
      
    • #95490

      Lev Leiderman
      Participant

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

You must be logged in to reply to this topic.