我有一个Powershell脚本,它读取包含共享及其属性的单行描述的文本文件。
然后,对于每个共享,将一个对象添加到具有属性的数组。
我最终获得了一系列股票,其中许多股票具有共同属性,但也有一些仅出现在少数股票上。
当我将完成的数组传输到Export-CSV
时,生成的CSV只有与数组中第一个对象的属性匹配的列。
任何想法/帮助都感激不尽。
以下是代码:
$shares_only = gc \\server\share\SHARES.txt | where {$_ -match '^*TYPE = DISK'}
$share_index = @()
$shares_only |foreach {
$sharename = ($_.Split(" ")[1])
$_ -match '\([\w\s.,"=<>()\/\*\+\-]*\);'|out-null
$shareparams = $matches[0]
$paramlist = ($shareparams.Substring(1,($shareparams.Length -3))).Split(",")
$obj = $null
$obj = New-Object System.Object
$obj | Add-Member -type NoteProperty -Name NAME -Value $sharename
$paramlist | foreach {
$obj `
| Add-Member -type NoteProperty -Name ($_.Split("=")[0]) -Value ($_.Split("=")[1])
}
$share_index += $obj
}
$share_index | Select * | Export-CSV -notype \\server\share\Shares.csv
以下是数组中的前两个对象作为示例(使用$share_index[0..2]
输出到控制台):
NAME : _ACCTEST_
TYPE : DISK
PREFIX : (<USERCODE>)
AREABYTES : 184320
ACCESS : ALL
FAMILY : ACCTESTPACK
DOWNSIZEAREA : TRUE
NAME : _HOME_
TYPE : DISK
PREFIX : (<USERCODE>)
COMMENT : Private user files
AREABYTES : 184320
ACCESS : ALL -EXTRACT
FAMILY : <FAMILY>
DOWNSIZEAREA : TRUE
ALLOWGUESTACCESS : TRUE
以下是CSV的前3行:
"NAME","TYPE ","PREFIX ","AREABYTES ","ACCESS ","FAMILY ","DOWNSIZEAREA "
"_ACCTEST_"," DISK "," (<USERCODE>) "," 184320 "," ALL "," ACCTESTPACK "," TRUE "
"_HOME_"," DISK "," (<USERCODE>) "," 184320 "," ALL -EXTRACT "," <FAMILY> "," TRUE "
您可以看到COMMENT
和ALLOWGUESTACCESS
属性已丢失,即使它们位于_HOME_
份额的数组中。
编辑:接受@JPBlancs答案的略微修改版本,所以我的代码的最后2行现在是:
$fixed_index = $share_index | Sort-Object -Property @{expression={(($_.psobject.Properties)|Measure-Object).count}} -Descending | ConvertTo-CSV -notype
$fixed_index | ConvertFrom-CSV | Sort -Property Name | Export-CSV -notype \\server\share\Shares.csv
因此,按照建议完成,然后在新对象中转换为CSV。 然后,将该对象从CSV转换回来,保留新属性,再次在Name上排序以获得我需要的字母列表,然后再次导出为CSV。
给我,例如:
"NAME","TYPE","PREFIX","PUBLIC","COMMENT","AREABYTES","ACCESS","FAMILY","DOWNSIZEAREA","ALLOWGUESTACCESS"
"_ACCTEST_"," DISK "," (<USERCODE>) ","",""," 184320 "," ALL "," ACCTESTPACK "," TRUE ",
"_HOME_"," DISK "," (<USERCODE>) ",""," Private user files "," 184320 "," ALL -EXTRACT "," <FAMILY> "," TRUE "," TRUE "
答案 0 :(得分:3)
Export-Csv
和ConvertTo-Csv
似乎只接受发送给它们的对象之间的属性联合。我认为您必须解析文本文件并编译所有属性的列表,并在创建对象时将任何缺少的属性值设置为null。
答案 1 :(得分:3)
我做了类似的事
$a = "" | select "P1","P2"
$b = "" | select "P1","P2","P3"
$c = "" | select "P1","P2","P3","P4"
$array = $a,$b,$c
$array | Export-Csv c:\temp\t.csv
在你说的时候给出:
#TYPE Selected.System.String
"P1","P2"
,
,
,
因此,我们的想法是按属性count对对象进行排序:
$array | Sort-Object -Property @{expression={$_.psobject.properties.count}} -Descending| Export-Csv c:\temp\t.csv
它给出了:
#TYPE Selected.System.String
"P1","P2","P3","P4"
,,,
,,,
,,,
对于问题(创建的对象,将成员添加到System.Object),您可以使用:
Sort-Object -Property @{expression={(($_.psobject.Properties)|Measure-Object).count}} -Descending
答案 2 :(得分:0)
我使用以下代码:
$a = "" | select "P1","P2"
$b = "" | select "P1","P2","P3"
$c = "" | select "P1","P2","P3","P4"
$props=@{n='P1';e={$_.p1}},@{n='P2';e={$_.p2}},@{n='P3';e={$_.p3}},@{n='P4';e={$_.p4}}
$array = $a,$b,$c
$array | select $props|Export-Csv c:\temp\t.csv
答案 3 :(得分:0)
JPBlanc的解决方案并不总是有效,因为最长的对象阵列不必是较小阵列的超集(例如,它不适用于下面显示的示例,其中所有对象都有不同的属性,但属性数量没有差异。)
我能够按如下方式解决这个问题:
$a = "" | select "P1","P2"
$b = "" | select "P2","P3"
$c = "" | select "P3","P4"
$array = $a,$b,$c
$array | Select ($array | ForEach {$_ | Get-Member -MemberType NoteProperty | Select -ExpandProperty Name} | Select -Unique) | Export-Csv ".\Union.csv"
不幸的是,这不适用于包含不同类型对象的WMI查询,但它与以下cmdlet一起使用:
Function Union-Object {
$Output = @()
$Input | ForEach {
If ($Output.Count) {$_ | Get-Member | Where {!($Output[0] | Get-Member $_.Name)} | ForEach {$Output[0] | Add-Member NoteProperty $_.Name $Null}}
$Output += $_
}
$Output
}; Set-Alias Union Union-Object
用法:
$array | Union | Export-Csv ".\Union.csv"