簡體   English   中英

創建新對象 PSObject 時出錯

[英]Error when creating a New-Object PSObject

這個 powershell 腳本在 csv 文件中最多占用 8 行,並通過復制列將它們組合成一行,然后保存在結果文件中(第一個結果文件保存得很好)。 如果 csv 中有 16 行,則意味着保存第二個結果文件等。

例如在 rows.csv 中:

第一場第二場第三場第四場

球棒球拍俱樂部

橙色香蕉芒果梨

在結果 1.csv 中:

第一1 第二1 第三1 第四1 第一2 第二2 第三2 第四2

球棒球拍俱樂部橙色香蕉芒果梨

我得到一個錯誤:

New-Object : Cannot convert 'System.Object[]' to the type 'System.Collections.IDictionary' required by parameter 'Property'. Specified method is not supported.
At C:csv.ps1:19 char:42
+ $results = New-Object PSObject -Property $details
+                                          ~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [New-Object], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.NewObjectCommand

請注意,第 16 行的第一個新對象創建工作正常。在 Powershell ISE 中,如果我重新運行腳本,它也會在第 16 行出錯。 我不知道這里出了什么問題,但假設我需要在保存每個 csv 文件后銷毀 PSObject?

$csvObjects = import-csv C:\rows.csv
$results = @()
$counter=1
foreach ($item in $csvObjects){
    $detailsnew = [ordered] @{            
        "first$counter" = $item.'First_field'          
        "second$counter" = $item.'Second_field'           
        "third$counter"  = $item.'Third_field'
        "fourth$counter" = $item.'Fourth_field'
    }   
    $details  +=  $detailsnew 
    # modulus comparison returns remainder - write out file every 8
    if ($counter % 8 -eq 0) {
        if ($counter -eq 8) {
            #works on line below on first run but fails on subsequent runs within Powershell ISE
            $results = New-Object PSObject -Property $details 
        }

        if ($counter -eq 16) {
            # fails on line below
            $results2 = New-Object PSObject -Property $details
        }

        $quotient = $counter / 8
        $results | export-csv -Path c:\result"$quotient".csv -noType
        $details = @()
        $results = @()
    }                     
    $counter++           
}
#write out final file if number not divisible by 8
if (-not($counter % 8 -eq 0)) {
    $results += New-Object PSObjectF -Property $details
    $modulo = $counter % 8
    $quotient_plus1 = (($counter-$modulo) / 8) +1
    $results | export-csv -Path C:\result"$quotient_plus1".csv -noType 
}

tl;博士

  • $details = @()應該是$details = [ordered] @{}

  • 為了使ISE 的重復執行也按預期工作,請在循環之前放置另一個$details = [ordered] @{}語句。


  • 在第一個循環迭代中, $details最初是undefined ,並且$details += $detailsnew分配$detailsnew (ordered) hash table (an [ordered] @{... } hash table in PowerShell is type System.Collections.Specialized.OrderedDictionary )原樣$details (即, $details未定義時, +=實際上與=行為相同)。

  • 在接下來的 7 次迭代中創建的$detailsnew hash 表然后通過+=合並到已存儲在$details中的 hash 表中。

  • 在第 8 次迭代之后,您錯誤地(重新)將$details初始化為數組( @() ),這是問題的根源:隨后使用+=然后將新的數組元素添加到$details而不是合並 hash表條目,並將數組而不是 hash 表(或任何實現System.Collections.IDictionary的字典類型)傳遞給New-Object-Property參數,然后 - 可以預見 - 失敗。

    • 相反,(重新)將$details初始化為有序的 hash 表: $details = [ordered] @{}

在 Powershell ISE 中,如果我重新運行腳本,它也會在第 16 行出錯。

PowerShell ISE 對其運行的腳本進行點源,這意味着來自先前調用的變量可能會持續存在。

順便說一句:這同樣適用帶有PowerShell 擴展名的 Visual Studio Code,您應該考慮將其遷移到[1] 但是,您可以選擇創建一個新的臨時 session ,如本答案底部所述。

在您的情況下,這意味着當您在 ISE 中重新執行腳本時, $details在第一次迭代中已經是一個數組


[1] PowerShell ISE 不再積極開發並且有理由不使用它(底部)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM