powershell - New-Item改变函数返回值

标签 powershell powershell-5.0

我想编写一个函数,在指定文件夹内创建一个具有指定名称的文件夹(如果它不存在)。
原来,取决于调用New-Item函数返回不同的值。我不知道它与 New-Item 有什么关系实际上。

$folderPath = "C:\tmp"

function CreateFolder([string] $name, [string] $parentFolder) 
{
  $path = "$parentFolder\$name"

  if(!(Test-Path $path))
  {
    New-Item -path $parentFolder -name $name -itemtype Directory
  }

  return $path
}

$FOLDER_NAME = "folder1"

$destination = CreateFolder $FOLDER_NAME $folderPath

echo $destination.GetType()

如果 文件夹 1 不存在 它会返回:
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

除此以外:
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

除非 Move-Item支持Object[]-destination范围。
echo $destination返回:
PSPath            : Microsoft.PowerShell.Core\FileSystem::C:\tmp\folder1
PSParentPath      : Microsoft.PowerShell.Core\FileSystem::C:\tmp
PSChildName       : folder1
PSDrive           : C
PSProvider        : Microsoft.PowerShell.Core\FileSystem
PSIsContainer     : True
Name              : folder1
Parent            : tmp
Exists            : True
Root              : C:\
FullName          : C:\tmp\folder1
Extension         : 
CreationTime      : 13.08.2015 10:53:11
CreationTimeUtc   : 13.08.2015 7:53:11
LastAccessTime    : 13.08.2015 10:53:11
LastAccessTimeUtc : 13.08.2015 7:53:11
LastWriteTime     : 13.08.2015 10:53:11
LastWriteTimeUtc  : 13.08.2015 7:53:11
Attributes        : Directory, NotContentIndexed
BaseName          : folder1
Target            : 
LinkType          : 
Mode              : d-----

我找到的唯一解决方案是不使用该功能:
$folderPath = "C:\tmp"

$FOLDER_NAME = "folder1"

$destination = "$folderPath\$FOLDER_NAME"

if(!(Test-Path $destination))
{
  New-Item -path $folderPath -name $FOLDER_NAME -itemtype Directory
}

Move-Item -path "C:\tmp\file1" -destination $destination

如果文件夹 1 不存在:
    Каталог: C:\tmp


Mode                LastWriteTime         Length Name                                                                                                                    
----                -------------         ------ ----                                                                                                                    
d-----       13.08.2015     11:06                folder1                                                                                                                 

MemberType                 : TypeInfo
DeclaringType              : 
DeclaringMethod            : 
ReflectedType              : 
StructLayoutAttribute      : System.Runtime.InteropServices.StructLayoutAttribute
GUID                       : 296afbff-1b0b-3ff5-9d6c-4e7e599f8b57
Module                     : CommonLanguageRuntimeLibrary
Assembly                   : mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
TypeHandle                 : System.RuntimeTypeHandle
FullName                   : System.String
Namespace                  : System
AssemblyQualifiedName      : System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
BaseType                   : System.Object
TypeInitializer            : 
IsNested                   : False
Attributes                 : AutoLayout, AnsiClass, Class, Public, Sealed, Serializable, BeforeFieldInit
GenericParameterAttributes : 
IsVisible                  : True
IsNotPublic                : False
IsPublic                   : True
IsNestedPublic             : False
IsNestedPrivate            : False
IsNestedFamily             : False
IsNestedAssembly           : False
IsNestedFamANDAssem        : False
IsNestedFamORAssem         : False
IsAutoLayout               : True
IsLayoutSequential         : False
IsExplicitLayout           : False
IsClass                    : True
IsInterface                : False
IsValueType                : False
IsAbstract                 : False
IsSealed                   : True
IsEnum                     : False
IsSpecialName              : False
IsImport                   : False
IsSerializable             : True
IsAnsiClass                : True
IsUnicodeClass             : False
IsAutoClass                : False
IsArray                    : False
IsGenericType              : False
IsGenericTypeDefinition    : False
IsConstructedGenericType   : False
IsGenericParameter         : False
GenericParameterPosition   : 
ContainsGenericParameters  : False
IsByRef                    : False
IsPointer                  : False
IsPrimitive                : False
IsCOMObject                : False
HasElementType             : False
IsContextful               : False
IsMarshalByRef             : False
GenericTypeArguments       : {}
IsSecurityCritical         : False
IsSecuritySafeCritical     : False
IsSecurityTransparent      : True
UnderlyingSystemType       : System.String
Name                       : String
CustomAttributes           : {[System.SerializableAttribute()], [System.Reflection.DefaultMemberAttribute("Chars")], [System.Runtime.InteropServices.ComVisibleAttribute(
                         (Boolean)True)], [__DynamicallyInvokableAttribute()]}
