【问题标题】:Add-Member to WMI object best practice?将成员添加到 WMI 对象最佳实践?
【发布时间】:2018-05-22 06:48:34
【问题描述】:

我正在编写一个使用 WMI 对象获取 Windows 版本的函数。但我想将 Windows 10 ReleaseId ("1709")(来自注册表项)添加到对象中。

这是一个愚蠢的想法吗? (它有效,我只是不知道这样做是否明智。)

function Get-OSVersion {
    [version]$OSVersion = (Get-WmiObject -Class Win32_OperatingSystem).Version

    if ($OSVersion.Major -ge '10') {
        $OSVersion | Add-Member -MemberType NoteProperty -Name ReleaseId -Value $([int]::Parse($(Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion" ReleaseId).ReleaseId)) -Force
    }

    return $OSVersion
}

$OSVersion = Get-OSVersion
if ($OSVersion -ge '6.1') {"At least Win7"} else {"Too old"}
if ($OSVersion.ReleaseID -ge '1703') {"At least 1703."} else {"Too old"}

另外,覆盖成员“Revision”(值始终为-1)而不是添加新成员“ReleaseId”是否不明智?

【问题讨论】:

    标签: windows powershell object wmi


    【解决方案1】:

    扩展我的评论:

    我不建议更改您不需要的 wmi 类,但您没有这样做。除了将成员添加到已定义的标准库类 (System.Version) 并与字符串进行数字比较之外,我认为您的方法没有任何问题。

    我建议做的是创建一个[pscustomobject] 与您需要的成员:

    function Get-OSVersion {
        $OSVersion = [version](Get-CimInstance -ClassName Win32_OperatingSystem).Version
    
        if ($OSVersion.Major -ge 10) {
            [pscustomobject]@{
                Version = $OSVersion
                ReleaseId = [int](Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion').ReleaseId
            }
        } else {
            [pscustomobject]@{
                Version = $OSVersion
            }
        }
    }
    

    使用中:

    $OS = Get-OSVersion
    if ($OS.Version -ge [version]'6.1') {
        'At least Win7'
    } else {
        'Too old'
    }
    if ($OS.ReleaseId -ge 1703) {
        'At least 1703.'
    } else {
        'Too old'
    }
    

    提供替代方案:使用哈希表,因为看起来您只是在进行键/值访问和比较而没有任何方法实现。

    function Get-OSVersion {
        $OS = @{
            Version = [version](Get-CimInstance -ClassName Win32_OperatingSystem).Version
        }
    
        if ($OS.Version.Major -ge 10) {
            $OS['ReleaseId'] = [int](Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion').ReleaseId
        }
    
        return $OS
    }
    

    【讨论】:

    • 感谢您的帮助,非常感谢。最后,如果我需要保持脚本与 PowerShell 2.0 兼容,那么 Ansgar Wiechers 的解决方案是否更适合我?因为我认为 [pscustomobject] 直到 3.0 才可用。
    • @mrkrch 你可以使用New-Object -TypeName pscustomobject -Property @{ hashtable here },但是如果你是2,他的解决方案其实更容易实现
    【解决方案2】:

    我的建议是使用calculated properties:

    function Get-OSVersion {
        Get-WmiObject -Class Win32_OperatingSystem |
            Select-Object @{n='Version';e={[version]$_.Version}},
                @{n='ReleaseId';e={
                    if (([version]$_.Version).Major -ge '10') {
                        [int](Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion').ReleaseId
                    }
                }}
    }
    

    【讨论】:

    • 我想指出Select-Object 返回一个[pscustomobject] 类型(并且您仍在对整数进行字符串比较)。
    • 是的,但我看不到该信息在给定上下文中的相关性。
    • 只是为了提供信息,因为 OP 似乎没有很好地掌握对象类型。
    猜你喜欢
    • 1970-01-01
    • 2012-07-20
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 2017-01-19
    • 2011-07-12
    • 2011-12-27
    • 1970-01-01
    相关资源
    最近更新 更多