Пустой сценарий Powershell для второй функции

Я пишу большой скрипт, который сканирует информацию WMI с компьютеров в AD. У меня есть функции для diskinfo, raminfo и videocardinfo, где диск и видеокарта имеют схожие стили вывода. Проблема в том, что в зависимости от порядка, в котором их запускает сценарий, вывод одного из них будет пустым. Вот две функции:

function Get-DiskInfo {

$disk = Get-WMIObject Win32_Logicaldisk -ComputerName $computer |
        Select  @{Name="Computer";Expression={$computer}}, DeviceID,
        @{Name="SizeGB";Expression={$_.Size/1GB -as [int]}},
        @{Name="FreeGB";Expression={[math]::Round($_.Freespace/1GB,2)}}
        Write-Host $Computer
        $disk

}

а также:

function Get-VRamInfo {

$vram = Get-WmiObject win32_videocontroller -ComputerName $computer | 
        Select @{Name="Computer";Expression={$computer}},
        @{Name="VideoRAM";Expression={$_.adapterram / 1MB}},
        Name
        Write-Host $computer
        $vram

}

Один получит предназначенный вывод, но тот, который запускается позже в сценарии, выведет только имена компьютеров, но не информацию

вот полный сценарий: https://gist.github.com/ErkkaKorpi/f1b10a62ac79763fa38082b6c25e8f1b

В чем может быть проблема?

2 ответа

Решение

По некоторым неясным причинам, Write-Output Командлет запоминает свойства пользовательского объекта из его первого / предыдущего использования для любого следующего использования, даже примененного к другому (определенному по-другому) пользовательскому объекту. К сожалению, я не знаю, как сбросить запомненные свойства.

Существует обходной путь: использование Format-Table следующее. (Обратите внимание, что я добавил SizeGB отметить свойство в Get-VRamInfo для лучшего понимания.)

Function Get-DiskInfo {
$disk = Get-WMIObject Win32_Logicaldisk -ComputerName $computer |
            Select-Object  @{Name="Computer";Expression={$computer}}, 
                DeviceID,
                @{Name="SizeGB";Expression={$_.Size/1GB -as [int]}},
                @{Name="FreeGB";Expression={[math]::Round($_.Freespace/1GB,2)}}
        #Write-Host $Computer -ForegroundColor Magenta
        $disk
}

Function Get-VRamInfo {
$vram = Get-WmiObject win32_videocontroller -ComputerName $computer | 
            Select-Object @{Name="Computer";Expression={$computer}},
                @{Name="VideoRAM";Expression={$_.adapterram / 1MB -as [int]}},
                @{Name="SizeGB";Expression={$_.adapterram/1GB -as [int]}},
                Name
        #Write-Host $computer -ForegroundColor Cyan
        $vram
}

$computer = '.'
"`nshrunk output #1"
Get-VRamInfo
Get-DiskInfo
"`nfull output"
Get-VRamInfo | Format-Table
Get-DiskInfo | Format-Table
"`nshrunk output #2"
Get-DiskInfo
Get-VRamInfo

Выход:

PS D:\PShell> D:\PShell\SF\884809.ps1

shrunk output #1

Computer VideoRAM SizeGB Name                 
-------- -------- ------ ----                 
.            2048      2 NVIDIA GeForce GT 740
.                    111                      
.                    932                      
.                      0                      

full output

Computer VideoRAM SizeGB Name                 
-------- -------- ------ ----                 
.            2048      2 NVIDIA GeForce GT 740


Computer DeviceID SizeGB FreeGB
-------- -------- ------ ------
.        C:          111  58.06
.        D:          932 856.47
.        E:            0      0

shrunk output #2

Computer DeviceID SizeGB FreeGB
-------- -------- ------ ------
.        C:          111  58.06
.        D:          932 856.47
.        E:            0      0
.                      2       

Write-Output Командлет обычно используется в сценариях для отображения строк и других объектов на консоли. Однако из-за поведения по умолчанию отображение объектов в конце конвейера обычно не требует использования командлета.
Например, Get-Process | Write-Output эквивалентно Get-Process,

Глядя на свои сценарии, вы не определяете $computer, поэтому он должен сразу выдавать ошибку для любой из этих функций. После определения я могу подтвердить, что вторая функция прекрасно возвращает адаптеры при использовании в Windows 10 1703:

Как видно из вывода, $vram уже содержит ваше имя компьютера, так что вы можете пропустить Write-Host $Computer часть.

Как я вижу, вы, похоже, одновременно осматриваете множество машин, поэтому имеет смысл взглянуть на рабочие процессы PowerShell, которые позволяют выполнять задачи параллельно, поэтому вы можете использовать свои функции в ForEach -Parallel цикл и заставить их выполняться намного быстрее.

Другие вопросы по тегам