基于 Powershell 的 WMI 命令替换
Powershell based replacement for WMI commands
我有一个旧脚本,它是我第一次开始使用 Powershell 时写的第一批脚本之一。它使用 Get-CimInstance -ClassName Win32_ComputerSystem
和 Get-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 有关。
我有一个旧脚本,它是我第一次开始使用 Powershell 时写的第一批脚本之一。它使用 Get-CimInstance -ClassName Win32_ComputerSystem
和 Get-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 有关。