如何在powershell中包含csv中所有数组对象的所有属性

8qgya5xd  于 2023-09-27  发布在  Shell
关注(0)|答案(4)|浏览(88)

我有一个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 "

您可以看到COMMENTALLOWGUESTACCESS属性丢失,即使它们位于_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 "
j8yoct9x

j8yoct9x1#

我做了这样的事

$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"
,
,
,

所以我们的想法是按照属性计数对对象进行排序:

$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
xmakbtuz

xmakbtuz2#

Export-CsvConvertTo-Csv似乎只接受发送给它们的对象之间的属性的并集。我认为你将不得不解析文本文件并编译一个所有属性的列表,当你创建你的对象时,将任何缺失的属性值设置为null。

btqmn9zl

btqmn9zl3#

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"

参见GitHub问题:#13906 Add -UnifyProperties parameter to Select-Object

j9per5c4

j9per5c44#

我使用以下代码:

$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

相关问题