none
Test-path from csv issue RRS feed

  • Question

  • Hello,

    I'm trying to make a script that allows me to check if a file is available on remote computers.

    To do so, I use a csv file that contains the pcs I want to check, also, to have a correct results, I add a test-connection to the script in case the pc isn't on the network.

    My file have 2 columns, "nom" for PCs name and "user" for the user profil I want to check into.

    Unfortunatly, it does not work as I'd like to.

    $results = @()
    import-csv "C:\Report\test_full.csv" | foreach-object {
    	$pc = $_.nom
    	$user = $_.user
    	$ping = Test-Connection -BufferSize 32 -Count 1 -ComputerName $pc -Quiet
    	if ($Count -eq $true)
    	{
    		$ping = "Online"
    	} 
    	Else 
    	{
            	$ping = "Offline"
    	}	
    	$path = Test-Path "\\$pc\c$\User\$user\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\looking_file.exe"
    	If ($path -eq $true) 
    	{
            $Output = "True"
        }
        	Else 
    	{    
            $Output = "False"
        }
    $details = @{
    	Computer_Name	= $pc
    	Username		= $user
    	ping			= $ping
    	Output			= $Output 
        }
        $results += New-Object PSObject -Property $details  
    }
    
    $results | select-object -property Computer_Name, username, ping, Output | Export-csv c:\results.csv -NoTypeInformation

    In this one, the export is correctly done, but the results for "ping" and "Output" are all Offline and False, despite the PCs being on the network and have the file.

    $results = @()
    Import-Csv C:\Report\test_full.csv | Foreach-object {
    	$pc = $_.nom
    	$user = $_.user
    	$conex = Test-Connection -BufferSize 32 -Count 1 -ComputerName $pc -Quiet
    	$path = Test-Path "\\$pc\c$\users\$user\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\Looking_file.exe"}
    	
    	$details = @{
    	pc =  $pc
    	Username= $user
    	ping= $conex
    	Output= $Path
    	}
    $results += New-Object PSObject -Property $details
    $results | Export-csv c:\results.csv -NoTypeInformation

    As for this one, the awaited result is correct but, it exports the result of the last row of the imported CSV "test is made on a 4 row file"

    If someone have an idea of what's missing of where I did wrong would be really helpfull…

    Thank you

    Nad

    Wednesday, January 23, 2019 3:31 PM

Answers

  • When building code as a new user you need to start simple and test each concept.

    PS is about objects, object inspection and object generation.

    Step #1 -  define simple  loop

    Import-Csv "C:\Report\test_full.csv" |
        foreach-object {
            Test-Connection $_.nom -Quiet
        }

    Step #2 - Generate objects

    Import-Csv "C:\Report\test_full.csv" |
        foreach-object {
            [pscustomobject]@{
                Nom = $_.nom
                IsOnline = Test-Connection $_.nom -Quiet
            }
        }

    Step #3 - Add remaining properties

    $pathTemplate = '\\{0}\c$\User\{1}\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\looking_file.exe'
    Import-Csv "C:\Report\test_full.csv" |
        foreach-object {
            [pscustomobject]@{
                ComputerName = $_.nom
                IsOnline = Test-Connection $_.nom -Quiet
                PathExists = Test-Path ($pathTemplate -f $_.Nom, $_.User)
            }
        }

    Now you have a complete object factory with the desired object properties.


    \_(ツ)_/

    Wednesday, January 23, 2019 3:56 PM

