Erstellen Sie ein Verzeichnis, wenn es nicht vorhanden ist

341

Ich schreibe ein PowerShell-Skript, um mehrere Verzeichnisse zu erstellen, falls diese nicht vorhanden sind.

Das Dateisystem sieht ähnlich aus

D:\
D:\TopDirec\SubDirec\Project1\Revision1\Reports\
D:\TopDirec\SubDirec\Project2\Revision1\
D:\TopDirec\SubDirec\Project3\Revision1\
  • Jeder Projektordner verfügt über mehrere Revisionen.
  • Jeder Revisionsordner benötigt einen Berichtsordner.
  • Einige der "Revisions" -Ordner enthalten bereits einen Berichtsordner. Die meisten jedoch nicht.

Ich muss ein Skript schreiben, das täglich ausgeführt wird, um diese Ordner für jedes Verzeichnis zu erstellen.

Ich kann das Skript schreiben, um einen Ordner zu erstellen, aber das Erstellen mehrerer Ordner ist problematisch.

ecollis6
quelle
3
"Das Erstellen mehrerer Ordner ist problematisch" - was für ein Problem haben Sie? Sind Sie nicht sicher, wie Sie den Kabeljau schreiben sollen? Erhalten Sie eine Fehlermeldung? Werden die Ordner nach dem Ausführen des Skripts nicht angezeigt? Unterschiedliche Probleme erfordern unterschiedliche Lösungen.
LarsH

Antworten:

535

Probieren Sie den -ForceParameter aus:

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

Sie können verwenden Test-Path -PathType Container, um zuerst zu überprüfen.

Sehen Sie sich den New-Item MSDN Hilfe - Artikel für weitere Details.

Andy Arismendi
quelle
101
Für die Faulen gibt es eine Abkürzung: md -Force c: \ foo \ bar \ baz
Matthew Fellows
74
Für diejenigen, die beim
Erstellen
20
Was wird -Force eigentlich tun? Die Dokumentation sagt „Forces dieses Cmdlet ein Element , das schreibt über ein bestehendes Nur - Lese-Element zu erstellen“ . Wird ein vorhandener Ordner gelöscht? Es sollte in dieser Antwort klar sein.
Peter Mortensen
25
@PeterMortensen Bei Verzeichnissen werden beim Erzwingen keine Verzeichnisse gelöscht, sondern nur die Fehlermeldung unterdrückt, dass sie bereits erstellt wurden. Dieser Befehl erstellt auch alle erforderlichen dazwischenliegenden Ordner, und der Inhalt dieser Ordner ist auch sicher, wenn sie bereits vorhanden sind.
John Neuhaus
160
$path = "C:\temp\NewFolder"
If(!(test-path $path))
{
      New-Item -ItemType Directory -Force -Path $path
}

Test-Pathprüft, ob der Pfad existiert. Wenn dies nicht der Fall ist, wird ein neues Verzeichnis erstellt.

Gast
quelle
Nett! Dadurch wird die Ausgabe stummgeschaltet, wenn das Verzeichnis bereits vorhanden ist (weil es verwendet wird test-path).
Warlike Schimpanse
17

Mit dem folgenden Codeausschnitt können Sie einen vollständigen Pfad erstellen.

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

Die obige Funktion teilt den Pfad auf, den Sie an die Funktion übergeben haben, und überprüft jeden Ordner, ob er vorhanden ist oder nicht. Wenn es nicht vorhanden ist, wird der entsprechende Ordner erstellt, bis der Ziel- / Endordner erstellt wurde.

Verwenden Sie die folgende Anweisung, um die Funktion aufzurufen:

GenerateFolder "H:\Desktop\Nithesh\SrcFolder"
Naredla Nithesh Reddy
quelle
1
Dieser ist nicht der einfachste, aber leicht zu verstehen.
Wang Jijun
schöne Lösung! danke;)
Alberto S.
13

Ich hatte genau das gleiche Problem. Sie können so etwas verwenden:

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

Wenn Sie das -ForceFlag angeben , beschwert sich PowerShell nicht, wenn der Ordner bereits vorhanden ist.

Einzeiler:

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

Übrigens, um die Aufgabe zu planen, lesen Sie bitte diesen Link: Planen von Hintergrundjobs .

Klark
quelle
10

Verwenden:

$path = "C:\temp\"

If (!(test-path $path))
{
    md C:\Temp\
}
  • In der ersten Zeile wird eine Variable mit dem Namen erstellt $pathund ihr der Zeichenfolgenwert "C: \ temp \" zugewiesen.

  • Die zweite Zeile ist eine IfAussage , die auf das beruht Test-Path - Cmdlets zu überprüfen , ob die Variable $pathist nicht vorhanden. Das nicht existierende wird mit dem !Symbol qualifiziert.

  • Dritte Zeile: Wenn der in der obigen Zeichenfolge gespeicherte Pfad nicht gefunden wird, wird der Code zwischen den geschweiften Klammern ausgeführt.

md ist die Kurzversion des Tippens: New-Item -ItemType Directory -Path $path

Hinweis: Ich habe den folgenden -ForceParameter nicht mit dem folgenden Parameter getestet, um festzustellen, ob ein unerwünschtes Verhalten vorliegt, wenn der Pfad bereits vorhanden ist.

New-Item -ItemType Directory -Path $path
Kyle
quelle
1
Dies funktioniert auch für eine Hierarchie von Verzeichnissen md "C:\first\second\third, die alle erstellen.
MortenB
9

Ich kenne drei Möglichkeiten, um ein Verzeichnis mit PowerShell zu erstellen:

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

Geben Sie hier die Bildbeschreibung ein

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

Geben Sie hier die Bildbeschreibung ein

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

Geben Sie hier die Bildbeschreibung ein

George Livingston
quelle
Beachten Sie, dass `md` einfach ein Powershell-Standardalias für` mkdir` (make-Verzeichnis) ist, ein Windows-Befehl ähnlich Linux / Unix mkdir. ref: `Get-Alias
md`
4

Aus Ihrer Situation heraus scheint es, als müssten Sie einmal täglich einen Ordner "Revision #" mit einem Ordner "Berichte" erstellen. Wenn dies der Fall ist, müssen Sie nur die nächste Revisionsnummer kennen. Schreiben Sie eine Funktion, die die nächste Revisionsnummer erhält, Get-NextRevisionNumber. Oder Sie könnten so etwas tun:

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

BÖSE
quelle
2

Ich wollte in der Lage sein, Benutzern das Erstellen eines Standardprofils für PowerShell zu ermöglichen, um einige Einstellungen zu überschreiben, und erhielt den folgenden Einzeiler (mehrere Anweisungen ja, kann aber in PowerShell eingefügt und sofort ausgeführt werden, was das Hauptziel war ):

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

Zur besseren Lesbarkeit würde ich dies stattdessen in einer .ps1-Datei tun:

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
quelle
1

Hier ist eine einfache, die für mich funktioniert hat. Es wird geprüft, ob der Pfad vorhanden ist. Wenn dies nicht der Fall ist, wird nicht nur der Stammpfad, sondern auch alle Unterverzeichnisse erstellt:

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

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