将包含PowerShell对象符号的文本文件转换为CSV

发布于 2025-02-13 12:03:51 字数 1060 浏览 0 评论 0原文

我有一个文本文件(psonobjects.txt),其中包含PowerShell对象表示法,如下所示:

@{Computer=Dektop123; ServiceA=Running; ServiceB=Running; RunspaceId=1a-1b}
@{Computer=Dektop456; ServiceA=Stopped; ServiceB=Stopped; RunspaceId=2b-2c}
@{Computer=Laptop123; ServiceA=NotFound; ServiceB=Running; RunspaceId=3c-4c}
@{ServiceA=NotFound; Computer=Laptop456; ServiceB=Running; RunspaceId=4d-5d}

我想将此PSON文件转换为CSV文件,但在整个尝试中都无法转换。

问题有时是对象的属性的顺序与以前的对象不同。就像上面示例中的最后一行一样。因此,简单地将半隆(';')转换为逗号(',')并删除'@{}'字符不会产生正确订购的CSV文件。

是否可以将此PSON(PowerShell对象符号)文件转换为CSV文件的简单方法?

我尝试了几种不同的方法,但是我一直在我的C​​SV输出文件中获取字符串的长度或HashTable输出的长度(ISReadOnly,IsFixedSize,IssyChronized,IssyChronized,IssyChronized,issychronized,issychronized,issychronized,issychronized,issychronized,issychronized,syncroot,count)。

非工作代码:

$inputFile = PsonObjects.txt
$CsvFileName = CsvOutput.csv
foreach($line in (Get-Contnet $inputfile)){
  $newline = $line | convertFrom-StringData
  $newline | Export-CSV $CsvFileName -Append 
} 

对此问题的任何帮助或建议将不胜感激。

I have a text file (PsonObjects.txt) that contains PowerShell Object Notation as follows:

@{Computer=Dektop123; ServiceA=Running; ServiceB=Running; RunspaceId=1a-1b}
@{Computer=Dektop456; ServiceA=Stopped; ServiceB=Stopped; RunspaceId=2b-2c}
@{Computer=Laptop123; ServiceA=NotFound; ServiceB=Running; RunspaceId=3c-4c}
@{ServiceA=NotFound; Computer=Laptop456; ServiceB=Running; RunspaceId=4d-5d}

I would like to convert this Pson file into a Csv file, but have been unable to throughout my attempts.

The problem is sometimes an object's properties are in a different order than the previous object. Like the last line in the above example. Therefor simply converting the semicolon (';') to a comma (',') and removing the '@{}' characters does not produce a properly ordered Csv file.

Is there an easy way to convert this Pson (Powershell object notation) file into a CSV file?

Ive tried a few different methods, but I keep getting either the length of the string, or hashtable output (IsReadOnly, IsFixedSize, IsSychronized, keys, Values, SyncRoot, Count) in my CSV output file.

Non Working code:

$inputFile = PsonObjects.txt
$CsvFileName = CsvOutput.csv
foreach($line in (Get-Contnet $inputfile)){
  $newline = $line | convertFrom-StringData
  $newline | Export-CSV $CsvFileName -Append 
} 

Any assistance or suggestions with this problem are appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

青巷忧颜 2025-02-20 12:03:51

convertfrom-stringdata输出一个未分类hashtable,其中元素可以按任何顺序为单位,因此在这里没有用。

这是使用-split运算符和分类步骤的可能解决方案,使用订购 Hashtable

$inputFile = 'PsonObjects.txt'
$csvFileName = 'CsvOutput.csv'

# The order of columns in the output CSV
$keyOrder = 'Computer','ServiceA','ServiceB','RunspaceId'

Get-Content $inputfile | ForEach-Object {
    $line = $_.Trim('@{}')   # Remove unwanted characters from current line

    # First parse the current line into an unordered hashtable
    $ht = @{}
    foreach( $field in $line -split '; ' ) {
        $key, $value = $field -split '='
        $ht[ $key ] = $value
    }   

    # Using the order specified by $keyOrder, create an ordered hashtable
    $orderedHt = [ordered] @{}
    foreach( $key in $keyOrder ) {
        $orderedHt[ $key ] = $ht[ $key ]
    }

    [PSCustomObject] $orderedHt     # Convert hashtable to custom object

} | Export-Csv $csvFileName

