2017-02-08 5 views
0

У меня есть сценарий powershell, который создает папки на нашем NAS для каждого ученика в соответствии с их номерами учеников. Имена папок поступают из CSV-файла, который я импортирую с сервера. Это то, что у меня есть:Создание папки Powershell

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" 

} 
} 

Этот скрипт отлично работает, если я запускаю его только один раз. Если я запустил его снова, я получаю ошибки в окне консоли о уже существующих папках. То, что я хочу сделать, это поймать ошибки с помощью IF-части скрипта, но я не уверен, правильно ли я использую IF для powershell. Это поможет, если я отредактирую CSV с большим числом учеников, он будет отображаться без ошибок.

Может кто-нибудь указать мне в правильном направлении?

EDIT:

Это то, что я имею в studfolders.csv

Name 
2003040052 
2003060213 
2003060310 
2003060467 
+0

Вы протестировали это с помощью безобидного заявления, заменяющего инструкцию 'New-Item', или используя' -WhatIf' в 'New-Item'? В качестве альтернативы, вы пробовали «Test-Path» напрямую, с одним известным из известных путей и неизвестным? –

+0

Ваш 'if' назад! 'Test-Path' возвращает' $ true', когда путь _found_ (т. Е. Он уже существует) – gvee

+0

Покажите нам содержимое вашего CSV-файла. Еще лучше покажите нам результат выполнения Импорта-Csv. Без этого мы только догадываемся о том, что делает ваш скрипт. –

ответ

0

Пробовав все со сценарием, я не смог заставить его поймать ошибки. Я решил спросить своего менеджера, и он придумал следующее решение, которое работает достаточно хорошо и ловит ошибки.

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 

} 

} 

Спасибо @Walter Mitty и @ 4c74356b41 за помощью, чтобы найти ответ.

+0

что вы хотите сказать, это именно то, что я предложил? – 4c74356b41

1

Давайте посмотрим на вашу логику:

  1. вы используете if заявление, в котором работает если что-то возвращается true
  2. Вы используете командлет test-path, который возвращает true, если что-то существует

Уточнить проблему? Вы должны сделать это наоборот:

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

или вы можете переключиться, если и другое содержанием, поэтому, когда if выполняет она возвращает «Папка уже созданная», а еще создает папку

+0

Нашел исправление для моего скрипта. Спасибо за помощь. – StBlade

1

По сути стиля кодирования , Я бы избегал использовать одно и то же имя переменной с другой семантикой, как в ($ Studfolders в $ Studfolders). Код, подобный этому, очень трудно прочитать через несколько месяцев после дороги. Обычно я использую единственное для каждого объекта в коллекции, как в ($ Studfolder в $ Studfolders). Но если ваш стиль работает для вас, хорошо.

Предыдущие ответы уже указывали, что ваша логика обратная. Вам нужно отменить это.

Далее, это не выглядит так, как будто вы обращаетесь к компоненту каждого элемента в цикле. Когда вы выполняете импорт-Csv, происходит несколько вещей: первая запись в файле csv рассматривается как заголовок, предоставляя имена для следующих полей. Если в файле csv действительно есть заголовок, вам нужно ссылаться на него, когда вы извлекаете первое поле из каждого элемента, даже если это единственное поле.

Результатом импорта-csv является массив пользовательских объектов. Каждый пользовательский объект выглядит как хэш-таблица, содержащая пары ключей, значений. Нечто подобное могло бы работать

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

Я предположил, что первая запись в файле Csv выглядит следующим образом:

"Name" 

Вот почему я сослалась на поле $ Studfolder.Name»

Если это не так, вам придется делать что-то другое.

+0

В какой-то момент у меня это было, и это работает, когда вы запускаете скрипт один раз. Если вы снова запустите сценарий, я надеялся получить сообщение папки «Папка», а не красные сообщения об ошибках в консоли для уже созданных папок. Это как если бы условие не проверялось IF. – StBlade

+0

Присмотритесь к состоянию внутри вашего оператора IF. Он не ссылается на $ Studfolders.Name. Он ссылается на $ Studfolders, который должен быть неверным. Не смотря на файл CSV, я не могу сказать вам, что правильно, но это не так. –

+0

Нашел исправление для моего скрипта. Спасибо за помощь. – StBlade