【问题标题】:Converting System.Collections.ArrayList to a string in Powershell将 System.Collections.ArrayList 转换为 Powershell 中的字符串
【发布时间】:2020-12-18 00:49:21
【问题描述】:

我在powershell中有以下测试脚本,我面临的问题是我想将错误的详细信息存储在自定义对象或变量中作为字符串,现在错误变量的值是类型System.Collections.ArrayList.

invoke-sqlcmd -ServerInstance "$sql" -inputfile $file  -Database test -OutputSqlErrors $true -ConnectionTimeout 10 -ErrorAction Continue -Errorvariable err | Out-Null

现在,奇怪的是,如果我跑了

$err | Get-Type

它的类型为System.Collections.ArrayList

如果我运行write-host $err,它会正确打印出错误,但是将$err 的值分配给自定义对象,然后我会丢失该值,而是得到'System.Collections.ArrayList'

$error_values += New-Object -TypeName psobject -Property @{ErrorMessage =$err}

现在正在运行$error_values | select ErrorMessage returns System.Collections.ArrayList

我只需要它是一个简单的字符串,不知道这里有什么不正确的。

【问题讨论】:

    标签: powershell formatting


    【解决方案1】:
    $arrayList = [System.Collections.ArrayList]::new()
    
    [void]$arrayList.Add("one")
    [void]$arrayList.Add("two")
    [void]$arrayList.Add("three")
    
    $msg = $arrayList -join ", "
    Write-Host $msg
    

    【讨论】:

      【解决方案2】:
      • 一般不要使用Write-Host输出数据,这样是不行的; 将其用于仅显示仅输出;要输出数据,请使用Write-Output,或者更好的是,使用 PowerShell 的 implicit 输出功能。

        • 在你的情况下,$error_values | select ErrorMessage本身不仅会将感兴趣的信息输出为数据,它还会导致有帮助 输出格式。

        • 请参阅this answer 了解更多信息。

      • 具体来说,即使需要仅显示输出,也不要使用Write-Host 打印复杂对象的表示 (粗略地说,具有属性的对象);
        改用Out-Host

        • $error_values | select ErrorMessage | Out-Host
        • 顺便说一句:select (Select-Object) 调用实际上是无操作的;我猜你的实际意思是$error_values | select -ExpandProperty ErrorMessage - 请参阅this answer 了解更多信息。
        • Write-Host执行丰富的输出格式,而 PowerShell 的默认显示格式和Out-Host 执行。由于Write-Host 使用简单的.ToString() 字符串化,复杂的对象通常会导致无用 表示 - 请参阅this answer 了解更多信息。

      一个完整的例子:

      # Create a sample ArrayList, as returned by 
      $err = [System.Collections.ArrayList] ('one', 'two')
      
      # Construct a custom object ([pscustomobject]) with an .ErrorMessage
      # property that contains the array list
      $obj = [pscustomobject] @{ ErrorMessage = $err }
      
      # !! Write-Host results in UNHELPFUL display:
      # !! Note how instead of listing the *elements* of the ArrayList
      # !! the *type name* ("System.Collections.ArrayList") is printed instead.
      PS> Write-Host $obj
      @{ErrorMessage=System.Collections.ArrayList}
      
      # OK: Out-Host produces richly formatted *display-only* output.
      PS> $obj | Out-Host
      
      ErrorMessage
      ------------
      {one, two}
      
      
      # OK as well: *implicit* output, *as data* - same representation.
      PS> $obj
      
      ErrorMessage
      ------------
      {one, two}
      

      注意:对于 direct 显示元素不是复杂对象的集合的输出,Write-Hostsingle-行输出是需要的,因为元素然后只是空间连接:

      $err = [System.Collections.ArrayList] ('one', 'two')
      
      # OK with collection of non-complex objects to get a 
      # *single-line* representation.
      # Out-Host and implicit output print each element on its own line.
      PS> Write-Host $err
      one two
      

      您甚至可以使用-Separator 来使用空格以外的分隔符:

      PS> Write-Host -Separator /  'one', 'two'
      one/two
      

      当然,您也可以使用 表达式 来创建这样的字符串,使用 -joinstring joining operator 运算符,这将允许您将输出 用作数据

      PS> 'one', 'two' -join '/'
      one/two
      

      可选阅读:为什么传递给-ErrorVariable 的目标变量会收到System.Collections.ArrayList 实例:

      common -ErrorVariable parameter——实际上是所有常见的-*Variable 参数,它们在变量中收集流的输出——总是返回一个带有收集输出的 System.Collections.ArrayList 实例,这在两个方面令人惊讶:

      • PowerShell 通常使用[object[]]arrays 作为其默认的集合数据类型。

      • 另外,在-OutVariable的情况下,行为与管道的direct输出不一致,其中一个命令输出的单个对象是输出as such - 而不是被包装在一个集合中,例如 ArrayList 在这种情况下;也就是说,即使您希望以下两个命令是等价的,它们也不是:

        $out = Get-Date  
        # -> $out is a [datetime] instance.
        
        # !! -OutVariable *always* creates ArrayList.
        $null = Get-Date -OutVariable out 
        # -> $out is a *single-element ArrayList* containing a [datetime] instance.
        

      有关这些不一致的讨论,请参阅GitHub issue #3154

      【讨论】:

        猜你喜欢
        • 2013-03-02
        • 1970-01-01
        • 1970-01-01
        • 2014-10-08
        • 2017-11-07
        • 2017-10-01
        • 2020-04-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多