Crear directorio si no existe

341

Estoy escribiendo un script de PowerShell para crear varios directorios si no existen.

El sistema de archivos se parece a esto

D:\
D:\TopDirec\SubDirec\Project1\Revision1\Reports\
D:\TopDirec\SubDirec\Project2\Revision1\
D:\TopDirec\SubDirec\Project3\Revision1\
  • Cada carpeta de proyecto tiene múltiples revisiones.
  • Cada carpeta de revisión necesita una carpeta de Informes.
  • Algunas de las carpetas de "revisiones" ya contienen una carpeta de Informes; Sin embargo, la mayoría no.

Necesito escribir un script que se ejecute diariamente para crear estas carpetas para cada directorio.

Puedo escribir el script para crear una carpeta, pero crear varias carpetas es problemático.

ecollis6
fuente
3
"crear varias carpetas es problemático": ¿qué tipo de problema tiene? ¿No estás seguro de cómo escribir el bacalao? ¿Está recibiendo un mensaje de error? ¿Las carpetas simplemente no aparecen después de ejecutar el script? Diferentes problemas requieren diferentes soluciones.
LarsH

Respuestas:

535

Prueba el -Forceparámetro:

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

Puede usar Test-Path -PathType Containerpara verificar primero.

Consulte el artículo de ayuda de MSDN New-Item para obtener más detalles.

Andy Arismendi
fuente
101
Para los perezosos, hay una abreviatura: md -Force c: \ foo \ bar \ baz
Matthew Fellows
74
Para aquellos que no desean ningún resultado cuando se crea la carpeta, agregue "| Out-Null" al final
armannvg
20
¿Qué hará -Force realmente? La documentación dice "Obliga a este cmdlet a crear un elemento que escriba sobre un elemento de solo lectura existente" . ¿Eliminará una carpeta existente? Debe quedar claro en esta respuesta.
Peter Mortensen
25
@PeterMortensen En el caso de los directorios, forzarlos no borra los contenidos existentes, solo suprime el mensaje de error que dice que ya está creado. Este comando también creará las carpetas intermedias necesarias, y el contenido de esas carpetas también es seguro si ya existen.
John Neuhaus
160
$path = "C:\temp\NewFolder"
If(!(test-path $path))
{
      New-Item -ItemType Directory -Force -Path $path
}

Test-Pathcomprueba si la ruta existe. Cuando no lo haga, creará un nuevo directorio.

Invitado
fuente
¡Agradable! Esto silencia la salida si el directorio ya existe (porque usa test-path).
Warlike Chimpanzee
17

El siguiente fragmento de código le ayuda a crear una ruta completa.

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 función anterior divide la ruta que pasó a la función y verificará cada carpeta si existe o no. Si no existe, creará la carpeta correspondiente hasta que se cree la carpeta de destino / final.

Para llamar a la función, use la siguiente declaración:

GenerateFolder "H:\Desktop\Nithesh\SrcFolder"
Naredla Nithesh Reddy
fuente
1
Este no es el más fácil, pero es fácil de entender.
Wang Jijun
buena solución! gracias;)
Alberto S.
13

Tuve exactamente el mismo problema. Puedes usar algo como esto:

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

Cuando especifique el -Forceindicador, PowerShell no se quejará si la carpeta ya existe.

Un trazador de líneas:

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

Por cierto, para programar la tarea, consulte este enlace: Programación de trabajos en segundo plano .

Klark
fuente
10

Utilizar:

$path = "C:\temp\"

If (!(test-path $path))
{
    md C:\Temp\
}
  • La primera línea crea una variable llamada $pathy le asigna el valor de cadena de "C: \ temp \"

  • La segunda línea es una Ifafirmación que se basa en el Test-Path cmdlet para comprobar si la variable $pathno no existe. Lo no existente se califica utilizando el !símbolo.

  • Tercera línea: Si es la ruta almacenada en la cadena anterior no se encuentra, se ejecutará el código entre las llaves.

md es la versión corta de escribir: New-Item -ItemType Directory -Path $path

Nota: No he probado usando el -Forceparámetro con el siguiente para ver si hay un comportamiento no deseado si la ruta ya existe.

New-Item -ItemType Directory -Path $path
Kyle
fuente
1
esto también funciona para una jerarquía de directorios, md "C:\first\second\thirdcréelos todos.
MortenB
9

Hay tres formas en que sé crear un directorio usando PowerShell:

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

Ingrese la descripción de la imagen aquí

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

Ingrese la descripción de la imagen aquí

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

Ingrese la descripción de la imagen aquí

George Livingston
fuente
Tenga en cuenta que `md` es simplemente un alias predeterminado de Powershell para `mkdir` (make directory), un comando de Windows similar a Linux / Unix mkdir. ref: `Get-Alias
md`
4

Según su situación, parece que necesita crear una carpeta "Revisión #" una vez al día con una carpeta "Informes" allí. Si ese es el caso, solo necesita saber cuál es el próximo número de revisión. Escriba una función que obtenga el siguiente número de revisión, Get-NextRevisionNumber. O podrías hacer algo como esto:

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

Instalación de PowerShell 3.0 .

MAL
fuente
2

Quería permitir que los usuarios crearan fácilmente un perfil predeterminado para PowerShell para anular algunas configuraciones, y terminé con la siguiente línea (varias afirmaciones, sí, pero se pueden pegar en PowerShell y ejecutar de una vez, que era el 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 la lectura, así es como lo haría en un archivo .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
fuente
1

Aquí hay uno simple que funcionó para mí. Comprueba si la ruta existe, y si no existe, creará no solo la ruta raíz, sino también todos los subdirectorios:

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

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