【问题标题】:Issues Overloading ToString on Nested PSObject Property在嵌套 PSObject 属性上重载 ToString 的问题
【发布时间】:2018-08-28 01:07:11
【问题描述】:

我已经创建了一个具有多种属性的自定义 PSObject,并且我正在尝试为其中一些属性重载 ToString。我在 TimeSpan 属性之一上取得了成功,但在 WMI 对象上却没有。

# Get WMI info
$wmiOS = Get-WmiObject -Class Win32_OperatingSystem
$wmiSystem = Get-WmiObject -Class Win32_ComputerSystem
$wmiDrives = Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType='3'"
$ipv4Address = (Test-Connection -ComputerName $env:COMPUTERNAME -Count 1).IPV4Address.IPAddressToString
$uptime = (Get-Date) - ($wmiOS.ConvertToDateTime($wmiOS.LastBootUpTime))
# Setup object
$result = New-Object -TypeName psobject -Property @{
    Hostname = $($wmiSystem.Name)
    Domain = $($wmiSystem.Domain)
    Username = $($wmiSystem.Username)
    OperatingSystem = $($wmiOS.Caption)
    OSArchitecture = $($wmiOS.OSArchitecture)
    PSVersion = "$($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor)"
    IPv4Address = $ipv4Address
    Uptime = $uptime
    DriveInfo = $wmiDrives
}

# Overload DriveInfo ToString
$result.DriveInfo = $result.DriveInfo | Add-Member -MemberType ScriptMethod -Name ToString -Value {
    "$($this.DeviceID) $($this.FreeSpace) GB;"
} -Force -PassThru

# Overload Uptime ToString 
$result.Uptime = $result.Uptime | Add-Member -MemberType ScriptMethod -Name ToString -Value {
    "$($this.Days) days, $($this.Hours) hours, $($this.Minutes) minutes, $($this.Seconds) seconds"
} -Force -PassThru

# Overload result ToString
$result = $result | Add-Member -MemberType ScriptMethod -Name ToString -Value {
    $temp = @"
Hostname: $($this.Hostname)
Domain: $($this.Domain)
Console User: $($this.Username)
Operating System: $($this.OperatingSystem)
OS Architecture: $($this.OSArchitecture)
PS Version: $($this.PSVersion)
IPv4 Address: $($this.IPv4Address)
Uptime: $($this.Uptime.ToString())
Free Space: $($this.DriveInfo)
"@
        $temp
    } -Force -PassThru

似乎一切正常,但 DriveInfo 过载。我只是得到“System.Object []”作为它的回报。对我来说奇怪的是,当我执行 $result.ToString() 时,我得到以下信息(请参阅“可用空间”):

Domain: domain.local
Console User: domain\username
Operating System: Microsoft Windows 10 Pro
OS Architecture: 64-bit
PS Version: 5.1
IPv4 Address: 1.1.1.1
Uptime: 2 days, 1 hours, 31 minutes, 49 seconds
Free Space: C: 58721181696; E: 631496687616;

$result.Uptime.ToString():

2 days, 1 hours, 19 minutes, 34 seconds

$result.DriveInfo.ToString():

System.Object[]

我可能遗漏了一些明显的东西,但我现在迷路了。感谢您提前提供的任何帮助!

【问题讨论】:

  • DriveInfo 是一个数组。您需要选择单个驱动器或自己找出 tostrong 逻辑,因为 Object 类型没有过载
  • 我认为可能是这样。知道为什么它甚至不会打印不相关的字符串吗?如果我只是用“这是一个测试”重载它,当我调用 $result.DriveInfo.ToString() 时它仍然不会打印它。当我在父对象的 ToString ($result.ToString()) 中引用它时,它似乎打印了我想要的内容。
  • 您可以扩展array 类型,方法是使用Update-TypeData 在数组的每个成员上调用ToString
  • 我会试一试。谢谢。

标签: powershell overloading psobject get-wmiobject


【解决方案1】:

你可以尝试替换吗:

$result.DriveInfo = $result.DriveInfo | Add-Member -MemberType ScriptMethod -Name ToString -Value {"$($this.DeviceID) $($this.FreeSpace) GB;"} -Force -PassThru

$result.DriveInfo | Add-Member -MemberType ScriptMethod -Name ToString -Value {"$($this.DeviceID) $($this.FreeSpace) GB;"} -Force -PassThru

据我了解,Add-Member 适用于每个驱动器,您不需要影响结果,因为您更改了列表中的每个对象。之后,您可以使用以下方法进行测试:

$n = 0
$result.DriveInfo[$n].ToString()

【讨论】:

  • 成功了!不知道为什么我不考虑在数组的单个成员上尝试它。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2022-11-10
  • 1970-01-01
  • 2015-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多