Powershell散列表不按预期写入文件 - 仅接收"System.Collections"行

ran*_*0m1 12 powershell hashtable

有人可以解释为什么我的第一个例子不起作用,为什么添加ForEach-Object解决了这个问题?提前致谢!


我将命令的返回值解析为哈希表(发布结束时的示例),并希望将信息记录到文件中作为我处理的一部分.我知道这$ht.GetEnumerator() | Sort-Object Name会将完整的哈希返回到屏幕,排序.但是,一旦我尝试将文件发送到文件,它就会中断.

$ht | Add-Content log.txt
Run Code Online (Sandbox Code Playgroud)

只记录一行System.Collections.Hashtable.所以,我也试过了

$ht.GetEnumerator() | Sort-Object Name | Add-Content log.txt 
Run Code Online (Sandbox Code Playgroud)

并最终成排

System.Collections.DictionaryEntry
System.Collections.DictionaryEntry
System.Collections.DictionaryEntry
Run Code Online (Sandbox Code Playgroud)

所以我试着循环并单独处理每一个

foreach ($key in $ht.keys) {
Add-Content log.txt "$key : $ht.$key" }
Run Code Online (Sandbox Code Playgroud)

并最终得到

Server address : System.Collections.Hashtable.Server address
Client address : System.Collections.Hashtable.Client address
User name : System.Collections.Hashtable.User name
Run Code Online (Sandbox Code Playgroud)

解决:

$ht.GetEnumerator() | Sort-Object Name |
ForEach-Object {"{0} : {1}" -f $_.Name,$_.Value} |
Add-Content log.txt 
Run Code Online (Sandbox Code Playgroud)

作为参考,哈希表样本:

$ht = @{
    "Server address" = "server.net";
    "Client address" = "10.20.121.153";
    "User name" = "myuser"
}
Run Code Online (Sandbox Code Playgroud)

ste*_*tej 13

回答原因部分,你显然有一个解决方案:)

在你的第一个例子中

$ht | Add-Content log.txt
Run Code Online (Sandbox Code Playgroud)

PowerShell采取$ht并尝试以某种方式将其转换为字符串,以便它可以存储Add-Content.由于没有为哈希表定义转换,因此仅从转换返回类型名称.与例如相同new-Object Random|Add-Content d:\log.txt.同样,只写入类型名称.

下一个

$ht.GetEnumerator() | Sort-Object Name | Add-Content log.txt 
Run Code Online (Sandbox Code Playgroud)

类似.GetEnumerator返回用于迭代的对象; System.Collections.DictionaryEntry返回类型的对象.同样,没有转换为字符串,因此返回类型名称.

就个人而言,我认为PowerShell应该足够聪明并且在这里提供帮助.问题是"如何?".设计人员可能不想硬编码输出.它可能是"{key}: {value}""{key} = {value}",或者"{key}/{value}"......或者格式不清楚,所以他们留给我们来决定和格式,就像你用foreach语句做的那样.


jri*_*523 8

我同意mjolinor ...只是没有足够的积分投票...加上我会补充说你不需要GetEnumerator

$ht | out-string | add-content log.txt
Run Code Online (Sandbox Code Playgroud)

会做的.


Emi*_*ggi 5

您的第一个示例不起作用,或者更好,部分起作用,因为您试图在字符串中获取属性值。通常,在字符串内部,解析器只能解析直接变量(如$key)。要解析更复杂的变量,您需要括号。

对于循环,这应该有效:

foreach ($ht.keys 中的 $key) {
添加内容 log.txt "$key : $($ht.$key)" }

甚至更好

$ht.keys | %{ 添加内容 log.txt "$_ : $($ht.$_)" }


JPB*_*anc 5

正如您在 Microsoft 文档中所见,哈希表只是名称-值对的集合。

所以$ht真的是System.Collections.HashtableSystem.Collections.DictionaryEntry.

使用它的一个好方法是

foreach ($i in $ht.keys)
{
  add-content log.txt ("{0} {1}" -f $i, $ht[$i])
}
Run Code Online (Sandbox Code Playgroud)