Crie um diretório se ele não existir

341

Estou escrevendo um script do PowerShell para criar vários diretórios se eles não existirem.

O sistema de arquivos é semelhante a este

D:\
D:\TopDirec\SubDirec\Project1\Revision1\Reports\
D:\TopDirec\SubDirec\Project2\Revision1\
D:\TopDirec\SubDirec\Project3\Revision1\
  • Cada pasta do projeto possui várias revisões.
  • Cada pasta de revisão precisa de uma pasta Relatórios.
  • Algumas das pastas "revisões" já contêm uma pasta Relatórios; no entanto, a maioria não.

Eu preciso escrever um script que é executado diariamente para criar essas pastas para cada diretório.

Consigo escrever o script para criar uma pasta, mas a criação de várias pastas é problemática.

ecollis6
fonte
3
"criar várias pastas é problemático" - que tipo de problema você está tendo? Você não tem certeza de como escrever o bacalhau? Você está recebendo uma mensagem de erro? As pastas simplesmente não aparecem depois que o script é executado? Problemas diferentes requerem soluções diferentes.
LarsH

Respostas:

535

Experimente o -Forceparâmetro:

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

Você pode usar Test-Path -PathType Containerpara verificar primeiro.

Consulte o artigo de ajuda do Novo Item do MSDN para obter mais detalhes.

Andy Arismendi
fonte
101
Para os preguiçosos, existe uma abreviação: md -Force c: \ foo \ bar \ baz #
Fellows Matthew Matthew
74
Para aqueles que não desejam saída quando a pasta é criada, adicione "| Out-Null" no final
armannvg
20
O que o -Force realmente fará? A documentação diz "Força esse cmdlet a criar um item que grava sobre um item somente leitura existente" . Isso excluirá uma pasta existente? Deve ficar claro nesta resposta.
Peter Mortensen
25
@PeterMortensen No caso de diretórios, forçá-los não limpa o conteúdo existente, apenas suprime a mensagem de erro dizendo que ele já foi criado. Este comando também criará todas as pastas intermediárias necessárias e o conteúdo dessas pastas também será seguro se elas já existirem.
John Neuhaus
160
$path = "C:\temp\NewFolder"
If(!(test-path $path))
{
      New-Item -ItemType Directory -Force -Path $path
}

Test-Pathverifica se o caminho existe. Quando isso não acontecer, ele criará um novo diretório.

Hóspede
fonte
Agradável! Isso silencia a saída se o diretório já existir (porque ele usa test-path).
Warim Chimpanzee
17

O seguinte trecho de código ajuda a criar um caminho completo.

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

A função acima divide o caminho que você passou para a função e verificará cada pasta se ela existe ou não. Se não existir, criará a respectiva pasta até a pasta de destino / final criada.

Para chamar a função, use a instrução abaixo:

GenerateFolder "H:\Desktop\Nithesh\SrcFolder"
Naredla Nithesh Reddy
fonte
11
Este não é o mais fácil, mas é fácil de entender.
Wang Jijun
boa solução! Obrigado;)
Alberto S.
13

Eu tive o mesmo problema. Você pode usar algo como isto:

$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
fonte
11

Quando você especifica o -Forcesinalizador, o PowerShell não reclama se a pasta já existir.

Uma linha:

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

BTW, para agendar a tarefa, consulte este link: Agendamento de trabalhos em segundo plano .

Klark
fonte
10

Usar:

$path = "C:\temp\"

If (!(test-path $path))
{
    md C:\Temp\
}
  • A primeira linha cria uma variável chamada $pathe atribui a ela o valor da string "C: \ temp \"

  • A segunda linha é uma Ifdeclaração que conta com a Test-Path cmdlet para verificar se a variável $pathque não existe. O não existe é qualificado usando o !símbolo.

  • Terceira linha: Se o caminho armazenado na string acima não for encontrado, o código entre os colchetes será executado.

md é a versão curta da digitação: New-Item -ItemType Directory -Path $path

Nota: Eu não testei usando o -Forceparâmetro com o abaixo para ver se há um comportamento indesejável se o caminho já existir.

New-Item -ItemType Directory -Path $path
Kyle
fonte
11
isso também funciona para uma hierarquia de diretórios para md "C:\first\second\thirdcriar todos eles.
MortenB 21/01
9

Existem três maneiras de criar um diretório usando o PowerShell:

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

Digite a descrição da imagem aqui

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

Digite a descrição da imagem aqui

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

Digite a descrição da imagem aqui

George Livingston
fonte
Note que o `md` é simplesmente um alias padrão do Powershell para o `mkdir` (make directory), um comando do Windows semelhante ao Linux / Unix mkdir. ref: `Get-Alias
md`
4

Da sua situação, parece que você precisa criar uma pasta "Revisão #" uma vez por dia com uma pasta "Relatórios". Se for esse o caso, você só precisa saber qual é o próximo número de revisão. Escreva uma função que obtenha o próximo número de revisão, Get-NextRevisionNumber. Ou você pode fazer algo assim:

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

Instalação do PowerShell 3.0 .

MAL
fonte
2

Queria poder permitir que os usuários criassem facilmente um perfil padrão para o PowerShell substituir algumas configurações e acabei com a seguinte linha única (várias instruções sim, mas pode ser colada no PowerShell e executada ao mesmo tempo, que era o objetivo principal) ):

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!' };

Para facilitar a leitura, veja como eu faria isso em um arquivo .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";
};
Johny Skovdal
fonte
1

Aqui está um simples que funcionou para mim. Ele verifica se o caminho existe e, se não existir, criará não apenas o caminho raiz, mas também todos os subdiretórios:

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

if (!(test-path -path $rptpath)) {new-item -path $rptpath -itemtype directory}
tklone
fonte