Войти

Показать полную графическую версию : [решено] извлечь данные о мониторах из реестра


Страниц : [1] 2 3

Griboed0ff
17-04-2020, 12:07
Доброго всем времени суток! Есть задача получить данные о мониторах в винде, а именно модель и серийный номер. Данные хранятся в реестре ("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY") в бинарном виде. Есть батник DispEDID, который умеет считывать и переводить в читабельный вид модель и серийник. Проблема в том, что данный батник выдает данные только 1 монитора, а если их 2 или 3 то, покажет данные последнего. Мозгов переписать такой сложный батник не хватает. Подумал может эту задачу проще решить через ps, по идее надо просто снять данные, конвертировать на человеческий, отправить в .cvs

Iska
17-04-2020, 12:44
Griboed0ff, обратите внимание ещё на:
wmic.exe DesktopMonitor get /value

Griboed0ff
17-04-2020, 13:06
Iska, данная команда не дает нужных данных. Они хранятся в бинарном виде и просто одной командой их не получить. Иначе зачем городили большой батник, если все было так просто.

Vadikan
17-04-2020, 13:09
Почитайте дискуссию в чате инсайдеров https://telega.at/winsiders/492449

Iska
17-04-2020, 13:33
Griboed0ff, а у меня даёт бо́́льшую часть:
C:\Мои проекты\0310>wmic.exe DesktopMonitor get /value


Availability=3
Bandwidth=
Caption=Philips 243V5 (23.6inch Wide LCD MONITOR 243V5)
ConfigManagerErrorCode=0
ConfigManagerUserConfig=FALSE
CreationClassName=Win32_DesktopMonitor
Description=Philips 243V5 (23.6inch Wide LCD MONITOR 243V5)
DeviceID=DesktopMonitor1
DisplayType=
ErrorCleared=
ErrorDescription=
InstallDate=
IsLocked=
LastErrorCode=
MonitorManufacturer=Philips Electronics
MonitorType=Philips 243V5 (23.6inch Wide LCD MONITOR 243V5)
Name=Philips 243V5 (23.6inch Wide LCD MONITOR 243V5)
PixelsPerXLogicalInch=96
PixelsPerYLogicalInch=96
PNPDeviceID=DISPLAY\PHLC0D1\4&2ED0BDF8&0&UID16843008
PowerManagementCapabilities=
PowerManagementSupported=
ScreenHeight=1080
ScreenWidth=1920
Status=OK
StatusInfo=
SystemCreationClassName=Win32_ComputerSystem
SystemName=XXX
Серийного номера в выдаче нет.

Griboed0ff
17-04-2020, 13:50
нашел в дискуссии инсайдеров скрипты для ps
Function Get-MonitorInfo
{
[CmdletBinding()]
Param
(
[Parameter(
Position=0,
ValueFromPipeLine=$true,
ValueFromPipeLineByPropertyName=$true)]
[string]$name = '.'
)

Process
{

$ActiveMonitors = Get-WmiObject -Namespace root\wmi -Class wmiMonitorID -ComputerName $name
$monitorInfo = @()

foreach ($monitor in $ActiveMonitors)
{
$mon = New-Object PSObject
$manufacturer = $null
$product = $null
$serial = $null
$name = $null
$week = $null
$year = $null

$monitor.ManufacturerName | foreach {$manufacturer += [char]$_}
$monitor.ProductCodeID | foreach {$product += [char]$_}
$monitor.SerialNumberID | foreach {$serial += [char]$_}
$monitor.UserFriendlyName | foreach {$name += [char]$_}

$mon | Add-Member NoteProperty Manufacturer $manufacturer
$mon | Add-Member NoteProperty ProductCode $product
$mon | Add-Member NoteProperty SerialNumber $serial
$mon | Add-Member NoteProperty Name $name
$mon | Add-Member NoteProperty Week $monitor.WeekOfManufacture
$mon | Add-Member NoteProperty Year $monitor.YearOfManufacture

$monitorInfo += $mon
}
$monitorInfo |
}
}

