powershell 对数组循环、foreach 方法、字符串感到困惑?

powershell confused about array loop, foreach method, string?

我正在尝试将所有 CA 证书导出到 Base64 格式的目录,我是 powershell 的新手,因为我习惯使用 bash 编写脚本。不知何故,我没有看到应该显而易见的东西。

这是我到目前为止的台词,

@(Get-ChildItem -path Cert:\Localmachine\ca).ForEach({Export-Certificate -Type CERT -FilePath "C:\ssl\certs.d$_.Thumbprint" -Cert "Cert:\LocalMachine\ca$_.Thumbprint"})

感谢任何帮助,因为我正在努力学习如何在 PS4 中保持地道。

这行代码包含3个问题:

第一。对象 属性. 的字符串插值 PS 解析器不理解 "$var.Property",它只理解 "string" 中的 $expression。但是因为它是表达式,而不仅仅是变量名,你可以让 PS 用 "$(something to evaluate)" 计算你的行。换句话说,您的 -FilePath 应该是:

-FilePath "C:\ssl\certs.d$($_.Thumbprint)"

其次。使用对象。 PS 下面是成熟的 .Net 框架。尽管许多对象以简单的、预定义的方式在输出中表示,但实际上它们是作为完整的活动对象输出的。根据 MSDN-Cert 参数是 <Certificate>,而不是指向证书的字符串,因此您的 -Cert 应该只是

-Cert $_

第三。 Arrays.Get-ChildItem下面无非就是DirectoryInfo.GetFileSystemInfos()其中returns一个数组对象。所以理想情况下,您不需要用任何东西包裹它,并且可以简单地通过管道进一步传输它 (Get-ChildItem | Foreach-Object{...})。但是很多人对PS语法有不同的口味,所以(gci).ForEach({...})(没有@)的形式也有生存的权利。但是您以 @(...) 的形式所做的是 创建一个新数组 其中一项是 gci 返回给您的数组。所以从技术上讲,它不应该起作用。不过它会的,因为 PS 会自动将您从此类错误中拯救出来:在 PS 中,您可以使用与直接处理此项目相同的方式处理 1 个项目的数组(除非明确指定相反)。为了说明,

@(4).Length # returns 1
@(@(2,3)).Length # returns 2
@(,@(2,3)).Length #returns 1

因此,您当前的 Get-ChildItem 语法容易出错并且依赖于自动 PS 错误处理糖。我建议在开头删除 @,或者以

的形式重写
Get-ChildItem -...... | Foreach-Object {...}