2016-09-23 58 views
0

我试图将所有CA证书导出到Base64格式的目录,我是新来的PowerShell,因为我习惯用bash做脚本。不知何故,我没有看到感觉应该是显而易见的事情。PowerShell混淆数组循环,foreach方法,字符串?

这是我行至今,

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

我感谢所有帮助,因为我想学习如何在PS4习惯。

回答

2

这行代码包含了3个问题:

第一。带对象属性的字符串插值。 PS解析器不了解"$var.Property",它只能理解$expression在“字符串”内。但既然它是表达式,而不仅仅是变量名称,你可以让PS用"$(something to evaluate)"来评估你的行。换句话说,你的-FilePath应该是:

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

二。使用对象。 PS下面是全面的.Net框架。即使许多对象以简单的,预定义的方式在输出中表示,实际上它们仍然被输出为完整的活动对象。据MSDN,该-Cert参数是<Certificate>,而不是指向一个证书一个字符串,所以你-Cert应该是简单的

-Cert $_ 

第三。阵列。Get-ChildItem下面只不过是DirectoryInfo.GetFileSystemInfos()它返回一个对象数组。所以理想情况下,你不需要用任何东西来包装它,并且可以简单地将其进一步管道化(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 {...} 
+0

形式改写_“'@(...)'是创建一个项目的一个新的数组是数组通过GCI还给你” _ - 不,如果输出已经是一个数组,那么使用数组subsppession将不会影响输出。例子:'@(@(1))[0] .GetType()' - 返回'Int32',而不是'Object []'。 – beatcracker

+0

这不是因为该项目是数组;它;因为超级数组包含1项。如果你说的是真实的,并且只限于你所说的话 - 那么你的例子会导致'System.Array'不是'System.Int32'。我用这三个例子来解释行为。 –