Создать каталог, если он не существует

342

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

Файловая система выглядит примерно так

D:\
D:\TopDirec\SubDirec\Project1\Revision1\Reports\
D:\TopDirec\SubDirec\Project2\Revision1\
D:\TopDirec\SubDirec\Project3\Revision1\
  • Каждая папка проекта имеет несколько ревизий.
  • Каждая ревизионная папка нуждается в папке отчетов.
  • Некоторые из папок «редакции» уже содержат папку «Отчеты»; однако большинство этого не делают.

Мне нужно написать скрипт, который запускается ежедневно для создания этих папок для каждого каталога.

Я могу написать скрипт для создания папки, но создание нескольких папок проблематично.

ecollis6
источник
3
«Создание нескольких папок проблематично» - что за проблема? Вы не уверены, как написать треску? Вы получаете сообщение об ошибке? Папки просто не появляются после запуска скрипта? Разные проблемы требуют разных решений.
LarsH

Ответы:

537

Попробуйте -Forceпараметр:

New-Item -ItemType Directory -Force -Path C:\Path\That\May\Or\May\Not\Exist

Вы можете использовать, Test-Path -PathType Containerчтобы проверить в первую очередь.

См. Справочную статью о новом элементе MSDN для получения более подробной информации.

Энди Арисменди
источник
101
Для ленивых есть сокращение: md -Force c: \ foo \ bar \ baz
Matthew Fellows
74
Для тех, кому не нужен вывод при создании папки, добавьте «| Out-Null» в конце
armannvg
20
Что будет на самом деле делать? В документации написано «Вынуждает этот командлет создавать элемент, который записывает поверх существующего элемента только для чтения» . Будет ли это удалить существующую папку? Это должно быть ясно в этом ответе.
Питер Мортенсен
25
@PeterMortensen В случае использования каталогов их удаление не удаляет существующее содержимое, оно только подавляет сообщение об ошибке, сообщающее, что оно уже создано. Эта команда также создаст все необходимые промежуточные папки, и содержимое этих папок также безопасно, если они уже существуют.
Джон Нейгауз
162
$path = "C:\temp\NewFolder"
If(!(test-path $path))
{
      New-Item -ItemType Directory -Force -Path $path
}

Test-Pathпроверяет, существует ли путь Когда этого не произойдет, он создаст новый каталог.

гость
источник
Ницца! Это отключает вывод, если каталог уже существует (потому что он использует test-path).
Воинственный шимпанзе
17

Следующий фрагмент кода поможет вам создать полный путь.

