Пустой сценарий 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
цикл и заставить их выполняться намного быстрее.