All replies

  • You have to build the objects inside the loop.

    Start here to learn how to use loops in PowerShell: https://mva.microsoft.com/en-us/training-courses/getting-started-with-microsoft-powershell-8276?l=r54IrOWy_2304984382


    \_(ツ)_/

    Wednesday, January 23, 2019 3:44 PM
  • In your first code snippet you use a variable you never defined ($count)!  ;-)

    You could start with something like this:

    Import-Csv "C:\Report\test_full.csv" | 
    foreach-object {
        $Result = [PSCustomObject]@{
            ComputerName = $_.nom
            UserName = $_.user
        }
        if (Test-Connection -Count 1 -ComputerName $pc -Quiet){
            $Result.Status = 'connected'
            $Result.TestPath = Test-Path "\\$($_.nom)\c$\User\$($_.user)\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\looking_file.exe"
        } 
        Else {
            $Result.Status = 'disconnected'
            $Result.TestPath = 'n/a'
        }
        $Result	
    }

    ... untested ... and as always: there's a lot of room for improvement ... ;-


    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''


    • Edited by BOfH-666 Wednesday, January 23, 2019 3:46 PM
    Wednesday, January 23, 2019 3:45 PM
  • When building code as a new user you need to start simple and test each concept.

    PS is about objects, object inspection and object generation.

    Step #1 -  define simple  loop

    Import-Csv "C:\Report\test_full.csv" |
        foreach-object {
            Test-Connection $_.nom -Quiet
        }

    Step #2 - Generate objects

    Import-Csv "C:\Report\test_full.csv" |
        foreach-object {
            [pscustomobject]@{
                Nom = $_.nom
                IsOnline = Test-Connection $_.nom -Quiet
            }
        }

    Step #3 - Add remaining properties

    $pathTemplate = '\\{0}\c$\User\{1}\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\looking_file.exe'
    Import-Csv "C:\Report\test_full.csv" |
        foreach-object {
            [pscustomobject]@{
                ComputerName = $_.nom
                IsOnline = Test-Connection $_.nom -Quiet
                PathExists = Test-Path ($pathTemplate -f $_.Nom, $_.User)
            }
        }

    Now you have a complete object factory with the desired object properties.


    \_(ツ)_/

    Wednesday, January 23, 2019 3:56 PM
  • Note that there is no guarantee that a user profile is the users name.  The system can change this during major updates by adding an extension.  In that case the path will be $false.

    We can add diagnostics very easily in the object to detect this.


    \_(ツ)_/

    Wednesday, January 23, 2019 4:10 PM
  • Ping is not natively enabled in Windows anymore, aside from what JRV is saying, I would check to see if IGMP is enabled on your local firewall settings OR make sure it's enabled via GPO.  That's the easiest thing to check...but JRV is probably right. 

    Please remember to click "Mark as Answer" on the post that helps you, and to click "Unmark as Answer" if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.

    Wednesday, January 23, 2019 6:10 PM
  • Ping is not natively enabled in Windows anymore, aside from what JRV is saying, I would check to see if IGMP is enabled on your local firewall settings OR make sure it's enabled via GPO.  That's the easiest thing to check...but JRV is probably right. 

    Please remember to click "Mark as Answer" on the post that helps you, and to click "Unmark as Answer" if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.

    Which has nothing to do with the original question.

    "Ping" is available on all versions of Windows and likely always will be because it is an industry standard.

    By default all outbound IGMP ports are enabled on almost any firewall.  Inbound IGMP may be blocked but that does not effect ping.

    Both ping and Test-Connection use the same IGMP API calls.

    If the firewall was blocking the Test-Connection CmdLet would show that except when "-Quiet" is used.

    All of the issues are due to bad programming and a lack of understanding how the CmdLets work and are intended to be used.

    'Ping" is never being used in the code.

    It is a mystery as to why you would think that "ping" is not enabled. 


    \_(ツ)_/

    Wednesday, January 23, 2019 6:18 PM
  • I"m not gonna fight with you, but what I did say is correct.  I also noted that you were probably correct and my response was probably the wrong direction, but easiest to check.


    Please remember to click "Mark as Answer" on the post that helps you, and to click "Unmark as Answer" if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.

    Wednesday, January 23, 2019 6:39 PM
  • I"m not gonna fight with you, but what I did say is correct.  I also noted that you were probably correct and my response was probably the wrong direction, but easiest to check.


    Please remember to click "Mark as Answer" on the post that helps you, and to click "Unmark as Answer" if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.

    But it is not correct. "ping" exists and the question was not about "ping"  it was about creating an output that was complete.

    Read the original post very carefully.

    I am not criticizing you I am just noting that you didn't understand the question and you have some misinformation about how IGMP is blocked.  It is blocked on inbound requests but not outbound.  The results of a blocked request is different from blocked outbound request.  The ping API is never unavailable or blocked.  Part of its usefulness is to test where a connection might be blocked.

    Test-NetConnection is even more useful for this.

    The main issue is the code as it is mostly wrong for its intention.

    This version returns the full status:

    $pathTemplate = '\\{0}\c$\User\{1}\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\looking_file.exe'
    Import-Csv "C:\Report\test_full.csv" |
        foreach-object {
            [pscustomobject]@{
                ComputerName = $_.nom
                PingStatus = (Test-NetConnection $_.nom).PingReplyDetails.Status
                PathExists = Test-Path ($pathTemplate -f $_.Nom, $_.User)
            }
        }
    


    \_(ツ)_/

    Wednesday, January 23, 2019 7:43 PM
  • Thank you a lot for this enlightment, jrv's answer was the more clear one.

    BofH's one is a bit challenging but actually helped me understand what was my biguest mistake "***$(variable)****"

    jrv, in your code, I'm suposing that {0} and {1} are the placement of my properties in the file wich will be used by the variable $_.Nom, $_.User, right?

    I haven't given much thought about object untill now, but I think they're a big deal breaker when trying to do many task .

    Thanks for your helps folks :)

    Nad

    Thursday, January 24, 2019 10:00 AM
  • I haven't given much thought about object untill now, but I think they're a big deal breaker when trying to do many task .

    PowerShell is all about objects. Everything in PowerShell is an Object.

    String, number are objects:

    PS D:\scripts> 'this is a string'.GetType().BaseType
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     Object
    
    
    PS D:\scripts> (888).GetType().BaseType
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     ValueType                                System.Object
    

    You cannot use PowerShell without learning objects.

    https://en.wikipedia.org/wiki/Object-oriented_programming


    \_(ツ)_/

    Thursday, January 24, 2019 8:14 PM
  • jrv, in your code, I'm suposing that {0} and {1} are the placement of my properties in the file wich will be used by the variable $_.Nom, $_.User, right?

    Look up the operator in the help:

    help operator

    You cannot use PowerShell without learning "operators".  "Operators" are a fundamental feature of the PowerShell scripting system.


    \_(ツ)_/

    Thursday, January 24, 2019 8:16 PM