Function GenerateFolder($path) {
    $global:foldPath = $null
    foreach($foldername in $path.split("\")) {
        $global:foldPath += ($foldername+"\")
        if (!(Test-Path $global:foldPath)){
            New-Item -ItemType Directory -Path $global:foldPath
            # Write-Host "$global:foldPath Folder Created Successfully"
        }
    }
}

Вышеуказанная функция разделит путь, который вы передали функции, и проверит каждую папку, существует она или нет. Если он не существует, он создаст соответствующую папку, пока не будет создана целевая / конечная папка.

Чтобы вызвать функцию, используйте следующую инструкцию:

GenerateFolder "H:\Desktop\Nithesh\SrcFolder"
Наредла Нитеш Редди
источник
1
Этот не самый простой, но легкий для понимания.
Ван Цзицзюнь,
13

У меня была точно такая же проблема. Вы можете использовать что-то вроде этого:

$local = Get-Location;
$final_local = "C:\Processing";

if(!$local.Equals("C:\"))
{
    cd "C:\";
    if((Test-Path $final_local) -eq 0)
    {
        mkdir $final_local;
        cd $final_local;
        liga;
    }

    ## If path already exists
    ## DB Connect
    elseif ((Test-Path $final_local) -eq 1)
    {
        cd $final_local;
        echo $final_local;
        liga;  (function created by you TODO something)
    }
}
pykimera
источник
11

Когда вы указываете -Forceфлаг, PowerShell не будет жаловаться, если папка уже существует.

Один лайнер:

Get-ChildItem D:\TopDirec\SubDirec\Project* | `
  %{ Get-ChildItem $_.FullName -Filter Revision* } | `
  %{ New-Item -ItemType Directory -Force -Path (Join-Path $_.FullName "Reports") }

Кстати, для планирования задачи, пожалуйста, проверьте эту ссылку: Планирование фоновых заданий .

Klark
источник
10

Использование:

$path = "C:\temp\"

If (!(test-path $path))
{
    md C:\Temp\
}
  • Первая строка создает переменную с именем $pathи присваивает ей строковое значение «C: \ temp \»

  • Вторая строка - это Ifоператор, который использует командлет Test-Path , чтобы проверить $path, не существует ли переменная . Не существует квалифицируется с использованием !символа.

  • Третья строка: если путь, сохраненный в приведенной выше строке, не найден, будет выполнен код между фигурными скобками.

md это короткая версия ввода: New-Item -ItemType Directory -Path $path

Примечание: я не проверял использование -Forceпараметра с нижеуказанным, чтобы видеть, есть ли нежелательное поведение, если путь уже существует.

New-Item -ItemType Directory -Path $path
рукав моря
источник
1
это также работает для иерархии каталогов, md "C:\first\second\thirdсоздающих их все.
MortenB
9

Существует три способа создания каталога с помощью PowerShell:

Method 1: PS C:\> New-Item -ItemType Directory -path "C:\livingston"

Введите описание изображения здесь

Method 2: PS C:\> [system.io.directory]::CreateDirectory("C:\livingston")

Введите описание изображения здесь

Method 3: PS C:\> md "C:\livingston"

Введите описание изображения здесь

Джордж Ливингстон
источник
Обратите внимание, что `md` - это просто псевдоним Powershell по умолчанию для` mkdir` (make directory), команды windows, аналогичной Linux / Unix mkdir. ref: `Get-Alias
md`
4

Исходя из вашей ситуации, создается впечатление, что вам нужно создавать папку «Revision #» один раз в день с папкой «Отчеты». Если это так, вам просто нужно знать номер следующей ревизии. Напишите функцию, которая получает следующий номер редакции, Get-NextRevisionNumber. Или вы можете сделать что-то вроде этого:

foreach($Project in (Get-ChildItem "D:\TopDirec" -Directory)){
    # Select all the Revision folders from the project folder.
    $Revisions = Get-ChildItem "$($Project.Fullname)\Revision*" -Directory

    # The next revision number is just going to be one more than the highest number.
    # You need to cast the string in the first pipeline to an int so Sort-Object works.
    # If you sort it descending the first number will be the biggest so you select that one.
    # Once you have the highest revision number you just add one to it.
    $NextRevision = ($Revisions.Name | Foreach-Object {[int]$_.Replace('Revision','')} | Sort-Object -Descending | Select-Object -First 1)+1

    # Now in this we kill two birds with one stone.
    # It will create the "Reports" folder but it also creates "Revision#" folder too.
    New-Item -Path "$($Project.Fullname)\Revision$NextRevision\Reports" -Type Directory

    # Move on to the next project folder.
    # This untested example loop requires PowerShell version 3.0.
}

Установка PowerShell 3.0 .

ЗЛОЙ
источник
2

Я хотел иметь возможность легко позволить пользователям создавать профиль по умолчанию для PowerShell, чтобы переопределять некоторые параметры, и в итоге получился следующий однострочный (несколько операторов да, но их можно вставить в PowerShell и выполнить сразу, что было главной целью). ):

cls; [string]$filePath = $profile; [string]$fileContents = '<our standard settings>'; if(!(Test-Path $filePath)){md -Force ([System.IO.Path]::GetDirectoryName($filePath)) | Out-Null; $fileContents | sc $filePath; Write-Host 'File created!'; } else { Write-Warning 'File already exists!' };

Для удобства чтения, вот как я бы сделал это в файле .ps1:

cls; # Clear console to better notice the results
[string]$filePath = $profile; # Declared as string, to allow the use of texts without plings and still not fail.
[string]$fileContents = '<our standard settings>'; # Statements can now be written on individual lines, instead of semicolon separated.
if(!(Test-Path $filePath)) {
  New-Item -Force ([System.IO.Path]::GetDirectoryName($filePath)) | Out-Null; # Ignore output of creating directory
  $fileContents | Set-Content $filePath; # Creates a new file with the input
  Write-Host 'File created!';
}
else {
  Write-Warning "File already exists! To remove the file, run the command: Remove-Item $filePath";
};
Джонни Сковдал
источник
1

Вот простой, который работал для меня. Он проверяет, существует ли путь, и если его нет, он создаст не только корневой путь, но и все подкаталоги:

$rptpath = "C:\temp\reports\exchange"

if (!(test-path -path $rptpath)) {new-item -path $rptpath -itemtype directory}
tklone
источник