Crea directory se non esiste


342

Sto scrivendo uno script di PowerShell per creare diverse directory se non esistono.

Il filesystem è simile a questo

D:\
D:\TopDirec\SubDirec\Project1\Revision1\Reports\
D:\TopDirec\SubDirec\Project2\Revision1\
D:\TopDirec\SubDirec\Project3\Revision1\
  • Ogni cartella del progetto ha più revisioni.
  • Ogni cartella di revisione necessita di una cartella Rapporti.
  • Alcune delle cartelle "revisioni" contengono già una cartella Rapporti; tuttavia, la maggior parte no.

Devo scrivere uno script che viene eseguito quotidianamente per creare queste cartelle per ogni directory.

Sono in grado di scrivere lo script per creare una cartella, ma creare diverse cartelle è problematico.


3
"la creazione di più cartelle è problematica" - che tipo di problema stai riscontrando? Non sei sicuro di come scrivere il merluzzo? stai ricevendo un messaggio di errore? Le cartelle non vengono visualizzate dopo l'esecuzione dello script? Problemi diversi richiedono soluzioni diverse.
LarsH

Risposte:


536

Prova il -Forceparametro:

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

Puoi usare Test-Path -PathType Containerper controllare prima.

Vedere l' articolo della guida MSDN New-Item per ulteriori dettagli.


101
Per i più pigri, c'è una scorciatoia: md -Force c: \ foo \ bar \ baz
Matthew Fellows,

74
Per coloro che non desiderano alcun output quando viene creata la cartella, aggiungere "| Out-Null" alla fine
armannvg

20
Cosa farà effettivamente -Force? La documentazione dice "Forza questo cmdlet a creare un elemento che scrive su un elemento di sola lettura esistente" . Eliminerà una cartella esistente? Dovrebbe essere chiaro in questa risposta.
Peter Mortensen,

25
@PeterMortensen Nel caso delle directory, forzarle non cancella i contenuti esistenti, sopprime solo il messaggio di errore dicendo che è già stata creata. Questo comando creerà anche tutte le cartelle intermedie necessarie e il contenuto di tali cartelle è sicuro anche se esiste già.
John Neuhaus,

162
$path = "C:\temp\NewFolder"
If(!(test-path $path))
{
      New-Item -ItemType Directory -Force -Path $path
}

Test-Pathcontrolla se esiste il percorso. In caso contrario, creerà una nuova directory.


Bello! Ciò silenzia l'output se la directory esiste già (perché utilizza test-path).
Warlike Chimpanzee,

17

Il seguente frammento di codice ti aiuta a creare un percorso 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"
        }
    }
}

La funzione sopra divisa il percorso che hai passato alla funzione e controllerà ogni cartella se esiste o no. Se non esiste, creerà la rispettiva cartella fino alla creazione della cartella di destinazione / finale.

Per chiamare la funzione, utilizzare la seguente istruzione:

GenerateFolder "H:\Desktop\Nithesh\SrcFolder"

1
Questo non è il più semplice, ma è facile da capire.
Wang Jijun,

13

Ho avuto lo stesso identico problema. Puoi usare qualcosa del genere:

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

11

Quando si specifica il -Forceflag, PowerShell non si lamenterà se la cartella esiste già.

One-liner:

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

A proposito, per programmare l'attività, controlla questo link: Pianificazione di lavori in background .


10

Uso:

$path = "C:\temp\"

If (!(test-path $path))
{
    md C:\Temp\
}
  • La prima riga crea una variabile denominata $pathe le assegna il valore stringa di "C: \ temp \"

  • La seconda linea è una Ifdichiarazione che si basa sul Test-Path cmdlet per verificare se la variabile $pathnon non esiste. Il non esiste è qualificato utilizzando il !simbolo.

  • Terza riga: se il percorso memorizzato nella stringa sopra non viene trovato, verrà eseguito il codice tra le parentesi graffe.

md è la versione breve della digitazione: New-Item -ItemType Directory -Path $path

Nota: non ho testato usando il -Forceparametro con il seguito per vedere se c'è un comportamento indesiderato se il percorso esiste già.

New-Item -ItemType Directory -Path $path

1
questo funziona anche per una gerarchia di directory md "C:\first\second\thirdcrearle tutte.
MortenB,

9

Esistono tre modi che conosco per creare una directory usando PowerShell:

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

Inserisci qui la descrizione dell'immagine

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

Inserisci qui la descrizione dell'immagine

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

Inserisci qui la descrizione dell'immagine


Si noti che `md` è semplicemente un alias predefinito di Powershell per `mkdir` (make directory), un comando di Windows simile a Linux / Unix mkdir. ref: `Get-Alias
md`

4

Dalla tua situazione sembra che sia necessario creare una cartella "Revision #" una volta al giorno con una cartella "Rapporti". In tal caso, devi solo sapere qual è il prossimo numero di revisione. Scrivi una funzione che ottiene il numero di revisione successivo, Get-NextRevisionNumber. Oppure potresti fare qualcosa del genere:

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

Installazione di PowerShell 3.0 .


2

Volevo essere in grado di consentire agli utenti di creare facilmente un profilo predefinito per PowerShell per ignorare alcune impostazioni e ho finito con il seguente one-liner (più istruzioni sì, ma può essere incollato in PowerShell ed eseguito in una sola volta, che era l'obiettivo principale ):

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

Per leggibilità, ecco come lo farei in un file .ps1 invece:

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

Eccone uno semplice che ha funzionato per me. Verifica se il percorso esiste e, in caso contrario, creerà non solo il percorso principale, ma anche tutte le sottodirectory:

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

if (!(test-path -path $rptpath)) {new-item -path $rptpath -itemtype directory}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.