Utwórz katalog, jeśli nie istnieje

342

Piszę skrypt PowerShell, aby utworzyć kilka katalogów, jeśli nie istnieją.

System plików wygląda podobnie do tego

D:\
D:\TopDirec\SubDirec\Project1\Revision1\Reports\
D:\TopDirec\SubDirec\Project2\Revision1\
D:\TopDirec\SubDirec\Project3\Revision1\
  • Każdy folder projektu ma wiele wersji.
  • Każdy folder wersji potrzebuje folderu raportów.
  • Niektóre foldery „wersji” zawierają już folder Raporty; jednak większość nie.

Muszę napisać skrypt uruchamiany codziennie, aby utworzyć te foldery dla każdego katalogu.

Jestem w stanie napisać skrypt, aby utworzyć folder, ale utworzenie kilku folderów jest problematyczne.

ecollis6
źródło
3
„tworzenie kilku folderów jest problematyczne” - jaki masz problem? Nie jesteś pewien, jak napisać dorsza? Czy pojawia się komunikat o błędzie? Czy foldery po prostu nie pojawiają się po uruchomieniu skryptu? Różne problemy wymagają różnych rozwiązań.
LarsH

Odpowiedzi:

536

Wypróbuj -Forceparametr:

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

Możesz użyć Test-Path -PathType Containerdo sprawdzenia w pierwszej kolejności.

Aby uzyskać więcej informacji, zobacz artykuł pomocy MSDN dotyczący nowego elementu .

Andy Arismendi
źródło
101
Dla leniwych istnieje skrót: md -Force c: \ foo \ bar \ baz
Matthew Fellows
74
Dla tych, którzy nie chcą żadnych danych wyjściowych podczas tworzenia folderu, dodaj „| Out-Null” na końcu
armannvg
20
Co faktycznie zrobi -Force? Dokumentacja mówi „Wymusza na tym poleceniu cmdlet utworzenie elementu, który zapisuje istniejący element tylko do odczytu” . Czy usunie istniejący folder? Powinno być jasne w tej odpowiedzi.
Peter Mortensen
25
@PeterMortensen W przypadku katalogów wymuszenie ich nie usuwa istniejącej zawartości, jedynie pomija komunikat o błędzie informujący, że jest już utworzony. To polecenie utworzy również niezbędne foldery pośredniczące, a zawartość tych folderów jest również bezpieczna, jeśli już istnieją.
John Neuhaus,
162
$path = "C:\temp\NewFolder"
If(!(test-path $path))
{
      New-Item -ItemType Directory -Force -Path $path
}

Test-Pathsprawdza, czy ścieżka istnieje. Kiedy tego nie zrobi, utworzy nowy katalog.

Gość
źródło
Miły! To wycisza dane wyjściowe, jeśli katalog już istnieje (ponieważ używa test-path).
Warlike Chimpanzee,
17

Poniższy fragment kodu pomaga utworzyć pełną ścieżkę.

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

Powyższa funkcja podzieli ścieżkę, którą przekazałeś do funkcji i sprawdzi każdy folder, czy istnieje, czy nie. Jeśli nie istnieje, utworzy odpowiedni folder do momentu utworzenia folderu docelowego / końcowego.

Aby wywołać funkcję, użyj poniższej instrukcji:

GenerateFolder "H:\Desktop\Nithesh\SrcFolder"
Naredla Nithesh Reddy
źródło
1
To nie jest najłatwiejsze, ale jest łatwe do zrozumienia.
Wang Jijun
13

Miałem dokładnie ten sam problem. Możesz użyć czegoś takiego:

$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
źródło
11

Po określeniu -Forceflagi PowerShell nie będzie narzekał, jeśli folder już istnieje.

Jednowarstwowy:

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

BTW, aby zaplanować zadanie, sprawdź ten link: Planowanie zadań w tle .

Klark
źródło
10

Posługiwać się:

$path = "C:\temp\"

If (!(test-path $path))
{
    md C:\Temp\
}
  • Pierwszy wiersz tworzy zmienną o nazwie $pathi przypisuje jej wartość ciągu „C: \ temp \”

  • Druga linia jest Ifoświadczenie, które opiera się na Test-Path cmdlet, aby sprawdzić, czy zmienna $pathma nie istnieć. Nie istnieje kwalifikuje się za pomocą !symbolu.

  • Trzeci wiersz: jeśli ścieżka zapisana w powyższym ciągu nie zostanie znaleziona, zostanie uruchomiony kod między nawiasami klamrowymi.

md to krótka wersja pisania: New-Item -ItemType Directory -Path $path

Uwaga: Nie testowałem przy użyciu -Forceparametru z poniższym, aby sprawdzić, czy nie ma niepożądanego zachowania, jeśli ścieżka już istnieje.

New-Item -ItemType Directory -Path $path
Kyle
źródło
1
działa to również w przypadku hierarchii katalogów md "C:\first\second\thirdtworzących je wszystkie.
MortenB
9

Istnieją trzy sposoby tworzenia katalogu za pomocą programu PowerShell:

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

Wpisz opis zdjęcia tutaj

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

Wpisz opis zdjęcia tutaj

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

Wpisz opis zdjęcia tutaj

George Livingston
źródło
Zauważ, że `md` jest po prostu domyślnym aliasem Powershell dla `mkdir` (make katalog), polecenia systemu Windows podobnego do mkdir dla Linux / Unix. ref: `Get-Alias
md`
4

Z twojej sytuacji wydaje się, że musisz utworzyć folder „Wersja nr” raz dziennie z folderem „Raporty”. W takim przypadku wystarczy wiedzieć, jaki jest następny numer wersji. Napisz funkcję, która otrzyma kolejny numer wersji, Get-NextRevisionNumber. Lub możesz zrobić coś takiego:

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

Instalacja PowerShell 3.0 .

ZŁO
źródło
2

Chciałem mieć możliwość łatwego umożliwienia użytkownikom utworzenia domyślnego profilu dla programu PowerShell w celu zastąpienia niektórych ustawień, i skończyłem z następującą linią pojedynczą (wiele instrukcji tak, ale można je wkleić do programu PowerShell i wykonać jednocześnie, co było głównym celem ):

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

Aby zapewnić czytelność, oto jak zrobiłbym to w pliku .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
źródło
1

Oto prosty, który dla mnie zadziałał. Sprawdza, czy ścieżka istnieje, a jeśli nie, utworzy nie tylko ścieżkę katalogu głównego, ale także wszystkie podkatalogi:

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

if (!(test-path -path $rptpath)) {new-item -path $rptpath -itemtype directory}
tklone
źródło