2015-08-13 111 views
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() 

如果folder1中不存在它會返回:

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 

工作實例後安斯加爾建議:

$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 

回答

3

New-Item返回創建的對象,和PowerShell函數返回的所有非捕獲輸出,而不僅僅是return關鍵字的說法。

在Windows PowerShell中,即使沒有包含Return關鍵字的語句,也會將每條語句的結果作爲輸出返回。像C或C#這樣的語言只返回由Return關鍵字指定的值。

這意味着如果路徑已經存在,你的函數只返回路徑字符串。否則,它會返回一個數組,其中包含新的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,這將允許您強制參數,定義參數順序,驗證輸入和許多其他事情。
  • 使用PowerShell命名約定和approved verbs作爲您的函數名稱。

例子:

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 
    } 
} 
+0

你救了我的一天。謝謝。並感謝您的建議 – Chintsu