【问题标题】:Single connection for multiple Get-WmiObject calls多个 Get-WmiObject 调用的单一连接
【发布时间】:2018-10-26 19:50:03
【问题描述】:

下面的脚本成功获取了我在hostnames.txt中提供的每台电脑的制造商、型号、序列号和操作系统。但是,它很慢,因为它必须连接到每台计算机上的 WMI 三次。

$OS = Get-WmiObject Win32_OperatingSystem -ComputerName $Computer
$CS = Get-WmiObject Win32_ComputerSystem -ComputerName $Computer
$BIOS = Get-WmiObject Win32_Bios -ComputerName $Computer

如何使用 PowerShell 连接到远程计算机的 WMI 一次并使用同一连接执行三个查询?

$Array = @() ## Create Array to hold the Data
$Computers = Get-Content -Path .\hostnames.txt

foreach ($Computer in $Computers)
{

    $Result = "" | Select HostPS,Mfg,Model,Serial,OS

    $Result.HostPS = $Computer
    $ErrorActionPreference = "SilentlyContinue" ## Don't output errors for offline computers
    $OS = Get-WmiObject Win32_OperatingSystem -ComputerName $Computer

    $CS = Get-WmiObject Win32_ComputerSystem -ComputerName $Computer

    $BIOS = Get-WmiObject Win32_Bios -ComputerName $Computer
    $ErrorActionPreference = "Continue"

    $Result.Mfg = $CS.Manufacturer
    $Result.Model = $CS.Model
    $Result.Serial = $BIOS.SerialNumber
    $Result.OS = $OS.Caption

    $Array += $Result ## Add the data to the array
}

$Array | Export-Csv file.csv -NoTypeInformation

【问题讨论】:

  • 我不会回答您的具体问题,但如果您只在使用Get-WMIObject 时选择您需要的内容,它应该会有所帮助。例如,$OS = Get-WmiObject Win32_OperatingSystem -ComputerName $Computer | Select-Object Caption

标签: powershell wmi get-wmiobject


【解决方案1】:

您可以使用 CIM(它有一个会话选项),more on CIM vs WMI(“WMI 是 Windows 平台的 CIM 的 Microsoft 实现”)

$CIMSession = New-CimSession -ComputerName $RemoteComputer

Get-CimInstance win32_OperatingSystem -CimSession $CIMSession -Property Caption
Get-CimInstance Win32_ComputerSystem -CimSession $CIMSession -Property Manufacturer,Model
Get-CimInstance Win32_Bios -CimSession $CIMSession -Property SerialNumber

【讨论】:

    【解决方案2】:

    对我来说,通常的做法是使用Invoke-Command 在每个目标系统上运行一个脚本块。如果您告诉它忽略错误,它将并行运行 [在目标系统上] 并从响应者返回您的数据。要获得无响应者,请将输入列表与结果进行比较。 [咧嘴一笑]

    这是一个想法的演示......

    #requires -RunAsAdministrator
    
    # fake reading in a list of computer names
    #    in real life, use Get-Content or (Get-ADComputer).Name
    $ComputerList = @'
    Localhost
    BetterNotBeThere
    127.0.0.1
    10.0.0.1
    ::1
    '@.Split("`n").Trim("`r")
    
    $IC_ScriptBlock = {
        $CIM_ComputerSystem = Get-CimInstance -ClassName CIM_ComputerSystem
        $CIM_BIOSElement = Get-CimInstance -ClassName CIM_BIOSElement
        $CIM_OperatingSystem = Get-CimInstance -ClassName CIM_OperatingSystem
        $CIM_Processor = Get-CimInstance -ClassName CIM_Processor
        $CIM_LogicalDisk = Get-CimInstance -ClassName CIM_LogicalDisk |
            Where-Object {$_.Name -eq $CIM_OperatingSystem.SystemDrive}
    
        [PSCustomObject]@{
            LocalComputerName = $env:COMPUTERNAME
            Manufacturer = $CIM_ComputerSystem.Manufacturer
            Model = $CIM_ComputerSystem.Model
            SerialNumber = $CIM_BIOSElement.SerialNumber
            CPU = $CIM_Processor.Name
            RAM_GB = '{0:N2}' -f ($CIM_ComputerSystem.TotalPhysicalMemory / 1GB)
            SysDrive_Capacity_GB = '{0:N2}' -f ($CIM_LogicalDisk.Size / 1GB)
            SysDrive_FreeSpace_GB ='{0:N2}' -f ($CIM_LogicalDisk.FreeSpace / 1GB)
            SysDrive_FreeSpace_Pct = '{0:N0}' -f ($CIM_LogicalDisk.FreeSpace / $CIM_LogicalDisk.Size * 100)
            OperatingSystem_Name = $CIM_OperatingSystem.Caption
            OperatingSystem_Version = $CIM_OperatingSystem.Version
            OperatingSystem_BuildNumber = $CIM_OperatingSystem.BuildNumber
            OperatingSystem_ServicePack = $CIM_OperatingSystem.ServicePackMajorVersion
            CurrentUser = $CIM_ComputerSystem.UserName
            LastBootUpTime = $CIM_OperatingSystem.LastBootUpTime
            UpTime_Days = '{0:N2}' -f ([datetime]::Now - $CIM_OperatingSystem.LastBootUpTime).Days
            }
    
        }
    
    $IC_Params = @{
        ComputerName = $ComputerList
        ScriptBlock = $IC_ScriptBlock
        ErrorAction = 'SilentlyContinue'
        }
    $RespondingSystems = Invoke-Command @IC_Params
    $NOT_RespondingSystems = $ComputerList.Where({
        # these two variants are needed to deal with an ipv6 localhost address
        "[$_]" -notin $RespondingSystems.PSComputerName -and
        $_ -notin $RespondingSystems.PSComputerName
        })
    
    $RespondingSystems
    $NOT_RespondingSystems
    

    $RespondingSystems 列表中的一项...

    LocalComputerName           : [MySystemName]
    Manufacturer                : System manufacturer
    Model                       : System Product Name
    SerialNumber                : System Serial Number
    CPU                         : AMD Phenom(tm) II X4 945 Processor
    RAM_GB                      : 8.00
    SysDrive_Capacity_GB        : 931.41
    SysDrive_FreeSpace_GB       : 735.15
    SysDrive_FreeSpace_Pct      : 79
    OperatingSystem_Name        : Microsoft Windows 7 Professional 
    OperatingSystem_Version     : 6.1.7601
    OperatingSystem_BuildNumber : 7601
    OperatingSystem_ServicePack : 1
    CurrentUser                 : [MySystemName]\[MyUserName]
    LastBootUpTime              : 2018-10-19 7:01:51 PM
    UpTime_Days                 : 7.00
    PSComputerName              : [::1]
    RunspaceId                  : e17c2741-ba8b-4fbb-b3db-9c7fd0d84f0d
    

    $NOT_RespondingSystems 列表...

    BetterNotBeThere
    10.0.0.1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-29
      • 1970-01-01
      • 1970-01-01
      • 2021-08-22
      • 1970-01-01
      • 2021-07-02
      • 2023-04-08
      相关资源
      最近更新 更多