0

I have a powershell script that creates folders on our NAS for each student according to their student numbers. The names for the folders comes from a .csv file that I import from the server. This is what I have got:

Set-Location "C:\studentdata"

$StudFolders = import-csv \\servername\datafolder\studfolders.csv

ForEach ($StudFolders in $StudFolders) {


   if(Test-Path -Path C:\Studentdata\$StudFolders) { 

     New-Item $StudFolders.Name -type directory 

}else{

     "Folders already created" 

}
}

This script works great, if I run it only once. If I run it again, I get errors in the console window about the folders already existing. What I want to do is catch the errors with the IF part of the script, but I am not sure if I have the correct usage of the IF for powershell. This will help if I edit the .csv with more student number it will display without errors.

Can someone point me in the right direction?

EDIT:

This is what I have in the studfolders.csv

Name
2003040052
2003060213
2003060310
2003060467
7
  • Have you tested this with either an innocuous statement replacing your New-Item statement, or using -WhatIf on the New-Item? Alternatively, have you tried the Test-Path directly, with one path known to exist and one known not to exist? Commented Feb 8, 2017 at 13:24
  • Your if is backwards! Test-Path returns $true when the path is found (i.e. it already exists) Commented Feb 8, 2017 at 13:34
  • Show us the content of your CSV file. Better yet, show us the result of doing an Import-Csv on it. Without that, we are only guessing at what your script is doing. Commented Feb 9, 2017 at 14:24
  • The condition on your IF is miswritten. Where you have referenced an entire row, you should be referencing one of the fields inside the row, by name. Commented Feb 9, 2017 at 14:26
  • Your IF is backwards. You need to say the file already exists when it does exist. @gvee and the answers are all telling you this. We aren't all of us wrong. Commented Feb 9, 2017 at 14:28

3 Answers 3

1

Lets take a look at your logic:

  1. you are using an if statement, which works if something returns true
  2. you are using a test-path cmdlet which returns true if something exists

See the problem? you need to do it vice versa:

if (!(test-path ...)) { ... } # ! - is the operator to invert true to false

or you can switch if and else content, so when if executes it returns "Folders already created", and else creates folders

Sign up to request clarification or add additional context in comments.

1 Comment

Found a fix for my script. Thanks for the help.
1

As a matter of coding style, I would avoid using the same variable name with different semantics, as in ($Studfolders in $Studfolders). Code like this is very hard to read a few months down the road. I generally use the singular for each object in the collection, as in ($Studfolder in $Studfolders). But if your style works for you, OK.

Previous answers have already pointed out that your logic is backwards. You need to reverse it.

Next, it doesn't look to me as though you are accessing the component of each item in the loop. When you do an Import-Csv, several things happen: The first record in the csv file is treated as a header, providing the names for the fields that follow. If there is indeed a header in your csv file, you need to reference it when you retrieve the first field from each item, even if it's the only field.

The result of an import-csv is an array of custom objects. Each custom object looks like a hashtable that contains key, value pairs. Something like this might work

Set-Location "C:\studentdata"

$StudFolders = import-csv \\servername\datafolder\studfolders.csv

ForEach ($StudFolder in $StudFolders) {
   if(Test-Path -Path C:\Studentdata\$StudFolder.Name) { 
     "Folders already created" 
   }else{
      New-Item $StudFolder.Name -type directory 
   }
}

I have presumed that the first record in the Csv file looks like this:

"Name"

That is why I referenced the field as $Studfolder.Name"

If this isn't the case, you are going to have to do something different.

3 Comments

At one point I did have it like this and it works when you run the script one time. If you run the script again, I was hoping to only get a message of Folder created and not the red error messages in the console for the folders that was already created. It is as if the condition is not tested by the IF.
Take a closer look at the condition inside your IF Statement. It doesn't reference $Studfolders.Name. It references $Studfolders, which has to be incorrect. Without looking at your CSV file, I can't tell you what is correct, but that isn't it.
Found a fix for my script. Thanks for the help.
0

Having tried everything with the script, I could not get it to catch the errors. I decided to ask my manager, and he came up with the following solution that works quite well and catches the errors.

import-csv '\\servername\datafolder\studfolders.csv'|ForEach-Object -process {

  $path =$_.Name
  $path='C:\Studentdata\'+$path
  if (Test-Path -Path $path){

    "Folder already created"

} else {

   New-Item $path -type directory

}

}

Thanks to @Walter Mitty and @4c74356b41 for help try to find an answer.

1 Comment

what do you mean try, this is exactly what i proposed?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.