Function Get-MonitorInfo
{
[CmdletBinding()]
Param
(
[Parameter(
Position=0,
ValueFromPipeLine=$true,
ValueFromPipeLineByPropertyName=$true)]
[alias("CN","MachineName","Name","Computer")]
[string[]]$ComputerName = $ENV:ComputerName
)

Begin {
$pipelineInput = -not $PSBoundParameters.ContainsKey('ComputerName')
}

Process
{
Function DoWork([string]$ComputerName) {
$ActiveMonitors = Get-WmiObject -Namespace root\wmi -Class wmiMonitorID -ComputerName $ComputerName
$monitorInfo = @()

foreach ($monitor in $ActiveMonitors)
{
$mon = $null

$mon = New-Object PSObject -Property @{
ManufacturerName=($monitor.ManufacturerName | % {[char]$_}) -join ''
ProductCodeID=($monitor.ProductCodeID | % {[char]$_}) -join ''
SerialNumberID=($monitor.SerialNumberID | % {[char]$_}) -join ''
UserFriendlyName=($monitor.UserFriendlyName | % {[char]$_}) -join ''
ComputerName=$ComputerName
WeekOfManufacture=$monitor.WeekOfManufacture
YearOfManufacture=$monitor.YearOfManufacture}

$monitorInfo += $mon
}
Write-Output $monitorInfo
}

if ($pipelineInput) {
DoWork($ComputerName)
} else {
foreach ($item in $ComputerName) {
DoWork($item)
}
}
}
}
Оба обрабатывают без ошибок, но и результат не выводят. просто запустил и ничего не происходит.

Vadikan
17-04-2020, 14:49
Нашел скрипты по ссылке, но ссылку не дал https://www.hofferle.com/retrieve-monitor-serial-numbers-with-powershell/

А так, все работает же, прямо из дискуссии копирую
$m = gwmi wmimonitorid -Namespace root\wmi
[string][char[]] ($m.UserFriendlyName) -join ""
[string][char[]] ($m.SerialNumberID) -join ""

Upd. Убрать [string] чтобы не было лишних пробелов:
$m = gwmi wmimonitorid -Namespace root\wmi
[char[]] ($m.UserFriendlyName) -join ""
[char[]] ($m.SerialNumberID) -join ""

Griboed0ff
17-04-2020, 15:42
А так, все работает же, прямо из дискуссии копирую »
Я видимо глазом в беседе за код не зацепился. Действительно работает команда. Спасибо!
Еще небольшой вопросик есть: как направить вывод в .csv, в виде таблицы как на картинке.

Iska
17-04-2020, 16:59
А у меня в среде ISE:
[string][char[]] ($m.UserFriendlyName) -join ""
приводит к лишним пробелам. Без приведения к [string] — отображение нормальное:
PS C:\> $m = gwmi wmimonitorid -Namespace root\wmi
[string][char[]] ($m.UserFriendlyName) -join ""
[string][char[]] ($m.SerialNumberID) -join ""
''
[char[]] ($m.UserFriendlyName) -join ""
[char[]] ($m.SerialNumberID) -join ""
P H L 2 4 3 V 5
Z V 0 1 4 4 3 0 1 3 5 6 3

PHL 243V5
ZV01443013563

PS C:\>

Vadikan
17-04-2020, 17:57
Iska, согласен, но я просто брал код из чата.

как направить вывод в .csv, в виде таблицы как на картинке. »
CSV это не таблица, а текст. С такими таблицами как на картинке можно мозг сломать, будьте проще...

YuS_2
17-04-2020, 19:31
можно мозг сломать »
или глаза, как минимум :)

как направить вывод в .csv, в виде таблицы как на картинке. »
Вывод в csv, просто. А про таблицы уже сказали.
Лучше так выводить:
gcim wmimonitorid -name root\wmi|%{$n=1}{
[pscustomobject]@{
'Монитор' = $n
'Модель'= -join [char[]]$_.UserFriendlyName
'Серийный номер' = -join [char[]]$_.SerialNumberID
}
$n++
}|export-csv out.csv -notype -enc utf8 -d ';'

Griboed0ff
18-04-2020, 08:20
приводит к лишним пробелам. Без приведения к [string] — отображение нормальное: »
в переписке такое решение: $ofs="";[string][char[]] ($m.UserFriendlyName) -join ""
$ofs="";[string][char[]] ($m.SerialNumberID) -join ""
тоже без пробелов получается.

Лучше так выводить: »
Спасибо! Мне как раз нужно было просто понятное представление.

что-то мне подсказывает, что сюда же можно сделать выведение информации о мак адресе\ах, которые есть на этом пк. Или лучше отдельную тему завести?

Iska
18-04-2020, 08:39
Или лучше отдельную тему завести? »
Или.

