locked
Test-path and export-csv RRS feed

  • Question

  • Good morning all,

    I'm triyng to check if a folder exist and append the results into csv file but the csv file is not on the correct format, can you please help, you can find here below my script:

    -ErrorAction SilentlyContinue
    
    $path = "c:\folder"
    
    {if ((Test-Path $path) -eq 1)  {Echo "the $path exist on pc $env:COMPUTERNAME-- with user $env:Username"}
        else {Echo "the $path do not exist on pc $env:COMPUTERNAME-- with user $env:Username"}}export-csv -path -append "C:\temp\results.csv" -notypeinformation}




    • Edited by Salento9 Tuesday, May 27, 2014 8:31 AM
    • Moved by Bill_Stewart Tuesday, July 15, 2014 9:17 PM Abandoned
    Tuesday, May 27, 2014 7:47 AM

All replies

  • Hi Salento,

    you need to pass some actual information to Export-Csv for it to output something. Here's a reworked example:

    $path = "c:\folder"
    $computer = $env:COMPUTERNAME
    $user = $env:USERNAME
    New-Object PSObject -Property @{ Path = $path; Computer = $computer; User = $user; Exists = (Test-Path $path)} | export-csv -path "C:\temp\results.csv" -append -notypeinformation
    

    Explanation:

    $path = "c:\folder"
    $computer = $env:COMPUTERNAME
    $user = $env:USERNAME

    These were declared ahead of time, to make the actual working line more readable.

    New-Object PSObject -Property @{ Path = $path; Computer = $computer; User = $user; Exists = (Test-Path $path)}

    This command creates an object that has 4 properties: Path, Computer, User, Exists (where "Exists" is either true or false on whether the folder exists.

    "|" passes the object to the next command in the pipeline.

    export-csv -path "C:\temp\results.csv" -append -notypeinformation

    Writes the object's properties to the csv file.

    Cheers,
    Fred


    There's no place like 127.0.0.1

    Tuesday, May 27, 2014 8:04 AM
  • thank you very much!!

    the -append do not works, don't undestand.

    We are using PS 2.0 ;o(


    • Edited by Salento9 Tuesday, May 27, 2014 8:23 AM
    Tuesday, May 27, 2014 8:13 AM
  • Hi Salento,

    Well, as the documentation of Export-Csv says on later PS versions, the -append Parameter was added in version 3. So you don't have it in PS2.

    To work around this, you can do the following trick:

    # Prepare storage for results
    $Results = @()
    
    # Gather previous content, if any, otherwise skip this step
    $Csvs = Import-Csv "C:\temp\results.csv"
    Csvs | %{$Results += New-Object PSObject -Property @{ Path = $_.Path; Computer = $_.Computer; User = $_.User; Exists = $_.Exists }}
    
    # Gather new information with whatever code you are using
    # ...
    
    # Export full result
    $Results | Export-Csv -Path "C:\temp\results.csv" -NoTypeInformation

    Cheers,
    Fred


    There's no place like 127.0.0.1

    Tuesday, May 27, 2014 8:48 AM
  • Thanks a lot for your help!!!

    Do you mean like:

    #variable
    $path = "c:\temp"
    $computer = $env:COMPUTERNAME
    $user = $env:USERNAME
    
    # Prepare storage for results
    $Results = @()
    
    # Gather previous content, if any, otherwise skip this step
    $Csvs = Import-Csv "C:\temp\results.csv"
    $Csvs | %{$Results += New-Object PSObject -Property @{ Path = $_.Path; Computer = $_.Computer; User = $_.User; Exists = $_.Exists }}
    
    # Gather new information with whatever code you are using
    # ...
    
    New-Object PSObject -Property @{ Path = $path; Computer = $computer; User = $user; Exist = (Test-Path $path)}
    # Export full result
    $Results | Export-Csv -Path "C:\temp\results.csv" -NoTypeInformation
    In this case the result is empty.


    • Edited by Salento9 Tuesday, May 27, 2014 9:06 AM
    Tuesday, May 27, 2014 8:57 AM
  • Hi Salento,

    if you want to have a script that periodically checks whether a certain folder exists, then yes, this will work, however you made one mistake in piecing things together, so I did a little rewrite:

    # Variables to store default Information
    $path = "c:\temp"
    $computer = $env:COMPUTERNAME
    $user = $env:USERNAME
    $csvPath = "C:\temp\results.csv"
    
    # Prepare storage for results
    $Results = @()
    
    # Gather previous content, if any, otherwise skip this step
    Import-Csv $csvPath | %{ $Results += New-Object PSObject -Property @{ Path = $_.Path; Computer = $_.Computer; User = $_.User; Exists = $_.Exists; Date = $_.Date } }
    
    # Gather new information
    # Add new result
    $Results += New-Object PSObject -Property @{ Path = $path; Computer = $computer; User = $user; Exist = (Test-Path $path); Date = (Get-Date) }
    
    # Export full result
    $Results | Export-Csv -Path $csvPath -NoTypeInformation

    To Note:
    If you want to add elements to a list, you have to use the "+=" Operator, as shown in this line:
    $Results += New-Object PSObject

    Also, I added the time to the list, as if you want to check periodically, you may want to know just when it was there and when it wasn't.

    Cheers,
    Fred


    There's no place like 127.0.0.1

    Tuesday, May 27, 2014 9:13 AM
  • Thanks again Fred it works really good, really appreciate your help.

    last question please:

    i'd like to assure that the script will not block ot hang the pc when the script runs and if any problems exit the script, does the following command is enough?

    -ErrorAction SilentlyContinue

    thanks again

    Salento.


    • Edited by Salento9 Tuesday, May 27, 2014 9:25 AM
    Tuesday, May 27, 2014 9:24 AM
  • Hi Salento,

    "-ErrorAction SilentlyContinue" doesn't do a thing for you. This is not a command, but a parameter you can use with most commands, so that they do not display their errors.

    If there's an error in this script, it will not hang the script, but rather terminate it with no harm done (though it probably will not tell you it crashed either, so you have to check whether it updated the csv file as it should have).

    If you want to read up on handling errors, try this library article.

    Cheers,
    Fred


    There's no place like 127.0.0.1

    Tuesday, May 27, 2014 9:43 AM
  • Fred, thanks!!!

    I'm busy to test the script and the goal of this script is to check if a folder exist and write down on csv file something like TRUE or False but i can't see nothing on csv file, the column "exist" is empty :o(

    Salento.

    Tuesday, May 27, 2014 10:12 AM
  • Hi Salento,

    sorry, my error, I slipped in a minor typo:

    # Wrong
     @{ Path = $path; Computer = $computer; User = $user; Exist = (Test-Path $path); Date = (Get-Date) }
    
    # Correct
    @{ Path = $path; Computer = $computer; User = $user; Exists = (Test-Path $path); Date = (Get-Date) }

    where the script gathers the new information ("exist" instead of "exists").

    Cheers,
    Fred


    There's no place like 127.0.0.1


    • Edited by FWN Tuesday, May 27, 2014 10:22 AM
    Tuesday, May 27, 2014 10:21 AM
  • Fred, can't do better! thank you very much ;o)

    Salento.

    Tuesday, May 27, 2014 10:37 AM
  • Hi Fred,

    I got a new request from my boss and i'll try to explain:

    because this script will be executed via gpo on a few pc's we need to create a file per pc

    it means that same script could be executed severals on the same pc and i only need a file with the last result;

    After that i need another script which get the content of all file and put it in one file.

    this is should be my way of working with 2 different script:

    What you think about?

    in the first script i only modified the csv file which will named with the computer name.

    1)

    # Variables to store default Information
    $path = "c:\dgpe1"
    $computer = $env:COMPUTERNAME
    $user = $env:USERNAME
    $csvPath = "C:\temp\Script\$env:COMPUTERNAME-results.csv"
    
    # Prepare storage for results
    $Results = @()
    
    # Gather previous content, if any, otherwise skip this step
    Import-Csv $csvPath | %{ $Results += New-Object PSObject -Property @{ Path = $_.Path; Computer = $_.Computer; User = $_.User; Exists = $_.Exists; Date = $_.Date } }
    
    # Gather new information
    # Add new result
    $Results += New-Object PSObject -Property @{ Path = $path; Computer = $computer; User = $user; Exists = (Test-Path $path); Date = (Get-Date) }
    
    # Export full result
    $Results | Export-Csv -Path $csvPath -NoTypeInformation

    2)

    $Path : "c:\temp\"
    
    $Files = get-childitem -name "$path"
    
    $varb = foreach ($a in $files) {gc "$path\$a"} | export-csv -path "c:\temp\result.csv"

    The second script will be executed manually when needed.

    Thanks again for your help.


    • Edited by Salento9 Tuesday, May 27, 2014 12:49 PM
    Tuesday, May 27, 2014 12:13 PM
  • Hi Salento,

    first of all, environmental variables are great! If you want users to write to their profiles, there actually is one that does that (same as for Computername):

    # Old
    $csvPath = "C:\Users\gindino\Documents\Script\$env:COMPUTERNAME-results.csv"
    
    # New
    $csvPath = "$env:USERPROFILE\Documents\Script\$env:COMPUTERNAME-results.csv"

    Just in case. You could also change the csv path to a network share where your users have write permissions, so you have the full list in one place (writing locally would of course have the benefit of working when the network is down). Also, if it's a per-computer thing, you may not want to use Userprofiles for that, but rather another path.

    Also, if only the last entry is relevant, you can skip the Import-Csv line, since that's what retains previous entries. You can just overwrite it.

    As for the second script, please clarify what you want it to do, bullet-point by bullet-point (That's the very basic law of scripting by the way: Figure out which steps you need to take, in what order, and then figure out how to do each step. A good thing to keep in mind, as it often already solves a problem, and when it doesn't, then you still know exactly what to ask for).

    Cheers,
    Fred


    There's no place like 127.0.0.1

    Tuesday, May 27, 2014 12:44 PM
  • Fred,

    i will use a network share.

    Because the first script will create a lot of files like "computername1-results.csv", "computername2-results.csv" ect...

    i need another script which will get all the content of those files and put it in one file. 

    Tuesday, May 27, 2014 12:55 PM
  • Hi Salento,

    alright, then that's reasonably simple:

    # Variables
    $NetShare = "\\SrvExample\Logs\ExampleLog"
    $OutFile = "\\SrvExample\Logs\ExampleLog\AllResults.csv"
    
    # List to store results
    $Results = @()
    
    # Get all Files, then add them all to the results list
    dir $NetShare -Filter "*-results.csv" | %{ $Results += Import-Csv $_.FullName }
    
    # Write results to file that gathers all the logs
    $Results | Export-Csv $OutFile

    Sooo, what do we do?

    • First of all, we declare the paths at the top. Not only does that make things easier to read, those who want to use (and change parameters) later on only need to read the first few lines.
    • Then we set up a List, so we can temporarily store all results (Not strictly necessary, but doing it all without storing things has proven to be unreliable on some Windows 6.1 Patchlevels)
    • Then we search the network share for all results, and then for each (| %{ ... } ) we Import its contents and add them to the results list. You used gc in your attempt to write this. Get-Content will work in reading a file, but it will return a list of strings that cover the whole line, not a list of objects (that would make working with it later bothersome, to say the least). Use Import-Csv, if you want to read a csv file.
    • Finally Export it all back to csv.

    Cheers,
    Fred


    There's no place like 127.0.0.1

    Tuesday, May 27, 2014 1:14 PM
  • We can shorten al of this:


    $Results
    = @()

    # Get all Files, then add them all to the results list
    dir $NetShare
    -Filter "*-results.csv" | %{$Results += Import-Csv$_.FullName }

    # Write results to file that gathers all the logs
    $Results
    | Export-Csv$OutFile

    To this:

    dir $NetShare -Filter *-results.csv |%{Import-Csv $_ } | Export-Csv$OutFile  -NoType

    You can also do header conversion in the pipe if needed.


    ¯\_(ツ)_/¯


    • Edited by jrv Tuesday, May 27, 2014 2:03 PM
    Tuesday, May 27, 2014 2:02 PM
  • Thank you very much, all works fine :o)

    i'd like to control the order of columns in csv file, at this moment i have:

    Path,Computer,Date,Exist and i'd like to have Computer,Path,Exist,Date,

    does it possible.

    Salento.

    Tuesday, May 27, 2014 2:23 PM
  • Hi,

    Yes, that's possible. Pipe your results through select before piping to Export-Csv:

    .... | Select Computer,Path,Exist,Date | Export-Csv


    Don't retire TechNet! - (Don't give up yet - 12,950+ strong and growing)

    Tuesday, May 27, 2014 2:28 PM
  • Thanks!!!

    Salento.

    Tuesday, May 27, 2014 3:40 PM