【问题标题】:PowerShell Export-Csv repeating last value in output - solutionPowerShell Export-Csv 在输出中重复最后一个值 - 解决方案
【发布时间】:2018-08-17 16:14:25
【问题描述】:

场景: 在我的脚本中,我创建一个对象,添加公共信息,然后在循环中更新每个对象的子信息,并将该对象添加到对象数组中。 我的详细说明显示添加到数组的对象中的值是正确的(报告数组中的最后一项),但 Export-Csv 重复最后一个对象值。 如果我每次都创建一个新对象,我就能解决这个问题。重复使用同一个对象会重复最后一个值,即使当我在数组中的对象上选择 * 时我可以看到它是正确的。数组对象必须有一些东西,例如为同一对象复制的 guid。 PowerShell 5.1 在 Windows 7、Windows 2008R2、Windows 2010R2 上验证

解决方案: 将对象添加到对象数组时不要重用它。

输出:

#TYPE MyGpoSetting
"SetName","SetCategory","SetType","SetState","SetValue","SetData","SetNote","SubName","SubState","SubValue","GpoDomain","GpoName","GpoLinks","GpoGuid"
"SetName","SetCategory","SetType","SetState","SetValue","SetData","SetNote","SubName3","SubState3","SubValue3","GpoDomain","GpoName","GpoLinks","GpoGuid"
"SetName","SetCategory","SetType","SetState","SetValue","SetData","SetNote","SubName3","SubState3","SubValue3","GpoDomain","GpoName","GpoLinks","GpoGuid"
"SetName","SetCategory","SetType","SetState","SetValue","SetData","SetNote","SubName3","SubState3","SubValue3","GpoDomain","GpoName","GpoLinks","GpoGuid"

脚本:

Add-Type -TypeDefinition @"
   public struct MyGpoSetting
   {
      public string  SetName;
      public string  SetCategory;
      public string  SetType;
      public string  SetState;
      public string  SetValue;
      public string  SetData;
      public string  SetNote;
      public string  SubName;
      public string  SubState;
      public string  SubValue;
      public string  GpoDomain;
      public string  GpoName;
      public string  GpoLinks;
      public string  GpoGuid;
   }
"@
$aoMyGpoSetting = @();
$oMyGpoSetting = New-Object -TypeName 'MyGpoSetting';
$oMyGpoSetting.SetName       = 'SetName';
$oMyGpoSetting.SetCategory   = 'SetCategory';
$oMyGpoSetting.SetType       = 'SetType';
$oMyGpoSetting.SetState      = 'SetState';
$oMyGpoSetting.SetValue      = 'SetValue';
$oMyGpoSetting.SetData       = 'SetData';
$oMyGpoSetting.SetNote       = 'SetNote';
$oMyGpoSetting.SubName       = 'SubName1';
$oMyGpoSetting.SubState      = 'SubState1';
$oMyGpoSetting.SubValue      = 'SubValue1';
$oMyGpoSetting.GpoDomain     = 'GpoDomain';
$oMyGpoSetting.GpoName       = 'GpoName';
$oMyGpoSetting.GpoLinks      = 'GpoLinks';
$oMyGpoSetting.GpoGuid       = 'GpoGuid';
$aoMyGpoSetting += $oMyGpoSetting;
#--- $oMyGpoSetting = New-Object -TypeName 'MyGpoSetting';
$oMyGpoSetting.SetName       = 'SetName';
$oMyGpoSetting.SetCategory   = 'SetCategory';
$oMyGpoSetting.SetType       = 'SetType';
$oMyGpoSetting.SetState      = 'SetState';
$oMyGpoSetting.SetValue      = 'SetValue';
$oMyGpoSetting.SetData       = 'SetData';
$oMyGpoSetting.SetNote       = 'SetNote';
$oMyGpoSetting.SubName       = 'SubName2';
$oMyGpoSetting.SubState      = 'SubState2';
$oMyGpoSetting.SubValue      = 'SubValue2';
$oMyGpoSetting.GpoDomain     = 'GpoDomain';
$oMyGpoSetting.GpoName       = 'GpoName';
$oMyGpoSetting.GpoLinks      = 'GpoLinks';
$oMyGpoSetting.GpoGuid       = 'GpoGuid';
$aoMyGpoSetting += $oMyGpoSetting;
#--- $oMyGpoSetting = New-Object -TypeName 'MyGpoSetting';
$oMyGpoSetting.SetName       = 'SetName';
$oMyGpoSetting.SetCategory   = 'SetCategory';
$oMyGpoSetting.SetType       = 'SetType';
$oMyGpoSetting.SetState      = 'SetState';
$oMyGpoSetting.SetValue      = 'SetValue';
$oMyGpoSetting.SetData       = 'SetData';
$oMyGpoSetting.SetNote       = 'SetNote';
$oMyGpoSetting.SubName       = 'SubName3';
$oMyGpoSetting.SubState      = 'SubState3';
$oMyGpoSetting.SubValue      = 'SubValue3';
$oMyGpoSetting.GpoDomain     = 'GpoDomain';
$oMyGpoSetting.GpoName       = 'GpoName';
$oMyGpoSetting.GpoLinks      = 'GpoLinks';
$oMyGpoSetting.GpoGuid       = 'GpoGuid';
$aoMyGpoSetting += $oMyGpoSetting;
$aoMyGpoSetting | Export-Csv -Path 'c:\temp\export.csv' -Encoding 'ASCII';

【问题讨论】:

    标签: powershell export-csv


    【解决方案1】:

    这是按预期工作的。将对象添加到数组 (+=) 不会复制对象,而是在下一个“插槽”中添加指向它的引用/指针。因此,实际上您正在添加对同一对象的三个引用。这就像在您最好的朋友的电话簿中有 3 个条目:

    John Smith - 01234 5678
    Jonnie - 01234 5678
    Smith, John - 01234 5678
    

    无论您打电话给哪个人,都会让您接通完全相同的人。

    同样,每次 PowerShell 从您的数组中显示一个对象时,它实际上都会返回到同一个源对象并将其显示给您。这就是为什么它们都具有与您添加的最后一个相同的属性的原因 - 它们实际上都是相同的。

    正如您所发现的,每次都创建一个新对象是继续的方法。

    【讨论】:

    • "将对象添加到数组 (+=) 不会复制对象,而是在下一个 'slot' 中添加指向它的引用/指针。"您在这里的措辞具有误导性。 PowerShell 使用 C# 数组和字符串,它们大小固定。数组/字符串上的+= 将在内部创建一个新数组/字符串,然后复制每个元素并将新元素添加到末尾。 This article explains it。我知道这不是您回答的重点,但这是一种非常常见的混淆和脚本反模式。
    • @BaconBits,绝对。这对我来说是糟糕的措辞。你是对的,它每次都会创建一个新数组,我确实考虑过如何最好地表达它,但认为它可能只会使问题变得模糊,因为在任何一种情况下,它都会导致提问者所询问的相同行为。我将保持原样 - 人们可以查看您的评论以更全面地解释数组的工作原理。
    猜你喜欢
    • 2019-07-18
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多