基于 Powershell 的 WMI 命令替换

Powershell based replacement for WMI commands

我有一个旧脚本,它是我第一次开始使用 Powershell 时写的第一批脚本之一。它使用 Get-CimInstance -ClassName Win32_ComputerSystemGet-CimInstance -ClassName Win32_OperatingSystem。将其除尘以便在某些用户系统上使用然后发现某些用户对 WMI 有某种奇怪的权限问题并且无法使用该脚本。就个人而言,我从来没有遇到过问题,也从没想过其他人会。

所以我希望摆脱 WMI/CIM 实例,并用 .NET 命令或其他用于 PowerShell 脚本的命令替换它们。除了 WMI/CIM 实例之外,脚本中还有其他用途吗?请参阅下面的脚本我要更改

$Comp = (Get-CimInstance -ClassName Win32_ComputerSystem); 
$DRole =   ($Comp).DomainRole;
switch ($DRole)
{
    0 {$DominRole = 'Standalone Workstation'}
    1 {$DominRole = 'Member Workstation'}
    2 {$DominRole = 'Standalone Server'}
    3 {$DominRole = 'Member Server'}
    4 {$DominRole = 'Backup Domain Controller'}
    5 {$DominRole = 'Primary Domain Controller'}
}
$PhyMem = [string][math]::Round(($Comp).TotalPhysicalMemory/1GB, 1);
$FreePhyMem = [string][math]::Round((Get-CimInstance -ClassName Win32_OperatingSystem).FreePhysicalMemory/1024/1024, 1);
$cpux = (Get-WmiObject Win32_Processor).Name;
$GBMem = $PhyMem + ' GB Physical Memory (' + $FreePhyMem + ' GB Free)';
Return $DominRole + ' - ' + $GBMem + '/' + $cpux

如果您使用的至少是 PowerShell 5.1,Get-ComputerInfo 会提供大量此类信息。可以看到它提供的相关属性...

PS> Get-ComputerInfo -Property 'CsDomainRole', '*Memory*', '*Processor*'

否则,您可以使用 System.Management namespace 中的 类 以与 Get-WmiObject 基本相同的方式直接查询 WMI...

$selectedProperties = 'DomainRole', 'TotalPhysicalMemory'
# https://docs.microsoft.com/dotnet/api/system.management.selectquery
$query = New-Object -TypeName 'System.Management.SelectQuery' `
    -ArgumentList ('Win32_ComputerSystem', $null, $selectedProperties)
# https://docs.microsoft.com/dotnet/api/system.management.managementobjectsearcher
$searcher = New-Object -TypeName 'System.Management.ManagementObjectSearcher' `
    -ArgumentList $query

try
{
    # https://docs.microsoft.com/dotnet/api/system.management.managementobjectsearcher.get
    $results = $searcher.Get()
    # ManagementObjectCollection exposes an enumerator but not an indexer
    $computerSystem = $results | Select-Object -First 1

    $domainRole = $computerSystem['DomainRole']
    $totalPhysicalMemory = $computerSystem['TotalPhysicalMemory']

    # Do something with $domainRole and $totalPhysicalMemory...
    $domainRoleText = switch ($domainRole) {
        0 { 'Standalone Workstation'   ; break }
        1 { 'Member Workstation'       ; break }
        2 { 'Standalone Server'        ; break }
        3 { 'Member Server'            ; break }
        4 { 'Backup Domain Controller' ; break }
        5 { 'Primary Domain Controller'; break }
        default { $domainRole.ToString() }
    }
    $totalPhysicalMemoryGB = [Math]::Round($totalPhysicalMemory / 1GB, 1)
}
finally
{
    $computerSystem.Dispose()
    $results.Dispose()
    $searcher.Dispose()
}

虽然没有更多详细信息,但很难知道您的问题是与 WMI 本身有关还是与访问它的 cmdlet 有关。