请注意,语法规范要求使用 STRING ARRAY; ala 字符串[]
SYNTAX
Copy-Item [[-Destination] <String>] [-Confirm] [-Container] [-Credential <PSCredential>] [-Exclude <String[]>] [-Filter <String>] [-Force] [-FromSession <PSSession>] [-Include
<String[]>] -LiteralPath <String[]> [-PassThru] [-Recurse] [-ToSession <PSSession>] [-UseTransaction] [-WhatIf] [<CommonParameters>]
如果您在数组生成中没有明确说明,您最终会得到一个 Object[] - 在许多情况下会被忽略,由于类型安全而留下“错误行为”的外观。由于 PowerShell 可以处理脚本块,因此对特定类型变量以外的评估(以便可以确定有效字符串)将为执行策略松懈的任何系统上的注入模式攻击的可能性留下一个机会。
所以这是不可靠的:
PS > $omissions = @("*.iso","*.pdf","*.zip","*.msi")
PS > $omissions.GetType()
Note the result....
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
这行得通....例如:
PS > $omissions = [string[]]@("*.iso","*.pdf","*.zip","*.msi")
**or**
PS > [string[]]$omissions = ("*.iso,*.pdf,*.zip,*.msi").split(',')
PS > $omissions.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String[] System.Array
请注意,即使是“单个”元素仍需要相同的转换,以便创建一个 1 元素数组。
如果您在家中尝试此操作,请务必使用 Replace-Variable “omissions” 清除 $omissions 的存在,然后再在上面显示的示例中重铸它。
就我测试过的可靠工作的管道而言......
--------------------------------------------------------------------------------------- cd $sourcelocation
ls | ?{$_ -ne $null} | ?{$_.BaseName -notmatch "^\.$"} | %{$_.Name} | cp -Destination $targetDir -Exclude $omissions -recurse -ErrorAction silentlycontinue
---------------------------------------------------------------------------------------
上面做了一个基本(选择“当前”)目录中源文件的目录列表,过滤掉潜在的问题项目,将文件转换为基本名称并强制cp(复制项目别名)重新访问“当前目录”中的“按名称”文件 - 从而重新获取文件对象并复制它。这将创建空目录,包括那些甚至可能包含排除文件的目录(当然少了排除)。另请注意,“ls”(get-childitem)不会 -recurse - 留给 cp。最后 - 如果您遇到问题并需要调试,请删除 -ErrorAction quietlycontinue 开关和参数,这隐藏了许多可能会中断脚本的麻烦。
对于那些 cmets 与“\”包含相关的人,请记住,您正在通过解释器(即 PowerShell)处理 .NET 子层,例如,在 c# 中,包含单个“ \" (或字符串中的多个单项),导致编译器要求您通过使用“\\”来转义反斜杠来更正条件,或者在字符串前面加上@,如@“\”;剩下的另一个选项是用单引号括起来的字符串,如'\'。所有这一切都是因为字符组合的 ASCII 插值,如“\n”等。
后者是一个更大的主题,所以我将把这个考虑留给你。