YuS_2
18-04-2020, 08:48
$ofs="" »
автоматическая переменная, имеющая значение по умолчанию:
$OFS
$OFS is a special variable that stores a string that you want to use as an output field separator. Use this variable when you are converting an array to a string. By default, the value of $OFS is " ", but you can change the value of $OFS in your session, by typing $OFS="<value>". If you are expecting the default value of " " in your script, module, or configuration output, be careful that the $OFS default value has not been changed elsewhere in your code.
Examples:
PS> $a="1","2","3","4"
PS> $a
1
2
3
4

PS> [string]$a
1 2 3 4
PS> $OFS="";[string]$a
1234

PS> $OFS=",";[string]$a
1,2,3,4

PS> $OFS="--PowerShellRocks--";[string]$a
1--PowerShellRocks--2--PowerShellRocks--3--PowerShellRocks--4
PS> $OFS="`n`n";[string]$a
1

2

3

4

Iska
18-04-2020, 11:51
YuS_2, с какой версии она появилась?

Busla
18-04-2020, 12:06
в переписке такое решение:
$ofs="";[string][char[]] ($m.UserFriendlyName) -join "" »
очередные заклинатели компьютеров писали
либо $ofs="";[string]
либо -join ""

И в мультимониторной конфигурации оно выдаст кашу в ответ

Лучше получать данные так:

$ofs = ''
gwmi wmimonitorid -Namespace root\wmi | Select @{n='UserFriendlyName';e={([string][Char[]]$_.UserFriendlyName).SubString(0,$_.UserFriendlyNameLength)}}, @{n='SerialNumberID';e={[string][Char[]]$_.SerialNumberID}}


Как показывает практика, SerialNumberID не всегда то, что написано на наклейке, и может выдавать разное на разных разъёмах одного и того же монитора.
У встроенных мониторов (ноутбуки, моноблоки) нет ни модели, ни серийного номера.

YuS_2
18-04-2020, 16:33
с какой версии она появилась? »
с версии 2.0 она точно есть... правда там описание своеобразное:
$OFS
----
Output Field Separator. Задает знак, разделяющий элементы
массива при преобразовании массива в строку.

Допустимые значения: любая строка.
Значение по умолчанию: пробел

По умолчанию переменная $OFS не существует и знаком-разделител
ем для выходных файлов является пробел, но пользователь может
добавить эту переменную и присвоить ей в качестве значения
любую строку.

ПРИМЕРЫ

Этот пример показывает, что при преобразовании массива в строку
для разделения значений используется пробел. В данном случае
массив целых чисел сохраняется в переменной, а затем переменная
приводится к типу string.

PS> $array = 1,2,3 # Сохраняется массив целых чисел.

PS> [string]$array # Массив приводится к типу string.
1 2 3 # Элементы разделяются пробелами


Чтобы изменить разделитель, добавьте переменную $OFS, назначив ей
значение. Для корректной работы переменная должна называться $OFS.

PS> $OFS = "+" # Создается переменная $OFS, ей присваивается значение "+"

PS> [string]$array # Команда повторяется
1+2+3 # Элементы разделяются знаками плюс


Чтобы восстановить поведение по умолчанию, можно присвоить пробел
(" ") в качестве значения переменной $OFS или удалить переменную.
Следующая команда удаляет переменную, затем выполняется проверка,
что разделителем является пробел.

PS> Remove-Variable OFS # Удаление переменной $OFS
PS>

PS> [string]$array # Команда повторяется
1 2 3 # Элементы разделяются пробелами

Iska
18-04-2020, 17:58
YuS_2, спасибо, ясно. Значит, я как обычно «прощёлкал».

Нет, PowerShell точно повёрнутый на всю голову язык.

Griboed0ff
19-04-2020, 09:51
И в мультимониторной конфигурации оно выдаст кашу в ответ
Лучше получать данные так: »
Код предложенный ранее и ваш выдают одинаковые значения на пк где 2 монитора.

Griboed0ff
19-04-2020, 09:57
Как показывает практика, SerialNumberID не всегда то, что написано на наклейке, и может выдавать разное на разных разъёмах одного и того же монитора.
У встроенных мониторов (ноутбуки, моноблоки) нет ни модели, ни серийного номера. »
как проводить инвентаризацию непонятно, но просматривать наклейки, а где-то их вообще и нет, не вариант.




© OSzone.net 2001-2012