输出:

"Computer","ServiceA","ServiceB","RunspaceId"
"Dektop123","Running","Running","1a-1b"
"Dektop456","Stopped","Stopped","2b-2c" 
"Laptop123","NotFound","Running","3c-4c"
"Laptop456","NotFound","Running","4d-5d"

ConvertFrom-StringData outputs an unsorted Hashtable, where the elements can be in any order, so it is of no use here.

Here is a possible solution, using the -split operator and a sorting step, using an ordered Hashtable:

$inputFile = 'PsonObjects.txt'
$csvFileName = 'CsvOutput.csv'

# The order of columns in the output CSV
$keyOrder = 'Computer','ServiceA','ServiceB','RunspaceId'

Get-Content $inputfile | ForEach-Object {
    $line = $_.Trim('@{}')   # Remove unwanted characters from current line

    # First parse the current line into an unordered hashtable
    $ht = @{}
    foreach( $field in $line -split '; ' ) {
        $key, $value = $field -split '='
        $ht[ $key ] = $value
    }   

    # Using the order specified by $keyOrder, create an ordered hashtable
    $orderedHt = [ordered] @{}
    foreach( $key in $keyOrder ) {
        $orderedHt[ $key ] = $ht[ $key ]
    }

    [PSCustomObject] $orderedHt     # Convert hashtable to custom object

} | Export-Csv $csvFileName

Output:

"Computer","ServiceA","ServiceB","RunspaceId"
"Dektop123","Running","Running","1a-1b"
"Dektop456","Stopped","Stopped","2b-2c" 
"Laptop123","NotFound","Running","3c-4c"
"Laptop456","NotFound","Running","4d-5d"
作业与我同在 2025-02-20 12:03:51

这是 zett42的有用答案使用使用 href =“ https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.parser.parser?view = powershellsdk-7.0.0.0” class

$parse = Get-Content PsonObjects.txt -Raw
$ast   = [System.Management.Automation.Language.Parser]::ParseInput($parse, [ref] $null, [ref] $null)
$ast.EndBlock.Statements.PipelineElements.Expression | ForEach-Object {
    $out = [ordered]@{}
    foreach($pair in $_.KeyValuePairs) {
        $out[$pair.Item1.Extent.Text] = $pair.Item2.Extent.Text
    }
    [pscustomobject] $out
}

如果在哪里,代码将更简单引用,因为我们可以选择 .safegetValue() ,正如您现在拥有的那样,解析器将它们解释为命令而不是字符串。

$test = @'
@{Computer='Dektop123'; ServiceA='Running'; ServiceB='Running'; RunspaceId='1a-1b'}
@{Computer='Dektop456'; ServiceA='Stopped'; ServiceB='Stopped'; RunspaceId='2b-2c'}
'@

[System.Management.Automation.Language.Parser]::ParseInput($test, [ref] $null, [ref] $null).
    EndBlock.Statements.PipelineElements.Expression.ForEach{ [pscustomobject] $_.SafeGetValue() }

Here is another alternative to zett42's helpful answer using the Parser Class:

$parse = Get-Content PsonObjects.txt -Raw
$ast   = [System.Management.Automation.Language.Parser]::ParseInput($parse, [ref] $null, [ref] $null)
$ast.EndBlock.Statements.PipelineElements.Expression | ForEach-Object {
    $out = [ordered]@{}
    foreach($pair in $_.KeyValuePairs) {
        $out[$pair.Item1.Extent.Text] = $pair.Item2.Extent.Text
    }
    [pscustomobject] $out
}

Code would be much simpler if the Values where quoted, since we would have the option to use .SafeGetValue(), as you have them right now the parser is interpreting them as commands instead of strings.

$test = @'
@{Computer='Dektop123'; ServiceA='Running'; ServiceB='Running'; RunspaceId='1a-1b'}
@{Computer='Dektop456'; ServiceA='Stopped'; ServiceB='Stopped'; RunspaceId='2b-2c'}
'@

[System.Management.Automation.Language.Parser]::ParseInput($test, [ref] $null, [ref] $null).
    EndBlock.Statements.PipelineElements.Expression.ForEach{ [pscustomobject] $_.SafeGetValue() }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文