如果目录不存在,则创建目录

519

我正在编写一个 PowerShell 脚本,用于创建若干个目录(如果它们不存在)。

文件系统看起来类似于这样

D:\
D:\TopDirec\SubDirec\Project1\Revision1\Reports\
D:\TopDirec\SubDirec\Project2\Revision1\
D:\TopDirec\SubDirec\Project3\Revision1\
  • 每个项目文件夹都有多个版本。
  • 每个版本文件夹都需要一个报告文件夹。
  • 有些“版本”文件夹已经包含了一个报告文件夹;但是,大多数没有。

我需要编写一个每天运行以为每个目录创建这些文件夹的脚本。

我能够编写创建文件夹的脚本,但创建多个文件夹会出现问题。


8
"创建多个文件夹存在问题" - 您遇到了哪种问题?您不确定如何编写代码吗?您收到错误消息了吗?脚本运行后文件夹是否没有出现?不同的问题需要不同的解决方案。 - LarsH
13个回答

753

尝试使用-Force参数:

New-Item -ItemType Directory -Force -Path C:\Path\That\May\Or\May\Not\Exist
你可以使用 Test-Path -PathType Container 来进行检查。
有关更多详细信息,请参阅 New-Item MSDN 帮助文章。

147
对于懒惰的人,有一个简写方式:md -Force c:\foo\bar\baz。(翻译说明:本文为一条命令提示符下的指令,其中的“md”代表“make directory”,意为创建文件夹;“-Force”表示强制执行操作,即使存在同名文件夹也会被覆盖;“c:\foo\bar\baz”是文件夹的路径,可以根据需要进行修改。) - Matthew Fellows
106
如果不想在文件夹创建时得到任何输出,可以在末尾加上 "| Out-Null"。 - armannvg
46
“-Force”参数实际上会做什么?文档中写道:“强制此 cmdlet 创建一个覆盖现有只读项的项”。它会删除现有文件夹吗?这个答案应该是清楚的。 - Peter Mortensen
53
对于目录而言,强制创建并不会清空已存在的内容,它只是抑制错误提示消息,表明该目录已经被创建。此命令还将创建必要的任何中间文件夹,如果这些文件夹的内容已经存在,则它们也是安全的。 - John Neuhaus
9
警告:如果路径上存在文件,这个操作将会静默执行,不像 [System.IO.Directory]::CreateDirectory('path')。 - Marco van Hilst
如果路径下存在文件,则会静默处理。这个 bug 在 PowerShell 7.3.1 中仍然存在。 - zett42

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

Test-Path -PathType container用于检查路径是否存在且为目录。如果不存在,它将创建一个新的目录。如果路径存在但是为文件,则New-Item会引发错误(如果您愿意冒险,可以使用-force参数覆盖该文件)。


不错!如果目录已经存在(因为它使用了“test-path”),这将使输出静音。 - Elliott Beach
2
为什么要使用选项“-Force”? - KCD
14
为了解释薛定谔的目录,需要对KCD进行核算。 - xorinzor
从我的测试来看,“-Force”选项并不会覆盖目录中的文件,而是会悄无声息地失败。 - apple apple

53
[System.IO.Directory]::CreateDirectory('full path to directory')

这个函数会检查目录是否存在,如果不存在则创建一个。只需要一行代码,使用本地 .NET 方法就可以完美工作。


我可以使用本地/相对路径到我的当前工作目录吗? - Aaron Franke
1
@AaronFranke,你可以使用[System.IO.Path]::Combine($PWD.Path, 'relativeDirectory')来实现。 - filimonic
@AaronFranke 是的。与大多数IO.Directory命名空间一样,在参数中传递相对路径即可。同样适用于它们的PowerShell等效项。 - Zacharious
在 PowerShell 中,"相对"路径可能会出现问题,因为诸如 Set-Location 的命令实际上不会影响 CreateDirectory 使用的当前目录,你可以通过使用 ::GetCurrentDirectory() 来验证这一点。为了正确地使用相对路径,应该使用 ::SetCurrentDirectory(...) 来更改工作目录。 (这些适用于 PowerShell 5.1 的行为) - filimonic
armannvg对另一个答案的建议是在创建文件夹时末尾添加| Out-Null,这样如果您不想要任何输出,也适用于这个答案。 - PolyTekPatrick
1
这个 .NET 实现的一个非常罕见而出色的特性是,它会创建沿路径中所有缺失的文件夹(不仅仅是最后一个/叶子)。 - Andrzej Martyna

31

使用:

$path = "C:\temp\"
    
If (!(test-path $path))
{
    md $path
}
  • 第一行创建了一个名为$path的变量,并将其赋值为字符串“C:\temp”。

  • 第二行是一个If语句,它依赖于Test-Path cmdlet来检查变量$path是否不存在。使用!符号对不存在进行限定。

  • 第三行:如果在上述字符串中存储的路径未找到,则将运行花括号之间的代码。

md是输入以下内容的简短版本:New-Item -ItemType Directory -Path $path

注意:我尚未使用-Force参数测试以下内容,以查看路径已存在时是否存在不良行为。

New-Item -ItemType Directory -Path $path

1
这也适用于目录层次结构:md "C:\first\second\third"将同时创建它们。 - MortenB
在上述情况下,如果第三个不存在,我该如何创建一个名为“third”的文件夹? - userAZLogicApps
对于一行代码,可以这样写:md $path -Force | Out-Null - Joe

20
以下代码片段可帮助您创建完整路径。
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"
        }
    }
}

上述函数会将您传递给函数的路径拆分,并检查每个文件夹是否存在。如果不存在,它会创建相应的文件夹,直到目标/最终文件夹被创建。

要调用该函数,请使用下面的语句:

GenerateFolder "H:\Desktop\Nithesh\SrcFolder"

1
这个不是最容易的,但是很容易理解。 - Wang Jijun
假设我有一个路径“\shared1\folder1\”,我想在这个路径下创建一个LOGS文件夹,如果它不存在,我该如何编写代码?因为“\shared1\folder1\”是一个变量而不是硬编码的内容。我的意思是,如果不存在,“\shared1\folder1\LOGS”必须被创建。 - userAZLogicApps

13

我遇到了完全相同的问题。你可以使用类似这样的东西:

$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

当您指定-Force标志时,PowerShell不会在文件夹已存在的情况下发出警告。

一行代码:

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

顺便说一下,如需安排任务,请查看此链接:安排后台作业


11

我知道使用PowerShell创建目录有三种方法:

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

在此输入图片描述

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

在此输入图像描述

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

输入图像描述


1
请注意,md是PowerShell中mkdir(创建目录)的默认别名,它类似于Linux/Unix的mkdir命令。参考:Get-Alias md - BentChainRing

4

根据您的情况,似乎您需要每天创建一个名为“Revision#” 的文件夹,并在其中创建一个名为“Reports”的文件夹。如果是这种情况,您只需要知道下一个修订号是什么。编写一个获取下一个修订号的函数,Get-NextRevisionNumber。或者您可以像这样做:

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


2

这是一个简单的方法,对我很有效。它检查路径是否存在,如果不存在,则会创建根路径以及所有子目录:

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接