MetadataToken              : 33554536

除此以外:
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

工作示例 根据 Ansgar 的建议:
$folderPath = "C:\tmp"

function GetDestination {
  [CmdletBinding()]
  Param(
    [Parameter(Mandatory=$true)]
    [string]$Name,

    [Parameter(Mandatory=$true)]
    [string]$ParentFolder
  )

  $path = Join-Path $ParentFolder $Name

  if(Test-Path -LiteralPath $path) {
    Get-Item -LiteralPath $path
  } else {
    New-Item -Path $ParentFolder -Name $Name -ItemType Directory
  }
}

$FOLDER_NAME = "folder1"

$destination = GetDestination $FOLDER_NAME $folderPath

Move-Item -LiteralPath "C:\tmp\file1" -Destination $destination

最佳答案

New-Item返回创建的对象,PowerShell 函数返回所有未捕获的输出,而不仅仅是 return 的参数关键词。

In Windows PowerShell, the results of each statement are returned as output, even without a statement that contains the Return keyword. Languages like C or C# return only the value or values that are specified by the Return keyword.



这意味着如果路径已经存在,您的函数只返回路径字符串。否则它返回一个带有新 DirectoryInfo 的数组。对象和路径字符串。

取决于你想要一个字符串还是 DirectoryInfo返回的对象,您可以抑制 New-Item 的输出:
if (!(Test-Path $path)) {
  New-Item -Path $parentFolder -Name $name -ItemType Directory | Out-Null
}

return $path

或删除 return声明,而是添加一个 else您调用的分支机构Get-Item在路径上:
if (!(Test-Path $path)) {
  New-Item -Path $parentFolder -Name $name -ItemType Directory
} else {
  Get-Item $path
}

在更一般的说明中,我建议对您的代码进行一些修改:
  • 使用 -LiteralPath Test-Path 的参数,因此当路径包含方括号等特殊字符时,您不会遇到问题。
  • 使用Join-Path用于构建路径,因为它会自动处理路径分隔符。
  • 使用advanced parameter definitions ,这将允许您强制参数、定义参数顺序、验证输入以及许多其他事情。
  • 使用带有 approved verbs 的 PowerShell 命名约定为您的函数名称。

  • 例子:
    function New-Folder {
      [CmdletBinding()]
      Param(
        [Parameter(Mandatory=$true)]
        [string]$Name,
        [Parameter(Mandatory=$true)]
        [string]$ParentFolder
      )
    
      $path = Join-Path $ParentFolder $Name
    
      if (-not (Test-Path -LiteralPath $path)) {
        New-Item -Path $ParentFolder -Name $Name -ItemType Directory
      } else {
        Get-Item -LiteralPath $path
      }
    }
    

    关于powershell - New-Item改变函数返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31982926/

    相关文章:

    powershell - 如何在Windows 7上为特定用户执行RunOnce?

    powershell - 将参数传递到 Powershell

    powershell - 搜索广告组成员

    powershell - 使用文本文件遍历PowerShell命令

    powershell - 通过PowerShell安装exe时可以替代时间延迟吗?

    powershell - 未加载 SQLASCmdlets,因为在任何模块目录中均未找到有效的模块文件

    azure - Azure CLI 和 Powershell cmdlet 之间的功能不一致

    file - 匹配文件名并使用PowerShell复制

    powershell - 我们可以在PowerShell中编写星级程序吗?

    powershell - Add-ADGroupMember变量类型问题